func newAtFuncGray16(p *image.Gray16) AtFunc { return func(x, y int) (r, g, b, a uint32) { i := p.PixOffset(x, y) yy := uint32(p.Pix[i+0])<<8 | uint32(p.Pix[i+1]) return yy, yy, yy, 0xffff } }
func newSetFuncGray16(p *image.Gray16) SetFunc { return func(x, y int, r, g, b, a uint32) { i := p.PixOffset(x, y) y16 := uint16((299*r + 587*g + 114*b + 500) / 1000) p.Pix[i+0] = uint8(y16 >> 8) p.Pix[i+1] = uint8(y16) } }
// Interpolate uint16/pixel images. func interpolate1x16(src *image.Gray16, 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 := uint64(binary.BigEndian.Uint16([]byte(src.Pix[pixOffset+0 : pixOffset+2]))) pixOffset += 2 // 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.NewGray16(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.PutUint16(dst.Pix[pixOffset+0:pixOffset+2], uint16(sum[index]/n)) pixOffset += 2 index++ } } return dst }