|
@@ -118,6 +118,45 @@ func nearestRGBA(in *image.RGBA, out *image.RGBA, scale float64, coeffs []bool,
|
118
|
118
|
}
|
119
|
119
|
}
|
120
|
120
|
|
|
121
|
+func nearestNRGBA(in *image.NRGBA, out *image.NRGBA, scale float64, coeffs []bool, offset []int, filterLength int) {
|
|
122
|
+ newBounds := out.Bounds()
|
|
123
|
+ maxX := in.Bounds().Dx() - 1
|
|
124
|
+
|
|
125
|
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
|
|
126
|
+ row := in.Pix[x*in.Stride:]
|
|
127
|
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
|
|
128
|
+ var rgba [4]float32
|
|
129
|
+ var sum float32
|
|
130
|
+ start := offset[y]
|
|
131
|
+ ci := y * filterLength
|
|
132
|
+ for i := 0; i < filterLength; i++ {
|
|
133
|
+ if coeffs[ci+i] {
|
|
134
|
+ xi := start + i
|
|
135
|
+ switch {
|
|
136
|
+ case uint(xi) < uint(maxX):
|
|
137
|
+ xi *= 4
|
|
138
|
+ case xi >= maxX:
|
|
139
|
+ xi = 4 * maxX
|
|
140
|
+ default:
|
|
141
|
+ xi = 0
|
|
142
|
+ }
|
|
143
|
+ rgba[0] += float32(row[xi+0])
|
|
144
|
+ rgba[1] += float32(row[xi+1])
|
|
145
|
+ rgba[2] += float32(row[xi+2])
|
|
146
|
+ rgba[3] += float32(row[xi+3])
|
|
147
|
+ sum++
|
|
148
|
+ }
|
|
149
|
+ }
|
|
150
|
+
|
|
151
|
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*4
|
|
152
|
+ out.Pix[xo+0] = floatToUint8(rgba[0] / sum)
|
|
153
|
+ out.Pix[xo+1] = floatToUint8(rgba[1] / sum)
|
|
154
|
+ out.Pix[xo+2] = floatToUint8(rgba[2] / sum)
|
|
155
|
+ out.Pix[xo+3] = floatToUint8(rgba[3] / sum)
|
|
156
|
+ }
|
|
157
|
+ }
|
|
158
|
+}
|
|
159
|
+
|
121
|
160
|
func nearestRGBA64(in *image.RGBA64, out *image.RGBA64, scale float64, coeffs []bool, offset []int, filterLength int) {
|
122
|
161
|
newBounds := out.Bounds()
|
123
|
162
|
maxX := in.Bounds().Dx() - 1
|
|
@@ -165,6 +204,53 @@ func nearestRGBA64(in *image.RGBA64, out *image.RGBA64, scale float64, coeffs []
|
165
|
204
|
}
|
166
|
205
|
}
|
167
|
206
|
|
|
207
|
+func nearestNRGBA64(in *image.NRGBA64, out *image.NRGBA64, scale float64, coeffs []bool, offset []int, filterLength int) {
|
|
208
|
+ newBounds := out.Bounds()
|
|
209
|
+ maxX := in.Bounds().Dx() - 1
|
|
210
|
+
|
|
211
|
+ for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
|
|
212
|
+ row := in.Pix[x*in.Stride:]
|
|
213
|
+ for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
|
|
214
|
+ var rgba [4]float32
|
|
215
|
+ var sum float32
|
|
216
|
+ start := offset[y]
|
|
217
|
+ ci := y * filterLength
|
|
218
|
+ for i := 0; i < filterLength; i++ {
|
|
219
|
+ if coeffs[ci+i] {
|
|
220
|
+ xi := start + i
|
|
221
|
+ switch {
|
|
222
|
+ case uint(xi) < uint(maxX):
|
|
223
|
+ xi *= 8
|
|
224
|
+ case xi >= maxX:
|
|
225
|
+ xi = 8 * maxX
|
|
226
|
+ default:
|
|
227
|
+ xi = 0
|
|
228
|
+ }
|
|
229
|
+ rgba[0] += float32(uint16(row[xi+0])<<8 | uint16(row[xi+1]))
|
|
230
|
+ rgba[1] += float32(uint16(row[xi+2])<<8 | uint16(row[xi+3]))
|
|
231
|
+ rgba[2] += float32(uint16(row[xi+4])<<8 | uint16(row[xi+5]))
|
|
232
|
+ rgba[3] += float32(uint16(row[xi+6])<<8 | uint16(row[xi+7]))
|
|
233
|
+ sum++
|
|
234
|
+ }
|
|
235
|
+ }
|
|
236
|
+
|
|
237
|
+ xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8
|
|
238
|
+ value := floatToUint16(rgba[0] / sum)
|
|
239
|
+ out.Pix[xo+0] = uint8(value >> 8)
|
|
240
|
+ out.Pix[xo+1] = uint8(value)
|
|
241
|
+ value = floatToUint16(rgba[1] / sum)
|
|
242
|
+ out.Pix[xo+2] = uint8(value >> 8)
|
|
243
|
+ out.Pix[xo+3] = uint8(value)
|
|
244
|
+ value = floatToUint16(rgba[2] / sum)
|
|
245
|
+ out.Pix[xo+4] = uint8(value >> 8)
|
|
246
|
+ out.Pix[xo+5] = uint8(value)
|
|
247
|
+ value = floatToUint16(rgba[3] / sum)
|
|
248
|
+ out.Pix[xo+6] = uint8(value >> 8)
|
|
249
|
+ out.Pix[xo+7] = uint8(value)
|
|
250
|
+ }
|
|
251
|
+ }
|
|
252
|
+}
|
|
253
|
+
|
168
|
254
|
func nearestGray(in *image.Gray, out *image.Gray, scale float64, coeffs []bool, offset []int, filterLength int) {
|
169
|
255
|
newBounds := out.Bounds()
|
170
|
256
|
maxX := in.Bounds().Dx() - 1
|