mirror of
				https://bitbucket.org/s_l_teichmann/mtsatellite
				synced 2025-11-04 01:55:25 +01:00 
			
		
		
		
	mtwebmapper: Added fast path for rendering RGBA sub base level tiles. Up to 5-10x faster.
This commit is contained in:
		@@ -7,7 +7,6 @@ package main
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"image"
 | 
			
		||||
	"image/color"
 | 
			
		||||
	"image/png"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
@@ -105,7 +104,56 @@ func (sb *subBaseLine) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
 | 
			
		||||
 | 
			
		||||
func blowUp(src image.Image) *image.RGBA {
 | 
			
		||||
 | 
			
		||||
	// TODO: Fast path for image.RGBA
 | 
			
		||||
	// Fast path for RGBA -> RGBA
 | 
			
		||||
	if rgba, ok := src.(*image.RGBA); ok {
 | 
			
		||||
		return blowUpRGBA(rgba)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Fallback
 | 
			
		||||
	dst := image.NewRGBA(image.Rect(0, 0, 256, 256))
 | 
			
		||||
 | 
			
		||||
	// fix point numbers x:8
 | 
			
		||||
	dx, dy := src.Bounds().Dx(), src.Bounds().Dy()
 | 
			
		||||
 | 
			
		||||
	bx, by := src.Bounds().Min.X<<8, src.Bounds().Min.Y<<8
 | 
			
		||||
 | 
			
		||||
	//start := time.Now()
 | 
			
		||||
 | 
			
		||||
	pix := dst.Pix
 | 
			
		||||
 | 
			
		||||
	lineOfs := dst.PixOffset(0, 0) // Should be 0.
 | 
			
		||||
 | 
			
		||||
	py := by
 | 
			
		||||
	var r, g, b, a uint8
 | 
			
		||||
	for y := 0; y < 256; y++ {
 | 
			
		||||
		sy := (py >> 8) & 0xff
 | 
			
		||||
		ox := -1
 | 
			
		||||
		px := bx
 | 
			
		||||
		ofs := lineOfs // Should not really b needed
 | 
			
		||||
		lineOfs += dst.Stride
 | 
			
		||||
		for x := 0; x < 256; x++ {
 | 
			
		||||
			sx := (px >> 8) & 0xff
 | 
			
		||||
			if sx != ox { // Minimize interface indirection access.
 | 
			
		||||
				ox = sx
 | 
			
		||||
				xr, xg, xb, xa := src.At(sx, sy).RGBA()
 | 
			
		||||
				r, g, b, a = uint8(xr), uint8(xg), uint8(xb), uint8(xa)
 | 
			
		||||
			}
 | 
			
		||||
			pix[ofs] = r
 | 
			
		||||
			pix[ofs+1] = g
 | 
			
		||||
			pix[ofs+2] = b
 | 
			
		||||
			pix[ofs+3] = a
 | 
			
		||||
			ofs += 4
 | 
			
		||||
			px += dx
 | 
			
		||||
		}
 | 
			
		||||
		py += dy
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//log.Printf("Rendering took: %s", time.Since(start))
 | 
			
		||||
 | 
			
		||||
	return dst
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func blowUpRGBA(src *image.RGBA) *image.RGBA {
 | 
			
		||||
 | 
			
		||||
	dst := image.NewRGBA(image.Rect(0, 0, 256, 256))
 | 
			
		||||
 | 
			
		||||
@@ -114,24 +162,31 @@ func blowUp(src image.Image) *image.RGBA {
 | 
			
		||||
 | 
			
		||||
	bx, by := src.Bounds().Min.X<<8, src.Bounds().Min.Y<<8
 | 
			
		||||
 | 
			
		||||
	//start := time.Now()
 | 
			
		||||
 | 
			
		||||
	sPix := src.Pix
 | 
			
		||||
	dPix := dst.Pix
 | 
			
		||||
 | 
			
		||||
	py := by
 | 
			
		||||
	for y := 0; y < 256; y++ {
 | 
			
		||||
	// Assuming memory layout is packed 256*256*4 with stride of 4*256.
 | 
			
		||||
	// for dLineOfs, dEnd := dst.PixOffset(0, 0), dst.PixOffset(0, 256); dLineOfs < dEnd; dLineOfs += dst.Stride {
 | 
			
		||||
	for ofs := 0; ofs < 256*256*4; {
 | 
			
		||||
		sy := (py >> 8) & 0xff
 | 
			
		||||
		ox := -1
 | 
			
		||||
		sLineOfs := src.PixOffset(0, sy)
 | 
			
		||||
		px := bx
 | 
			
		||||
		var col color.Color
 | 
			
		||||
		for x := 0; x < 256; x++ {
 | 
			
		||||
			sx := (px >> 8) & 0xff
 | 
			
		||||
			if sx != ox { // Minimize interface indirection access.
 | 
			
		||||
				ox = sx
 | 
			
		||||
				col = src.At(sx, sy)
 | 
			
		||||
			}
 | 
			
		||||
			dst.Set(x, y, col)
 | 
			
		||||
		// ofs := dLineOfs
 | 
			
		||||
		for end := ofs + 4*256; ofs < end; ofs += 4 {
 | 
			
		||||
			sOfs := sLineOfs + ((px >> 6) & 0x3fc)
 | 
			
		||||
			px += dx
 | 
			
		||||
			dPix[ofs] = sPix[sOfs]
 | 
			
		||||
			dPix[ofs+1] = sPix[sOfs+1]
 | 
			
		||||
			dPix[ofs+2] = sPix[sOfs+2]
 | 
			
		||||
			dPix[ofs+3] = sPix[sOfs+3]
 | 
			
		||||
		}
 | 
			
		||||
		py += dy
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//log.Printf("Rendering took: %s", time.Since(start))
 | 
			
		||||
	return dst
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user