Exemplo n.º 1
0
func AverageNRGBA64(rect image.Rectangle, img *image.NRGBA64) color.NRGBA64 {

	// Only use the area of the rectangle that overlaps with the image bounds.
	rect = rect.Intersect(img.Bounds())

	// Determine whether or not there's any area over which to determine an
	// average.
	d := uint64(rect.Dx() * rect.Dy())
	if d == 0 {
		return color.NRGBA64{}
	}

	var r, g, b, a uint64
	AllPointsRP(
		func(pt image.Point) {
			c := img.NRGBA64At(pt.X, pt.Y)
			r += uint64(c.R)
			g += uint64(c.G)
			b += uint64(c.B)
			a += uint64(c.A)
		},
	)(rect)

	return color.NRGBA64{
		R: uint16(r / d),
		G: uint16(g / d),
		B: uint16(b / d),
		A: uint16(a / d),
	}
}
Exemplo n.º 2
0
func resizeNRGBA64(in *image.NRGBA64, out *image.RGBA64, scale float64, coeffs []int32, offset []int, filterLength int) {
	newBounds := out.Bounds()
	maxX := in.Bounds().Dx() - 1

	for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
		row := in.Pix[x*in.Stride:]
		for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
			var rgba [4]int64
			var sum int64
			start := offset[y]
			ci := y * filterLength
			for i := 0; i < filterLength; i++ {
				coeff := coeffs[ci+i]
				if coeff != 0 {
					xi := start + i
					switch {
					case uint(xi) < uint(maxX):
						xi *= 8
					case xi >= maxX:
						xi = 8 * maxX
					default:
						xi = 0
					}

					// Forward alpha-premultiplication
					a := int64(uint16(row[xi+6])<<8 | uint16(row[xi+7]))
					r := int64(uint16(row[xi+0])<<8|uint16(row[xi+1])) * a
					r /= 0xffff
					g := int64(uint16(row[xi+2])<<8|uint16(row[xi+3])) * a
					g /= 0xffff
					b := int64(uint16(row[xi+4])<<8|uint16(row[xi+5])) * a
					b /= 0xffff

					rgba[0] += int64(coeff) * r
					rgba[1] += int64(coeff) * g
					rgba[2] += int64(coeff) * b
					rgba[3] += int64(coeff) * a
					sum += int64(coeff)
				}
			}

			xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8

			value := clampUint16(rgba[0] / sum)
			out.Pix[xo+0] = uint8(value >> 8)
			out.Pix[xo+1] = uint8(value)
			value = clampUint16(rgba[1] / sum)
			out.Pix[xo+2] = uint8(value >> 8)
			out.Pix[xo+3] = uint8(value)
			value = clampUint16(rgba[2] / sum)
			out.Pix[xo+4] = uint8(value >> 8)
			out.Pix[xo+5] = uint8(value)
			value = clampUint16(rgba[3] / sum)
			out.Pix[xo+6] = uint8(value >> 8)
			out.Pix[xo+7] = uint8(value)
		}
	}
}
Exemplo n.º 3
0
func resizeGeneric(in image.Image, out *image.NRGBA64, scale float64, coeffs []int32, offset []int, filterLength int) {
	newBounds := out.Bounds()
	maxX := in.Bounds().Dx() - 1

	for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
		for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
			var rgba [4]int64
			var sum int64
			start := offset[y]
			ci := y * filterLength
			for i := 0; i < filterLength; i++ {
				coeff := coeffs[ci+i]
				if coeff != 0 {
					xi := start + i
					switch {
					case xi < 0:
						xi = 0
					case xi >= maxX:
						xi = maxX
					}
					r, g, b, a := in.At(xi+in.Bounds().Min.X, x+in.Bounds().Min.Y).RGBA()

					// reverse alpha-premultiplication.
					if a != 0 {
						r *= 0xffff
						r /= a
						g *= 0xffff
						g /= a
						b *= 0xffff
						b /= a
					}

					rgba[0] += int64(coeff) * int64(r)
					rgba[1] += int64(coeff) * int64(g)
					rgba[2] += int64(coeff) * int64(b)
					rgba[3] += int64(coeff) * int64(a)
					sum += int64(coeff)
				}
			}

			offset := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8
			value := clampUint16(rgba[0] / sum)
			out.Pix[offset+0] = uint8(value >> 8)
			out.Pix[offset+1] = uint8(value)
			value = clampUint16(rgba[1] / sum)
			out.Pix[offset+2] = uint8(value >> 8)
			out.Pix[offset+3] = uint8(value)
			value = clampUint16(rgba[2] / sum)
			out.Pix[offset+4] = uint8(value >> 8)
			out.Pix[offset+5] = uint8(value)
			value = clampUint16(rgba[3] / sum)
			out.Pix[offset+6] = uint8(value >> 8)
			out.Pix[offset+7] = uint8(value)
		}
	}
}
Exemplo n.º 4
0
// 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
}
Exemplo n.º 5
0
func putLineNRGBA64(flipXY bool, column []f32RGBA, x int, dst *image.NRGBA64) {
	dy := dst.Bounds().Min.Y
	dx := dst.Bounds().Min.X
	for y, dst_c := range column {
		dst_nrgba := color.NRGBA64{
			R: clampF32ToUint16(f32_to_uint16 * dst_c.R),
			G: clampF32ToUint16(f32_to_uint16 * dst_c.G),
			B: clampF32ToUint16(f32_to_uint16 * dst_c.B),
			A: clampF32ToUint16(f32_to_uint16 * dst_c.A),
		}
		if flipXY {
			dst.SetNRGBA64(y+dx, x+dy, dst_nrgba)
		} else {
			dst.SetNRGBA64(x+dx, y+dy, dst_nrgba)
		}
	}
}
Exemplo n.º 6
0
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]))
	}
}
Exemplo n.º 7
0
func nearestNRGBA64(in *image.NRGBA64, out *image.NRGBA64, scale float64, coeffs []bool, offset []int, filterLength int) {
	newBounds := out.Bounds()
	maxX := in.Bounds().Dx() - 1

	for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
		row := in.Pix[x*in.Stride:]
		for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
			var rgba [4]float32
			var sum float32
			start := offset[y]
			ci := y * filterLength
			for i := 0; i < filterLength; i++ {
				if coeffs[ci+i] {
					xi := start + i
					switch {
					case uint(xi) < uint(maxX):
						xi *= 8
					case xi >= maxX:
						xi = 8 * maxX
					default:
						xi = 0
					}
					rgba[0] += float32(uint16(row[xi+0])<<8 | uint16(row[xi+1]))
					rgba[1] += float32(uint16(row[xi+2])<<8 | uint16(row[xi+3]))
					rgba[2] += float32(uint16(row[xi+4])<<8 | uint16(row[xi+5]))
					rgba[3] += float32(uint16(row[xi+6])<<8 | uint16(row[xi+7]))
					sum++
				}
			}

			xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8
			value := floatToUint16(rgba[0] / sum)
			out.Pix[xo+0] = uint8(value >> 8)
			out.Pix[xo+1] = uint8(value)
			value = floatToUint16(rgba[1] / sum)
			out.Pix[xo+2] = uint8(value >> 8)
			out.Pix[xo+3] = uint8(value)
			value = floatToUint16(rgba[2] / sum)
			out.Pix[xo+4] = uint8(value >> 8)
			out.Pix[xo+5] = uint8(value)
			value = floatToUint16(rgba[3] / sum)
			out.Pix[xo+6] = uint8(value >> 8)
			out.Pix[xo+7] = uint8(value)
		}
	}
}
Exemplo n.º 8
0
func resize64(src *image.NRGBA64, dstW, dstH int) image.Image {
	srcRect := src.Bounds()
	srcW := srcRect.Dx()
	srcH := srcRect.Dy()

	dstW64, dstH64 := uint64(dstW), uint64(dstH)
	srcW64, srcH64 := uint64(srcW), uint64(srcH)

	dst := image.NewNRGBA64(image.Rect(0, 0, dstW, dstH))
	var x, y uint64
	dstI := 0
	for y = 0; y < dstH64; y++ {
		srcY := int(y * srcH64 / dstH64)
		for x = 0; x < dstW64; x++ {
			srcX := int(x * srcW64 / dstW64)
			srcI := 8 * (srcY*srcW + srcX)
			copy(dst.Pix[dstI:dstI+8], src.Pix[srcI:srcI+8])
			dstI += 8
		}
	}
	return dst
}
Exemplo n.º 9
0
// 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
}