mirror of
https://bitbucket.org/s_l_teichmann/mtsatellite
synced 2024-11-08 11:10:27 +01:00
mtwebmapper: Added fast path for rendering RGBA sub base level tiles. Up to 5-10x faster.
This commit is contained in:
parent
8c29975d27
commit
2709761255
|
@ -7,7 +7,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
|
||||||
"image/png"
|
"image/png"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -105,7 +104,56 @@ func (sb *subBaseLine) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
func blowUp(src image.Image) *image.RGBA {
|
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))
|
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
|
bx, by := src.Bounds().Min.X<<8, src.Bounds().Min.Y<<8
|
||||||
|
|
||||||
|
//start := time.Now()
|
||||||
|
|
||||||
|
sPix := src.Pix
|
||||||
|
dPix := dst.Pix
|
||||||
|
|
||||||
py := by
|
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
|
sy := (py >> 8) & 0xff
|
||||||
ox := -1
|
sLineOfs := src.PixOffset(0, sy)
|
||||||
px := bx
|
px := bx
|
||||||
var col color.Color
|
// ofs := dLineOfs
|
||||||
for x := 0; x < 256; x++ {
|
for end := ofs + 4*256; ofs < end; ofs += 4 {
|
||||||
sx := (px >> 8) & 0xff
|
sOfs := sLineOfs + ((px >> 6) & 0x3fc)
|
||||||
if sx != ox { // Minimize interface indirection access.
|
|
||||||
ox = sx
|
|
||||||
col = src.At(sx, sy)
|
|
||||||
}
|
|
||||||
dst.Set(x, y, col)
|
|
||||||
px += dx
|
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
|
py += dy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//log.Printf("Rendering took: %s", time.Since(start))
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user