Просмотр исходного кода

Add functions for nearest-neighbor resize of NRGBA, NRGBA16.

jst 11 лет назад
Родитель
Сommit
79dc2b616d
1 измененных файлов с 86 добавлено и 0 удалено
  1. 86 0
      nearest.go

+ 86 - 0
nearest.go

@@ -118,6 +118,45 @@ func nearestRGBA(in *image.RGBA, out *image.RGBA, scale float64, coeffs []bool,
 	}
 	}
 }
 }
 
 
+func nearestNRGBA(in *image.NRGBA, out *image.NRGBA, 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 *= 4
+					case xi >= maxX:
+						xi = 4 * maxX
+					default:
+						xi = 0
+					}
+					rgba[0] += float32(row[xi+0])
+					rgba[1] += float32(row[xi+1])
+					rgba[2] += float32(row[xi+2])
+					rgba[3] += float32(row[xi+3])
+					sum++
+				}
+			}
+
+			xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*4
+			out.Pix[xo+0] = floatToUint8(rgba[0] / sum)
+			out.Pix[xo+1] = floatToUint8(rgba[1] / sum)
+			out.Pix[xo+2] = floatToUint8(rgba[2] / sum)
+			out.Pix[xo+3] = floatToUint8(rgba[3] / sum)
+		}
+	}
+}
+
 func nearestRGBA64(in *image.RGBA64, out *image.RGBA64, scale float64, coeffs []bool, offset []int, filterLength int) {
 func nearestRGBA64(in *image.RGBA64, out *image.RGBA64, scale float64, coeffs []bool, offset []int, filterLength int) {
 	newBounds := out.Bounds()
 	newBounds := out.Bounds()
 	maxX := in.Bounds().Dx() - 1
 	maxX := in.Bounds().Dx() - 1
@@ -165,6 +204,53 @@ func nearestRGBA64(in *image.RGBA64, out *image.RGBA64, scale float64, coeffs []
 	}
 	}
 }
 }
 
 
+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)
+		}
+	}
+}
+
 func nearestGray(in *image.Gray, out *image.Gray, scale float64, coeffs []bool, offset []int, filterLength int) {
 func nearestGray(in *image.Gray, out *image.Gray, scale float64, coeffs []bool, offset []int, filterLength int) {
 	newBounds := out.Bounds()
 	newBounds := out.Bounds()
 	maxX := in.Bounds().Dx() - 1
 	maxX := in.Bounds().Dx() - 1