// Interpolate uint64/pixel images. func interpolate1x64(src *image.NRGBA64, dstW, dstH int) image.Image { srcRect := src.Bounds() srcW := srcRect.Dx() srcH := srcRect.Dy() ww, hh := uint64(dstW), uint64(dstH) dx, dy := uint64(srcW), uint64(srcH) n, sum := dx*dy, make([]uint64, dstW*dstH) for y := 0; y < srcH; y++ { pixOffset := src.PixOffset(0, y) for x := 0; x < srcW; x++ { // Get the source pixel. val64 := binary.BigEndian.Uint64([]byte(src.Pix[pixOffset+0 : pixOffset+8])) pixOffset += 8 // Spread the source pixel over 1 or more destination rows. py := uint64(y) * hh for remy := hh; remy > 0; { qy := dy - (py % dy) if qy > remy { qy = remy } // Spread the source pixel over 1 or more destination columns. px := uint64(x) * ww index := (py/dy)*ww + (px / dx) for remx := ww; remx > 0; { qx := dx - (px % dx) if qx > remx { qx = remx } qxy := qx * qy sum[index] += val64 * qxy index++ px += qx remx -= qx } py += qy remy -= qy } } } dst := image.NewNRGBA64(image.Rect(0, 0, dstW, dstH)) index := 0 for y := 0; y < dstH; y++ { pixOffset := dst.PixOffset(0, y) for x := 0; x < dstW; x++ { binary.BigEndian.PutUint64(dst.Pix[pixOffset+0:pixOffset+8], sum[index]/n) pixOffset += 8 index++ } } return dst }
func newSetFuncNRGBA64(p *image.NRGBA64) SetFunc { return func(x, y int, r, g, b, a uint32) { r, g, b, a = RGBAToNRGBA(r, g, b, a) i := p.PixOffset(x, y) p.Pix[i+0] = uint8(r >> 8) p.Pix[i+1] = uint8(r) p.Pix[i+2] = uint8(g >> 8) p.Pix[i+3] = uint8(g) p.Pix[i+4] = uint8(b >> 8) p.Pix[i+5] = uint8(b) p.Pix[i+6] = uint8(a >> 8) p.Pix[i+7] = uint8(a) } }
func convertNRGBA64(dest *Image, src *image.NRGBA64) { var x, y, i, si int var a uint16 for x = dest.Rect.Min.X; x < dest.Rect.Max.X; x++ { for y = dest.Rect.Min.Y; y < dest.Rect.Max.Y; y++ { si = src.PixOffset(x, y) i = dest.PixOffset(x, y) a = uint16(src.Pix[si+6]) dest.Pix[i+0] = uint8((uint16(src.Pix[si+4]) * a) / 0xff) dest.Pix[i+1] = uint8((uint16(src.Pix[si+2]) * a) / 0xff) dest.Pix[i+2] = uint8((uint16(src.Pix[si+0]) * a) / 0xff) dest.Pix[i+3] = src.Pix[si+6] } } }
func fetchLineNRGBA64(flipXY bool, column []f32RGBA, x int, src *image.NRGBA64) { dy := src.Bounds().Min.Y dx := src.Bounds().Min.X pix := src.Pix var idx int for y := 0; y != len(column); y++ { if flipXY { idx = src.PixOffset(y+dx, x+dy) } else { idx = src.PixOffset(x+dx, y+dy) } column[y].R = uint16_to_f32 * float32(uint16(pix[idx+0])<<8|uint16(pix[idx+1])) column[y].G = uint16_to_f32 * float32(uint16(pix[idx+2])<<8|uint16(pix[idx+3])) column[y].B = uint16_to_f32 * float32(uint16(pix[idx+4])<<8|uint16(pix[idx+5])) column[y].A = uint16_to_f32 * float32(uint16(pix[idx+6])<<8|uint16(pix[idx+7])) } }
func newAtFuncNRGBA64(p *image.NRGBA64) AtFunc { return func(x, y int) (r, g, b, a uint32) { i := p.PixOffset(x, y) a = uint32(p.Pix[i+6])<<8 | uint32(p.Pix[i+7]) if a == 0 { return } r = uint32(p.Pix[i+0])<<8 | uint32(p.Pix[i+1]) g = uint32(p.Pix[i+2])<<8 | uint32(p.Pix[i+3]) b = uint32(p.Pix[i+4])<<8 | uint32(p.Pix[i+5]) if a == 0xffff { return } r = r * a / 0xffff g = g * a / 0xffff b = b * a / 0xffff return } }
// Interpolate 4 interleaved uint16 per pixel images. func interpolate4x16(src *image.NRGBA64, dstW, dstH int) image.Image { srcRect := src.Bounds() srcW := srcRect.Dx() srcH := srcRect.Dy() ww, hh := uint64(dstW), uint64(dstH) dx, dy := uint64(srcW), uint64(srcH) n, sum := dx*dy, make([]uint64, 4*dstW*dstH) for y := 0; y < srcH; y++ { pixOffset := src.PixOffset(0, y) for x := 0; x < srcW; x++ { // Get the source pixel. r64 := uint64(binary.BigEndian.Uint16([]byte(src.Pix[pixOffset+0 : pixOffset+2]))) g64 := uint64(binary.BigEndian.Uint16([]byte(src.Pix[pixOffset+2 : pixOffset+4]))) b64 := uint64(binary.BigEndian.Uint16([]byte(src.Pix[pixOffset+4 : pixOffset+6]))) a64 := uint64(binary.BigEndian.Uint16([]byte(src.Pix[pixOffset+6 : pixOffset+8]))) pixOffset += 8 // Spread the source pixel over 1 or more destination rows. py := uint64(y) * hh for remy := hh; remy > 0; { qy := dy - (py % dy) if qy > remy { qy = remy } // Spread the source pixel over 1 or more destination columns. px := uint64(x) * ww index := 4 * ((py/dy)*ww + (px / dx)) for remx := ww; remx > 0; { qx := dx - (px % dx) if qx > remx { qx = remx } qxy := qx * qy sum[index+0] += r64 * qxy sum[index+1] += g64 * qxy sum[index+2] += b64 * qxy sum[index+3] += a64 * qxy index += 4 px += qx remx -= qx } py += qy remy -= qy } } } dst := image.NewNRGBA64(image.Rect(0, 0, dstW, dstH)) for y := 0; y < dstH; y++ { pixOffset := dst.PixOffset(0, y) index := 4 * y * dstW for x := 0; x < dstW; x++ { binary.BigEndian.PutUint16(dst.Pix[pixOffset+0:pixOffset+2], uint16(sum[index+0]/n)) binary.BigEndian.PutUint16(dst.Pix[pixOffset+2:pixOffset+4], uint16(sum[index+1]/n)) binary.BigEndian.PutUint16(dst.Pix[pixOffset+4:pixOffset+6], uint16(sum[index+2]/n)) binary.BigEndian.PutUint16(dst.Pix[pixOffset+6:pixOffset+8], uint16(sum[index+3]/n)) pixOffset += 8 index += 4 } } return dst }