1
2
3 package draw
4
5 import (
6 "image"
7 "image/color"
8 "math"
9
10 "golang.org/x/image/math/f64"
11 )
12
13 func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
14
15
16 if dr.Size() == sr.Size() && (opts == nil || opts.DstMask == nil) {
17 Copy(dst, dr.Min, src, sr, op, opts)
18 return
19 }
20
21 var o Options
22 if opts != nil {
23 o = *opts
24 }
25
26
27 adr := dst.Bounds().Intersect(dr)
28 adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP)
29 if adr.Empty() || sr.Empty() {
30 return
31 }
32
33 adr = adr.Sub(dr.Min)
34 if op == Over && o.SrcMask == nil && opaque(src) {
35 op = Src
36 }
37
38
39
40
41
42
43 if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
44 switch op {
45 case Over:
46 z.scale_Image_Image_Over(dst, dr, adr, src, sr, &o)
47 case Src:
48 z.scale_Image_Image_Src(dst, dr, adr, src, sr, &o)
49 }
50 } else if _, ok := src.(*image.Uniform); ok {
51 Draw(dst, dr, src, src.Bounds().Min, op)
52 } else {
53 switch op {
54 case Over:
55 switch dst := dst.(type) {
56 case *image.RGBA:
57 switch src := src.(type) {
58 case *image.NRGBA:
59 z.scale_RGBA_NRGBA_Over(dst, dr, adr, src, sr, &o)
60 case *image.RGBA:
61 z.scale_RGBA_RGBA_Over(dst, dr, adr, src, sr, &o)
62 case image.RGBA64Image:
63 z.scale_RGBA_RGBA64Image_Over(dst, dr, adr, src, sr, &o)
64 default:
65 z.scale_RGBA_Image_Over(dst, dr, adr, src, sr, &o)
66 }
67 case RGBA64Image:
68 switch src := src.(type) {
69 case image.RGBA64Image:
70 z.scale_RGBA64Image_RGBA64Image_Over(dst, dr, adr, src, sr, &o)
71 }
72 default:
73 switch src := src.(type) {
74 default:
75 z.scale_Image_Image_Over(dst, dr, adr, src, sr, &o)
76 }
77 }
78 case Src:
79 switch dst := dst.(type) {
80 case *image.RGBA:
81 switch src := src.(type) {
82 case *image.Gray:
83 z.scale_RGBA_Gray_Src(dst, dr, adr, src, sr, &o)
84 case *image.NRGBA:
85 z.scale_RGBA_NRGBA_Src(dst, dr, adr, src, sr, &o)
86 case *image.RGBA:
87 z.scale_RGBA_RGBA_Src(dst, dr, adr, src, sr, &o)
88 case *image.YCbCr:
89 switch src.SubsampleRatio {
90 default:
91 z.scale_RGBA_Image_Src(dst, dr, adr, src, sr, &o)
92 case image.YCbCrSubsampleRatio444:
93 z.scale_RGBA_YCbCr444_Src(dst, dr, adr, src, sr, &o)
94 case image.YCbCrSubsampleRatio422:
95 z.scale_RGBA_YCbCr422_Src(dst, dr, adr, src, sr, &o)
96 case image.YCbCrSubsampleRatio420:
97 z.scale_RGBA_YCbCr420_Src(dst, dr, adr, src, sr, &o)
98 case image.YCbCrSubsampleRatio440:
99 z.scale_RGBA_YCbCr440_Src(dst, dr, adr, src, sr, &o)
100 }
101 case image.RGBA64Image:
102 z.scale_RGBA_RGBA64Image_Src(dst, dr, adr, src, sr, &o)
103 default:
104 z.scale_RGBA_Image_Src(dst, dr, adr, src, sr, &o)
105 }
106 case RGBA64Image:
107 switch src := src.(type) {
108 case image.RGBA64Image:
109 z.scale_RGBA64Image_RGBA64Image_Src(dst, dr, adr, src, sr, &o)
110 }
111 default:
112 switch src := src.(type) {
113 default:
114 z.scale_Image_Image_Src(dst, dr, adr, src, sr, &o)
115 }
116 }
117 }
118 }
119 }
120
121 func (z nnInterpolator) Transform(dst Image, s2d f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
122
123 if s2d[0] == 1 && s2d[1] == 0 && s2d[3] == 0 && s2d[4] == 1 {
124 dx := int(s2d[2])
125 dy := int(s2d[5])
126 if float64(dx) == s2d[2] && float64(dy) == s2d[5] {
127 Copy(dst, image.Point{X: sr.Min.X + dx, Y: sr.Min.X + dy}, src, sr, op, opts)
128 return
129 }
130 }
131
132 var o Options
133 if opts != nil {
134 o = *opts
135 }
136
137 dr := transformRect(&s2d, &sr)
138
139 adr := dst.Bounds().Intersect(dr)
140 adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP)
141 if adr.Empty() || sr.Empty() {
142 return
143 }
144 if op == Over && o.SrcMask == nil && opaque(src) {
145 op = Src
146 }
147
148 d2s := invert(&s2d)
149
150
151
152
153
154
155
156 bias := transformRect(&d2s, &adr).Min
157 bias.X--
158 bias.Y--
159 d2s[2] -= float64(bias.X)
160 d2s[5] -= float64(bias.Y)
161
162 adr = adr.Sub(dr.Min)
163
164
165
166
167
168 if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
169 switch op {
170 case Over:
171 z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
172 case Src:
173 z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
174 }
175 } else if u, ok := src.(*image.Uniform); ok {
176 transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
177 } else {
178 switch op {
179 case Over:
180 switch dst := dst.(type) {
181 case *image.RGBA:
182 switch src := src.(type) {
183 case *image.NRGBA:
184 z.transform_RGBA_NRGBA_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
185 case *image.RGBA:
186 z.transform_RGBA_RGBA_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
187 case image.RGBA64Image:
188 z.transform_RGBA_RGBA64Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
189 default:
190 z.transform_RGBA_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
191 }
192 case RGBA64Image:
193 switch src := src.(type) {
194 case image.RGBA64Image:
195 z.transform_RGBA64Image_RGBA64Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
196 }
197 default:
198 switch src := src.(type) {
199 default:
200 z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
201 }
202 }
203 case Src:
204 switch dst := dst.(type) {
205 case *image.RGBA:
206 switch src := src.(type) {
207 case *image.Gray:
208 z.transform_RGBA_Gray_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
209 case *image.NRGBA:
210 z.transform_RGBA_NRGBA_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
211 case *image.RGBA:
212 z.transform_RGBA_RGBA_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
213 case *image.YCbCr:
214 switch src.SubsampleRatio {
215 default:
216 z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
217 case image.YCbCrSubsampleRatio444:
218 z.transform_RGBA_YCbCr444_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
219 case image.YCbCrSubsampleRatio422:
220 z.transform_RGBA_YCbCr422_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
221 case image.YCbCrSubsampleRatio420:
222 z.transform_RGBA_YCbCr420_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
223 case image.YCbCrSubsampleRatio440:
224 z.transform_RGBA_YCbCr440_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
225 }
226 case image.RGBA64Image:
227 z.transform_RGBA_RGBA64Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
228 default:
229 z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
230 }
231 case RGBA64Image:
232 switch src := src.(type) {
233 case image.RGBA64Image:
234 z.transform_RGBA64Image_RGBA64Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
235 }
236 default:
237 switch src := src.(type) {
238 default:
239 z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
240 }
241 }
242 }
243 }
244 }
245
246 func (nnInterpolator) scale_RGBA_Gray_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.Gray, sr image.Rectangle, opts *Options) {
247 dw2 := uint64(dr.Dx()) * 2
248 dh2 := uint64(dr.Dy()) * 2
249 sw := uint64(sr.Dx())
250 sh := uint64(sr.Dy())
251 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
252 sy := (2*uint64(dy) + 1) * sh / dh2
253 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
254 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
255 sx := (2*uint64(dx) + 1) * sw / dw2
256 pi := (sr.Min.Y+int(sy)-src.Rect.Min.Y)*src.Stride + (sr.Min.X + int(sx) - src.Rect.Min.X)
257 pr := uint32(src.Pix[pi]) * 0x101
258 out := uint8(pr >> 8)
259 dst.Pix[d+0] = out
260 dst.Pix[d+1] = out
261 dst.Pix[d+2] = out
262 dst.Pix[d+3] = 0xff
263 }
264 }
265 }
266
267 func (nnInterpolator) scale_RGBA_NRGBA_Over(dst *image.RGBA, dr, adr image.Rectangle, src *image.NRGBA, sr image.Rectangle, opts *Options) {
268 dw2 := uint64(dr.Dx()) * 2
269 dh2 := uint64(dr.Dy()) * 2
270 sw := uint64(sr.Dx())
271 sh := uint64(sr.Dy())
272 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
273 sy := (2*uint64(dy) + 1) * sh / dh2
274 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
275 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
276 sx := (2*uint64(dx) + 1) * sw / dw2
277 pi := (sr.Min.Y+int(sy)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx)-src.Rect.Min.X)*4
278 pa := uint32(src.Pix[pi+3]) * 0x101
279 pr := uint32(src.Pix[pi+0]) * pa / 0xff
280 pg := uint32(src.Pix[pi+1]) * pa / 0xff
281 pb := uint32(src.Pix[pi+2]) * pa / 0xff
282 pa1 := (0xffff - pa) * 0x101
283 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
284 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
285 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
286 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
287 }
288 }
289 }
290
291 func (nnInterpolator) scale_RGBA_NRGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.NRGBA, sr image.Rectangle, opts *Options) {
292 dw2 := uint64(dr.Dx()) * 2
293 dh2 := uint64(dr.Dy()) * 2
294 sw := uint64(sr.Dx())
295 sh := uint64(sr.Dy())
296 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
297 sy := (2*uint64(dy) + 1) * sh / dh2
298 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
299 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
300 sx := (2*uint64(dx) + 1) * sw / dw2
301 pi := (sr.Min.Y+int(sy)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx)-src.Rect.Min.X)*4
302 pa := uint32(src.Pix[pi+3]) * 0x101
303 pr := uint32(src.Pix[pi+0]) * pa / 0xff
304 pg := uint32(src.Pix[pi+1]) * pa / 0xff
305 pb := uint32(src.Pix[pi+2]) * pa / 0xff
306 dst.Pix[d+0] = uint8(pr >> 8)
307 dst.Pix[d+1] = uint8(pg >> 8)
308 dst.Pix[d+2] = uint8(pb >> 8)
309 dst.Pix[d+3] = uint8(pa >> 8)
310 }
311 }
312 }
313
314 func (nnInterpolator) scale_RGBA_RGBA_Over(dst *image.RGBA, dr, adr image.Rectangle, src *image.RGBA, sr image.Rectangle, opts *Options) {
315 dw2 := uint64(dr.Dx()) * 2
316 dh2 := uint64(dr.Dy()) * 2
317 sw := uint64(sr.Dx())
318 sh := uint64(sr.Dy())
319 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
320 sy := (2*uint64(dy) + 1) * sh / dh2
321 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
322 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
323 sx := (2*uint64(dx) + 1) * sw / dw2
324 pi := (sr.Min.Y+int(sy)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx)-src.Rect.Min.X)*4
325 pr := uint32(src.Pix[pi+0]) * 0x101
326 pg := uint32(src.Pix[pi+1]) * 0x101
327 pb := uint32(src.Pix[pi+2]) * 0x101
328 pa := uint32(src.Pix[pi+3]) * 0x101
329 pa1 := (0xffff - pa) * 0x101
330 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
331 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
332 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
333 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
334 }
335 }
336 }
337
338 func (nnInterpolator) scale_RGBA_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.RGBA, sr image.Rectangle, opts *Options) {
339 dw2 := uint64(dr.Dx()) * 2
340 dh2 := uint64(dr.Dy()) * 2
341 sw := uint64(sr.Dx())
342 sh := uint64(sr.Dy())
343 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
344 sy := (2*uint64(dy) + 1) * sh / dh2
345 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
346 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
347 sx := (2*uint64(dx) + 1) * sw / dw2
348 pi := (sr.Min.Y+int(sy)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx)-src.Rect.Min.X)*4
349 pr := uint32(src.Pix[pi+0]) * 0x101
350 pg := uint32(src.Pix[pi+1]) * 0x101
351 pb := uint32(src.Pix[pi+2]) * 0x101
352 pa := uint32(src.Pix[pi+3]) * 0x101
353 dst.Pix[d+0] = uint8(pr >> 8)
354 dst.Pix[d+1] = uint8(pg >> 8)
355 dst.Pix[d+2] = uint8(pb >> 8)
356 dst.Pix[d+3] = uint8(pa >> 8)
357 }
358 }
359 }
360
361 func (nnInterpolator) scale_RGBA_YCbCr444_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle, opts *Options) {
362 dw2 := uint64(dr.Dx()) * 2
363 dh2 := uint64(dr.Dy()) * 2
364 sw := uint64(sr.Dx())
365 sh := uint64(sr.Dy())
366 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
367 sy := (2*uint64(dy) + 1) * sh / dh2
368 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
369 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
370 sx := (2*uint64(dx) + 1) * sw / dw2
371 pi := (sr.Min.Y+int(sy)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx) - src.Rect.Min.X)
372 pj := (sr.Min.Y+int(sy)-src.Rect.Min.Y)*src.CStride + (sr.Min.X + int(sx) - src.Rect.Min.X)
373
374
375 pyy1 := int(src.Y[pi]) * 0x10101
376 pcb1 := int(src.Cb[pj]) - 128
377 pcr1 := int(src.Cr[pj]) - 128
378 pr := (pyy1 + 91881*pcr1) >> 8
379 pg := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
380 pb := (pyy1 + 116130*pcb1) >> 8
381 if pr < 0 {
382 pr = 0
383 } else if pr > 0xffff {
384 pr = 0xffff
385 }
386 if pg < 0 {
387 pg = 0
388 } else if pg > 0xffff {
389 pg = 0xffff
390 }
391 if pb < 0 {
392 pb = 0
393 } else if pb > 0xffff {
394 pb = 0xffff
395 }
396 dst.Pix[d+0] = uint8(pr >> 8)
397 dst.Pix[d+1] = uint8(pg >> 8)
398 dst.Pix[d+2] = uint8(pb >> 8)
399 dst.Pix[d+3] = 0xff
400 }
401 }
402 }
403
404 func (nnInterpolator) scale_RGBA_YCbCr422_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle, opts *Options) {
405 dw2 := uint64(dr.Dx()) * 2
406 dh2 := uint64(dr.Dy()) * 2
407 sw := uint64(sr.Dx())
408 sh := uint64(sr.Dy())
409 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
410 sy := (2*uint64(dy) + 1) * sh / dh2
411 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
412 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
413 sx := (2*uint64(dx) + 1) * sw / dw2
414 pi := (sr.Min.Y+int(sy)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx) - src.Rect.Min.X)
415 pj := (sr.Min.Y+int(sy)-src.Rect.Min.Y)*src.CStride + ((sr.Min.X+int(sx))/2 - src.Rect.Min.X/2)
416
417
418 pyy1 := int(src.Y[pi]) * 0x10101
419 pcb1 := int(src.Cb[pj]) - 128
420 pcr1 := int(src.Cr[pj]) - 128
421 pr := (pyy1 + 91881*pcr1) >> 8
422 pg := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
423 pb := (pyy1 + 116130*pcb1) >> 8
424 if pr < 0 {
425 pr = 0
426 } else if pr > 0xffff {
427 pr = 0xffff
428 }
429 if pg < 0 {
430 pg = 0
431 } else if pg > 0xffff {
432 pg = 0xffff
433 }
434 if pb < 0 {
435 pb = 0
436 } else if pb > 0xffff {
437 pb = 0xffff
438 }
439 dst.Pix[d+0] = uint8(pr >> 8)
440 dst.Pix[d+1] = uint8(pg >> 8)
441 dst.Pix[d+2] = uint8(pb >> 8)
442 dst.Pix[d+3] = 0xff
443 }
444 }
445 }
446
447 func (nnInterpolator) scale_RGBA_YCbCr420_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle, opts *Options) {
448 dw2 := uint64(dr.Dx()) * 2
449 dh2 := uint64(dr.Dy()) * 2
450 sw := uint64(sr.Dx())
451 sh := uint64(sr.Dy())
452 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
453 sy := (2*uint64(dy) + 1) * sh / dh2
454 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
455 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
456 sx := (2*uint64(dx) + 1) * sw / dw2
457 pi := (sr.Min.Y+int(sy)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx) - src.Rect.Min.X)
458 pj := ((sr.Min.Y+int(sy))/2-src.Rect.Min.Y/2)*src.CStride + ((sr.Min.X+int(sx))/2 - src.Rect.Min.X/2)
459
460
461 pyy1 := int(src.Y[pi]) * 0x10101
462 pcb1 := int(src.Cb[pj]) - 128
463 pcr1 := int(src.Cr[pj]) - 128
464 pr := (pyy1 + 91881*pcr1) >> 8
465 pg := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
466 pb := (pyy1 + 116130*pcb1) >> 8
467 if pr < 0 {
468 pr = 0
469 } else if pr > 0xffff {
470 pr = 0xffff
471 }
472 if pg < 0 {
473 pg = 0
474 } else if pg > 0xffff {
475 pg = 0xffff
476 }
477 if pb < 0 {
478 pb = 0
479 } else if pb > 0xffff {
480 pb = 0xffff
481 }
482 dst.Pix[d+0] = uint8(pr >> 8)
483 dst.Pix[d+1] = uint8(pg >> 8)
484 dst.Pix[d+2] = uint8(pb >> 8)
485 dst.Pix[d+3] = 0xff
486 }
487 }
488 }
489
490 func (nnInterpolator) scale_RGBA_YCbCr440_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle, opts *Options) {
491 dw2 := uint64(dr.Dx()) * 2
492 dh2 := uint64(dr.Dy()) * 2
493 sw := uint64(sr.Dx())
494 sh := uint64(sr.Dy())
495 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
496 sy := (2*uint64(dy) + 1) * sh / dh2
497 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
498 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
499 sx := (2*uint64(dx) + 1) * sw / dw2
500 pi := (sr.Min.Y+int(sy)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx) - src.Rect.Min.X)
501 pj := ((sr.Min.Y+int(sy))/2-src.Rect.Min.Y/2)*src.CStride + (sr.Min.X + int(sx) - src.Rect.Min.X)
502
503
504 pyy1 := int(src.Y[pi]) * 0x10101
505 pcb1 := int(src.Cb[pj]) - 128
506 pcr1 := int(src.Cr[pj]) - 128
507 pr := (pyy1 + 91881*pcr1) >> 8
508 pg := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
509 pb := (pyy1 + 116130*pcb1) >> 8
510 if pr < 0 {
511 pr = 0
512 } else if pr > 0xffff {
513 pr = 0xffff
514 }
515 if pg < 0 {
516 pg = 0
517 } else if pg > 0xffff {
518 pg = 0xffff
519 }
520 if pb < 0 {
521 pb = 0
522 } else if pb > 0xffff {
523 pb = 0xffff
524 }
525 dst.Pix[d+0] = uint8(pr >> 8)
526 dst.Pix[d+1] = uint8(pg >> 8)
527 dst.Pix[d+2] = uint8(pb >> 8)
528 dst.Pix[d+3] = 0xff
529 }
530 }
531 }
532
533 func (nnInterpolator) scale_RGBA_RGBA64Image_Over(dst *image.RGBA, dr, adr image.Rectangle, src image.RGBA64Image, sr image.Rectangle, opts *Options) {
534 dw2 := uint64(dr.Dx()) * 2
535 dh2 := uint64(dr.Dy()) * 2
536 sw := uint64(sr.Dx())
537 sh := uint64(sr.Dy())
538 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
539 sy := (2*uint64(dy) + 1) * sh / dh2
540 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
541 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
542 sx := (2*uint64(dx) + 1) * sw / dw2
543 p := src.RGBA64At(sr.Min.X+int(sx), sr.Min.Y+int(sy))
544 pa1 := (0xffff - uint32(p.A)) * 0x101
545 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + uint32(p.R)) >> 8)
546 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + uint32(p.G)) >> 8)
547 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + uint32(p.B)) >> 8)
548 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + uint32(p.A)) >> 8)
549 }
550 }
551 }
552
553 func (nnInterpolator) scale_RGBA_RGBA64Image_Src(dst *image.RGBA, dr, adr image.Rectangle, src image.RGBA64Image, sr image.Rectangle, opts *Options) {
554 dw2 := uint64(dr.Dx()) * 2
555 dh2 := uint64(dr.Dy()) * 2
556 sw := uint64(sr.Dx())
557 sh := uint64(sr.Dy())
558 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
559 sy := (2*uint64(dy) + 1) * sh / dh2
560 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
561 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
562 sx := (2*uint64(dx) + 1) * sw / dw2
563 p := src.RGBA64At(sr.Min.X+int(sx), sr.Min.Y+int(sy))
564 dst.Pix[d+0] = uint8(p.R >> 8)
565 dst.Pix[d+1] = uint8(p.G >> 8)
566 dst.Pix[d+2] = uint8(p.B >> 8)
567 dst.Pix[d+3] = uint8(p.A >> 8)
568 }
569 }
570 }
571
572 func (nnInterpolator) scale_RGBA_Image_Over(dst *image.RGBA, dr, adr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
573 dw2 := uint64(dr.Dx()) * 2
574 dh2 := uint64(dr.Dy()) * 2
575 sw := uint64(sr.Dx())
576 sh := uint64(sr.Dy())
577 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
578 sy := (2*uint64(dy) + 1) * sh / dh2
579 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
580 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
581 sx := (2*uint64(dx) + 1) * sw / dw2
582 pr, pg, pb, pa := src.At(sr.Min.X+int(sx), sr.Min.Y+int(sy)).RGBA()
583 pa1 := (0xffff - pa) * 0x101
584 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
585 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
586 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
587 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
588 }
589 }
590 }
591
592 func (nnInterpolator) scale_RGBA_Image_Src(dst *image.RGBA, dr, adr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
593 dw2 := uint64(dr.Dx()) * 2
594 dh2 := uint64(dr.Dy()) * 2
595 sw := uint64(sr.Dx())
596 sh := uint64(sr.Dy())
597 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
598 sy := (2*uint64(dy) + 1) * sh / dh2
599 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
600 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
601 sx := (2*uint64(dx) + 1) * sw / dw2
602 pr, pg, pb, pa := src.At(sr.Min.X+int(sx), sr.Min.Y+int(sy)).RGBA()
603 dst.Pix[d+0] = uint8(pr >> 8)
604 dst.Pix[d+1] = uint8(pg >> 8)
605 dst.Pix[d+2] = uint8(pb >> 8)
606 dst.Pix[d+3] = uint8(pa >> 8)
607 }
608 }
609 }
610
611 func (nnInterpolator) scale_RGBA64Image_RGBA64Image_Over(dst RGBA64Image, dr, adr image.Rectangle, src image.RGBA64Image, sr image.Rectangle, opts *Options) {
612 dw2 := uint64(dr.Dx()) * 2
613 dh2 := uint64(dr.Dy()) * 2
614 sw := uint64(sr.Dx())
615 sh := uint64(sr.Dy())
616 srcMask, smp := opts.SrcMask, opts.SrcMaskP
617 dstMask, dmp := opts.DstMask, opts.DstMaskP
618 dstColorRGBA64 := color.RGBA64{}
619
620 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
621 sy := (2*uint64(dy) + 1) * sh / dh2
622 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
623 sx := (2*uint64(dx) + 1) * sw / dw2
624 p := src.RGBA64At(sr.Min.X+int(sx), sr.Min.Y+int(sy))
625 if srcMask != nil {
626 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx), smp.Y+sr.Min.Y+int(sy)).RGBA()
627 p.R = uint16(uint32(p.R) * ma / 0xffff)
628 p.G = uint16(uint32(p.G) * ma / 0xffff)
629 p.B = uint16(uint32(p.B) * ma / 0xffff)
630 p.A = uint16(uint32(p.A) * ma / 0xffff)
631 }
632 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(dy))
633 if dstMask != nil {
634 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
635 p.R = uint16(uint32(p.R) * ma / 0xffff)
636 p.G = uint16(uint32(p.G) * ma / 0xffff)
637 p.B = uint16(uint32(p.B) * ma / 0xffff)
638 p.A = uint16(uint32(p.A) * ma / 0xffff)
639 }
640 pa1 := 0xffff - uint32(p.A)
641 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + uint32(p.R))
642 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + uint32(p.G))
643 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + uint32(p.B))
644 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + uint32(p.A))
645 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColorRGBA64)
646 }
647 }
648 }
649
650 func (nnInterpolator) scale_RGBA64Image_RGBA64Image_Src(dst RGBA64Image, dr, adr image.Rectangle, src image.RGBA64Image, sr image.Rectangle, opts *Options) {
651 dw2 := uint64(dr.Dx()) * 2
652 dh2 := uint64(dr.Dy()) * 2
653 sw := uint64(sr.Dx())
654 sh := uint64(sr.Dy())
655 srcMask, smp := opts.SrcMask, opts.SrcMaskP
656 dstMask, dmp := opts.DstMask, opts.DstMaskP
657 dstColorRGBA64 := color.RGBA64{}
658
659 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
660 sy := (2*uint64(dy) + 1) * sh / dh2
661 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
662 sx := (2*uint64(dx) + 1) * sw / dw2
663 p := src.RGBA64At(sr.Min.X+int(sx), sr.Min.Y+int(sy))
664 if srcMask != nil {
665 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx), smp.Y+sr.Min.Y+int(sy)).RGBA()
666 p.R = uint16(uint32(p.R) * ma / 0xffff)
667 p.G = uint16(uint32(p.G) * ma / 0xffff)
668 p.B = uint16(uint32(p.B) * ma / 0xffff)
669 p.A = uint16(uint32(p.A) * ma / 0xffff)
670 }
671 if dstMask != nil {
672 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(dy))
673 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
674 p.R = uint16(uint32(p.R) * ma / 0xffff)
675 p.G = uint16(uint32(p.G) * ma / 0xffff)
676 p.B = uint16(uint32(p.B) * ma / 0xffff)
677 p.A = uint16(uint32(p.A) * ma / 0xffff)
678 pa1 := 0xffff - ma
679 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + uint32(p.R))
680 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + uint32(p.G))
681 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + uint32(p.B))
682 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + uint32(p.A))
683 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColorRGBA64)
684 } else {
685 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), p)
686 }
687 }
688 }
689 }
690
691 func (nnInterpolator) scale_Image_Image_Over(dst Image, dr, adr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
692 dw2 := uint64(dr.Dx()) * 2
693 dh2 := uint64(dr.Dy()) * 2
694 sw := uint64(sr.Dx())
695 sh := uint64(sr.Dy())
696 srcMask, smp := opts.SrcMask, opts.SrcMaskP
697 dstMask, dmp := opts.DstMask, opts.DstMaskP
698 dstColorRGBA64 := &color.RGBA64{}
699 dstColor := color.Color(dstColorRGBA64)
700 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
701 sy := (2*uint64(dy) + 1) * sh / dh2
702 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
703 sx := (2*uint64(dx) + 1) * sw / dw2
704 pr, pg, pb, pa := src.At(sr.Min.X+int(sx), sr.Min.Y+int(sy)).RGBA()
705 if srcMask != nil {
706 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx), smp.Y+sr.Min.Y+int(sy)).RGBA()
707 pr = pr * ma / 0xffff
708 pg = pg * ma / 0xffff
709 pb = pb * ma / 0xffff
710 pa = pa * ma / 0xffff
711 }
712 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(dy)).RGBA()
713 if dstMask != nil {
714 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
715 pr = pr * ma / 0xffff
716 pg = pg * ma / 0xffff
717 pb = pb * ma / 0xffff
718 pa = pa * ma / 0xffff
719 }
720 pa1 := 0xffff - pa
721 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr)
722 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg)
723 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb)
724 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa)
725 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
726 }
727 }
728 }
729
730 func (nnInterpolator) scale_Image_Image_Src(dst Image, dr, adr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
731 dw2 := uint64(dr.Dx()) * 2
732 dh2 := uint64(dr.Dy()) * 2
733 sw := uint64(sr.Dx())
734 sh := uint64(sr.Dy())
735 srcMask, smp := opts.SrcMask, opts.SrcMaskP
736 dstMask, dmp := opts.DstMask, opts.DstMaskP
737 dstColorRGBA64 := &color.RGBA64{}
738 dstColor := color.Color(dstColorRGBA64)
739 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
740 sy := (2*uint64(dy) + 1) * sh / dh2
741 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
742 sx := (2*uint64(dx) + 1) * sw / dw2
743 pr, pg, pb, pa := src.At(sr.Min.X+int(sx), sr.Min.Y+int(sy)).RGBA()
744 if srcMask != nil {
745 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx), smp.Y+sr.Min.Y+int(sy)).RGBA()
746 pr = pr * ma / 0xffff
747 pg = pg * ma / 0xffff
748 pb = pb * ma / 0xffff
749 pa = pa * ma / 0xffff
750 }
751 if dstMask != nil {
752 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(dy)).RGBA()
753 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
754 pr = pr * ma / 0xffff
755 pg = pg * ma / 0xffff
756 pb = pb * ma / 0xffff
757 pa = pa * ma / 0xffff
758 pa1 := 0xffff - ma
759 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr)
760 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg)
761 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb)
762 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa)
763 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
764 } else {
765 dstColorRGBA64.R = uint16(pr)
766 dstColorRGBA64.G = uint16(pg)
767 dstColorRGBA64.B = uint16(pb)
768 dstColorRGBA64.A = uint16(pa)
769 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
770 }
771 }
772 }
773 }
774
775 func (nnInterpolator) transform_RGBA_Gray_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.Gray, sr image.Rectangle, bias image.Point, opts *Options) {
776 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
777 dyf := float64(dr.Min.Y+int(dy)) + 0.5
778 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
779 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
780 dxf := float64(dr.Min.X+int(dx)) + 0.5
781 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
782 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
783 if !(image.Point{sx0, sy0}).In(sr) {
784 continue
785 }
786 pi := (sy0-src.Rect.Min.Y)*src.Stride + (sx0 - src.Rect.Min.X)
787 pr := uint32(src.Pix[pi]) * 0x101
788 out := uint8(pr >> 8)
789 dst.Pix[d+0] = out
790 dst.Pix[d+1] = out
791 dst.Pix[d+2] = out
792 dst.Pix[d+3] = 0xff
793 }
794 }
795 }
796
797 func (nnInterpolator) transform_RGBA_NRGBA_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point, opts *Options) {
798 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
799 dyf := float64(dr.Min.Y+int(dy)) + 0.5
800 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
801 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
802 dxf := float64(dr.Min.X+int(dx)) + 0.5
803 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
804 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
805 if !(image.Point{sx0, sy0}).In(sr) {
806 continue
807 }
808 pi := (sy0-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
809 pa := uint32(src.Pix[pi+3]) * 0x101
810 pr := uint32(src.Pix[pi+0]) * pa / 0xff
811 pg := uint32(src.Pix[pi+1]) * pa / 0xff
812 pb := uint32(src.Pix[pi+2]) * pa / 0xff
813 pa1 := (0xffff - pa) * 0x101
814 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
815 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
816 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
817 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
818 }
819 }
820 }
821
822 func (nnInterpolator) transform_RGBA_NRGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point, opts *Options) {
823 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
824 dyf := float64(dr.Min.Y+int(dy)) + 0.5
825 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
826 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
827 dxf := float64(dr.Min.X+int(dx)) + 0.5
828 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
829 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
830 if !(image.Point{sx0, sy0}).In(sr) {
831 continue
832 }
833 pi := (sy0-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
834 pa := uint32(src.Pix[pi+3]) * 0x101
835 pr := uint32(src.Pix[pi+0]) * pa / 0xff
836 pg := uint32(src.Pix[pi+1]) * pa / 0xff
837 pb := uint32(src.Pix[pi+2]) * pa / 0xff
838 dst.Pix[d+0] = uint8(pr >> 8)
839 dst.Pix[d+1] = uint8(pg >> 8)
840 dst.Pix[d+2] = uint8(pb >> 8)
841 dst.Pix[d+3] = uint8(pa >> 8)
842 }
843 }
844 }
845
846 func (nnInterpolator) transform_RGBA_RGBA_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point, opts *Options) {
847 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
848 dyf := float64(dr.Min.Y+int(dy)) + 0.5
849 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
850 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
851 dxf := float64(dr.Min.X+int(dx)) + 0.5
852 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
853 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
854 if !(image.Point{sx0, sy0}).In(sr) {
855 continue
856 }
857 pi := (sy0-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
858 pr := uint32(src.Pix[pi+0]) * 0x101
859 pg := uint32(src.Pix[pi+1]) * 0x101
860 pb := uint32(src.Pix[pi+2]) * 0x101
861 pa := uint32(src.Pix[pi+3]) * 0x101
862 pa1 := (0xffff - pa) * 0x101
863 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
864 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
865 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
866 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
867 }
868 }
869 }
870
871 func (nnInterpolator) transform_RGBA_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point, opts *Options) {
872 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
873 dyf := float64(dr.Min.Y+int(dy)) + 0.5
874 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
875 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
876 dxf := float64(dr.Min.X+int(dx)) + 0.5
877 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
878 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
879 if !(image.Point{sx0, sy0}).In(sr) {
880 continue
881 }
882 pi := (sy0-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
883 pr := uint32(src.Pix[pi+0]) * 0x101
884 pg := uint32(src.Pix[pi+1]) * 0x101
885 pb := uint32(src.Pix[pi+2]) * 0x101
886 pa := uint32(src.Pix[pi+3]) * 0x101
887 dst.Pix[d+0] = uint8(pr >> 8)
888 dst.Pix[d+1] = uint8(pg >> 8)
889 dst.Pix[d+2] = uint8(pb >> 8)
890 dst.Pix[d+3] = uint8(pa >> 8)
891 }
892 }
893 }
894
895 func (nnInterpolator) transform_RGBA_YCbCr444_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, opts *Options) {
896 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
897 dyf := float64(dr.Min.Y+int(dy)) + 0.5
898 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
899 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
900 dxf := float64(dr.Min.X+int(dx)) + 0.5
901 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
902 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
903 if !(image.Point{sx0, sy0}).In(sr) {
904 continue
905 }
906 pi := (sy0-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
907 pj := (sy0-src.Rect.Min.Y)*src.CStride + (sx0 - src.Rect.Min.X)
908
909
910 pyy1 := int(src.Y[pi]) * 0x10101
911 pcb1 := int(src.Cb[pj]) - 128
912 pcr1 := int(src.Cr[pj]) - 128
913 pr := (pyy1 + 91881*pcr1) >> 8
914 pg := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
915 pb := (pyy1 + 116130*pcb1) >> 8
916 if pr < 0 {
917 pr = 0
918 } else if pr > 0xffff {
919 pr = 0xffff
920 }
921 if pg < 0 {
922 pg = 0
923 } else if pg > 0xffff {
924 pg = 0xffff
925 }
926 if pb < 0 {
927 pb = 0
928 } else if pb > 0xffff {
929 pb = 0xffff
930 }
931 dst.Pix[d+0] = uint8(pr >> 8)
932 dst.Pix[d+1] = uint8(pg >> 8)
933 dst.Pix[d+2] = uint8(pb >> 8)
934 dst.Pix[d+3] = 0xff
935 }
936 }
937 }
938
939 func (nnInterpolator) transform_RGBA_YCbCr422_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, opts *Options) {
940 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
941 dyf := float64(dr.Min.Y+int(dy)) + 0.5
942 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
943 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
944 dxf := float64(dr.Min.X+int(dx)) + 0.5
945 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
946 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
947 if !(image.Point{sx0, sy0}).In(sr) {
948 continue
949 }
950 pi := (sy0-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
951 pj := (sy0-src.Rect.Min.Y)*src.CStride + ((sx0)/2 - src.Rect.Min.X/2)
952
953
954 pyy1 := int(src.Y[pi]) * 0x10101
955 pcb1 := int(src.Cb[pj]) - 128
956 pcr1 := int(src.Cr[pj]) - 128
957 pr := (pyy1 + 91881*pcr1) >> 8
958 pg := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
959 pb := (pyy1 + 116130*pcb1) >> 8
960 if pr < 0 {
961 pr = 0
962 } else if pr > 0xffff {
963 pr = 0xffff
964 }
965 if pg < 0 {
966 pg = 0
967 } else if pg > 0xffff {
968 pg = 0xffff
969 }
970 if pb < 0 {
971 pb = 0
972 } else if pb > 0xffff {
973 pb = 0xffff
974 }
975 dst.Pix[d+0] = uint8(pr >> 8)
976 dst.Pix[d+1] = uint8(pg >> 8)
977 dst.Pix[d+2] = uint8(pb >> 8)
978 dst.Pix[d+3] = 0xff
979 }
980 }
981 }
982
983 func (nnInterpolator) transform_RGBA_YCbCr420_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, opts *Options) {
984 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
985 dyf := float64(dr.Min.Y+int(dy)) + 0.5
986 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
987 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
988 dxf := float64(dr.Min.X+int(dx)) + 0.5
989 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
990 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
991 if !(image.Point{sx0, sy0}).In(sr) {
992 continue
993 }
994 pi := (sy0-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
995 pj := ((sy0)/2-src.Rect.Min.Y/2)*src.CStride + ((sx0)/2 - src.Rect.Min.X/2)
996
997
998 pyy1 := int(src.Y[pi]) * 0x10101
999 pcb1 := int(src.Cb[pj]) - 128
1000 pcr1 := int(src.Cr[pj]) - 128
1001 pr := (pyy1 + 91881*pcr1) >> 8
1002 pg := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
1003 pb := (pyy1 + 116130*pcb1) >> 8
1004 if pr < 0 {
1005 pr = 0
1006 } else if pr > 0xffff {
1007 pr = 0xffff
1008 }
1009 if pg < 0 {
1010 pg = 0
1011 } else if pg > 0xffff {
1012 pg = 0xffff
1013 }
1014 if pb < 0 {
1015 pb = 0
1016 } else if pb > 0xffff {
1017 pb = 0xffff
1018 }
1019 dst.Pix[d+0] = uint8(pr >> 8)
1020 dst.Pix[d+1] = uint8(pg >> 8)
1021 dst.Pix[d+2] = uint8(pb >> 8)
1022 dst.Pix[d+3] = 0xff
1023 }
1024 }
1025 }
1026
1027 func (nnInterpolator) transform_RGBA_YCbCr440_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, opts *Options) {
1028 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1029 dyf := float64(dr.Min.Y+int(dy)) + 0.5
1030 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
1031 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
1032 dxf := float64(dr.Min.X+int(dx)) + 0.5
1033 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
1034 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
1035 if !(image.Point{sx0, sy0}).In(sr) {
1036 continue
1037 }
1038 pi := (sy0-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
1039 pj := ((sy0)/2-src.Rect.Min.Y/2)*src.CStride + (sx0 - src.Rect.Min.X)
1040
1041
1042 pyy1 := int(src.Y[pi]) * 0x10101
1043 pcb1 := int(src.Cb[pj]) - 128
1044 pcr1 := int(src.Cr[pj]) - 128
1045 pr := (pyy1 + 91881*pcr1) >> 8
1046 pg := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
1047 pb := (pyy1 + 116130*pcb1) >> 8
1048 if pr < 0 {
1049 pr = 0
1050 } else if pr > 0xffff {
1051 pr = 0xffff
1052 }
1053 if pg < 0 {
1054 pg = 0
1055 } else if pg > 0xffff {
1056 pg = 0xffff
1057 }
1058 if pb < 0 {
1059 pb = 0
1060 } else if pb > 0xffff {
1061 pb = 0xffff
1062 }
1063 dst.Pix[d+0] = uint8(pr >> 8)
1064 dst.Pix[d+1] = uint8(pg >> 8)
1065 dst.Pix[d+2] = uint8(pb >> 8)
1066 dst.Pix[d+3] = 0xff
1067 }
1068 }
1069 }
1070
1071 func (nnInterpolator) transform_RGBA_RGBA64Image_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, opts *Options) {
1072 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1073 dyf := float64(dr.Min.Y+int(dy)) + 0.5
1074 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
1075 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
1076 dxf := float64(dr.Min.X+int(dx)) + 0.5
1077 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
1078 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
1079 if !(image.Point{sx0, sy0}).In(sr) {
1080 continue
1081 }
1082 p := src.RGBA64At(sx0, sy0)
1083 pa1 := (0xffff - uint32(p.A)) * 0x101
1084 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + uint32(p.R)) >> 8)
1085 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + uint32(p.G)) >> 8)
1086 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + uint32(p.B)) >> 8)
1087 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + uint32(p.A)) >> 8)
1088 }
1089 }
1090 }
1091
1092 func (nnInterpolator) transform_RGBA_RGBA64Image_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, opts *Options) {
1093 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1094 dyf := float64(dr.Min.Y+int(dy)) + 0.5
1095 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
1096 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
1097 dxf := float64(dr.Min.X+int(dx)) + 0.5
1098 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
1099 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
1100 if !(image.Point{sx0, sy0}).In(sr) {
1101 continue
1102 }
1103 p := src.RGBA64At(sx0, sy0)
1104 dst.Pix[d+0] = uint8(p.R >> 8)
1105 dst.Pix[d+1] = uint8(p.G >> 8)
1106 dst.Pix[d+2] = uint8(p.B >> 8)
1107 dst.Pix[d+3] = uint8(p.A >> 8)
1108 }
1109 }
1110 }
1111
1112 func (nnInterpolator) transform_RGBA_Image_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, opts *Options) {
1113 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1114 dyf := float64(dr.Min.Y+int(dy)) + 0.5
1115 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
1116 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
1117 dxf := float64(dr.Min.X+int(dx)) + 0.5
1118 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
1119 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
1120 if !(image.Point{sx0, sy0}).In(sr) {
1121 continue
1122 }
1123 pr, pg, pb, pa := src.At(sx0, sy0).RGBA()
1124 pa1 := (0xffff - pa) * 0x101
1125 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
1126 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
1127 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
1128 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
1129 }
1130 }
1131 }
1132
1133 func (nnInterpolator) transform_RGBA_Image_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, opts *Options) {
1134 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1135 dyf := float64(dr.Min.Y+int(dy)) + 0.5
1136 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
1137 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
1138 dxf := float64(dr.Min.X+int(dx)) + 0.5
1139 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
1140 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
1141 if !(image.Point{sx0, sy0}).In(sr) {
1142 continue
1143 }
1144 pr, pg, pb, pa := src.At(sx0, sy0).RGBA()
1145 dst.Pix[d+0] = uint8(pr >> 8)
1146 dst.Pix[d+1] = uint8(pg >> 8)
1147 dst.Pix[d+2] = uint8(pb >> 8)
1148 dst.Pix[d+3] = uint8(pa >> 8)
1149 }
1150 }
1151 }
1152
1153 func (nnInterpolator) transform_RGBA64Image_RGBA64Image_Over(dst RGBA64Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, opts *Options) {
1154 srcMask, smp := opts.SrcMask, opts.SrcMaskP
1155 dstMask, dmp := opts.DstMask, opts.DstMaskP
1156 dstColorRGBA64 := color.RGBA64{}
1157
1158 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1159 dyf := float64(dr.Min.Y+int(dy)) + 0.5
1160 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
1161 dxf := float64(dr.Min.X+int(dx)) + 0.5
1162 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
1163 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
1164 if !(image.Point{sx0, sy0}).In(sr) {
1165 continue
1166 }
1167 p := src.RGBA64At(sx0, sy0)
1168 if srcMask != nil {
1169 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy0).RGBA()
1170 p.R = uint16(uint32(p.R) * ma / 0xffff)
1171 p.G = uint16(uint32(p.G) * ma / 0xffff)
1172 p.B = uint16(uint32(p.B) * ma / 0xffff)
1173 p.A = uint16(uint32(p.A) * ma / 0xffff)
1174 }
1175 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(dy))
1176 if dstMask != nil {
1177 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
1178 p.R = uint16(uint32(p.R) * ma / 0xffff)
1179 p.G = uint16(uint32(p.G) * ma / 0xffff)
1180 p.B = uint16(uint32(p.B) * ma / 0xffff)
1181 p.A = uint16(uint32(p.A) * ma / 0xffff)
1182 }
1183 pa1 := 0xffff - uint32(p.A)
1184 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + uint32(p.R))
1185 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + uint32(p.G))
1186 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + uint32(p.B))
1187 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + uint32(p.A))
1188 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColorRGBA64)
1189 }
1190 }
1191 }
1192
1193 func (nnInterpolator) transform_RGBA64Image_RGBA64Image_Src(dst RGBA64Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, opts *Options) {
1194 srcMask, smp := opts.SrcMask, opts.SrcMaskP
1195 dstMask, dmp := opts.DstMask, opts.DstMaskP
1196 dstColorRGBA64 := color.RGBA64{}
1197
1198 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1199 dyf := float64(dr.Min.Y+int(dy)) + 0.5
1200 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
1201 dxf := float64(dr.Min.X+int(dx)) + 0.5
1202 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
1203 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
1204 if !(image.Point{sx0, sy0}).In(sr) {
1205 continue
1206 }
1207 p := src.RGBA64At(sx0, sy0)
1208 if srcMask != nil {
1209 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy0).RGBA()
1210 p.R = uint16(uint32(p.R) * ma / 0xffff)
1211 p.G = uint16(uint32(p.G) * ma / 0xffff)
1212 p.B = uint16(uint32(p.B) * ma / 0xffff)
1213 p.A = uint16(uint32(p.A) * ma / 0xffff)
1214 }
1215 if dstMask != nil {
1216 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(dy))
1217 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
1218 p.R = uint16(uint32(p.R) * ma / 0xffff)
1219 p.G = uint16(uint32(p.G) * ma / 0xffff)
1220 p.B = uint16(uint32(p.B) * ma / 0xffff)
1221 p.A = uint16(uint32(p.A) * ma / 0xffff)
1222 pa1 := 0xffff - ma
1223 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + uint32(p.R))
1224 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + uint32(p.G))
1225 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + uint32(p.B))
1226 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + uint32(p.A))
1227 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColorRGBA64)
1228 } else {
1229 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), p)
1230 }
1231 }
1232 }
1233 }
1234
1235 func (nnInterpolator) transform_Image_Image_Over(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, opts *Options) {
1236 srcMask, smp := opts.SrcMask, opts.SrcMaskP
1237 dstMask, dmp := opts.DstMask, opts.DstMaskP
1238 dstColorRGBA64 := &color.RGBA64{}
1239 dstColor := color.Color(dstColorRGBA64)
1240 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1241 dyf := float64(dr.Min.Y+int(dy)) + 0.5
1242 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
1243 dxf := float64(dr.Min.X+int(dx)) + 0.5
1244 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
1245 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
1246 if !(image.Point{sx0, sy0}).In(sr) {
1247 continue
1248 }
1249 pr, pg, pb, pa := src.At(sx0, sy0).RGBA()
1250 if srcMask != nil {
1251 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy0).RGBA()
1252 pr = pr * ma / 0xffff
1253 pg = pg * ma / 0xffff
1254 pb = pb * ma / 0xffff
1255 pa = pa * ma / 0xffff
1256 }
1257 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(dy)).RGBA()
1258 if dstMask != nil {
1259 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
1260 pr = pr * ma / 0xffff
1261 pg = pg * ma / 0xffff
1262 pb = pb * ma / 0xffff
1263 pa = pa * ma / 0xffff
1264 }
1265 pa1 := 0xffff - pa
1266 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr)
1267 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg)
1268 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb)
1269 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa)
1270 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
1271 }
1272 }
1273 }
1274
1275 func (nnInterpolator) transform_Image_Image_Src(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, opts *Options) {
1276 srcMask, smp := opts.SrcMask, opts.SrcMaskP
1277 dstMask, dmp := opts.DstMask, opts.DstMaskP
1278 dstColorRGBA64 := &color.RGBA64{}
1279 dstColor := color.Color(dstColorRGBA64)
1280 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1281 dyf := float64(dr.Min.Y+int(dy)) + 0.5
1282 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
1283 dxf := float64(dr.Min.X+int(dx)) + 0.5
1284 sx0 := int(d2s[0]*dxf+d2s[1]*dyf+d2s[2]) + bias.X
1285 sy0 := int(d2s[3]*dxf+d2s[4]*dyf+d2s[5]) + bias.Y
1286 if !(image.Point{sx0, sy0}).In(sr) {
1287 continue
1288 }
1289 pr, pg, pb, pa := src.At(sx0, sy0).RGBA()
1290 if srcMask != nil {
1291 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy0).RGBA()
1292 pr = pr * ma / 0xffff
1293 pg = pg * ma / 0xffff
1294 pb = pb * ma / 0xffff
1295 pa = pa * ma / 0xffff
1296 }
1297 if dstMask != nil {
1298 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(dy)).RGBA()
1299 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
1300 pr = pr * ma / 0xffff
1301 pg = pg * ma / 0xffff
1302 pb = pb * ma / 0xffff
1303 pa = pa * ma / 0xffff
1304 pa1 := 0xffff - ma
1305 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr)
1306 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg)
1307 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb)
1308 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa)
1309 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
1310 } else {
1311 dstColorRGBA64.R = uint16(pr)
1312 dstColorRGBA64.G = uint16(pg)
1313 dstColorRGBA64.B = uint16(pb)
1314 dstColorRGBA64.A = uint16(pa)
1315 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
1316 }
1317 }
1318 }
1319 }
1320
1321 func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
1322
1323
1324 if dr.Size() == sr.Size() && (opts == nil || opts.DstMask == nil) {
1325 Copy(dst, dr.Min, src, sr, op, opts)
1326 return
1327 }
1328
1329 var o Options
1330 if opts != nil {
1331 o = *opts
1332 }
1333
1334
1335 adr := dst.Bounds().Intersect(dr)
1336 adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP)
1337 if adr.Empty() || sr.Empty() {
1338 return
1339 }
1340
1341 adr = adr.Sub(dr.Min)
1342 if op == Over && o.SrcMask == nil && opaque(src) {
1343 op = Src
1344 }
1345
1346
1347
1348
1349
1350
1351 if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
1352 switch op {
1353 case Over:
1354 z.scale_Image_Image_Over(dst, dr, adr, src, sr, &o)
1355 case Src:
1356 z.scale_Image_Image_Src(dst, dr, adr, src, sr, &o)
1357 }
1358 } else if _, ok := src.(*image.Uniform); ok {
1359 Draw(dst, dr, src, src.Bounds().Min, op)
1360 } else {
1361 switch op {
1362 case Over:
1363 switch dst := dst.(type) {
1364 case *image.RGBA:
1365 switch src := src.(type) {
1366 case *image.NRGBA:
1367 z.scale_RGBA_NRGBA_Over(dst, dr, adr, src, sr, &o)
1368 case *image.RGBA:
1369 z.scale_RGBA_RGBA_Over(dst, dr, adr, src, sr, &o)
1370 case image.RGBA64Image:
1371 z.scale_RGBA_RGBA64Image_Over(dst, dr, adr, src, sr, &o)
1372 default:
1373 z.scale_RGBA_Image_Over(dst, dr, adr, src, sr, &o)
1374 }
1375 case RGBA64Image:
1376 switch src := src.(type) {
1377 case image.RGBA64Image:
1378 z.scale_RGBA64Image_RGBA64Image_Over(dst, dr, adr, src, sr, &o)
1379 }
1380 default:
1381 switch src := src.(type) {
1382 default:
1383 z.scale_Image_Image_Over(dst, dr, adr, src, sr, &o)
1384 }
1385 }
1386 case Src:
1387 switch dst := dst.(type) {
1388 case *image.RGBA:
1389 switch src := src.(type) {
1390 case *image.Gray:
1391 z.scale_RGBA_Gray_Src(dst, dr, adr, src, sr, &o)
1392 case *image.NRGBA:
1393 z.scale_RGBA_NRGBA_Src(dst, dr, adr, src, sr, &o)
1394 case *image.RGBA:
1395 z.scale_RGBA_RGBA_Src(dst, dr, adr, src, sr, &o)
1396 case *image.YCbCr:
1397 switch src.SubsampleRatio {
1398 default:
1399 z.scale_RGBA_Image_Src(dst, dr, adr, src, sr, &o)
1400 case image.YCbCrSubsampleRatio444:
1401 z.scale_RGBA_YCbCr444_Src(dst, dr, adr, src, sr, &o)
1402 case image.YCbCrSubsampleRatio422:
1403 z.scale_RGBA_YCbCr422_Src(dst, dr, adr, src, sr, &o)
1404 case image.YCbCrSubsampleRatio420:
1405 z.scale_RGBA_YCbCr420_Src(dst, dr, adr, src, sr, &o)
1406 case image.YCbCrSubsampleRatio440:
1407 z.scale_RGBA_YCbCr440_Src(dst, dr, adr, src, sr, &o)
1408 }
1409 case image.RGBA64Image:
1410 z.scale_RGBA_RGBA64Image_Src(dst, dr, adr, src, sr, &o)
1411 default:
1412 z.scale_RGBA_Image_Src(dst, dr, adr, src, sr, &o)
1413 }
1414 case RGBA64Image:
1415 switch src := src.(type) {
1416 case image.RGBA64Image:
1417 z.scale_RGBA64Image_RGBA64Image_Src(dst, dr, adr, src, sr, &o)
1418 }
1419 default:
1420 switch src := src.(type) {
1421 default:
1422 z.scale_Image_Image_Src(dst, dr, adr, src, sr, &o)
1423 }
1424 }
1425 }
1426 }
1427 }
1428
1429 func (z ablInterpolator) Transform(dst Image, s2d f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
1430
1431 if s2d[0] == 1 && s2d[1] == 0 && s2d[3] == 0 && s2d[4] == 1 {
1432 dx := int(s2d[2])
1433 dy := int(s2d[5])
1434 if float64(dx) == s2d[2] && float64(dy) == s2d[5] {
1435 Copy(dst, image.Point{X: sr.Min.X + dx, Y: sr.Min.X + dy}, src, sr, op, opts)
1436 return
1437 }
1438 }
1439
1440 var o Options
1441 if opts != nil {
1442 o = *opts
1443 }
1444
1445 dr := transformRect(&s2d, &sr)
1446
1447 adr := dst.Bounds().Intersect(dr)
1448 adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP)
1449 if adr.Empty() || sr.Empty() {
1450 return
1451 }
1452 if op == Over && o.SrcMask == nil && opaque(src) {
1453 op = Src
1454 }
1455
1456 d2s := invert(&s2d)
1457
1458
1459
1460
1461
1462
1463
1464 bias := transformRect(&d2s, &adr).Min
1465 bias.X--
1466 bias.Y--
1467 d2s[2] -= float64(bias.X)
1468 d2s[5] -= float64(bias.Y)
1469
1470 adr = adr.Sub(dr.Min)
1471
1472
1473
1474
1475
1476 if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
1477 switch op {
1478 case Over:
1479 z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
1480 case Src:
1481 z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1482 }
1483 } else if u, ok := src.(*image.Uniform); ok {
1484 transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
1485 } else {
1486 switch op {
1487 case Over:
1488 switch dst := dst.(type) {
1489 case *image.RGBA:
1490 switch src := src.(type) {
1491 case *image.NRGBA:
1492 z.transform_RGBA_NRGBA_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
1493 case *image.RGBA:
1494 z.transform_RGBA_RGBA_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
1495 case image.RGBA64Image:
1496 z.transform_RGBA_RGBA64Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
1497 default:
1498 z.transform_RGBA_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
1499 }
1500 case RGBA64Image:
1501 switch src := src.(type) {
1502 case image.RGBA64Image:
1503 z.transform_RGBA64Image_RGBA64Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
1504 }
1505 default:
1506 switch src := src.(type) {
1507 default:
1508 z.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, &o)
1509 }
1510 }
1511 case Src:
1512 switch dst := dst.(type) {
1513 case *image.RGBA:
1514 switch src := src.(type) {
1515 case *image.Gray:
1516 z.transform_RGBA_Gray_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1517 case *image.NRGBA:
1518 z.transform_RGBA_NRGBA_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1519 case *image.RGBA:
1520 z.transform_RGBA_RGBA_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1521 case *image.YCbCr:
1522 switch src.SubsampleRatio {
1523 default:
1524 z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1525 case image.YCbCrSubsampleRatio444:
1526 z.transform_RGBA_YCbCr444_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1527 case image.YCbCrSubsampleRatio422:
1528 z.transform_RGBA_YCbCr422_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1529 case image.YCbCrSubsampleRatio420:
1530 z.transform_RGBA_YCbCr420_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1531 case image.YCbCrSubsampleRatio440:
1532 z.transform_RGBA_YCbCr440_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1533 }
1534 case image.RGBA64Image:
1535 z.transform_RGBA_RGBA64Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1536 default:
1537 z.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1538 }
1539 case RGBA64Image:
1540 switch src := src.(type) {
1541 case image.RGBA64Image:
1542 z.transform_RGBA64Image_RGBA64Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1543 }
1544 default:
1545 switch src := src.(type) {
1546 default:
1547 z.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, &o)
1548 }
1549 }
1550 }
1551 }
1552 }
1553
1554 func (ablInterpolator) scale_RGBA_Gray_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.Gray, sr image.Rectangle, opts *Options) {
1555 sw := int32(sr.Dx())
1556 sh := int32(sr.Dy())
1557 yscale := float64(sh) / float64(dr.Dy())
1558 xscale := float64(sw) / float64(dr.Dx())
1559 swMinus1, shMinus1 := sw-1, sh-1
1560
1561 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1562 sy := (float64(dy)+0.5)*yscale - 0.5
1563
1564
1565
1566 sy0 := int32(sy)
1567 yFrac0 := sy - float64(sy0)
1568 yFrac1 := 1 - yFrac0
1569 sy1 := sy0 + 1
1570 if sy < 0 {
1571 sy0, sy1 = 0, 0
1572 yFrac0, yFrac1 = 0, 1
1573 } else if sy1 > shMinus1 {
1574 sy0, sy1 = shMinus1, shMinus1
1575 yFrac0, yFrac1 = 1, 0
1576 }
1577 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
1578
1579 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
1580 sx := (float64(dx)+0.5)*xscale - 0.5
1581 sx0 := int32(sx)
1582 xFrac0 := sx - float64(sx0)
1583 xFrac1 := 1 - xFrac0
1584 sx1 := sx0 + 1
1585 if sx < 0 {
1586 sx0, sx1 = 0, 0
1587 xFrac0, xFrac1 = 0, 1
1588 } else if sx1 > swMinus1 {
1589 sx0, sx1 = swMinus1, swMinus1
1590 xFrac0, xFrac1 = 1, 0
1591 }
1592
1593 s00i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.Stride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
1594 s00ru := uint32(src.Pix[s00i]) * 0x101
1595 s00r := float64(s00ru)
1596 s10i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.Stride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
1597 s10ru := uint32(src.Pix[s10i]) * 0x101
1598 s10r := float64(s10ru)
1599 s10r = xFrac1*s00r + xFrac0*s10r
1600 s01i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.Stride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
1601 s01ru := uint32(src.Pix[s01i]) * 0x101
1602 s01r := float64(s01ru)
1603 s11i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.Stride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
1604 s11ru := uint32(src.Pix[s11i]) * 0x101
1605 s11r := float64(s11ru)
1606 s11r = xFrac1*s01r + xFrac0*s11r
1607 s11r = yFrac1*s10r + yFrac0*s11r
1608 pr := uint32(s11r)
1609 out := uint8(pr >> 8)
1610 dst.Pix[d+0] = out
1611 dst.Pix[d+1] = out
1612 dst.Pix[d+2] = out
1613 dst.Pix[d+3] = 0xff
1614 }
1615 }
1616 }
1617
1618 func (ablInterpolator) scale_RGBA_NRGBA_Over(dst *image.RGBA, dr, adr image.Rectangle, src *image.NRGBA, sr image.Rectangle, opts *Options) {
1619 sw := int32(sr.Dx())
1620 sh := int32(sr.Dy())
1621 yscale := float64(sh) / float64(dr.Dy())
1622 xscale := float64(sw) / float64(dr.Dx())
1623 swMinus1, shMinus1 := sw-1, sh-1
1624
1625 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1626 sy := (float64(dy)+0.5)*yscale - 0.5
1627
1628
1629
1630 sy0 := int32(sy)
1631 yFrac0 := sy - float64(sy0)
1632 yFrac1 := 1 - yFrac0
1633 sy1 := sy0 + 1
1634 if sy < 0 {
1635 sy0, sy1 = 0, 0
1636 yFrac0, yFrac1 = 0, 1
1637 } else if sy1 > shMinus1 {
1638 sy0, sy1 = shMinus1, shMinus1
1639 yFrac0, yFrac1 = 1, 0
1640 }
1641 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
1642
1643 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
1644 sx := (float64(dx)+0.5)*xscale - 0.5
1645 sx0 := int32(sx)
1646 xFrac0 := sx - float64(sx0)
1647 xFrac1 := 1 - xFrac0
1648 sx1 := sx0 + 1
1649 if sx < 0 {
1650 sx0, sx1 = 0, 0
1651 xFrac0, xFrac1 = 0, 1
1652 } else if sx1 > swMinus1 {
1653 sx0, sx1 = swMinus1, swMinus1
1654 xFrac0, xFrac1 = 1, 0
1655 }
1656
1657 s00i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx0)-src.Rect.Min.X)*4
1658 s00au := uint32(src.Pix[s00i+3]) * 0x101
1659 s00ru := uint32(src.Pix[s00i+0]) * s00au / 0xff
1660 s00gu := uint32(src.Pix[s00i+1]) * s00au / 0xff
1661 s00bu := uint32(src.Pix[s00i+2]) * s00au / 0xff
1662 s00r := float64(s00ru)
1663 s00g := float64(s00gu)
1664 s00b := float64(s00bu)
1665 s00a := float64(s00au)
1666 s10i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx1)-src.Rect.Min.X)*4
1667 s10au := uint32(src.Pix[s10i+3]) * 0x101
1668 s10ru := uint32(src.Pix[s10i+0]) * s10au / 0xff
1669 s10gu := uint32(src.Pix[s10i+1]) * s10au / 0xff
1670 s10bu := uint32(src.Pix[s10i+2]) * s10au / 0xff
1671 s10r := float64(s10ru)
1672 s10g := float64(s10gu)
1673 s10b := float64(s10bu)
1674 s10a := float64(s10au)
1675 s10r = xFrac1*s00r + xFrac0*s10r
1676 s10g = xFrac1*s00g + xFrac0*s10g
1677 s10b = xFrac1*s00b + xFrac0*s10b
1678 s10a = xFrac1*s00a + xFrac0*s10a
1679 s01i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx0)-src.Rect.Min.X)*4
1680 s01au := uint32(src.Pix[s01i+3]) * 0x101
1681 s01ru := uint32(src.Pix[s01i+0]) * s01au / 0xff
1682 s01gu := uint32(src.Pix[s01i+1]) * s01au / 0xff
1683 s01bu := uint32(src.Pix[s01i+2]) * s01au / 0xff
1684 s01r := float64(s01ru)
1685 s01g := float64(s01gu)
1686 s01b := float64(s01bu)
1687 s01a := float64(s01au)
1688 s11i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx1)-src.Rect.Min.X)*4
1689 s11au := uint32(src.Pix[s11i+3]) * 0x101
1690 s11ru := uint32(src.Pix[s11i+0]) * s11au / 0xff
1691 s11gu := uint32(src.Pix[s11i+1]) * s11au / 0xff
1692 s11bu := uint32(src.Pix[s11i+2]) * s11au / 0xff
1693 s11r := float64(s11ru)
1694 s11g := float64(s11gu)
1695 s11b := float64(s11bu)
1696 s11a := float64(s11au)
1697 s11r = xFrac1*s01r + xFrac0*s11r
1698 s11g = xFrac1*s01g + xFrac0*s11g
1699 s11b = xFrac1*s01b + xFrac0*s11b
1700 s11a = xFrac1*s01a + xFrac0*s11a
1701 s11r = yFrac1*s10r + yFrac0*s11r
1702 s11g = yFrac1*s10g + yFrac0*s11g
1703 s11b = yFrac1*s10b + yFrac0*s11b
1704 s11a = yFrac1*s10a + yFrac0*s11a
1705 pr := uint32(s11r)
1706 pg := uint32(s11g)
1707 pb := uint32(s11b)
1708 pa := uint32(s11a)
1709 pa1 := (0xffff - pa) * 0x101
1710 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
1711 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
1712 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
1713 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
1714 }
1715 }
1716 }
1717
1718 func (ablInterpolator) scale_RGBA_NRGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.NRGBA, sr image.Rectangle, opts *Options) {
1719 sw := int32(sr.Dx())
1720 sh := int32(sr.Dy())
1721 yscale := float64(sh) / float64(dr.Dy())
1722 xscale := float64(sw) / float64(dr.Dx())
1723 swMinus1, shMinus1 := sw-1, sh-1
1724
1725 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1726 sy := (float64(dy)+0.5)*yscale - 0.5
1727
1728
1729
1730 sy0 := int32(sy)
1731 yFrac0 := sy - float64(sy0)
1732 yFrac1 := 1 - yFrac0
1733 sy1 := sy0 + 1
1734 if sy < 0 {
1735 sy0, sy1 = 0, 0
1736 yFrac0, yFrac1 = 0, 1
1737 } else if sy1 > shMinus1 {
1738 sy0, sy1 = shMinus1, shMinus1
1739 yFrac0, yFrac1 = 1, 0
1740 }
1741 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
1742
1743 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
1744 sx := (float64(dx)+0.5)*xscale - 0.5
1745 sx0 := int32(sx)
1746 xFrac0 := sx - float64(sx0)
1747 xFrac1 := 1 - xFrac0
1748 sx1 := sx0 + 1
1749 if sx < 0 {
1750 sx0, sx1 = 0, 0
1751 xFrac0, xFrac1 = 0, 1
1752 } else if sx1 > swMinus1 {
1753 sx0, sx1 = swMinus1, swMinus1
1754 xFrac0, xFrac1 = 1, 0
1755 }
1756
1757 s00i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx0)-src.Rect.Min.X)*4
1758 s00au := uint32(src.Pix[s00i+3]) * 0x101
1759 s00ru := uint32(src.Pix[s00i+0]) * s00au / 0xff
1760 s00gu := uint32(src.Pix[s00i+1]) * s00au / 0xff
1761 s00bu := uint32(src.Pix[s00i+2]) * s00au / 0xff
1762 s00r := float64(s00ru)
1763 s00g := float64(s00gu)
1764 s00b := float64(s00bu)
1765 s00a := float64(s00au)
1766 s10i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx1)-src.Rect.Min.X)*4
1767 s10au := uint32(src.Pix[s10i+3]) * 0x101
1768 s10ru := uint32(src.Pix[s10i+0]) * s10au / 0xff
1769 s10gu := uint32(src.Pix[s10i+1]) * s10au / 0xff
1770 s10bu := uint32(src.Pix[s10i+2]) * s10au / 0xff
1771 s10r := float64(s10ru)
1772 s10g := float64(s10gu)
1773 s10b := float64(s10bu)
1774 s10a := float64(s10au)
1775 s10r = xFrac1*s00r + xFrac0*s10r
1776 s10g = xFrac1*s00g + xFrac0*s10g
1777 s10b = xFrac1*s00b + xFrac0*s10b
1778 s10a = xFrac1*s00a + xFrac0*s10a
1779 s01i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx0)-src.Rect.Min.X)*4
1780 s01au := uint32(src.Pix[s01i+3]) * 0x101
1781 s01ru := uint32(src.Pix[s01i+0]) * s01au / 0xff
1782 s01gu := uint32(src.Pix[s01i+1]) * s01au / 0xff
1783 s01bu := uint32(src.Pix[s01i+2]) * s01au / 0xff
1784 s01r := float64(s01ru)
1785 s01g := float64(s01gu)
1786 s01b := float64(s01bu)
1787 s01a := float64(s01au)
1788 s11i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx1)-src.Rect.Min.X)*4
1789 s11au := uint32(src.Pix[s11i+3]) * 0x101
1790 s11ru := uint32(src.Pix[s11i+0]) * s11au / 0xff
1791 s11gu := uint32(src.Pix[s11i+1]) * s11au / 0xff
1792 s11bu := uint32(src.Pix[s11i+2]) * s11au / 0xff
1793 s11r := float64(s11ru)
1794 s11g := float64(s11gu)
1795 s11b := float64(s11bu)
1796 s11a := float64(s11au)
1797 s11r = xFrac1*s01r + xFrac0*s11r
1798 s11g = xFrac1*s01g + xFrac0*s11g
1799 s11b = xFrac1*s01b + xFrac0*s11b
1800 s11a = xFrac1*s01a + xFrac0*s11a
1801 s11r = yFrac1*s10r + yFrac0*s11r
1802 s11g = yFrac1*s10g + yFrac0*s11g
1803 s11b = yFrac1*s10b + yFrac0*s11b
1804 s11a = yFrac1*s10a + yFrac0*s11a
1805 pr := uint32(s11r)
1806 pg := uint32(s11g)
1807 pb := uint32(s11b)
1808 pa := uint32(s11a)
1809 dst.Pix[d+0] = uint8(pr >> 8)
1810 dst.Pix[d+1] = uint8(pg >> 8)
1811 dst.Pix[d+2] = uint8(pb >> 8)
1812 dst.Pix[d+3] = uint8(pa >> 8)
1813 }
1814 }
1815 }
1816
1817 func (ablInterpolator) scale_RGBA_RGBA_Over(dst *image.RGBA, dr, adr image.Rectangle, src *image.RGBA, sr image.Rectangle, opts *Options) {
1818 sw := int32(sr.Dx())
1819 sh := int32(sr.Dy())
1820 yscale := float64(sh) / float64(dr.Dy())
1821 xscale := float64(sw) / float64(dr.Dx())
1822 swMinus1, shMinus1 := sw-1, sh-1
1823
1824 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1825 sy := (float64(dy)+0.5)*yscale - 0.5
1826
1827
1828
1829 sy0 := int32(sy)
1830 yFrac0 := sy - float64(sy0)
1831 yFrac1 := 1 - yFrac0
1832 sy1 := sy0 + 1
1833 if sy < 0 {
1834 sy0, sy1 = 0, 0
1835 yFrac0, yFrac1 = 0, 1
1836 } else if sy1 > shMinus1 {
1837 sy0, sy1 = shMinus1, shMinus1
1838 yFrac0, yFrac1 = 1, 0
1839 }
1840 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
1841
1842 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
1843 sx := (float64(dx)+0.5)*xscale - 0.5
1844 sx0 := int32(sx)
1845 xFrac0 := sx - float64(sx0)
1846 xFrac1 := 1 - xFrac0
1847 sx1 := sx0 + 1
1848 if sx < 0 {
1849 sx0, sx1 = 0, 0
1850 xFrac0, xFrac1 = 0, 1
1851 } else if sx1 > swMinus1 {
1852 sx0, sx1 = swMinus1, swMinus1
1853 xFrac0, xFrac1 = 1, 0
1854 }
1855
1856 s00i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx0)-src.Rect.Min.X)*4
1857 s00ru := uint32(src.Pix[s00i+0]) * 0x101
1858 s00gu := uint32(src.Pix[s00i+1]) * 0x101
1859 s00bu := uint32(src.Pix[s00i+2]) * 0x101
1860 s00au := uint32(src.Pix[s00i+3]) * 0x101
1861 s00r := float64(s00ru)
1862 s00g := float64(s00gu)
1863 s00b := float64(s00bu)
1864 s00a := float64(s00au)
1865 s10i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx1)-src.Rect.Min.X)*4
1866 s10ru := uint32(src.Pix[s10i+0]) * 0x101
1867 s10gu := uint32(src.Pix[s10i+1]) * 0x101
1868 s10bu := uint32(src.Pix[s10i+2]) * 0x101
1869 s10au := uint32(src.Pix[s10i+3]) * 0x101
1870 s10r := float64(s10ru)
1871 s10g := float64(s10gu)
1872 s10b := float64(s10bu)
1873 s10a := float64(s10au)
1874 s10r = xFrac1*s00r + xFrac0*s10r
1875 s10g = xFrac1*s00g + xFrac0*s10g
1876 s10b = xFrac1*s00b + xFrac0*s10b
1877 s10a = xFrac1*s00a + xFrac0*s10a
1878 s01i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx0)-src.Rect.Min.X)*4
1879 s01ru := uint32(src.Pix[s01i+0]) * 0x101
1880 s01gu := uint32(src.Pix[s01i+1]) * 0x101
1881 s01bu := uint32(src.Pix[s01i+2]) * 0x101
1882 s01au := uint32(src.Pix[s01i+3]) * 0x101
1883 s01r := float64(s01ru)
1884 s01g := float64(s01gu)
1885 s01b := float64(s01bu)
1886 s01a := float64(s01au)
1887 s11i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx1)-src.Rect.Min.X)*4
1888 s11ru := uint32(src.Pix[s11i+0]) * 0x101
1889 s11gu := uint32(src.Pix[s11i+1]) * 0x101
1890 s11bu := uint32(src.Pix[s11i+2]) * 0x101
1891 s11au := uint32(src.Pix[s11i+3]) * 0x101
1892 s11r := float64(s11ru)
1893 s11g := float64(s11gu)
1894 s11b := float64(s11bu)
1895 s11a := float64(s11au)
1896 s11r = xFrac1*s01r + xFrac0*s11r
1897 s11g = xFrac1*s01g + xFrac0*s11g
1898 s11b = xFrac1*s01b + xFrac0*s11b
1899 s11a = xFrac1*s01a + xFrac0*s11a
1900 s11r = yFrac1*s10r + yFrac0*s11r
1901 s11g = yFrac1*s10g + yFrac0*s11g
1902 s11b = yFrac1*s10b + yFrac0*s11b
1903 s11a = yFrac1*s10a + yFrac0*s11a
1904 pr := uint32(s11r)
1905 pg := uint32(s11g)
1906 pb := uint32(s11b)
1907 pa := uint32(s11a)
1908 pa1 := (0xffff - pa) * 0x101
1909 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
1910 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
1911 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
1912 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
1913 }
1914 }
1915 }
1916
1917 func (ablInterpolator) scale_RGBA_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.RGBA, sr image.Rectangle, opts *Options) {
1918 sw := int32(sr.Dx())
1919 sh := int32(sr.Dy())
1920 yscale := float64(sh) / float64(dr.Dy())
1921 xscale := float64(sw) / float64(dr.Dx())
1922 swMinus1, shMinus1 := sw-1, sh-1
1923
1924 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
1925 sy := (float64(dy)+0.5)*yscale - 0.5
1926
1927
1928
1929 sy0 := int32(sy)
1930 yFrac0 := sy - float64(sy0)
1931 yFrac1 := 1 - yFrac0
1932 sy1 := sy0 + 1
1933 if sy < 0 {
1934 sy0, sy1 = 0, 0
1935 yFrac0, yFrac1 = 0, 1
1936 } else if sy1 > shMinus1 {
1937 sy0, sy1 = shMinus1, shMinus1
1938 yFrac0, yFrac1 = 1, 0
1939 }
1940 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
1941
1942 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
1943 sx := (float64(dx)+0.5)*xscale - 0.5
1944 sx0 := int32(sx)
1945 xFrac0 := sx - float64(sx0)
1946 xFrac1 := 1 - xFrac0
1947 sx1 := sx0 + 1
1948 if sx < 0 {
1949 sx0, sx1 = 0, 0
1950 xFrac0, xFrac1 = 0, 1
1951 } else if sx1 > swMinus1 {
1952 sx0, sx1 = swMinus1, swMinus1
1953 xFrac0, xFrac1 = 1, 0
1954 }
1955
1956 s00i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx0)-src.Rect.Min.X)*4
1957 s00ru := uint32(src.Pix[s00i+0]) * 0x101
1958 s00gu := uint32(src.Pix[s00i+1]) * 0x101
1959 s00bu := uint32(src.Pix[s00i+2]) * 0x101
1960 s00au := uint32(src.Pix[s00i+3]) * 0x101
1961 s00r := float64(s00ru)
1962 s00g := float64(s00gu)
1963 s00b := float64(s00bu)
1964 s00a := float64(s00au)
1965 s10i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx1)-src.Rect.Min.X)*4
1966 s10ru := uint32(src.Pix[s10i+0]) * 0x101
1967 s10gu := uint32(src.Pix[s10i+1]) * 0x101
1968 s10bu := uint32(src.Pix[s10i+2]) * 0x101
1969 s10au := uint32(src.Pix[s10i+3]) * 0x101
1970 s10r := float64(s10ru)
1971 s10g := float64(s10gu)
1972 s10b := float64(s10bu)
1973 s10a := float64(s10au)
1974 s10r = xFrac1*s00r + xFrac0*s10r
1975 s10g = xFrac1*s00g + xFrac0*s10g
1976 s10b = xFrac1*s00b + xFrac0*s10b
1977 s10a = xFrac1*s00a + xFrac0*s10a
1978 s01i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx0)-src.Rect.Min.X)*4
1979 s01ru := uint32(src.Pix[s01i+0]) * 0x101
1980 s01gu := uint32(src.Pix[s01i+1]) * 0x101
1981 s01bu := uint32(src.Pix[s01i+2]) * 0x101
1982 s01au := uint32(src.Pix[s01i+3]) * 0x101
1983 s01r := float64(s01ru)
1984 s01g := float64(s01gu)
1985 s01b := float64(s01bu)
1986 s01a := float64(s01au)
1987 s11i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(sx1)-src.Rect.Min.X)*4
1988 s11ru := uint32(src.Pix[s11i+0]) * 0x101
1989 s11gu := uint32(src.Pix[s11i+1]) * 0x101
1990 s11bu := uint32(src.Pix[s11i+2]) * 0x101
1991 s11au := uint32(src.Pix[s11i+3]) * 0x101
1992 s11r := float64(s11ru)
1993 s11g := float64(s11gu)
1994 s11b := float64(s11bu)
1995 s11a := float64(s11au)
1996 s11r = xFrac1*s01r + xFrac0*s11r
1997 s11g = xFrac1*s01g + xFrac0*s11g
1998 s11b = xFrac1*s01b + xFrac0*s11b
1999 s11a = xFrac1*s01a + xFrac0*s11a
2000 s11r = yFrac1*s10r + yFrac0*s11r
2001 s11g = yFrac1*s10g + yFrac0*s11g
2002 s11b = yFrac1*s10b + yFrac0*s11b
2003 s11a = yFrac1*s10a + yFrac0*s11a
2004 pr := uint32(s11r)
2005 pg := uint32(s11g)
2006 pb := uint32(s11b)
2007 pa := uint32(s11a)
2008 dst.Pix[d+0] = uint8(pr >> 8)
2009 dst.Pix[d+1] = uint8(pg >> 8)
2010 dst.Pix[d+2] = uint8(pb >> 8)
2011 dst.Pix[d+3] = uint8(pa >> 8)
2012 }
2013 }
2014 }
2015
2016 func (ablInterpolator) scale_RGBA_YCbCr444_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle, opts *Options) {
2017 sw := int32(sr.Dx())
2018 sh := int32(sr.Dy())
2019 yscale := float64(sh) / float64(dr.Dy())
2020 xscale := float64(sw) / float64(dr.Dx())
2021 swMinus1, shMinus1 := sw-1, sh-1
2022
2023 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
2024 sy := (float64(dy)+0.5)*yscale - 0.5
2025
2026
2027
2028 sy0 := int32(sy)
2029 yFrac0 := sy - float64(sy0)
2030 yFrac1 := 1 - yFrac0
2031 sy1 := sy0 + 1
2032 if sy < 0 {
2033 sy0, sy1 = 0, 0
2034 yFrac0, yFrac1 = 0, 1
2035 } else if sy1 > shMinus1 {
2036 sy0, sy1 = shMinus1, shMinus1
2037 yFrac0, yFrac1 = 1, 0
2038 }
2039 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
2040
2041 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
2042 sx := (float64(dx)+0.5)*xscale - 0.5
2043 sx0 := int32(sx)
2044 xFrac0 := sx - float64(sx0)
2045 xFrac1 := 1 - xFrac0
2046 sx1 := sx0 + 1
2047 if sx < 0 {
2048 sx0, sx1 = 0, 0
2049 xFrac0, xFrac1 = 0, 1
2050 } else if sx1 > swMinus1 {
2051 sx0, sx1 = swMinus1, swMinus1
2052 xFrac0, xFrac1 = 1, 0
2053 }
2054
2055 s00i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2056 s00j := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.CStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2057
2058
2059 s00yy1 := int(src.Y[s00i]) * 0x10101
2060 s00cb1 := int(src.Cb[s00j]) - 128
2061 s00cr1 := int(src.Cr[s00j]) - 128
2062 s00ru := (s00yy1 + 91881*s00cr1) >> 8
2063 s00gu := (s00yy1 - 22554*s00cb1 - 46802*s00cr1) >> 8
2064 s00bu := (s00yy1 + 116130*s00cb1) >> 8
2065 if s00ru < 0 {
2066 s00ru = 0
2067 } else if s00ru > 0xffff {
2068 s00ru = 0xffff
2069 }
2070 if s00gu < 0 {
2071 s00gu = 0
2072 } else if s00gu > 0xffff {
2073 s00gu = 0xffff
2074 }
2075 if s00bu < 0 {
2076 s00bu = 0
2077 } else if s00bu > 0xffff {
2078 s00bu = 0xffff
2079 }
2080
2081 s00r := float64(s00ru)
2082 s00g := float64(s00gu)
2083 s00b := float64(s00bu)
2084 s10i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2085 s10j := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.CStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2086
2087
2088 s10yy1 := int(src.Y[s10i]) * 0x10101
2089 s10cb1 := int(src.Cb[s10j]) - 128
2090 s10cr1 := int(src.Cr[s10j]) - 128
2091 s10ru := (s10yy1 + 91881*s10cr1) >> 8
2092 s10gu := (s10yy1 - 22554*s10cb1 - 46802*s10cr1) >> 8
2093 s10bu := (s10yy1 + 116130*s10cb1) >> 8
2094 if s10ru < 0 {
2095 s10ru = 0
2096 } else if s10ru > 0xffff {
2097 s10ru = 0xffff
2098 }
2099 if s10gu < 0 {
2100 s10gu = 0
2101 } else if s10gu > 0xffff {
2102 s10gu = 0xffff
2103 }
2104 if s10bu < 0 {
2105 s10bu = 0
2106 } else if s10bu > 0xffff {
2107 s10bu = 0xffff
2108 }
2109
2110 s10r := float64(s10ru)
2111 s10g := float64(s10gu)
2112 s10b := float64(s10bu)
2113 s10r = xFrac1*s00r + xFrac0*s10r
2114 s10g = xFrac1*s00g + xFrac0*s10g
2115 s10b = xFrac1*s00b + xFrac0*s10b
2116 s01i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2117 s01j := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.CStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2118
2119
2120 s01yy1 := int(src.Y[s01i]) * 0x10101
2121 s01cb1 := int(src.Cb[s01j]) - 128
2122 s01cr1 := int(src.Cr[s01j]) - 128
2123 s01ru := (s01yy1 + 91881*s01cr1) >> 8
2124 s01gu := (s01yy1 - 22554*s01cb1 - 46802*s01cr1) >> 8
2125 s01bu := (s01yy1 + 116130*s01cb1) >> 8
2126 if s01ru < 0 {
2127 s01ru = 0
2128 } else if s01ru > 0xffff {
2129 s01ru = 0xffff
2130 }
2131 if s01gu < 0 {
2132 s01gu = 0
2133 } else if s01gu > 0xffff {
2134 s01gu = 0xffff
2135 }
2136 if s01bu < 0 {
2137 s01bu = 0
2138 } else if s01bu > 0xffff {
2139 s01bu = 0xffff
2140 }
2141
2142 s01r := float64(s01ru)
2143 s01g := float64(s01gu)
2144 s01b := float64(s01bu)
2145 s11i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2146 s11j := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.CStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2147
2148
2149 s11yy1 := int(src.Y[s11i]) * 0x10101
2150 s11cb1 := int(src.Cb[s11j]) - 128
2151 s11cr1 := int(src.Cr[s11j]) - 128
2152 s11ru := (s11yy1 + 91881*s11cr1) >> 8
2153 s11gu := (s11yy1 - 22554*s11cb1 - 46802*s11cr1) >> 8
2154 s11bu := (s11yy1 + 116130*s11cb1) >> 8
2155 if s11ru < 0 {
2156 s11ru = 0
2157 } else if s11ru > 0xffff {
2158 s11ru = 0xffff
2159 }
2160 if s11gu < 0 {
2161 s11gu = 0
2162 } else if s11gu > 0xffff {
2163 s11gu = 0xffff
2164 }
2165 if s11bu < 0 {
2166 s11bu = 0
2167 } else if s11bu > 0xffff {
2168 s11bu = 0xffff
2169 }
2170
2171 s11r := float64(s11ru)
2172 s11g := float64(s11gu)
2173 s11b := float64(s11bu)
2174 s11r = xFrac1*s01r + xFrac0*s11r
2175 s11g = xFrac1*s01g + xFrac0*s11g
2176 s11b = xFrac1*s01b + xFrac0*s11b
2177 s11r = yFrac1*s10r + yFrac0*s11r
2178 s11g = yFrac1*s10g + yFrac0*s11g
2179 s11b = yFrac1*s10b + yFrac0*s11b
2180 pr := uint32(s11r)
2181 pg := uint32(s11g)
2182 pb := uint32(s11b)
2183 dst.Pix[d+0] = uint8(pr >> 8)
2184 dst.Pix[d+1] = uint8(pg >> 8)
2185 dst.Pix[d+2] = uint8(pb >> 8)
2186 dst.Pix[d+3] = 0xff
2187 }
2188 }
2189 }
2190
2191 func (ablInterpolator) scale_RGBA_YCbCr422_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle, opts *Options) {
2192 sw := int32(sr.Dx())
2193 sh := int32(sr.Dy())
2194 yscale := float64(sh) / float64(dr.Dy())
2195 xscale := float64(sw) / float64(dr.Dx())
2196 swMinus1, shMinus1 := sw-1, sh-1
2197
2198 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
2199 sy := (float64(dy)+0.5)*yscale - 0.5
2200
2201
2202
2203 sy0 := int32(sy)
2204 yFrac0 := sy - float64(sy0)
2205 yFrac1 := 1 - yFrac0
2206 sy1 := sy0 + 1
2207 if sy < 0 {
2208 sy0, sy1 = 0, 0
2209 yFrac0, yFrac1 = 0, 1
2210 } else if sy1 > shMinus1 {
2211 sy0, sy1 = shMinus1, shMinus1
2212 yFrac0, yFrac1 = 1, 0
2213 }
2214 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
2215
2216 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
2217 sx := (float64(dx)+0.5)*xscale - 0.5
2218 sx0 := int32(sx)
2219 xFrac0 := sx - float64(sx0)
2220 xFrac1 := 1 - xFrac0
2221 sx1 := sx0 + 1
2222 if sx < 0 {
2223 sx0, sx1 = 0, 0
2224 xFrac0, xFrac1 = 0, 1
2225 } else if sx1 > swMinus1 {
2226 sx0, sx1 = swMinus1, swMinus1
2227 xFrac0, xFrac1 = 1, 0
2228 }
2229
2230 s00i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2231 s00j := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.CStride + ((sr.Min.X+int(sx0))/2 - src.Rect.Min.X/2)
2232
2233
2234 s00yy1 := int(src.Y[s00i]) * 0x10101
2235 s00cb1 := int(src.Cb[s00j]) - 128
2236 s00cr1 := int(src.Cr[s00j]) - 128
2237 s00ru := (s00yy1 + 91881*s00cr1) >> 8
2238 s00gu := (s00yy1 - 22554*s00cb1 - 46802*s00cr1) >> 8
2239 s00bu := (s00yy1 + 116130*s00cb1) >> 8
2240 if s00ru < 0 {
2241 s00ru = 0
2242 } else if s00ru > 0xffff {
2243 s00ru = 0xffff
2244 }
2245 if s00gu < 0 {
2246 s00gu = 0
2247 } else if s00gu > 0xffff {
2248 s00gu = 0xffff
2249 }
2250 if s00bu < 0 {
2251 s00bu = 0
2252 } else if s00bu > 0xffff {
2253 s00bu = 0xffff
2254 }
2255
2256 s00r := float64(s00ru)
2257 s00g := float64(s00gu)
2258 s00b := float64(s00bu)
2259 s10i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2260 s10j := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.CStride + ((sr.Min.X+int(sx1))/2 - src.Rect.Min.X/2)
2261
2262
2263 s10yy1 := int(src.Y[s10i]) * 0x10101
2264 s10cb1 := int(src.Cb[s10j]) - 128
2265 s10cr1 := int(src.Cr[s10j]) - 128
2266 s10ru := (s10yy1 + 91881*s10cr1) >> 8
2267 s10gu := (s10yy1 - 22554*s10cb1 - 46802*s10cr1) >> 8
2268 s10bu := (s10yy1 + 116130*s10cb1) >> 8
2269 if s10ru < 0 {
2270 s10ru = 0
2271 } else if s10ru > 0xffff {
2272 s10ru = 0xffff
2273 }
2274 if s10gu < 0 {
2275 s10gu = 0
2276 } else if s10gu > 0xffff {
2277 s10gu = 0xffff
2278 }
2279 if s10bu < 0 {
2280 s10bu = 0
2281 } else if s10bu > 0xffff {
2282 s10bu = 0xffff
2283 }
2284
2285 s10r := float64(s10ru)
2286 s10g := float64(s10gu)
2287 s10b := float64(s10bu)
2288 s10r = xFrac1*s00r + xFrac0*s10r
2289 s10g = xFrac1*s00g + xFrac0*s10g
2290 s10b = xFrac1*s00b + xFrac0*s10b
2291 s01i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2292 s01j := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.CStride + ((sr.Min.X+int(sx0))/2 - src.Rect.Min.X/2)
2293
2294
2295 s01yy1 := int(src.Y[s01i]) * 0x10101
2296 s01cb1 := int(src.Cb[s01j]) - 128
2297 s01cr1 := int(src.Cr[s01j]) - 128
2298 s01ru := (s01yy1 + 91881*s01cr1) >> 8
2299 s01gu := (s01yy1 - 22554*s01cb1 - 46802*s01cr1) >> 8
2300 s01bu := (s01yy1 + 116130*s01cb1) >> 8
2301 if s01ru < 0 {
2302 s01ru = 0
2303 } else if s01ru > 0xffff {
2304 s01ru = 0xffff
2305 }
2306 if s01gu < 0 {
2307 s01gu = 0
2308 } else if s01gu > 0xffff {
2309 s01gu = 0xffff
2310 }
2311 if s01bu < 0 {
2312 s01bu = 0
2313 } else if s01bu > 0xffff {
2314 s01bu = 0xffff
2315 }
2316
2317 s01r := float64(s01ru)
2318 s01g := float64(s01gu)
2319 s01b := float64(s01bu)
2320 s11i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2321 s11j := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.CStride + ((sr.Min.X+int(sx1))/2 - src.Rect.Min.X/2)
2322
2323
2324 s11yy1 := int(src.Y[s11i]) * 0x10101
2325 s11cb1 := int(src.Cb[s11j]) - 128
2326 s11cr1 := int(src.Cr[s11j]) - 128
2327 s11ru := (s11yy1 + 91881*s11cr1) >> 8
2328 s11gu := (s11yy1 - 22554*s11cb1 - 46802*s11cr1) >> 8
2329 s11bu := (s11yy1 + 116130*s11cb1) >> 8
2330 if s11ru < 0 {
2331 s11ru = 0
2332 } else if s11ru > 0xffff {
2333 s11ru = 0xffff
2334 }
2335 if s11gu < 0 {
2336 s11gu = 0
2337 } else if s11gu > 0xffff {
2338 s11gu = 0xffff
2339 }
2340 if s11bu < 0 {
2341 s11bu = 0
2342 } else if s11bu > 0xffff {
2343 s11bu = 0xffff
2344 }
2345
2346 s11r := float64(s11ru)
2347 s11g := float64(s11gu)
2348 s11b := float64(s11bu)
2349 s11r = xFrac1*s01r + xFrac0*s11r
2350 s11g = xFrac1*s01g + xFrac0*s11g
2351 s11b = xFrac1*s01b + xFrac0*s11b
2352 s11r = yFrac1*s10r + yFrac0*s11r
2353 s11g = yFrac1*s10g + yFrac0*s11g
2354 s11b = yFrac1*s10b + yFrac0*s11b
2355 pr := uint32(s11r)
2356 pg := uint32(s11g)
2357 pb := uint32(s11b)
2358 dst.Pix[d+0] = uint8(pr >> 8)
2359 dst.Pix[d+1] = uint8(pg >> 8)
2360 dst.Pix[d+2] = uint8(pb >> 8)
2361 dst.Pix[d+3] = 0xff
2362 }
2363 }
2364 }
2365
2366 func (ablInterpolator) scale_RGBA_YCbCr420_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle, opts *Options) {
2367 sw := int32(sr.Dx())
2368 sh := int32(sr.Dy())
2369 yscale := float64(sh) / float64(dr.Dy())
2370 xscale := float64(sw) / float64(dr.Dx())
2371 swMinus1, shMinus1 := sw-1, sh-1
2372
2373 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
2374 sy := (float64(dy)+0.5)*yscale - 0.5
2375
2376
2377
2378 sy0 := int32(sy)
2379 yFrac0 := sy - float64(sy0)
2380 yFrac1 := 1 - yFrac0
2381 sy1 := sy0 + 1
2382 if sy < 0 {
2383 sy0, sy1 = 0, 0
2384 yFrac0, yFrac1 = 0, 1
2385 } else if sy1 > shMinus1 {
2386 sy0, sy1 = shMinus1, shMinus1
2387 yFrac0, yFrac1 = 1, 0
2388 }
2389 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
2390
2391 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
2392 sx := (float64(dx)+0.5)*xscale - 0.5
2393 sx0 := int32(sx)
2394 xFrac0 := sx - float64(sx0)
2395 xFrac1 := 1 - xFrac0
2396 sx1 := sx0 + 1
2397 if sx < 0 {
2398 sx0, sx1 = 0, 0
2399 xFrac0, xFrac1 = 0, 1
2400 } else if sx1 > swMinus1 {
2401 sx0, sx1 = swMinus1, swMinus1
2402 xFrac0, xFrac1 = 1, 0
2403 }
2404
2405 s00i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2406 s00j := ((sr.Min.Y+int(sy0))/2-src.Rect.Min.Y/2)*src.CStride + ((sr.Min.X+int(sx0))/2 - src.Rect.Min.X/2)
2407
2408
2409 s00yy1 := int(src.Y[s00i]) * 0x10101
2410 s00cb1 := int(src.Cb[s00j]) - 128
2411 s00cr1 := int(src.Cr[s00j]) - 128
2412 s00ru := (s00yy1 + 91881*s00cr1) >> 8
2413 s00gu := (s00yy1 - 22554*s00cb1 - 46802*s00cr1) >> 8
2414 s00bu := (s00yy1 + 116130*s00cb1) >> 8
2415 if s00ru < 0 {
2416 s00ru = 0
2417 } else if s00ru > 0xffff {
2418 s00ru = 0xffff
2419 }
2420 if s00gu < 0 {
2421 s00gu = 0
2422 } else if s00gu > 0xffff {
2423 s00gu = 0xffff
2424 }
2425 if s00bu < 0 {
2426 s00bu = 0
2427 } else if s00bu > 0xffff {
2428 s00bu = 0xffff
2429 }
2430
2431 s00r := float64(s00ru)
2432 s00g := float64(s00gu)
2433 s00b := float64(s00bu)
2434 s10i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2435 s10j := ((sr.Min.Y+int(sy0))/2-src.Rect.Min.Y/2)*src.CStride + ((sr.Min.X+int(sx1))/2 - src.Rect.Min.X/2)
2436
2437
2438 s10yy1 := int(src.Y[s10i]) * 0x10101
2439 s10cb1 := int(src.Cb[s10j]) - 128
2440 s10cr1 := int(src.Cr[s10j]) - 128
2441 s10ru := (s10yy1 + 91881*s10cr1) >> 8
2442 s10gu := (s10yy1 - 22554*s10cb1 - 46802*s10cr1) >> 8
2443 s10bu := (s10yy1 + 116130*s10cb1) >> 8
2444 if s10ru < 0 {
2445 s10ru = 0
2446 } else if s10ru > 0xffff {
2447 s10ru = 0xffff
2448 }
2449 if s10gu < 0 {
2450 s10gu = 0
2451 } else if s10gu > 0xffff {
2452 s10gu = 0xffff
2453 }
2454 if s10bu < 0 {
2455 s10bu = 0
2456 } else if s10bu > 0xffff {
2457 s10bu = 0xffff
2458 }
2459
2460 s10r := float64(s10ru)
2461 s10g := float64(s10gu)
2462 s10b := float64(s10bu)
2463 s10r = xFrac1*s00r + xFrac0*s10r
2464 s10g = xFrac1*s00g + xFrac0*s10g
2465 s10b = xFrac1*s00b + xFrac0*s10b
2466 s01i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2467 s01j := ((sr.Min.Y+int(sy1))/2-src.Rect.Min.Y/2)*src.CStride + ((sr.Min.X+int(sx0))/2 - src.Rect.Min.X/2)
2468
2469
2470 s01yy1 := int(src.Y[s01i]) * 0x10101
2471 s01cb1 := int(src.Cb[s01j]) - 128
2472 s01cr1 := int(src.Cr[s01j]) - 128
2473 s01ru := (s01yy1 + 91881*s01cr1) >> 8
2474 s01gu := (s01yy1 - 22554*s01cb1 - 46802*s01cr1) >> 8
2475 s01bu := (s01yy1 + 116130*s01cb1) >> 8
2476 if s01ru < 0 {
2477 s01ru = 0
2478 } else if s01ru > 0xffff {
2479 s01ru = 0xffff
2480 }
2481 if s01gu < 0 {
2482 s01gu = 0
2483 } else if s01gu > 0xffff {
2484 s01gu = 0xffff
2485 }
2486 if s01bu < 0 {
2487 s01bu = 0
2488 } else if s01bu > 0xffff {
2489 s01bu = 0xffff
2490 }
2491
2492 s01r := float64(s01ru)
2493 s01g := float64(s01gu)
2494 s01b := float64(s01bu)
2495 s11i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2496 s11j := ((sr.Min.Y+int(sy1))/2-src.Rect.Min.Y/2)*src.CStride + ((sr.Min.X+int(sx1))/2 - src.Rect.Min.X/2)
2497
2498
2499 s11yy1 := int(src.Y[s11i]) * 0x10101
2500 s11cb1 := int(src.Cb[s11j]) - 128
2501 s11cr1 := int(src.Cr[s11j]) - 128
2502 s11ru := (s11yy1 + 91881*s11cr1) >> 8
2503 s11gu := (s11yy1 - 22554*s11cb1 - 46802*s11cr1) >> 8
2504 s11bu := (s11yy1 + 116130*s11cb1) >> 8
2505 if s11ru < 0 {
2506 s11ru = 0
2507 } else if s11ru > 0xffff {
2508 s11ru = 0xffff
2509 }
2510 if s11gu < 0 {
2511 s11gu = 0
2512 } else if s11gu > 0xffff {
2513 s11gu = 0xffff
2514 }
2515 if s11bu < 0 {
2516 s11bu = 0
2517 } else if s11bu > 0xffff {
2518 s11bu = 0xffff
2519 }
2520
2521 s11r := float64(s11ru)
2522 s11g := float64(s11gu)
2523 s11b := float64(s11bu)
2524 s11r = xFrac1*s01r + xFrac0*s11r
2525 s11g = xFrac1*s01g + xFrac0*s11g
2526 s11b = xFrac1*s01b + xFrac0*s11b
2527 s11r = yFrac1*s10r + yFrac0*s11r
2528 s11g = yFrac1*s10g + yFrac0*s11g
2529 s11b = yFrac1*s10b + yFrac0*s11b
2530 pr := uint32(s11r)
2531 pg := uint32(s11g)
2532 pb := uint32(s11b)
2533 dst.Pix[d+0] = uint8(pr >> 8)
2534 dst.Pix[d+1] = uint8(pg >> 8)
2535 dst.Pix[d+2] = uint8(pb >> 8)
2536 dst.Pix[d+3] = 0xff
2537 }
2538 }
2539 }
2540
2541 func (ablInterpolator) scale_RGBA_YCbCr440_Src(dst *image.RGBA, dr, adr image.Rectangle, src *image.YCbCr, sr image.Rectangle, opts *Options) {
2542 sw := int32(sr.Dx())
2543 sh := int32(sr.Dy())
2544 yscale := float64(sh) / float64(dr.Dy())
2545 xscale := float64(sw) / float64(dr.Dx())
2546 swMinus1, shMinus1 := sw-1, sh-1
2547
2548 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
2549 sy := (float64(dy)+0.5)*yscale - 0.5
2550
2551
2552
2553 sy0 := int32(sy)
2554 yFrac0 := sy - float64(sy0)
2555 yFrac1 := 1 - yFrac0
2556 sy1 := sy0 + 1
2557 if sy < 0 {
2558 sy0, sy1 = 0, 0
2559 yFrac0, yFrac1 = 0, 1
2560 } else if sy1 > shMinus1 {
2561 sy0, sy1 = shMinus1, shMinus1
2562 yFrac0, yFrac1 = 1, 0
2563 }
2564 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
2565
2566 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
2567 sx := (float64(dx)+0.5)*xscale - 0.5
2568 sx0 := int32(sx)
2569 xFrac0 := sx - float64(sx0)
2570 xFrac1 := 1 - xFrac0
2571 sx1 := sx0 + 1
2572 if sx < 0 {
2573 sx0, sx1 = 0, 0
2574 xFrac0, xFrac1 = 0, 1
2575 } else if sx1 > swMinus1 {
2576 sx0, sx1 = swMinus1, swMinus1
2577 xFrac0, xFrac1 = 1, 0
2578 }
2579
2580 s00i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2581 s00j := ((sr.Min.Y+int(sy0))/2-src.Rect.Min.Y/2)*src.CStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2582
2583
2584 s00yy1 := int(src.Y[s00i]) * 0x10101
2585 s00cb1 := int(src.Cb[s00j]) - 128
2586 s00cr1 := int(src.Cr[s00j]) - 128
2587 s00ru := (s00yy1 + 91881*s00cr1) >> 8
2588 s00gu := (s00yy1 - 22554*s00cb1 - 46802*s00cr1) >> 8
2589 s00bu := (s00yy1 + 116130*s00cb1) >> 8
2590 if s00ru < 0 {
2591 s00ru = 0
2592 } else if s00ru > 0xffff {
2593 s00ru = 0xffff
2594 }
2595 if s00gu < 0 {
2596 s00gu = 0
2597 } else if s00gu > 0xffff {
2598 s00gu = 0xffff
2599 }
2600 if s00bu < 0 {
2601 s00bu = 0
2602 } else if s00bu > 0xffff {
2603 s00bu = 0xffff
2604 }
2605
2606 s00r := float64(s00ru)
2607 s00g := float64(s00gu)
2608 s00b := float64(s00bu)
2609 s10i := (sr.Min.Y+int(sy0)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2610 s10j := ((sr.Min.Y+int(sy0))/2-src.Rect.Min.Y/2)*src.CStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2611
2612
2613 s10yy1 := int(src.Y[s10i]) * 0x10101
2614 s10cb1 := int(src.Cb[s10j]) - 128
2615 s10cr1 := int(src.Cr[s10j]) - 128
2616 s10ru := (s10yy1 + 91881*s10cr1) >> 8
2617 s10gu := (s10yy1 - 22554*s10cb1 - 46802*s10cr1) >> 8
2618 s10bu := (s10yy1 + 116130*s10cb1) >> 8
2619 if s10ru < 0 {
2620 s10ru = 0
2621 } else if s10ru > 0xffff {
2622 s10ru = 0xffff
2623 }
2624 if s10gu < 0 {
2625 s10gu = 0
2626 } else if s10gu > 0xffff {
2627 s10gu = 0xffff
2628 }
2629 if s10bu < 0 {
2630 s10bu = 0
2631 } else if s10bu > 0xffff {
2632 s10bu = 0xffff
2633 }
2634
2635 s10r := float64(s10ru)
2636 s10g := float64(s10gu)
2637 s10b := float64(s10bu)
2638 s10r = xFrac1*s00r + xFrac0*s10r
2639 s10g = xFrac1*s00g + xFrac0*s10g
2640 s10b = xFrac1*s00b + xFrac0*s10b
2641 s01i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2642 s01j := ((sr.Min.Y+int(sy1))/2-src.Rect.Min.Y/2)*src.CStride + (sr.Min.X + int(sx0) - src.Rect.Min.X)
2643
2644
2645 s01yy1 := int(src.Y[s01i]) * 0x10101
2646 s01cb1 := int(src.Cb[s01j]) - 128
2647 s01cr1 := int(src.Cr[s01j]) - 128
2648 s01ru := (s01yy1 + 91881*s01cr1) >> 8
2649 s01gu := (s01yy1 - 22554*s01cb1 - 46802*s01cr1) >> 8
2650 s01bu := (s01yy1 + 116130*s01cb1) >> 8
2651 if s01ru < 0 {
2652 s01ru = 0
2653 } else if s01ru > 0xffff {
2654 s01ru = 0xffff
2655 }
2656 if s01gu < 0 {
2657 s01gu = 0
2658 } else if s01gu > 0xffff {
2659 s01gu = 0xffff
2660 }
2661 if s01bu < 0 {
2662 s01bu = 0
2663 } else if s01bu > 0xffff {
2664 s01bu = 0xffff
2665 }
2666
2667 s01r := float64(s01ru)
2668 s01g := float64(s01gu)
2669 s01b := float64(s01bu)
2670 s11i := (sr.Min.Y+int(sy1)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2671 s11j := ((sr.Min.Y+int(sy1))/2-src.Rect.Min.Y/2)*src.CStride + (sr.Min.X + int(sx1) - src.Rect.Min.X)
2672
2673
2674 s11yy1 := int(src.Y[s11i]) * 0x10101
2675 s11cb1 := int(src.Cb[s11j]) - 128
2676 s11cr1 := int(src.Cr[s11j]) - 128
2677 s11ru := (s11yy1 + 91881*s11cr1) >> 8
2678 s11gu := (s11yy1 - 22554*s11cb1 - 46802*s11cr1) >> 8
2679 s11bu := (s11yy1 + 116130*s11cb1) >> 8
2680 if s11ru < 0 {
2681 s11ru = 0
2682 } else if s11ru > 0xffff {
2683 s11ru = 0xffff
2684 }
2685 if s11gu < 0 {
2686 s11gu = 0
2687 } else if s11gu > 0xffff {
2688 s11gu = 0xffff
2689 }
2690 if s11bu < 0 {
2691 s11bu = 0
2692 } else if s11bu > 0xffff {
2693 s11bu = 0xffff
2694 }
2695
2696 s11r := float64(s11ru)
2697 s11g := float64(s11gu)
2698 s11b := float64(s11bu)
2699 s11r = xFrac1*s01r + xFrac0*s11r
2700 s11g = xFrac1*s01g + xFrac0*s11g
2701 s11b = xFrac1*s01b + xFrac0*s11b
2702 s11r = yFrac1*s10r + yFrac0*s11r
2703 s11g = yFrac1*s10g + yFrac0*s11g
2704 s11b = yFrac1*s10b + yFrac0*s11b
2705 pr := uint32(s11r)
2706 pg := uint32(s11g)
2707 pb := uint32(s11b)
2708 dst.Pix[d+0] = uint8(pr >> 8)
2709 dst.Pix[d+1] = uint8(pg >> 8)
2710 dst.Pix[d+2] = uint8(pb >> 8)
2711 dst.Pix[d+3] = 0xff
2712 }
2713 }
2714 }
2715
2716 func (ablInterpolator) scale_RGBA_RGBA64Image_Over(dst *image.RGBA, dr, adr image.Rectangle, src image.RGBA64Image, sr image.Rectangle, opts *Options) {
2717 sw := int32(sr.Dx())
2718 sh := int32(sr.Dy())
2719 yscale := float64(sh) / float64(dr.Dy())
2720 xscale := float64(sw) / float64(dr.Dx())
2721 swMinus1, shMinus1 := sw-1, sh-1
2722
2723 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
2724 sy := (float64(dy)+0.5)*yscale - 0.5
2725
2726
2727
2728 sy0 := int32(sy)
2729 yFrac0 := sy - float64(sy0)
2730 yFrac1 := 1 - yFrac0
2731 sy1 := sy0 + 1
2732 if sy < 0 {
2733 sy0, sy1 = 0, 0
2734 yFrac0, yFrac1 = 0, 1
2735 } else if sy1 > shMinus1 {
2736 sy0, sy1 = shMinus1, shMinus1
2737 yFrac0, yFrac1 = 1, 0
2738 }
2739 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
2740
2741 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
2742 sx := (float64(dx)+0.5)*xscale - 0.5
2743 sx0 := int32(sx)
2744 xFrac0 := sx - float64(sx0)
2745 xFrac1 := 1 - xFrac0
2746 sx1 := sx0 + 1
2747 if sx < 0 {
2748 sx0, sx1 = 0, 0
2749 xFrac0, xFrac1 = 0, 1
2750 } else if sx1 > swMinus1 {
2751 sx0, sx1 = swMinus1, swMinus1
2752 xFrac0, xFrac1 = 1, 0
2753 }
2754
2755 s00u := src.RGBA64At(sr.Min.X+int(sx0), sr.Min.Y+int(sy0))
2756 s00r := float64(s00u.R)
2757 s00g := float64(s00u.G)
2758 s00b := float64(s00u.B)
2759 s00a := float64(s00u.A)
2760 s10u := src.RGBA64At(sr.Min.X+int(sx1), sr.Min.Y+int(sy0))
2761 s10r := float64(s10u.R)
2762 s10g := float64(s10u.G)
2763 s10b := float64(s10u.B)
2764 s10a := float64(s10u.A)
2765 s10r = xFrac1*s00r + xFrac0*s10r
2766 s10g = xFrac1*s00g + xFrac0*s10g
2767 s10b = xFrac1*s00b + xFrac0*s10b
2768 s10a = xFrac1*s00a + xFrac0*s10a
2769 s01u := src.RGBA64At(sr.Min.X+int(sx0), sr.Min.Y+int(sy1))
2770 s01r := float64(s01u.R)
2771 s01g := float64(s01u.G)
2772 s01b := float64(s01u.B)
2773 s01a := float64(s01u.A)
2774 s11u := src.RGBA64At(sr.Min.X+int(sx1), sr.Min.Y+int(sy1))
2775 s11r := float64(s11u.R)
2776 s11g := float64(s11u.G)
2777 s11b := float64(s11u.B)
2778 s11a := float64(s11u.A)
2779 s11r = xFrac1*s01r + xFrac0*s11r
2780 s11g = xFrac1*s01g + xFrac0*s11g
2781 s11b = xFrac1*s01b + xFrac0*s11b
2782 s11a = xFrac1*s01a + xFrac0*s11a
2783 s11r = yFrac1*s10r + yFrac0*s11r
2784 s11g = yFrac1*s10g + yFrac0*s11g
2785 s11b = yFrac1*s10b + yFrac0*s11b
2786 s11a = yFrac1*s10a + yFrac0*s11a
2787 p := color.RGBA64{uint16(s11r), uint16(s11g), uint16(s11b), uint16(s11a)}
2788 pa1 := (0xffff - uint32(p.A)) * 0x101
2789 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + uint32(p.R)) >> 8)
2790 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + uint32(p.G)) >> 8)
2791 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + uint32(p.B)) >> 8)
2792 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + uint32(p.A)) >> 8)
2793 }
2794 }
2795 }
2796
2797 func (ablInterpolator) scale_RGBA_RGBA64Image_Src(dst *image.RGBA, dr, adr image.Rectangle, src image.RGBA64Image, sr image.Rectangle, opts *Options) {
2798 sw := int32(sr.Dx())
2799 sh := int32(sr.Dy())
2800 yscale := float64(sh) / float64(dr.Dy())
2801 xscale := float64(sw) / float64(dr.Dx())
2802 swMinus1, shMinus1 := sw-1, sh-1
2803
2804 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
2805 sy := (float64(dy)+0.5)*yscale - 0.5
2806
2807
2808
2809 sy0 := int32(sy)
2810 yFrac0 := sy - float64(sy0)
2811 yFrac1 := 1 - yFrac0
2812 sy1 := sy0 + 1
2813 if sy < 0 {
2814 sy0, sy1 = 0, 0
2815 yFrac0, yFrac1 = 0, 1
2816 } else if sy1 > shMinus1 {
2817 sy0, sy1 = shMinus1, shMinus1
2818 yFrac0, yFrac1 = 1, 0
2819 }
2820 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
2821
2822 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
2823 sx := (float64(dx)+0.5)*xscale - 0.5
2824 sx0 := int32(sx)
2825 xFrac0 := sx - float64(sx0)
2826 xFrac1 := 1 - xFrac0
2827 sx1 := sx0 + 1
2828 if sx < 0 {
2829 sx0, sx1 = 0, 0
2830 xFrac0, xFrac1 = 0, 1
2831 } else if sx1 > swMinus1 {
2832 sx0, sx1 = swMinus1, swMinus1
2833 xFrac0, xFrac1 = 1, 0
2834 }
2835
2836 s00u := src.RGBA64At(sr.Min.X+int(sx0), sr.Min.Y+int(sy0))
2837 s00r := float64(s00u.R)
2838 s00g := float64(s00u.G)
2839 s00b := float64(s00u.B)
2840 s00a := float64(s00u.A)
2841 s10u := src.RGBA64At(sr.Min.X+int(sx1), sr.Min.Y+int(sy0))
2842 s10r := float64(s10u.R)
2843 s10g := float64(s10u.G)
2844 s10b := float64(s10u.B)
2845 s10a := float64(s10u.A)
2846 s10r = xFrac1*s00r + xFrac0*s10r
2847 s10g = xFrac1*s00g + xFrac0*s10g
2848 s10b = xFrac1*s00b + xFrac0*s10b
2849 s10a = xFrac1*s00a + xFrac0*s10a
2850 s01u := src.RGBA64At(sr.Min.X+int(sx0), sr.Min.Y+int(sy1))
2851 s01r := float64(s01u.R)
2852 s01g := float64(s01u.G)
2853 s01b := float64(s01u.B)
2854 s01a := float64(s01u.A)
2855 s11u := src.RGBA64At(sr.Min.X+int(sx1), sr.Min.Y+int(sy1))
2856 s11r := float64(s11u.R)
2857 s11g := float64(s11u.G)
2858 s11b := float64(s11u.B)
2859 s11a := float64(s11u.A)
2860 s11r = xFrac1*s01r + xFrac0*s11r
2861 s11g = xFrac1*s01g + xFrac0*s11g
2862 s11b = xFrac1*s01b + xFrac0*s11b
2863 s11a = xFrac1*s01a + xFrac0*s11a
2864 s11r = yFrac1*s10r + yFrac0*s11r
2865 s11g = yFrac1*s10g + yFrac0*s11g
2866 s11b = yFrac1*s10b + yFrac0*s11b
2867 s11a = yFrac1*s10a + yFrac0*s11a
2868 p := color.RGBA64{uint16(s11r), uint16(s11g), uint16(s11b), uint16(s11a)}
2869 dst.Pix[d+0] = uint8(p.R >> 8)
2870 dst.Pix[d+1] = uint8(p.G >> 8)
2871 dst.Pix[d+2] = uint8(p.B >> 8)
2872 dst.Pix[d+3] = uint8(p.A >> 8)
2873 }
2874 }
2875 }
2876
2877 func (ablInterpolator) scale_RGBA_Image_Over(dst *image.RGBA, dr, adr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
2878 sw := int32(sr.Dx())
2879 sh := int32(sr.Dy())
2880 yscale := float64(sh) / float64(dr.Dy())
2881 xscale := float64(sw) / float64(dr.Dx())
2882 swMinus1, shMinus1 := sw-1, sh-1
2883
2884 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
2885 sy := (float64(dy)+0.5)*yscale - 0.5
2886
2887
2888
2889 sy0 := int32(sy)
2890 yFrac0 := sy - float64(sy0)
2891 yFrac1 := 1 - yFrac0
2892 sy1 := sy0 + 1
2893 if sy < 0 {
2894 sy0, sy1 = 0, 0
2895 yFrac0, yFrac1 = 0, 1
2896 } else if sy1 > shMinus1 {
2897 sy0, sy1 = shMinus1, shMinus1
2898 yFrac0, yFrac1 = 1, 0
2899 }
2900 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
2901
2902 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
2903 sx := (float64(dx)+0.5)*xscale - 0.5
2904 sx0 := int32(sx)
2905 xFrac0 := sx - float64(sx0)
2906 xFrac1 := 1 - xFrac0
2907 sx1 := sx0 + 1
2908 if sx < 0 {
2909 sx0, sx1 = 0, 0
2910 xFrac0, xFrac1 = 0, 1
2911 } else if sx1 > swMinus1 {
2912 sx0, sx1 = swMinus1, swMinus1
2913 xFrac0, xFrac1 = 1, 0
2914 }
2915
2916 s00ru, s00gu, s00bu, s00au := src.At(sr.Min.X+int(sx0), sr.Min.Y+int(sy0)).RGBA()
2917 s00r := float64(s00ru)
2918 s00g := float64(s00gu)
2919 s00b := float64(s00bu)
2920 s00a := float64(s00au)
2921 s10ru, s10gu, s10bu, s10au := src.At(sr.Min.X+int(sx1), sr.Min.Y+int(sy0)).RGBA()
2922 s10r := float64(s10ru)
2923 s10g := float64(s10gu)
2924 s10b := float64(s10bu)
2925 s10a := float64(s10au)
2926 s10r = xFrac1*s00r + xFrac0*s10r
2927 s10g = xFrac1*s00g + xFrac0*s10g
2928 s10b = xFrac1*s00b + xFrac0*s10b
2929 s10a = xFrac1*s00a + xFrac0*s10a
2930 s01ru, s01gu, s01bu, s01au := src.At(sr.Min.X+int(sx0), sr.Min.Y+int(sy1)).RGBA()
2931 s01r := float64(s01ru)
2932 s01g := float64(s01gu)
2933 s01b := float64(s01bu)
2934 s01a := float64(s01au)
2935 s11ru, s11gu, s11bu, s11au := src.At(sr.Min.X+int(sx1), sr.Min.Y+int(sy1)).RGBA()
2936 s11r := float64(s11ru)
2937 s11g := float64(s11gu)
2938 s11b := float64(s11bu)
2939 s11a := float64(s11au)
2940 s11r = xFrac1*s01r + xFrac0*s11r
2941 s11g = xFrac1*s01g + xFrac0*s11g
2942 s11b = xFrac1*s01b + xFrac0*s11b
2943 s11a = xFrac1*s01a + xFrac0*s11a
2944 s11r = yFrac1*s10r + yFrac0*s11r
2945 s11g = yFrac1*s10g + yFrac0*s11g
2946 s11b = yFrac1*s10b + yFrac0*s11b
2947 s11a = yFrac1*s10a + yFrac0*s11a
2948 pr := uint32(s11r)
2949 pg := uint32(s11g)
2950 pb := uint32(s11b)
2951 pa := uint32(s11a)
2952 pa1 := (0xffff - pa) * 0x101
2953 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
2954 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
2955 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
2956 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
2957 }
2958 }
2959 }
2960
2961 func (ablInterpolator) scale_RGBA_Image_Src(dst *image.RGBA, dr, adr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
2962 sw := int32(sr.Dx())
2963 sh := int32(sr.Dy())
2964 yscale := float64(sh) / float64(dr.Dy())
2965 xscale := float64(sw) / float64(dr.Dx())
2966 swMinus1, shMinus1 := sw-1, sh-1
2967
2968 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
2969 sy := (float64(dy)+0.5)*yscale - 0.5
2970
2971
2972
2973 sy0 := int32(sy)
2974 yFrac0 := sy - float64(sy0)
2975 yFrac1 := 1 - yFrac0
2976 sy1 := sy0 + 1
2977 if sy < 0 {
2978 sy0, sy1 = 0, 0
2979 yFrac0, yFrac1 = 0, 1
2980 } else if sy1 > shMinus1 {
2981 sy0, sy1 = shMinus1, shMinus1
2982 yFrac0, yFrac1 = 1, 0
2983 }
2984 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
2985
2986 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
2987 sx := (float64(dx)+0.5)*xscale - 0.5
2988 sx0 := int32(sx)
2989 xFrac0 := sx - float64(sx0)
2990 xFrac1 := 1 - xFrac0
2991 sx1 := sx0 + 1
2992 if sx < 0 {
2993 sx0, sx1 = 0, 0
2994 xFrac0, xFrac1 = 0, 1
2995 } else if sx1 > swMinus1 {
2996 sx0, sx1 = swMinus1, swMinus1
2997 xFrac0, xFrac1 = 1, 0
2998 }
2999
3000 s00ru, s00gu, s00bu, s00au := src.At(sr.Min.X+int(sx0), sr.Min.Y+int(sy0)).RGBA()
3001 s00r := float64(s00ru)
3002 s00g := float64(s00gu)
3003 s00b := float64(s00bu)
3004 s00a := float64(s00au)
3005 s10ru, s10gu, s10bu, s10au := src.At(sr.Min.X+int(sx1), sr.Min.Y+int(sy0)).RGBA()
3006 s10r := float64(s10ru)
3007 s10g := float64(s10gu)
3008 s10b := float64(s10bu)
3009 s10a := float64(s10au)
3010 s10r = xFrac1*s00r + xFrac0*s10r
3011 s10g = xFrac1*s00g + xFrac0*s10g
3012 s10b = xFrac1*s00b + xFrac0*s10b
3013 s10a = xFrac1*s00a + xFrac0*s10a
3014 s01ru, s01gu, s01bu, s01au := src.At(sr.Min.X+int(sx0), sr.Min.Y+int(sy1)).RGBA()
3015 s01r := float64(s01ru)
3016 s01g := float64(s01gu)
3017 s01b := float64(s01bu)
3018 s01a := float64(s01au)
3019 s11ru, s11gu, s11bu, s11au := src.At(sr.Min.X+int(sx1), sr.Min.Y+int(sy1)).RGBA()
3020 s11r := float64(s11ru)
3021 s11g := float64(s11gu)
3022 s11b := float64(s11bu)
3023 s11a := float64(s11au)
3024 s11r = xFrac1*s01r + xFrac0*s11r
3025 s11g = xFrac1*s01g + xFrac0*s11g
3026 s11b = xFrac1*s01b + xFrac0*s11b
3027 s11a = xFrac1*s01a + xFrac0*s11a
3028 s11r = yFrac1*s10r + yFrac0*s11r
3029 s11g = yFrac1*s10g + yFrac0*s11g
3030 s11b = yFrac1*s10b + yFrac0*s11b
3031 s11a = yFrac1*s10a + yFrac0*s11a
3032 pr := uint32(s11r)
3033 pg := uint32(s11g)
3034 pb := uint32(s11b)
3035 pa := uint32(s11a)
3036 dst.Pix[d+0] = uint8(pr >> 8)
3037 dst.Pix[d+1] = uint8(pg >> 8)
3038 dst.Pix[d+2] = uint8(pb >> 8)
3039 dst.Pix[d+3] = uint8(pa >> 8)
3040 }
3041 }
3042 }
3043
3044 func (ablInterpolator) scale_RGBA64Image_RGBA64Image_Over(dst RGBA64Image, dr, adr image.Rectangle, src image.RGBA64Image, sr image.Rectangle, opts *Options) {
3045 sw := int32(sr.Dx())
3046 sh := int32(sr.Dy())
3047 yscale := float64(sh) / float64(dr.Dy())
3048 xscale := float64(sw) / float64(dr.Dx())
3049 swMinus1, shMinus1 := sw-1, sh-1
3050 srcMask, smp := opts.SrcMask, opts.SrcMaskP
3051 dstMask, dmp := opts.DstMask, opts.DstMaskP
3052 dstColorRGBA64 := color.RGBA64{}
3053
3054 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
3055 sy := (float64(dy)+0.5)*yscale - 0.5
3056
3057
3058
3059 sy0 := int32(sy)
3060 yFrac0 := sy - float64(sy0)
3061 yFrac1 := 1 - yFrac0
3062 sy1 := sy0 + 1
3063 if sy < 0 {
3064 sy0, sy1 = 0, 0
3065 yFrac0, yFrac1 = 0, 1
3066 } else if sy1 > shMinus1 {
3067 sy0, sy1 = shMinus1, shMinus1
3068 yFrac0, yFrac1 = 1, 0
3069 }
3070
3071 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
3072 sx := (float64(dx)+0.5)*xscale - 0.5
3073 sx0 := int32(sx)
3074 xFrac0 := sx - float64(sx0)
3075 xFrac1 := 1 - xFrac0
3076 sx1 := sx0 + 1
3077 if sx < 0 {
3078 sx0, sx1 = 0, 0
3079 xFrac0, xFrac1 = 0, 1
3080 } else if sx1 > swMinus1 {
3081 sx0, sx1 = swMinus1, swMinus1
3082 xFrac0, xFrac1 = 1, 0
3083 }
3084
3085 s00u := src.RGBA64At(sr.Min.X+int(sx0), sr.Min.Y+int(sy0))
3086 if srcMask != nil {
3087 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx0), smp.Y+sr.Min.Y+int(sy0)).RGBA()
3088 s00u.R = uint16(uint32(s00u.R) * ma / 0xffff)
3089 s00u.G = uint16(uint32(s00u.G) * ma / 0xffff)
3090 s00u.B = uint16(uint32(s00u.B) * ma / 0xffff)
3091 s00u.A = uint16(uint32(s00u.A) * ma / 0xffff)
3092 }
3093 s00r := float64(s00u.R)
3094 s00g := float64(s00u.G)
3095 s00b := float64(s00u.B)
3096 s00a := float64(s00u.A)
3097 s10u := src.RGBA64At(sr.Min.X+int(sx1), sr.Min.Y+int(sy0))
3098 if srcMask != nil {
3099 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx1), smp.Y+sr.Min.Y+int(sy0)).RGBA()
3100 s10u.R = uint16(uint32(s10u.R) * ma / 0xffff)
3101 s10u.G = uint16(uint32(s10u.G) * ma / 0xffff)
3102 s10u.B = uint16(uint32(s10u.B) * ma / 0xffff)
3103 s10u.A = uint16(uint32(s10u.A) * ma / 0xffff)
3104 }
3105 s10r := float64(s10u.R)
3106 s10g := float64(s10u.G)
3107 s10b := float64(s10u.B)
3108 s10a := float64(s10u.A)
3109 s10r = xFrac1*s00r + xFrac0*s10r
3110 s10g = xFrac1*s00g + xFrac0*s10g
3111 s10b = xFrac1*s00b + xFrac0*s10b
3112 s10a = xFrac1*s00a + xFrac0*s10a
3113 s01u := src.RGBA64At(sr.Min.X+int(sx0), sr.Min.Y+int(sy1))
3114 if srcMask != nil {
3115 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx0), smp.Y+sr.Min.Y+int(sy1)).RGBA()
3116 s01u.R = uint16(uint32(s01u.R) * ma / 0xffff)
3117 s01u.G = uint16(uint32(s01u.G) * ma / 0xffff)
3118 s01u.B = uint16(uint32(s01u.B) * ma / 0xffff)
3119 s01u.A = uint16(uint32(s01u.A) * ma / 0xffff)
3120 }
3121 s01r := float64(s01u.R)
3122 s01g := float64(s01u.G)
3123 s01b := float64(s01u.B)
3124 s01a := float64(s01u.A)
3125 s11u := src.RGBA64At(sr.Min.X+int(sx1), sr.Min.Y+int(sy1))
3126 if srcMask != nil {
3127 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx1), smp.Y+sr.Min.Y+int(sy1)).RGBA()
3128 s11u.R = uint16(uint32(s11u.R) * ma / 0xffff)
3129 s11u.G = uint16(uint32(s11u.G) * ma / 0xffff)
3130 s11u.B = uint16(uint32(s11u.B) * ma / 0xffff)
3131 s11u.A = uint16(uint32(s11u.A) * ma / 0xffff)
3132 }
3133 s11r := float64(s11u.R)
3134 s11g := float64(s11u.G)
3135 s11b := float64(s11u.B)
3136 s11a := float64(s11u.A)
3137 s11r = xFrac1*s01r + xFrac0*s11r
3138 s11g = xFrac1*s01g + xFrac0*s11g
3139 s11b = xFrac1*s01b + xFrac0*s11b
3140 s11a = xFrac1*s01a + xFrac0*s11a
3141 s11r = yFrac1*s10r + yFrac0*s11r
3142 s11g = yFrac1*s10g + yFrac0*s11g
3143 s11b = yFrac1*s10b + yFrac0*s11b
3144 s11a = yFrac1*s10a + yFrac0*s11a
3145 p := color.RGBA64{uint16(s11r), uint16(s11g), uint16(s11b), uint16(s11a)}
3146 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(dy))
3147 if dstMask != nil {
3148 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
3149 p.R = uint16(uint32(p.R) * ma / 0xffff)
3150 p.G = uint16(uint32(p.G) * ma / 0xffff)
3151 p.B = uint16(uint32(p.B) * ma / 0xffff)
3152 p.A = uint16(uint32(p.A) * ma / 0xffff)
3153 }
3154 pa1 := 0xffff - uint32(p.A)
3155 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + uint32(p.R))
3156 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + uint32(p.G))
3157 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + uint32(p.B))
3158 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + uint32(p.A))
3159 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColorRGBA64)
3160 }
3161 }
3162 }
3163
3164 func (ablInterpolator) scale_RGBA64Image_RGBA64Image_Src(dst RGBA64Image, dr, adr image.Rectangle, src image.RGBA64Image, sr image.Rectangle, opts *Options) {
3165 sw := int32(sr.Dx())
3166 sh := int32(sr.Dy())
3167 yscale := float64(sh) / float64(dr.Dy())
3168 xscale := float64(sw) / float64(dr.Dx())
3169 swMinus1, shMinus1 := sw-1, sh-1
3170 srcMask, smp := opts.SrcMask, opts.SrcMaskP
3171 dstMask, dmp := opts.DstMask, opts.DstMaskP
3172 dstColorRGBA64 := color.RGBA64{}
3173
3174 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
3175 sy := (float64(dy)+0.5)*yscale - 0.5
3176
3177
3178
3179 sy0 := int32(sy)
3180 yFrac0 := sy - float64(sy0)
3181 yFrac1 := 1 - yFrac0
3182 sy1 := sy0 + 1
3183 if sy < 0 {
3184 sy0, sy1 = 0, 0
3185 yFrac0, yFrac1 = 0, 1
3186 } else if sy1 > shMinus1 {
3187 sy0, sy1 = shMinus1, shMinus1
3188 yFrac0, yFrac1 = 1, 0
3189 }
3190
3191 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
3192 sx := (float64(dx)+0.5)*xscale - 0.5
3193 sx0 := int32(sx)
3194 xFrac0 := sx - float64(sx0)
3195 xFrac1 := 1 - xFrac0
3196 sx1 := sx0 + 1
3197 if sx < 0 {
3198 sx0, sx1 = 0, 0
3199 xFrac0, xFrac1 = 0, 1
3200 } else if sx1 > swMinus1 {
3201 sx0, sx1 = swMinus1, swMinus1
3202 xFrac0, xFrac1 = 1, 0
3203 }
3204
3205 s00u := src.RGBA64At(sr.Min.X+int(sx0), sr.Min.Y+int(sy0))
3206 if srcMask != nil {
3207 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx0), smp.Y+sr.Min.Y+int(sy0)).RGBA()
3208 s00u.R = uint16(uint32(s00u.R) * ma / 0xffff)
3209 s00u.G = uint16(uint32(s00u.G) * ma / 0xffff)
3210 s00u.B = uint16(uint32(s00u.B) * ma / 0xffff)
3211 s00u.A = uint16(uint32(s00u.A) * ma / 0xffff)
3212 }
3213 s00r := float64(s00u.R)
3214 s00g := float64(s00u.G)
3215 s00b := float64(s00u.B)
3216 s00a := float64(s00u.A)
3217 s10u := src.RGBA64At(sr.Min.X+int(sx1), sr.Min.Y+int(sy0))
3218 if srcMask != nil {
3219 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx1), smp.Y+sr.Min.Y+int(sy0)).RGBA()
3220 s10u.R = uint16(uint32(s10u.R) * ma / 0xffff)
3221 s10u.G = uint16(uint32(s10u.G) * ma / 0xffff)
3222 s10u.B = uint16(uint32(s10u.B) * ma / 0xffff)
3223 s10u.A = uint16(uint32(s10u.A) * ma / 0xffff)
3224 }
3225 s10r := float64(s10u.R)
3226 s10g := float64(s10u.G)
3227 s10b := float64(s10u.B)
3228 s10a := float64(s10u.A)
3229 s10r = xFrac1*s00r + xFrac0*s10r
3230 s10g = xFrac1*s00g + xFrac0*s10g
3231 s10b = xFrac1*s00b + xFrac0*s10b
3232 s10a = xFrac1*s00a + xFrac0*s10a
3233 s01u := src.RGBA64At(sr.Min.X+int(sx0), sr.Min.Y+int(sy1))
3234 if srcMask != nil {
3235 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx0), smp.Y+sr.Min.Y+int(sy1)).RGBA()
3236 s01u.R = uint16(uint32(s01u.R) * ma / 0xffff)
3237 s01u.G = uint16(uint32(s01u.G) * ma / 0xffff)
3238 s01u.B = uint16(uint32(s01u.B) * ma / 0xffff)
3239 s01u.A = uint16(uint32(s01u.A) * ma / 0xffff)
3240 }
3241 s01r := float64(s01u.R)
3242 s01g := float64(s01u.G)
3243 s01b := float64(s01u.B)
3244 s01a := float64(s01u.A)
3245 s11u := src.RGBA64At(sr.Min.X+int(sx1), sr.Min.Y+int(sy1))
3246 if srcMask != nil {
3247 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx1), smp.Y+sr.Min.Y+int(sy1)).RGBA()
3248 s11u.R = uint16(uint32(s11u.R) * ma / 0xffff)
3249 s11u.G = uint16(uint32(s11u.G) * ma / 0xffff)
3250 s11u.B = uint16(uint32(s11u.B) * ma / 0xffff)
3251 s11u.A = uint16(uint32(s11u.A) * ma / 0xffff)
3252 }
3253 s11r := float64(s11u.R)
3254 s11g := float64(s11u.G)
3255 s11b := float64(s11u.B)
3256 s11a := float64(s11u.A)
3257 s11r = xFrac1*s01r + xFrac0*s11r
3258 s11g = xFrac1*s01g + xFrac0*s11g
3259 s11b = xFrac1*s01b + xFrac0*s11b
3260 s11a = xFrac1*s01a + xFrac0*s11a
3261 s11r = yFrac1*s10r + yFrac0*s11r
3262 s11g = yFrac1*s10g + yFrac0*s11g
3263 s11b = yFrac1*s10b + yFrac0*s11b
3264 s11a = yFrac1*s10a + yFrac0*s11a
3265 p := color.RGBA64{uint16(s11r), uint16(s11g), uint16(s11b), uint16(s11a)}
3266 if dstMask != nil {
3267 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(dy))
3268 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
3269 p.R = uint16(uint32(p.R) * ma / 0xffff)
3270 p.G = uint16(uint32(p.G) * ma / 0xffff)
3271 p.B = uint16(uint32(p.B) * ma / 0xffff)
3272 p.A = uint16(uint32(p.A) * ma / 0xffff)
3273 pa1 := 0xffff - ma
3274 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + uint32(p.R))
3275 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + uint32(p.G))
3276 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + uint32(p.B))
3277 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + uint32(p.A))
3278 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColorRGBA64)
3279 } else {
3280 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), p)
3281 }
3282 }
3283 }
3284 }
3285
3286 func (ablInterpolator) scale_Image_Image_Over(dst Image, dr, adr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
3287 sw := int32(sr.Dx())
3288 sh := int32(sr.Dy())
3289 yscale := float64(sh) / float64(dr.Dy())
3290 xscale := float64(sw) / float64(dr.Dx())
3291 swMinus1, shMinus1 := sw-1, sh-1
3292 srcMask, smp := opts.SrcMask, opts.SrcMaskP
3293 dstMask, dmp := opts.DstMask, opts.DstMaskP
3294 dstColorRGBA64 := &color.RGBA64{}
3295 dstColor := color.Color(dstColorRGBA64)
3296
3297 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
3298 sy := (float64(dy)+0.5)*yscale - 0.5
3299
3300
3301
3302 sy0 := int32(sy)
3303 yFrac0 := sy - float64(sy0)
3304 yFrac1 := 1 - yFrac0
3305 sy1 := sy0 + 1
3306 if sy < 0 {
3307 sy0, sy1 = 0, 0
3308 yFrac0, yFrac1 = 0, 1
3309 } else if sy1 > shMinus1 {
3310 sy0, sy1 = shMinus1, shMinus1
3311 yFrac0, yFrac1 = 1, 0
3312 }
3313
3314 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
3315 sx := (float64(dx)+0.5)*xscale - 0.5
3316 sx0 := int32(sx)
3317 xFrac0 := sx - float64(sx0)
3318 xFrac1 := 1 - xFrac0
3319 sx1 := sx0 + 1
3320 if sx < 0 {
3321 sx0, sx1 = 0, 0
3322 xFrac0, xFrac1 = 0, 1
3323 } else if sx1 > swMinus1 {
3324 sx0, sx1 = swMinus1, swMinus1
3325 xFrac0, xFrac1 = 1, 0
3326 }
3327
3328 s00ru, s00gu, s00bu, s00au := src.At(sr.Min.X+int(sx0), sr.Min.Y+int(sy0)).RGBA()
3329 if srcMask != nil {
3330 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx0), smp.Y+sr.Min.Y+int(sy0)).RGBA()
3331 s00ru = s00ru * ma / 0xffff
3332 s00gu = s00gu * ma / 0xffff
3333 s00bu = s00bu * ma / 0xffff
3334 s00au = s00au * ma / 0xffff
3335 }
3336 s00r := float64(s00ru)
3337 s00g := float64(s00gu)
3338 s00b := float64(s00bu)
3339 s00a := float64(s00au)
3340 s10ru, s10gu, s10bu, s10au := src.At(sr.Min.X+int(sx1), sr.Min.Y+int(sy0)).RGBA()
3341 if srcMask != nil {
3342 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx1), smp.Y+sr.Min.Y+int(sy0)).RGBA()
3343 s10ru = s10ru * ma / 0xffff
3344 s10gu = s10gu * ma / 0xffff
3345 s10bu = s10bu * ma / 0xffff
3346 s10au = s10au * ma / 0xffff
3347 }
3348 s10r := float64(s10ru)
3349 s10g := float64(s10gu)
3350 s10b := float64(s10bu)
3351 s10a := float64(s10au)
3352 s10r = xFrac1*s00r + xFrac0*s10r
3353 s10g = xFrac1*s00g + xFrac0*s10g
3354 s10b = xFrac1*s00b + xFrac0*s10b
3355 s10a = xFrac1*s00a + xFrac0*s10a
3356 s01ru, s01gu, s01bu, s01au := src.At(sr.Min.X+int(sx0), sr.Min.Y+int(sy1)).RGBA()
3357 if srcMask != nil {
3358 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx0), smp.Y+sr.Min.Y+int(sy1)).RGBA()
3359 s01ru = s01ru * ma / 0xffff
3360 s01gu = s01gu * ma / 0xffff
3361 s01bu = s01bu * ma / 0xffff
3362 s01au = s01au * ma / 0xffff
3363 }
3364 s01r := float64(s01ru)
3365 s01g := float64(s01gu)
3366 s01b := float64(s01bu)
3367 s01a := float64(s01au)
3368 s11ru, s11gu, s11bu, s11au := src.At(sr.Min.X+int(sx1), sr.Min.Y+int(sy1)).RGBA()
3369 if srcMask != nil {
3370 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx1), smp.Y+sr.Min.Y+int(sy1)).RGBA()
3371 s11ru = s11ru * ma / 0xffff
3372 s11gu = s11gu * ma / 0xffff
3373 s11bu = s11bu * ma / 0xffff
3374 s11au = s11au * ma / 0xffff
3375 }
3376 s11r := float64(s11ru)
3377 s11g := float64(s11gu)
3378 s11b := float64(s11bu)
3379 s11a := float64(s11au)
3380 s11r = xFrac1*s01r + xFrac0*s11r
3381 s11g = xFrac1*s01g + xFrac0*s11g
3382 s11b = xFrac1*s01b + xFrac0*s11b
3383 s11a = xFrac1*s01a + xFrac0*s11a
3384 s11r = yFrac1*s10r + yFrac0*s11r
3385 s11g = yFrac1*s10g + yFrac0*s11g
3386 s11b = yFrac1*s10b + yFrac0*s11b
3387 s11a = yFrac1*s10a + yFrac0*s11a
3388 pr := uint32(s11r)
3389 pg := uint32(s11g)
3390 pb := uint32(s11b)
3391 pa := uint32(s11a)
3392 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(dy)).RGBA()
3393 if dstMask != nil {
3394 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
3395 pr = pr * ma / 0xffff
3396 pg = pg * ma / 0xffff
3397 pb = pb * ma / 0xffff
3398 pa = pa * ma / 0xffff
3399 }
3400 pa1 := 0xffff - pa
3401 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr)
3402 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg)
3403 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb)
3404 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa)
3405 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
3406 }
3407 }
3408 }
3409
3410 func (ablInterpolator) scale_Image_Image_Src(dst Image, dr, adr image.Rectangle, src image.Image, sr image.Rectangle, opts *Options) {
3411 sw := int32(sr.Dx())
3412 sh := int32(sr.Dy())
3413 yscale := float64(sh) / float64(dr.Dy())
3414 xscale := float64(sw) / float64(dr.Dx())
3415 swMinus1, shMinus1 := sw-1, sh-1
3416 srcMask, smp := opts.SrcMask, opts.SrcMaskP
3417 dstMask, dmp := opts.DstMask, opts.DstMaskP
3418 dstColorRGBA64 := &color.RGBA64{}
3419 dstColor := color.Color(dstColorRGBA64)
3420
3421 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
3422 sy := (float64(dy)+0.5)*yscale - 0.5
3423
3424
3425
3426 sy0 := int32(sy)
3427 yFrac0 := sy - float64(sy0)
3428 yFrac1 := 1 - yFrac0
3429 sy1 := sy0 + 1
3430 if sy < 0 {
3431 sy0, sy1 = 0, 0
3432 yFrac0, yFrac1 = 0, 1
3433 } else if sy1 > shMinus1 {
3434 sy0, sy1 = shMinus1, shMinus1
3435 yFrac0, yFrac1 = 1, 0
3436 }
3437
3438 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
3439 sx := (float64(dx)+0.5)*xscale - 0.5
3440 sx0 := int32(sx)
3441 xFrac0 := sx - float64(sx0)
3442 xFrac1 := 1 - xFrac0
3443 sx1 := sx0 + 1
3444 if sx < 0 {
3445 sx0, sx1 = 0, 0
3446 xFrac0, xFrac1 = 0, 1
3447 } else if sx1 > swMinus1 {
3448 sx0, sx1 = swMinus1, swMinus1
3449 xFrac0, xFrac1 = 1, 0
3450 }
3451
3452 s00ru, s00gu, s00bu, s00au := src.At(sr.Min.X+int(sx0), sr.Min.Y+int(sy0)).RGBA()
3453 if srcMask != nil {
3454 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx0), smp.Y+sr.Min.Y+int(sy0)).RGBA()
3455 s00ru = s00ru * ma / 0xffff
3456 s00gu = s00gu * ma / 0xffff
3457 s00bu = s00bu * ma / 0xffff
3458 s00au = s00au * ma / 0xffff
3459 }
3460 s00r := float64(s00ru)
3461 s00g := float64(s00gu)
3462 s00b := float64(s00bu)
3463 s00a := float64(s00au)
3464 s10ru, s10gu, s10bu, s10au := src.At(sr.Min.X+int(sx1), sr.Min.Y+int(sy0)).RGBA()
3465 if srcMask != nil {
3466 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx1), smp.Y+sr.Min.Y+int(sy0)).RGBA()
3467 s10ru = s10ru * ma / 0xffff
3468 s10gu = s10gu * ma / 0xffff
3469 s10bu = s10bu * ma / 0xffff
3470 s10au = s10au * ma / 0xffff
3471 }
3472 s10r := float64(s10ru)
3473 s10g := float64(s10gu)
3474 s10b := float64(s10bu)
3475 s10a := float64(s10au)
3476 s10r = xFrac1*s00r + xFrac0*s10r
3477 s10g = xFrac1*s00g + xFrac0*s10g
3478 s10b = xFrac1*s00b + xFrac0*s10b
3479 s10a = xFrac1*s00a + xFrac0*s10a
3480 s01ru, s01gu, s01bu, s01au := src.At(sr.Min.X+int(sx0), sr.Min.Y+int(sy1)).RGBA()
3481 if srcMask != nil {
3482 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx0), smp.Y+sr.Min.Y+int(sy1)).RGBA()
3483 s01ru = s01ru * ma / 0xffff
3484 s01gu = s01gu * ma / 0xffff
3485 s01bu = s01bu * ma / 0xffff
3486 s01au = s01au * ma / 0xffff
3487 }
3488 s01r := float64(s01ru)
3489 s01g := float64(s01gu)
3490 s01b := float64(s01bu)
3491 s01a := float64(s01au)
3492 s11ru, s11gu, s11bu, s11au := src.At(sr.Min.X+int(sx1), sr.Min.Y+int(sy1)).RGBA()
3493 if srcMask != nil {
3494 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(sx1), smp.Y+sr.Min.Y+int(sy1)).RGBA()
3495 s11ru = s11ru * ma / 0xffff
3496 s11gu = s11gu * ma / 0xffff
3497 s11bu = s11bu * ma / 0xffff
3498 s11au = s11au * ma / 0xffff
3499 }
3500 s11r := float64(s11ru)
3501 s11g := float64(s11gu)
3502 s11b := float64(s11bu)
3503 s11a := float64(s11au)
3504 s11r = xFrac1*s01r + xFrac0*s11r
3505 s11g = xFrac1*s01g + xFrac0*s11g
3506 s11b = xFrac1*s01b + xFrac0*s11b
3507 s11a = xFrac1*s01a + xFrac0*s11a
3508 s11r = yFrac1*s10r + yFrac0*s11r
3509 s11g = yFrac1*s10g + yFrac0*s11g
3510 s11b = yFrac1*s10b + yFrac0*s11b
3511 s11a = yFrac1*s10a + yFrac0*s11a
3512 pr := uint32(s11r)
3513 pg := uint32(s11g)
3514 pb := uint32(s11b)
3515 pa := uint32(s11a)
3516 if dstMask != nil {
3517 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(dy)).RGBA()
3518 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
3519 pr = pr * ma / 0xffff
3520 pg = pg * ma / 0xffff
3521 pb = pb * ma / 0xffff
3522 pa = pa * ma / 0xffff
3523 pa1 := 0xffff - ma
3524 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr)
3525 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg)
3526 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb)
3527 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa)
3528 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
3529 } else {
3530 dstColorRGBA64.R = uint16(pr)
3531 dstColorRGBA64.G = uint16(pg)
3532 dstColorRGBA64.B = uint16(pb)
3533 dstColorRGBA64.A = uint16(pa)
3534 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
3535 }
3536 }
3537 }
3538 }
3539
3540 func (ablInterpolator) transform_RGBA_Gray_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.Gray, sr image.Rectangle, bias image.Point, opts *Options) {
3541 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
3542 dyf := float64(dr.Min.Y+int(dy)) + 0.5
3543 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
3544 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
3545 dxf := float64(dr.Min.X+int(dx)) + 0.5
3546 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
3547 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
3548 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
3549 continue
3550 }
3551
3552 sx -= 0.5
3553 sx0 := int(sx)
3554 xFrac0 := sx - float64(sx0)
3555 xFrac1 := 1 - xFrac0
3556 sx0 += bias.X
3557 sx1 := sx0 + 1
3558 if sx0 < sr.Min.X {
3559 sx0, sx1 = sr.Min.X, sr.Min.X
3560 xFrac0, xFrac1 = 0, 1
3561 } else if sx1 >= sr.Max.X {
3562 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
3563 xFrac0, xFrac1 = 1, 0
3564 }
3565
3566 sy -= 0.5
3567 sy0 := int(sy)
3568 yFrac0 := sy - float64(sy0)
3569 yFrac1 := 1 - yFrac0
3570 sy0 += bias.Y
3571 sy1 := sy0 + 1
3572 if sy0 < sr.Min.Y {
3573 sy0, sy1 = sr.Min.Y, sr.Min.Y
3574 yFrac0, yFrac1 = 0, 1
3575 } else if sy1 >= sr.Max.Y {
3576 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
3577 yFrac0, yFrac1 = 1, 0
3578 }
3579
3580 s00i := (sy0-src.Rect.Min.Y)*src.Stride + (sx0 - src.Rect.Min.X)
3581 s00ru := uint32(src.Pix[s00i]) * 0x101
3582 s00r := float64(s00ru)
3583 s10i := (sy0-src.Rect.Min.Y)*src.Stride + (sx1 - src.Rect.Min.X)
3584 s10ru := uint32(src.Pix[s10i]) * 0x101
3585 s10r := float64(s10ru)
3586 s10r = xFrac1*s00r + xFrac0*s10r
3587 s01i := (sy1-src.Rect.Min.Y)*src.Stride + (sx0 - src.Rect.Min.X)
3588 s01ru := uint32(src.Pix[s01i]) * 0x101
3589 s01r := float64(s01ru)
3590 s11i := (sy1-src.Rect.Min.Y)*src.Stride + (sx1 - src.Rect.Min.X)
3591 s11ru := uint32(src.Pix[s11i]) * 0x101
3592 s11r := float64(s11ru)
3593 s11r = xFrac1*s01r + xFrac0*s11r
3594 s11r = yFrac1*s10r + yFrac0*s11r
3595 pr := uint32(s11r)
3596 out := uint8(pr >> 8)
3597 dst.Pix[d+0] = out
3598 dst.Pix[d+1] = out
3599 dst.Pix[d+2] = out
3600 dst.Pix[d+3] = 0xff
3601 }
3602 }
3603 }
3604
3605 func (ablInterpolator) transform_RGBA_NRGBA_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point, opts *Options) {
3606 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
3607 dyf := float64(dr.Min.Y+int(dy)) + 0.5
3608 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
3609 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
3610 dxf := float64(dr.Min.X+int(dx)) + 0.5
3611 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
3612 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
3613 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
3614 continue
3615 }
3616
3617 sx -= 0.5
3618 sx0 := int(sx)
3619 xFrac0 := sx - float64(sx0)
3620 xFrac1 := 1 - xFrac0
3621 sx0 += bias.X
3622 sx1 := sx0 + 1
3623 if sx0 < sr.Min.X {
3624 sx0, sx1 = sr.Min.X, sr.Min.X
3625 xFrac0, xFrac1 = 0, 1
3626 } else if sx1 >= sr.Max.X {
3627 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
3628 xFrac0, xFrac1 = 1, 0
3629 }
3630
3631 sy -= 0.5
3632 sy0 := int(sy)
3633 yFrac0 := sy - float64(sy0)
3634 yFrac1 := 1 - yFrac0
3635 sy0 += bias.Y
3636 sy1 := sy0 + 1
3637 if sy0 < sr.Min.Y {
3638 sy0, sy1 = sr.Min.Y, sr.Min.Y
3639 yFrac0, yFrac1 = 0, 1
3640 } else if sy1 >= sr.Max.Y {
3641 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
3642 yFrac0, yFrac1 = 1, 0
3643 }
3644
3645 s00i := (sy0-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
3646 s00au := uint32(src.Pix[s00i+3]) * 0x101
3647 s00ru := uint32(src.Pix[s00i+0]) * s00au / 0xff
3648 s00gu := uint32(src.Pix[s00i+1]) * s00au / 0xff
3649 s00bu := uint32(src.Pix[s00i+2]) * s00au / 0xff
3650 s00r := float64(s00ru)
3651 s00g := float64(s00gu)
3652 s00b := float64(s00bu)
3653 s00a := float64(s00au)
3654 s10i := (sy0-src.Rect.Min.Y)*src.Stride + (sx1-src.Rect.Min.X)*4
3655 s10au := uint32(src.Pix[s10i+3]) * 0x101
3656 s10ru := uint32(src.Pix[s10i+0]) * s10au / 0xff
3657 s10gu := uint32(src.Pix[s10i+1]) * s10au / 0xff
3658 s10bu := uint32(src.Pix[s10i+2]) * s10au / 0xff
3659 s10r := float64(s10ru)
3660 s10g := float64(s10gu)
3661 s10b := float64(s10bu)
3662 s10a := float64(s10au)
3663 s10r = xFrac1*s00r + xFrac0*s10r
3664 s10g = xFrac1*s00g + xFrac0*s10g
3665 s10b = xFrac1*s00b + xFrac0*s10b
3666 s10a = xFrac1*s00a + xFrac0*s10a
3667 s01i := (sy1-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
3668 s01au := uint32(src.Pix[s01i+3]) * 0x101
3669 s01ru := uint32(src.Pix[s01i+0]) * s01au / 0xff
3670 s01gu := uint32(src.Pix[s01i+1]) * s01au / 0xff
3671 s01bu := uint32(src.Pix[s01i+2]) * s01au / 0xff
3672 s01r := float64(s01ru)
3673 s01g := float64(s01gu)
3674 s01b := float64(s01bu)
3675 s01a := float64(s01au)
3676 s11i := (sy1-src.Rect.Min.Y)*src.Stride + (sx1-src.Rect.Min.X)*4
3677 s11au := uint32(src.Pix[s11i+3]) * 0x101
3678 s11ru := uint32(src.Pix[s11i+0]) * s11au / 0xff
3679 s11gu := uint32(src.Pix[s11i+1]) * s11au / 0xff
3680 s11bu := uint32(src.Pix[s11i+2]) * s11au / 0xff
3681 s11r := float64(s11ru)
3682 s11g := float64(s11gu)
3683 s11b := float64(s11bu)
3684 s11a := float64(s11au)
3685 s11r = xFrac1*s01r + xFrac0*s11r
3686 s11g = xFrac1*s01g + xFrac0*s11g
3687 s11b = xFrac1*s01b + xFrac0*s11b
3688 s11a = xFrac1*s01a + xFrac0*s11a
3689 s11r = yFrac1*s10r + yFrac0*s11r
3690 s11g = yFrac1*s10g + yFrac0*s11g
3691 s11b = yFrac1*s10b + yFrac0*s11b
3692 s11a = yFrac1*s10a + yFrac0*s11a
3693 pr := uint32(s11r)
3694 pg := uint32(s11g)
3695 pb := uint32(s11b)
3696 pa := uint32(s11a)
3697 pa1 := (0xffff - pa) * 0x101
3698 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
3699 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
3700 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
3701 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
3702 }
3703 }
3704 }
3705
3706 func (ablInterpolator) transform_RGBA_NRGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point, opts *Options) {
3707 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
3708 dyf := float64(dr.Min.Y+int(dy)) + 0.5
3709 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
3710 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
3711 dxf := float64(dr.Min.X+int(dx)) + 0.5
3712 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
3713 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
3714 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
3715 continue
3716 }
3717
3718 sx -= 0.5
3719 sx0 := int(sx)
3720 xFrac0 := sx - float64(sx0)
3721 xFrac1 := 1 - xFrac0
3722 sx0 += bias.X
3723 sx1 := sx0 + 1
3724 if sx0 < sr.Min.X {
3725 sx0, sx1 = sr.Min.X, sr.Min.X
3726 xFrac0, xFrac1 = 0, 1
3727 } else if sx1 >= sr.Max.X {
3728 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
3729 xFrac0, xFrac1 = 1, 0
3730 }
3731
3732 sy -= 0.5
3733 sy0 := int(sy)
3734 yFrac0 := sy - float64(sy0)
3735 yFrac1 := 1 - yFrac0
3736 sy0 += bias.Y
3737 sy1 := sy0 + 1
3738 if sy0 < sr.Min.Y {
3739 sy0, sy1 = sr.Min.Y, sr.Min.Y
3740 yFrac0, yFrac1 = 0, 1
3741 } else if sy1 >= sr.Max.Y {
3742 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
3743 yFrac0, yFrac1 = 1, 0
3744 }
3745
3746 s00i := (sy0-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
3747 s00au := uint32(src.Pix[s00i+3]) * 0x101
3748 s00ru := uint32(src.Pix[s00i+0]) * s00au / 0xff
3749 s00gu := uint32(src.Pix[s00i+1]) * s00au / 0xff
3750 s00bu := uint32(src.Pix[s00i+2]) * s00au / 0xff
3751 s00r := float64(s00ru)
3752 s00g := float64(s00gu)
3753 s00b := float64(s00bu)
3754 s00a := float64(s00au)
3755 s10i := (sy0-src.Rect.Min.Y)*src.Stride + (sx1-src.Rect.Min.X)*4
3756 s10au := uint32(src.Pix[s10i+3]) * 0x101
3757 s10ru := uint32(src.Pix[s10i+0]) * s10au / 0xff
3758 s10gu := uint32(src.Pix[s10i+1]) * s10au / 0xff
3759 s10bu := uint32(src.Pix[s10i+2]) * s10au / 0xff
3760 s10r := float64(s10ru)
3761 s10g := float64(s10gu)
3762 s10b := float64(s10bu)
3763 s10a := float64(s10au)
3764 s10r = xFrac1*s00r + xFrac0*s10r
3765 s10g = xFrac1*s00g + xFrac0*s10g
3766 s10b = xFrac1*s00b + xFrac0*s10b
3767 s10a = xFrac1*s00a + xFrac0*s10a
3768 s01i := (sy1-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
3769 s01au := uint32(src.Pix[s01i+3]) * 0x101
3770 s01ru := uint32(src.Pix[s01i+0]) * s01au / 0xff
3771 s01gu := uint32(src.Pix[s01i+1]) * s01au / 0xff
3772 s01bu := uint32(src.Pix[s01i+2]) * s01au / 0xff
3773 s01r := float64(s01ru)
3774 s01g := float64(s01gu)
3775 s01b := float64(s01bu)
3776 s01a := float64(s01au)
3777 s11i := (sy1-src.Rect.Min.Y)*src.Stride + (sx1-src.Rect.Min.X)*4
3778 s11au := uint32(src.Pix[s11i+3]) * 0x101
3779 s11ru := uint32(src.Pix[s11i+0]) * s11au / 0xff
3780 s11gu := uint32(src.Pix[s11i+1]) * s11au / 0xff
3781 s11bu := uint32(src.Pix[s11i+2]) * s11au / 0xff
3782 s11r := float64(s11ru)
3783 s11g := float64(s11gu)
3784 s11b := float64(s11bu)
3785 s11a := float64(s11au)
3786 s11r = xFrac1*s01r + xFrac0*s11r
3787 s11g = xFrac1*s01g + xFrac0*s11g
3788 s11b = xFrac1*s01b + xFrac0*s11b
3789 s11a = xFrac1*s01a + xFrac0*s11a
3790 s11r = yFrac1*s10r + yFrac0*s11r
3791 s11g = yFrac1*s10g + yFrac0*s11g
3792 s11b = yFrac1*s10b + yFrac0*s11b
3793 s11a = yFrac1*s10a + yFrac0*s11a
3794 pr := uint32(s11r)
3795 pg := uint32(s11g)
3796 pb := uint32(s11b)
3797 pa := uint32(s11a)
3798 dst.Pix[d+0] = uint8(pr >> 8)
3799 dst.Pix[d+1] = uint8(pg >> 8)
3800 dst.Pix[d+2] = uint8(pb >> 8)
3801 dst.Pix[d+3] = uint8(pa >> 8)
3802 }
3803 }
3804 }
3805
3806 func (ablInterpolator) transform_RGBA_RGBA_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point, opts *Options) {
3807 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
3808 dyf := float64(dr.Min.Y+int(dy)) + 0.5
3809 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
3810 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
3811 dxf := float64(dr.Min.X+int(dx)) + 0.5
3812 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
3813 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
3814 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
3815 continue
3816 }
3817
3818 sx -= 0.5
3819 sx0 := int(sx)
3820 xFrac0 := sx - float64(sx0)
3821 xFrac1 := 1 - xFrac0
3822 sx0 += bias.X
3823 sx1 := sx0 + 1
3824 if sx0 < sr.Min.X {
3825 sx0, sx1 = sr.Min.X, sr.Min.X
3826 xFrac0, xFrac1 = 0, 1
3827 } else if sx1 >= sr.Max.X {
3828 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
3829 xFrac0, xFrac1 = 1, 0
3830 }
3831
3832 sy -= 0.5
3833 sy0 := int(sy)
3834 yFrac0 := sy - float64(sy0)
3835 yFrac1 := 1 - yFrac0
3836 sy0 += bias.Y
3837 sy1 := sy0 + 1
3838 if sy0 < sr.Min.Y {
3839 sy0, sy1 = sr.Min.Y, sr.Min.Y
3840 yFrac0, yFrac1 = 0, 1
3841 } else if sy1 >= sr.Max.Y {
3842 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
3843 yFrac0, yFrac1 = 1, 0
3844 }
3845
3846 s00i := (sy0-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
3847 s00ru := uint32(src.Pix[s00i+0]) * 0x101
3848 s00gu := uint32(src.Pix[s00i+1]) * 0x101
3849 s00bu := uint32(src.Pix[s00i+2]) * 0x101
3850 s00au := uint32(src.Pix[s00i+3]) * 0x101
3851 s00r := float64(s00ru)
3852 s00g := float64(s00gu)
3853 s00b := float64(s00bu)
3854 s00a := float64(s00au)
3855 s10i := (sy0-src.Rect.Min.Y)*src.Stride + (sx1-src.Rect.Min.X)*4
3856 s10ru := uint32(src.Pix[s10i+0]) * 0x101
3857 s10gu := uint32(src.Pix[s10i+1]) * 0x101
3858 s10bu := uint32(src.Pix[s10i+2]) * 0x101
3859 s10au := uint32(src.Pix[s10i+3]) * 0x101
3860 s10r := float64(s10ru)
3861 s10g := float64(s10gu)
3862 s10b := float64(s10bu)
3863 s10a := float64(s10au)
3864 s10r = xFrac1*s00r + xFrac0*s10r
3865 s10g = xFrac1*s00g + xFrac0*s10g
3866 s10b = xFrac1*s00b + xFrac0*s10b
3867 s10a = xFrac1*s00a + xFrac0*s10a
3868 s01i := (sy1-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
3869 s01ru := uint32(src.Pix[s01i+0]) * 0x101
3870 s01gu := uint32(src.Pix[s01i+1]) * 0x101
3871 s01bu := uint32(src.Pix[s01i+2]) * 0x101
3872 s01au := uint32(src.Pix[s01i+3]) * 0x101
3873 s01r := float64(s01ru)
3874 s01g := float64(s01gu)
3875 s01b := float64(s01bu)
3876 s01a := float64(s01au)
3877 s11i := (sy1-src.Rect.Min.Y)*src.Stride + (sx1-src.Rect.Min.X)*4
3878 s11ru := uint32(src.Pix[s11i+0]) * 0x101
3879 s11gu := uint32(src.Pix[s11i+1]) * 0x101
3880 s11bu := uint32(src.Pix[s11i+2]) * 0x101
3881 s11au := uint32(src.Pix[s11i+3]) * 0x101
3882 s11r := float64(s11ru)
3883 s11g := float64(s11gu)
3884 s11b := float64(s11bu)
3885 s11a := float64(s11au)
3886 s11r = xFrac1*s01r + xFrac0*s11r
3887 s11g = xFrac1*s01g + xFrac0*s11g
3888 s11b = xFrac1*s01b + xFrac0*s11b
3889 s11a = xFrac1*s01a + xFrac0*s11a
3890 s11r = yFrac1*s10r + yFrac0*s11r
3891 s11g = yFrac1*s10g + yFrac0*s11g
3892 s11b = yFrac1*s10b + yFrac0*s11b
3893 s11a = yFrac1*s10a + yFrac0*s11a
3894 pr := uint32(s11r)
3895 pg := uint32(s11g)
3896 pb := uint32(s11b)
3897 pa := uint32(s11a)
3898 pa1 := (0xffff - pa) * 0x101
3899 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
3900 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
3901 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
3902 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
3903 }
3904 }
3905 }
3906
3907 func (ablInterpolator) transform_RGBA_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point, opts *Options) {
3908 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
3909 dyf := float64(dr.Min.Y+int(dy)) + 0.5
3910 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
3911 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
3912 dxf := float64(dr.Min.X+int(dx)) + 0.5
3913 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
3914 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
3915 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
3916 continue
3917 }
3918
3919 sx -= 0.5
3920 sx0 := int(sx)
3921 xFrac0 := sx - float64(sx0)
3922 xFrac1 := 1 - xFrac0
3923 sx0 += bias.X
3924 sx1 := sx0 + 1
3925 if sx0 < sr.Min.X {
3926 sx0, sx1 = sr.Min.X, sr.Min.X
3927 xFrac0, xFrac1 = 0, 1
3928 } else if sx1 >= sr.Max.X {
3929 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
3930 xFrac0, xFrac1 = 1, 0
3931 }
3932
3933 sy -= 0.5
3934 sy0 := int(sy)
3935 yFrac0 := sy - float64(sy0)
3936 yFrac1 := 1 - yFrac0
3937 sy0 += bias.Y
3938 sy1 := sy0 + 1
3939 if sy0 < sr.Min.Y {
3940 sy0, sy1 = sr.Min.Y, sr.Min.Y
3941 yFrac0, yFrac1 = 0, 1
3942 } else if sy1 >= sr.Max.Y {
3943 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
3944 yFrac0, yFrac1 = 1, 0
3945 }
3946
3947 s00i := (sy0-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
3948 s00ru := uint32(src.Pix[s00i+0]) * 0x101
3949 s00gu := uint32(src.Pix[s00i+1]) * 0x101
3950 s00bu := uint32(src.Pix[s00i+2]) * 0x101
3951 s00au := uint32(src.Pix[s00i+3]) * 0x101
3952 s00r := float64(s00ru)
3953 s00g := float64(s00gu)
3954 s00b := float64(s00bu)
3955 s00a := float64(s00au)
3956 s10i := (sy0-src.Rect.Min.Y)*src.Stride + (sx1-src.Rect.Min.X)*4
3957 s10ru := uint32(src.Pix[s10i+0]) * 0x101
3958 s10gu := uint32(src.Pix[s10i+1]) * 0x101
3959 s10bu := uint32(src.Pix[s10i+2]) * 0x101
3960 s10au := uint32(src.Pix[s10i+3]) * 0x101
3961 s10r := float64(s10ru)
3962 s10g := float64(s10gu)
3963 s10b := float64(s10bu)
3964 s10a := float64(s10au)
3965 s10r = xFrac1*s00r + xFrac0*s10r
3966 s10g = xFrac1*s00g + xFrac0*s10g
3967 s10b = xFrac1*s00b + xFrac0*s10b
3968 s10a = xFrac1*s00a + xFrac0*s10a
3969 s01i := (sy1-src.Rect.Min.Y)*src.Stride + (sx0-src.Rect.Min.X)*4
3970 s01ru := uint32(src.Pix[s01i+0]) * 0x101
3971 s01gu := uint32(src.Pix[s01i+1]) * 0x101
3972 s01bu := uint32(src.Pix[s01i+2]) * 0x101
3973 s01au := uint32(src.Pix[s01i+3]) * 0x101
3974 s01r := float64(s01ru)
3975 s01g := float64(s01gu)
3976 s01b := float64(s01bu)
3977 s01a := float64(s01au)
3978 s11i := (sy1-src.Rect.Min.Y)*src.Stride + (sx1-src.Rect.Min.X)*4
3979 s11ru := uint32(src.Pix[s11i+0]) * 0x101
3980 s11gu := uint32(src.Pix[s11i+1]) * 0x101
3981 s11bu := uint32(src.Pix[s11i+2]) * 0x101
3982 s11au := uint32(src.Pix[s11i+3]) * 0x101
3983 s11r := float64(s11ru)
3984 s11g := float64(s11gu)
3985 s11b := float64(s11bu)
3986 s11a := float64(s11au)
3987 s11r = xFrac1*s01r + xFrac0*s11r
3988 s11g = xFrac1*s01g + xFrac0*s11g
3989 s11b = xFrac1*s01b + xFrac0*s11b
3990 s11a = xFrac1*s01a + xFrac0*s11a
3991 s11r = yFrac1*s10r + yFrac0*s11r
3992 s11g = yFrac1*s10g + yFrac0*s11g
3993 s11b = yFrac1*s10b + yFrac0*s11b
3994 s11a = yFrac1*s10a + yFrac0*s11a
3995 pr := uint32(s11r)
3996 pg := uint32(s11g)
3997 pb := uint32(s11b)
3998 pa := uint32(s11a)
3999 dst.Pix[d+0] = uint8(pr >> 8)
4000 dst.Pix[d+1] = uint8(pg >> 8)
4001 dst.Pix[d+2] = uint8(pb >> 8)
4002 dst.Pix[d+3] = uint8(pa >> 8)
4003 }
4004 }
4005 }
4006
4007 func (ablInterpolator) transform_RGBA_YCbCr444_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, opts *Options) {
4008 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
4009 dyf := float64(dr.Min.Y+int(dy)) + 0.5
4010 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
4011 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
4012 dxf := float64(dr.Min.X+int(dx)) + 0.5
4013 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
4014 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
4015 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
4016 continue
4017 }
4018
4019 sx -= 0.5
4020 sx0 := int(sx)
4021 xFrac0 := sx - float64(sx0)
4022 xFrac1 := 1 - xFrac0
4023 sx0 += bias.X
4024 sx1 := sx0 + 1
4025 if sx0 < sr.Min.X {
4026 sx0, sx1 = sr.Min.X, sr.Min.X
4027 xFrac0, xFrac1 = 0, 1
4028 } else if sx1 >= sr.Max.X {
4029 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
4030 xFrac0, xFrac1 = 1, 0
4031 }
4032
4033 sy -= 0.5
4034 sy0 := int(sy)
4035 yFrac0 := sy - float64(sy0)
4036 yFrac1 := 1 - yFrac0
4037 sy0 += bias.Y
4038 sy1 := sy0 + 1
4039 if sy0 < sr.Min.Y {
4040 sy0, sy1 = sr.Min.Y, sr.Min.Y
4041 yFrac0, yFrac1 = 0, 1
4042 } else if sy1 >= sr.Max.Y {
4043 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
4044 yFrac0, yFrac1 = 1, 0
4045 }
4046
4047 s00i := (sy0-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
4048 s00j := (sy0-src.Rect.Min.Y)*src.CStride + (sx0 - src.Rect.Min.X)
4049
4050
4051 s00yy1 := int(src.Y[s00i]) * 0x10101
4052 s00cb1 := int(src.Cb[s00j]) - 128
4053 s00cr1 := int(src.Cr[s00j]) - 128
4054 s00ru := (s00yy1 + 91881*s00cr1) >> 8
4055 s00gu := (s00yy1 - 22554*s00cb1 - 46802*s00cr1) >> 8
4056 s00bu := (s00yy1 + 116130*s00cb1) >> 8
4057 if s00ru < 0 {
4058 s00ru = 0
4059 } else if s00ru > 0xffff {
4060 s00ru = 0xffff
4061 }
4062 if s00gu < 0 {
4063 s00gu = 0
4064 } else if s00gu > 0xffff {
4065 s00gu = 0xffff
4066 }
4067 if s00bu < 0 {
4068 s00bu = 0
4069 } else if s00bu > 0xffff {
4070 s00bu = 0xffff
4071 }
4072
4073 s00r := float64(s00ru)
4074 s00g := float64(s00gu)
4075 s00b := float64(s00bu)
4076 s10i := (sy0-src.Rect.Min.Y)*src.YStride + (sx1 - src.Rect.Min.X)
4077 s10j := (sy0-src.Rect.Min.Y)*src.CStride + (sx1 - src.Rect.Min.X)
4078
4079
4080 s10yy1 := int(src.Y[s10i]) * 0x10101
4081 s10cb1 := int(src.Cb[s10j]) - 128
4082 s10cr1 := int(src.Cr[s10j]) - 128
4083 s10ru := (s10yy1 + 91881*s10cr1) >> 8
4084 s10gu := (s10yy1 - 22554*s10cb1 - 46802*s10cr1) >> 8
4085 s10bu := (s10yy1 + 116130*s10cb1) >> 8
4086 if s10ru < 0 {
4087 s10ru = 0
4088 } else if s10ru > 0xffff {
4089 s10ru = 0xffff
4090 }
4091 if s10gu < 0 {
4092 s10gu = 0
4093 } else if s10gu > 0xffff {
4094 s10gu = 0xffff
4095 }
4096 if s10bu < 0 {
4097 s10bu = 0
4098 } else if s10bu > 0xffff {
4099 s10bu = 0xffff
4100 }
4101
4102 s10r := float64(s10ru)
4103 s10g := float64(s10gu)
4104 s10b := float64(s10bu)
4105 s10r = xFrac1*s00r + xFrac0*s10r
4106 s10g = xFrac1*s00g + xFrac0*s10g
4107 s10b = xFrac1*s00b + xFrac0*s10b
4108 s01i := (sy1-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
4109 s01j := (sy1-src.Rect.Min.Y)*src.CStride + (sx0 - src.Rect.Min.X)
4110
4111
4112 s01yy1 := int(src.Y[s01i]) * 0x10101
4113 s01cb1 := int(src.Cb[s01j]) - 128
4114 s01cr1 := int(src.Cr[s01j]) - 128
4115 s01ru := (s01yy1 + 91881*s01cr1) >> 8
4116 s01gu := (s01yy1 - 22554*s01cb1 - 46802*s01cr1) >> 8
4117 s01bu := (s01yy1 + 116130*s01cb1) >> 8
4118 if s01ru < 0 {
4119 s01ru = 0
4120 } else if s01ru > 0xffff {
4121 s01ru = 0xffff
4122 }
4123 if s01gu < 0 {
4124 s01gu = 0
4125 } else if s01gu > 0xffff {
4126 s01gu = 0xffff
4127 }
4128 if s01bu < 0 {
4129 s01bu = 0
4130 } else if s01bu > 0xffff {
4131 s01bu = 0xffff
4132 }
4133
4134 s01r := float64(s01ru)
4135 s01g := float64(s01gu)
4136 s01b := float64(s01bu)
4137 s11i := (sy1-src.Rect.Min.Y)*src.YStride + (sx1 - src.Rect.Min.X)
4138 s11j := (sy1-src.Rect.Min.Y)*src.CStride + (sx1 - src.Rect.Min.X)
4139
4140
4141 s11yy1 := int(src.Y[s11i]) * 0x10101
4142 s11cb1 := int(src.Cb[s11j]) - 128
4143 s11cr1 := int(src.Cr[s11j]) - 128
4144 s11ru := (s11yy1 + 91881*s11cr1) >> 8
4145 s11gu := (s11yy1 - 22554*s11cb1 - 46802*s11cr1) >> 8
4146 s11bu := (s11yy1 + 116130*s11cb1) >> 8
4147 if s11ru < 0 {
4148 s11ru = 0
4149 } else if s11ru > 0xffff {
4150 s11ru = 0xffff
4151 }
4152 if s11gu < 0 {
4153 s11gu = 0
4154 } else if s11gu > 0xffff {
4155 s11gu = 0xffff
4156 }
4157 if s11bu < 0 {
4158 s11bu = 0
4159 } else if s11bu > 0xffff {
4160 s11bu = 0xffff
4161 }
4162
4163 s11r := float64(s11ru)
4164 s11g := float64(s11gu)
4165 s11b := float64(s11bu)
4166 s11r = xFrac1*s01r + xFrac0*s11r
4167 s11g = xFrac1*s01g + xFrac0*s11g
4168 s11b = xFrac1*s01b + xFrac0*s11b
4169 s11r = yFrac1*s10r + yFrac0*s11r
4170 s11g = yFrac1*s10g + yFrac0*s11g
4171 s11b = yFrac1*s10b + yFrac0*s11b
4172 pr := uint32(s11r)
4173 pg := uint32(s11g)
4174 pb := uint32(s11b)
4175 dst.Pix[d+0] = uint8(pr >> 8)
4176 dst.Pix[d+1] = uint8(pg >> 8)
4177 dst.Pix[d+2] = uint8(pb >> 8)
4178 dst.Pix[d+3] = 0xff
4179 }
4180 }
4181 }
4182
4183 func (ablInterpolator) transform_RGBA_YCbCr422_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, opts *Options) {
4184 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
4185 dyf := float64(dr.Min.Y+int(dy)) + 0.5
4186 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
4187 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
4188 dxf := float64(dr.Min.X+int(dx)) + 0.5
4189 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
4190 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
4191 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
4192 continue
4193 }
4194
4195 sx -= 0.5
4196 sx0 := int(sx)
4197 xFrac0 := sx - float64(sx0)
4198 xFrac1 := 1 - xFrac0
4199 sx0 += bias.X
4200 sx1 := sx0 + 1
4201 if sx0 < sr.Min.X {
4202 sx0, sx1 = sr.Min.X, sr.Min.X
4203 xFrac0, xFrac1 = 0, 1
4204 } else if sx1 >= sr.Max.X {
4205 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
4206 xFrac0, xFrac1 = 1, 0
4207 }
4208
4209 sy -= 0.5
4210 sy0 := int(sy)
4211 yFrac0 := sy - float64(sy0)
4212 yFrac1 := 1 - yFrac0
4213 sy0 += bias.Y
4214 sy1 := sy0 + 1
4215 if sy0 < sr.Min.Y {
4216 sy0, sy1 = sr.Min.Y, sr.Min.Y
4217 yFrac0, yFrac1 = 0, 1
4218 } else if sy1 >= sr.Max.Y {
4219 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
4220 yFrac0, yFrac1 = 1, 0
4221 }
4222
4223 s00i := (sy0-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
4224 s00j := (sy0-src.Rect.Min.Y)*src.CStride + ((sx0)/2 - src.Rect.Min.X/2)
4225
4226
4227 s00yy1 := int(src.Y[s00i]) * 0x10101
4228 s00cb1 := int(src.Cb[s00j]) - 128
4229 s00cr1 := int(src.Cr[s00j]) - 128
4230 s00ru := (s00yy1 + 91881*s00cr1) >> 8
4231 s00gu := (s00yy1 - 22554*s00cb1 - 46802*s00cr1) >> 8
4232 s00bu := (s00yy1 + 116130*s00cb1) >> 8
4233 if s00ru < 0 {
4234 s00ru = 0
4235 } else if s00ru > 0xffff {
4236 s00ru = 0xffff
4237 }
4238 if s00gu < 0 {
4239 s00gu = 0
4240 } else if s00gu > 0xffff {
4241 s00gu = 0xffff
4242 }
4243 if s00bu < 0 {
4244 s00bu = 0
4245 } else if s00bu > 0xffff {
4246 s00bu = 0xffff
4247 }
4248
4249 s00r := float64(s00ru)
4250 s00g := float64(s00gu)
4251 s00b := float64(s00bu)
4252 s10i := (sy0-src.Rect.Min.Y)*src.YStride + (sx1 - src.Rect.Min.X)
4253 s10j := (sy0-src.Rect.Min.Y)*src.CStride + ((sx1)/2 - src.Rect.Min.X/2)
4254
4255
4256 s10yy1 := int(src.Y[s10i]) * 0x10101
4257 s10cb1 := int(src.Cb[s10j]) - 128
4258 s10cr1 := int(src.Cr[s10j]) - 128
4259 s10ru := (s10yy1 + 91881*s10cr1) >> 8
4260 s10gu := (s10yy1 - 22554*s10cb1 - 46802*s10cr1) >> 8
4261 s10bu := (s10yy1 + 116130*s10cb1) >> 8
4262 if s10ru < 0 {
4263 s10ru = 0
4264 } else if s10ru > 0xffff {
4265 s10ru = 0xffff
4266 }
4267 if s10gu < 0 {
4268 s10gu = 0
4269 } else if s10gu > 0xffff {
4270 s10gu = 0xffff
4271 }
4272 if s10bu < 0 {
4273 s10bu = 0
4274 } else if s10bu > 0xffff {
4275 s10bu = 0xffff
4276 }
4277
4278 s10r := float64(s10ru)
4279 s10g := float64(s10gu)
4280 s10b := float64(s10bu)
4281 s10r = xFrac1*s00r + xFrac0*s10r
4282 s10g = xFrac1*s00g + xFrac0*s10g
4283 s10b = xFrac1*s00b + xFrac0*s10b
4284 s01i := (sy1-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
4285 s01j := (sy1-src.Rect.Min.Y)*src.CStride + ((sx0)/2 - src.Rect.Min.X/2)
4286
4287
4288 s01yy1 := int(src.Y[s01i]) * 0x10101
4289 s01cb1 := int(src.Cb[s01j]) - 128
4290 s01cr1 := int(src.Cr[s01j]) - 128
4291 s01ru := (s01yy1 + 91881*s01cr1) >> 8
4292 s01gu := (s01yy1 - 22554*s01cb1 - 46802*s01cr1) >> 8
4293 s01bu := (s01yy1 + 116130*s01cb1) >> 8
4294 if s01ru < 0 {
4295 s01ru = 0
4296 } else if s01ru > 0xffff {
4297 s01ru = 0xffff
4298 }
4299 if s01gu < 0 {
4300 s01gu = 0
4301 } else if s01gu > 0xffff {
4302 s01gu = 0xffff
4303 }
4304 if s01bu < 0 {
4305 s01bu = 0
4306 } else if s01bu > 0xffff {
4307 s01bu = 0xffff
4308 }
4309
4310 s01r := float64(s01ru)
4311 s01g := float64(s01gu)
4312 s01b := float64(s01bu)
4313 s11i := (sy1-src.Rect.Min.Y)*src.YStride + (sx1 - src.Rect.Min.X)
4314 s11j := (sy1-src.Rect.Min.Y)*src.CStride + ((sx1)/2 - src.Rect.Min.X/2)
4315
4316
4317 s11yy1 := int(src.Y[s11i]) * 0x10101
4318 s11cb1 := int(src.Cb[s11j]) - 128
4319 s11cr1 := int(src.Cr[s11j]) - 128
4320 s11ru := (s11yy1 + 91881*s11cr1) >> 8
4321 s11gu := (s11yy1 - 22554*s11cb1 - 46802*s11cr1) >> 8
4322 s11bu := (s11yy1 + 116130*s11cb1) >> 8
4323 if s11ru < 0 {
4324 s11ru = 0
4325 } else if s11ru > 0xffff {
4326 s11ru = 0xffff
4327 }
4328 if s11gu < 0 {
4329 s11gu = 0
4330 } else if s11gu > 0xffff {
4331 s11gu = 0xffff
4332 }
4333 if s11bu < 0 {
4334 s11bu = 0
4335 } else if s11bu > 0xffff {
4336 s11bu = 0xffff
4337 }
4338
4339 s11r := float64(s11ru)
4340 s11g := float64(s11gu)
4341 s11b := float64(s11bu)
4342 s11r = xFrac1*s01r + xFrac0*s11r
4343 s11g = xFrac1*s01g + xFrac0*s11g
4344 s11b = xFrac1*s01b + xFrac0*s11b
4345 s11r = yFrac1*s10r + yFrac0*s11r
4346 s11g = yFrac1*s10g + yFrac0*s11g
4347 s11b = yFrac1*s10b + yFrac0*s11b
4348 pr := uint32(s11r)
4349 pg := uint32(s11g)
4350 pb := uint32(s11b)
4351 dst.Pix[d+0] = uint8(pr >> 8)
4352 dst.Pix[d+1] = uint8(pg >> 8)
4353 dst.Pix[d+2] = uint8(pb >> 8)
4354 dst.Pix[d+3] = 0xff
4355 }
4356 }
4357 }
4358
4359 func (ablInterpolator) transform_RGBA_YCbCr420_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, opts *Options) {
4360 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
4361 dyf := float64(dr.Min.Y+int(dy)) + 0.5
4362 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
4363 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
4364 dxf := float64(dr.Min.X+int(dx)) + 0.5
4365 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
4366 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
4367 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
4368 continue
4369 }
4370
4371 sx -= 0.5
4372 sx0 := int(sx)
4373 xFrac0 := sx - float64(sx0)
4374 xFrac1 := 1 - xFrac0
4375 sx0 += bias.X
4376 sx1 := sx0 + 1
4377 if sx0 < sr.Min.X {
4378 sx0, sx1 = sr.Min.X, sr.Min.X
4379 xFrac0, xFrac1 = 0, 1
4380 } else if sx1 >= sr.Max.X {
4381 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
4382 xFrac0, xFrac1 = 1, 0
4383 }
4384
4385 sy -= 0.5
4386 sy0 := int(sy)
4387 yFrac0 := sy - float64(sy0)
4388 yFrac1 := 1 - yFrac0
4389 sy0 += bias.Y
4390 sy1 := sy0 + 1
4391 if sy0 < sr.Min.Y {
4392 sy0, sy1 = sr.Min.Y, sr.Min.Y
4393 yFrac0, yFrac1 = 0, 1
4394 } else if sy1 >= sr.Max.Y {
4395 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
4396 yFrac0, yFrac1 = 1, 0
4397 }
4398
4399 s00i := (sy0-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
4400 s00j := ((sy0)/2-src.Rect.Min.Y/2)*src.CStride + ((sx0)/2 - src.Rect.Min.X/2)
4401
4402
4403 s00yy1 := int(src.Y[s00i]) * 0x10101
4404 s00cb1 := int(src.Cb[s00j]) - 128
4405 s00cr1 := int(src.Cr[s00j]) - 128
4406 s00ru := (s00yy1 + 91881*s00cr1) >> 8
4407 s00gu := (s00yy1 - 22554*s00cb1 - 46802*s00cr1) >> 8
4408 s00bu := (s00yy1 + 116130*s00cb1) >> 8
4409 if s00ru < 0 {
4410 s00ru = 0
4411 } else if s00ru > 0xffff {
4412 s00ru = 0xffff
4413 }
4414 if s00gu < 0 {
4415 s00gu = 0
4416 } else if s00gu > 0xffff {
4417 s00gu = 0xffff
4418 }
4419 if s00bu < 0 {
4420 s00bu = 0
4421 } else if s00bu > 0xffff {
4422 s00bu = 0xffff
4423 }
4424
4425 s00r := float64(s00ru)
4426 s00g := float64(s00gu)
4427 s00b := float64(s00bu)
4428 s10i := (sy0-src.Rect.Min.Y)*src.YStride + (sx1 - src.Rect.Min.X)
4429 s10j := ((sy0)/2-src.Rect.Min.Y/2)*src.CStride + ((sx1)/2 - src.Rect.Min.X/2)
4430
4431
4432 s10yy1 := int(src.Y[s10i]) * 0x10101
4433 s10cb1 := int(src.Cb[s10j]) - 128
4434 s10cr1 := int(src.Cr[s10j]) - 128
4435 s10ru := (s10yy1 + 91881*s10cr1) >> 8
4436 s10gu := (s10yy1 - 22554*s10cb1 - 46802*s10cr1) >> 8
4437 s10bu := (s10yy1 + 116130*s10cb1) >> 8
4438 if s10ru < 0 {
4439 s10ru = 0
4440 } else if s10ru > 0xffff {
4441 s10ru = 0xffff
4442 }
4443 if s10gu < 0 {
4444 s10gu = 0
4445 } else if s10gu > 0xffff {
4446 s10gu = 0xffff
4447 }
4448 if s10bu < 0 {
4449 s10bu = 0
4450 } else if s10bu > 0xffff {
4451 s10bu = 0xffff
4452 }
4453
4454 s10r := float64(s10ru)
4455 s10g := float64(s10gu)
4456 s10b := float64(s10bu)
4457 s10r = xFrac1*s00r + xFrac0*s10r
4458 s10g = xFrac1*s00g + xFrac0*s10g
4459 s10b = xFrac1*s00b + xFrac0*s10b
4460 s01i := (sy1-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
4461 s01j := ((sy1)/2-src.Rect.Min.Y/2)*src.CStride + ((sx0)/2 - src.Rect.Min.X/2)
4462
4463
4464 s01yy1 := int(src.Y[s01i]) * 0x10101
4465 s01cb1 := int(src.Cb[s01j]) - 128
4466 s01cr1 := int(src.Cr[s01j]) - 128
4467 s01ru := (s01yy1 + 91881*s01cr1) >> 8
4468 s01gu := (s01yy1 - 22554*s01cb1 - 46802*s01cr1) >> 8
4469 s01bu := (s01yy1 + 116130*s01cb1) >> 8
4470 if s01ru < 0 {
4471 s01ru = 0
4472 } else if s01ru > 0xffff {
4473 s01ru = 0xffff
4474 }
4475 if s01gu < 0 {
4476 s01gu = 0
4477 } else if s01gu > 0xffff {
4478 s01gu = 0xffff
4479 }
4480 if s01bu < 0 {
4481 s01bu = 0
4482 } else if s01bu > 0xffff {
4483 s01bu = 0xffff
4484 }
4485
4486 s01r := float64(s01ru)
4487 s01g := float64(s01gu)
4488 s01b := float64(s01bu)
4489 s11i := (sy1-src.Rect.Min.Y)*src.YStride + (sx1 - src.Rect.Min.X)
4490 s11j := ((sy1)/2-src.Rect.Min.Y/2)*src.CStride + ((sx1)/2 - src.Rect.Min.X/2)
4491
4492
4493 s11yy1 := int(src.Y[s11i]) * 0x10101
4494 s11cb1 := int(src.Cb[s11j]) - 128
4495 s11cr1 := int(src.Cr[s11j]) - 128
4496 s11ru := (s11yy1 + 91881*s11cr1) >> 8
4497 s11gu := (s11yy1 - 22554*s11cb1 - 46802*s11cr1) >> 8
4498 s11bu := (s11yy1 + 116130*s11cb1) >> 8
4499 if s11ru < 0 {
4500 s11ru = 0
4501 } else if s11ru > 0xffff {
4502 s11ru = 0xffff
4503 }
4504 if s11gu < 0 {
4505 s11gu = 0
4506 } else if s11gu > 0xffff {
4507 s11gu = 0xffff
4508 }
4509 if s11bu < 0 {
4510 s11bu = 0
4511 } else if s11bu > 0xffff {
4512 s11bu = 0xffff
4513 }
4514
4515 s11r := float64(s11ru)
4516 s11g := float64(s11gu)
4517 s11b := float64(s11bu)
4518 s11r = xFrac1*s01r + xFrac0*s11r
4519 s11g = xFrac1*s01g + xFrac0*s11g
4520 s11b = xFrac1*s01b + xFrac0*s11b
4521 s11r = yFrac1*s10r + yFrac0*s11r
4522 s11g = yFrac1*s10g + yFrac0*s11g
4523 s11b = yFrac1*s10b + yFrac0*s11b
4524 pr := uint32(s11r)
4525 pg := uint32(s11g)
4526 pb := uint32(s11b)
4527 dst.Pix[d+0] = uint8(pr >> 8)
4528 dst.Pix[d+1] = uint8(pg >> 8)
4529 dst.Pix[d+2] = uint8(pb >> 8)
4530 dst.Pix[d+3] = 0xff
4531 }
4532 }
4533 }
4534
4535 func (ablInterpolator) transform_RGBA_YCbCr440_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, opts *Options) {
4536 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
4537 dyf := float64(dr.Min.Y+int(dy)) + 0.5
4538 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
4539 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
4540 dxf := float64(dr.Min.X+int(dx)) + 0.5
4541 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
4542 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
4543 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
4544 continue
4545 }
4546
4547 sx -= 0.5
4548 sx0 := int(sx)
4549 xFrac0 := sx - float64(sx0)
4550 xFrac1 := 1 - xFrac0
4551 sx0 += bias.X
4552 sx1 := sx0 + 1
4553 if sx0 < sr.Min.X {
4554 sx0, sx1 = sr.Min.X, sr.Min.X
4555 xFrac0, xFrac1 = 0, 1
4556 } else if sx1 >= sr.Max.X {
4557 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
4558 xFrac0, xFrac1 = 1, 0
4559 }
4560
4561 sy -= 0.5
4562 sy0 := int(sy)
4563 yFrac0 := sy - float64(sy0)
4564 yFrac1 := 1 - yFrac0
4565 sy0 += bias.Y
4566 sy1 := sy0 + 1
4567 if sy0 < sr.Min.Y {
4568 sy0, sy1 = sr.Min.Y, sr.Min.Y
4569 yFrac0, yFrac1 = 0, 1
4570 } else if sy1 >= sr.Max.Y {
4571 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
4572 yFrac0, yFrac1 = 1, 0
4573 }
4574
4575 s00i := (sy0-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
4576 s00j := ((sy0)/2-src.Rect.Min.Y/2)*src.CStride + (sx0 - src.Rect.Min.X)
4577
4578
4579 s00yy1 := int(src.Y[s00i]) * 0x10101
4580 s00cb1 := int(src.Cb[s00j]) - 128
4581 s00cr1 := int(src.Cr[s00j]) - 128
4582 s00ru := (s00yy1 + 91881*s00cr1) >> 8
4583 s00gu := (s00yy1 - 22554*s00cb1 - 46802*s00cr1) >> 8
4584 s00bu := (s00yy1 + 116130*s00cb1) >> 8
4585 if s00ru < 0 {
4586 s00ru = 0
4587 } else if s00ru > 0xffff {
4588 s00ru = 0xffff
4589 }
4590 if s00gu < 0 {
4591 s00gu = 0
4592 } else if s00gu > 0xffff {
4593 s00gu = 0xffff
4594 }
4595 if s00bu < 0 {
4596 s00bu = 0
4597 } else if s00bu > 0xffff {
4598 s00bu = 0xffff
4599 }
4600
4601 s00r := float64(s00ru)
4602 s00g := float64(s00gu)
4603 s00b := float64(s00bu)
4604 s10i := (sy0-src.Rect.Min.Y)*src.YStride + (sx1 - src.Rect.Min.X)
4605 s10j := ((sy0)/2-src.Rect.Min.Y/2)*src.CStride + (sx1 - src.Rect.Min.X)
4606
4607
4608 s10yy1 := int(src.Y[s10i]) * 0x10101
4609 s10cb1 := int(src.Cb[s10j]) - 128
4610 s10cr1 := int(src.Cr[s10j]) - 128
4611 s10ru := (s10yy1 + 91881*s10cr1) >> 8
4612 s10gu := (s10yy1 - 22554*s10cb1 - 46802*s10cr1) >> 8
4613 s10bu := (s10yy1 + 116130*s10cb1) >> 8
4614 if s10ru < 0 {
4615 s10ru = 0
4616 } else if s10ru > 0xffff {
4617 s10ru = 0xffff
4618 }
4619 if s10gu < 0 {
4620 s10gu = 0
4621 } else if s10gu > 0xffff {
4622 s10gu = 0xffff
4623 }
4624 if s10bu < 0 {
4625 s10bu = 0
4626 } else if s10bu > 0xffff {
4627 s10bu = 0xffff
4628 }
4629
4630 s10r := float64(s10ru)
4631 s10g := float64(s10gu)
4632 s10b := float64(s10bu)
4633 s10r = xFrac1*s00r + xFrac0*s10r
4634 s10g = xFrac1*s00g + xFrac0*s10g
4635 s10b = xFrac1*s00b + xFrac0*s10b
4636 s01i := (sy1-src.Rect.Min.Y)*src.YStride + (sx0 - src.Rect.Min.X)
4637 s01j := ((sy1)/2-src.Rect.Min.Y/2)*src.CStride + (sx0 - src.Rect.Min.X)
4638
4639
4640 s01yy1 := int(src.Y[s01i]) * 0x10101
4641 s01cb1 := int(src.Cb[s01j]) - 128
4642 s01cr1 := int(src.Cr[s01j]) - 128
4643 s01ru := (s01yy1 + 91881*s01cr1) >> 8
4644 s01gu := (s01yy1 - 22554*s01cb1 - 46802*s01cr1) >> 8
4645 s01bu := (s01yy1 + 116130*s01cb1) >> 8
4646 if s01ru < 0 {
4647 s01ru = 0
4648 } else if s01ru > 0xffff {
4649 s01ru = 0xffff
4650 }
4651 if s01gu < 0 {
4652 s01gu = 0
4653 } else if s01gu > 0xffff {
4654 s01gu = 0xffff
4655 }
4656 if s01bu < 0 {
4657 s01bu = 0
4658 } else if s01bu > 0xffff {
4659 s01bu = 0xffff
4660 }
4661
4662 s01r := float64(s01ru)
4663 s01g := float64(s01gu)
4664 s01b := float64(s01bu)
4665 s11i := (sy1-src.Rect.Min.Y)*src.YStride + (sx1 - src.Rect.Min.X)
4666 s11j := ((sy1)/2-src.Rect.Min.Y/2)*src.CStride + (sx1 - src.Rect.Min.X)
4667
4668
4669 s11yy1 := int(src.Y[s11i]) * 0x10101
4670 s11cb1 := int(src.Cb[s11j]) - 128
4671 s11cr1 := int(src.Cr[s11j]) - 128
4672 s11ru := (s11yy1 + 91881*s11cr1) >> 8
4673 s11gu := (s11yy1 - 22554*s11cb1 - 46802*s11cr1) >> 8
4674 s11bu := (s11yy1 + 116130*s11cb1) >> 8
4675 if s11ru < 0 {
4676 s11ru = 0
4677 } else if s11ru > 0xffff {
4678 s11ru = 0xffff
4679 }
4680 if s11gu < 0 {
4681 s11gu = 0
4682 } else if s11gu > 0xffff {
4683 s11gu = 0xffff
4684 }
4685 if s11bu < 0 {
4686 s11bu = 0
4687 } else if s11bu > 0xffff {
4688 s11bu = 0xffff
4689 }
4690
4691 s11r := float64(s11ru)
4692 s11g := float64(s11gu)
4693 s11b := float64(s11bu)
4694 s11r = xFrac1*s01r + xFrac0*s11r
4695 s11g = xFrac1*s01g + xFrac0*s11g
4696 s11b = xFrac1*s01b + xFrac0*s11b
4697 s11r = yFrac1*s10r + yFrac0*s11r
4698 s11g = yFrac1*s10g + yFrac0*s11g
4699 s11b = yFrac1*s10b + yFrac0*s11b
4700 pr := uint32(s11r)
4701 pg := uint32(s11g)
4702 pb := uint32(s11b)
4703 dst.Pix[d+0] = uint8(pr >> 8)
4704 dst.Pix[d+1] = uint8(pg >> 8)
4705 dst.Pix[d+2] = uint8(pb >> 8)
4706 dst.Pix[d+3] = 0xff
4707 }
4708 }
4709 }
4710
4711 func (ablInterpolator) transform_RGBA_RGBA64Image_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, opts *Options) {
4712 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
4713 dyf := float64(dr.Min.Y+int(dy)) + 0.5
4714 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
4715 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
4716 dxf := float64(dr.Min.X+int(dx)) + 0.5
4717 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
4718 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
4719 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
4720 continue
4721 }
4722
4723 sx -= 0.5
4724 sx0 := int(sx)
4725 xFrac0 := sx - float64(sx0)
4726 xFrac1 := 1 - xFrac0
4727 sx0 += bias.X
4728 sx1 := sx0 + 1
4729 if sx0 < sr.Min.X {
4730 sx0, sx1 = sr.Min.X, sr.Min.X
4731 xFrac0, xFrac1 = 0, 1
4732 } else if sx1 >= sr.Max.X {
4733 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
4734 xFrac0, xFrac1 = 1, 0
4735 }
4736
4737 sy -= 0.5
4738 sy0 := int(sy)
4739 yFrac0 := sy - float64(sy0)
4740 yFrac1 := 1 - yFrac0
4741 sy0 += bias.Y
4742 sy1 := sy0 + 1
4743 if sy0 < sr.Min.Y {
4744 sy0, sy1 = sr.Min.Y, sr.Min.Y
4745 yFrac0, yFrac1 = 0, 1
4746 } else if sy1 >= sr.Max.Y {
4747 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
4748 yFrac0, yFrac1 = 1, 0
4749 }
4750
4751 s00u := src.RGBA64At(sx0, sy0)
4752 s00r := float64(s00u.R)
4753 s00g := float64(s00u.G)
4754 s00b := float64(s00u.B)
4755 s00a := float64(s00u.A)
4756 s10u := src.RGBA64At(sx1, sy0)
4757 s10r := float64(s10u.R)
4758 s10g := float64(s10u.G)
4759 s10b := float64(s10u.B)
4760 s10a := float64(s10u.A)
4761 s10r = xFrac1*s00r + xFrac0*s10r
4762 s10g = xFrac1*s00g + xFrac0*s10g
4763 s10b = xFrac1*s00b + xFrac0*s10b
4764 s10a = xFrac1*s00a + xFrac0*s10a
4765 s01u := src.RGBA64At(sx0, sy1)
4766 s01r := float64(s01u.R)
4767 s01g := float64(s01u.G)
4768 s01b := float64(s01u.B)
4769 s01a := float64(s01u.A)
4770 s11u := src.RGBA64At(sx1, sy1)
4771 s11r := float64(s11u.R)
4772 s11g := float64(s11u.G)
4773 s11b := float64(s11u.B)
4774 s11a := float64(s11u.A)
4775 s11r = xFrac1*s01r + xFrac0*s11r
4776 s11g = xFrac1*s01g + xFrac0*s11g
4777 s11b = xFrac1*s01b + xFrac0*s11b
4778 s11a = xFrac1*s01a + xFrac0*s11a
4779 s11r = yFrac1*s10r + yFrac0*s11r
4780 s11g = yFrac1*s10g + yFrac0*s11g
4781 s11b = yFrac1*s10b + yFrac0*s11b
4782 s11a = yFrac1*s10a + yFrac0*s11a
4783 p := color.RGBA64{uint16(s11r), uint16(s11g), uint16(s11b), uint16(s11a)}
4784 pa1 := (0xffff - uint32(p.A)) * 0x101
4785 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + uint32(p.R)) >> 8)
4786 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + uint32(p.G)) >> 8)
4787 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + uint32(p.B)) >> 8)
4788 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + uint32(p.A)) >> 8)
4789 }
4790 }
4791 }
4792
4793 func (ablInterpolator) transform_RGBA_RGBA64Image_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, opts *Options) {
4794 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
4795 dyf := float64(dr.Min.Y+int(dy)) + 0.5
4796 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
4797 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
4798 dxf := float64(dr.Min.X+int(dx)) + 0.5
4799 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
4800 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
4801 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
4802 continue
4803 }
4804
4805 sx -= 0.5
4806 sx0 := int(sx)
4807 xFrac0 := sx - float64(sx0)
4808 xFrac1 := 1 - xFrac0
4809 sx0 += bias.X
4810 sx1 := sx0 + 1
4811 if sx0 < sr.Min.X {
4812 sx0, sx1 = sr.Min.X, sr.Min.X
4813 xFrac0, xFrac1 = 0, 1
4814 } else if sx1 >= sr.Max.X {
4815 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
4816 xFrac0, xFrac1 = 1, 0
4817 }
4818
4819 sy -= 0.5
4820 sy0 := int(sy)
4821 yFrac0 := sy - float64(sy0)
4822 yFrac1 := 1 - yFrac0
4823 sy0 += bias.Y
4824 sy1 := sy0 + 1
4825 if sy0 < sr.Min.Y {
4826 sy0, sy1 = sr.Min.Y, sr.Min.Y
4827 yFrac0, yFrac1 = 0, 1
4828 } else if sy1 >= sr.Max.Y {
4829 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
4830 yFrac0, yFrac1 = 1, 0
4831 }
4832
4833 s00u := src.RGBA64At(sx0, sy0)
4834 s00r := float64(s00u.R)
4835 s00g := float64(s00u.G)
4836 s00b := float64(s00u.B)
4837 s00a := float64(s00u.A)
4838 s10u := src.RGBA64At(sx1, sy0)
4839 s10r := float64(s10u.R)
4840 s10g := float64(s10u.G)
4841 s10b := float64(s10u.B)
4842 s10a := float64(s10u.A)
4843 s10r = xFrac1*s00r + xFrac0*s10r
4844 s10g = xFrac1*s00g + xFrac0*s10g
4845 s10b = xFrac1*s00b + xFrac0*s10b
4846 s10a = xFrac1*s00a + xFrac0*s10a
4847 s01u := src.RGBA64At(sx0, sy1)
4848 s01r := float64(s01u.R)
4849 s01g := float64(s01u.G)
4850 s01b := float64(s01u.B)
4851 s01a := float64(s01u.A)
4852 s11u := src.RGBA64At(sx1, sy1)
4853 s11r := float64(s11u.R)
4854 s11g := float64(s11u.G)
4855 s11b := float64(s11u.B)
4856 s11a := float64(s11u.A)
4857 s11r = xFrac1*s01r + xFrac0*s11r
4858 s11g = xFrac1*s01g + xFrac0*s11g
4859 s11b = xFrac1*s01b + xFrac0*s11b
4860 s11a = xFrac1*s01a + xFrac0*s11a
4861 s11r = yFrac1*s10r + yFrac0*s11r
4862 s11g = yFrac1*s10g + yFrac0*s11g
4863 s11b = yFrac1*s10b + yFrac0*s11b
4864 s11a = yFrac1*s10a + yFrac0*s11a
4865 p := color.RGBA64{uint16(s11r), uint16(s11g), uint16(s11b), uint16(s11a)}
4866 dst.Pix[d+0] = uint8(p.R >> 8)
4867 dst.Pix[d+1] = uint8(p.G >> 8)
4868 dst.Pix[d+2] = uint8(p.B >> 8)
4869 dst.Pix[d+3] = uint8(p.A >> 8)
4870 }
4871 }
4872 }
4873
4874 func (ablInterpolator) transform_RGBA_Image_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, opts *Options) {
4875 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
4876 dyf := float64(dr.Min.Y+int(dy)) + 0.5
4877 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
4878 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
4879 dxf := float64(dr.Min.X+int(dx)) + 0.5
4880 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
4881 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
4882 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
4883 continue
4884 }
4885
4886 sx -= 0.5
4887 sx0 := int(sx)
4888 xFrac0 := sx - float64(sx0)
4889 xFrac1 := 1 - xFrac0
4890 sx0 += bias.X
4891 sx1 := sx0 + 1
4892 if sx0 < sr.Min.X {
4893 sx0, sx1 = sr.Min.X, sr.Min.X
4894 xFrac0, xFrac1 = 0, 1
4895 } else if sx1 >= sr.Max.X {
4896 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
4897 xFrac0, xFrac1 = 1, 0
4898 }
4899
4900 sy -= 0.5
4901 sy0 := int(sy)
4902 yFrac0 := sy - float64(sy0)
4903 yFrac1 := 1 - yFrac0
4904 sy0 += bias.Y
4905 sy1 := sy0 + 1
4906 if sy0 < sr.Min.Y {
4907 sy0, sy1 = sr.Min.Y, sr.Min.Y
4908 yFrac0, yFrac1 = 0, 1
4909 } else if sy1 >= sr.Max.Y {
4910 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
4911 yFrac0, yFrac1 = 1, 0
4912 }
4913
4914 s00ru, s00gu, s00bu, s00au := src.At(sx0, sy0).RGBA()
4915 s00r := float64(s00ru)
4916 s00g := float64(s00gu)
4917 s00b := float64(s00bu)
4918 s00a := float64(s00au)
4919 s10ru, s10gu, s10bu, s10au := src.At(sx1, sy0).RGBA()
4920 s10r := float64(s10ru)
4921 s10g := float64(s10gu)
4922 s10b := float64(s10bu)
4923 s10a := float64(s10au)
4924 s10r = xFrac1*s00r + xFrac0*s10r
4925 s10g = xFrac1*s00g + xFrac0*s10g
4926 s10b = xFrac1*s00b + xFrac0*s10b
4927 s10a = xFrac1*s00a + xFrac0*s10a
4928 s01ru, s01gu, s01bu, s01au := src.At(sx0, sy1).RGBA()
4929 s01r := float64(s01ru)
4930 s01g := float64(s01gu)
4931 s01b := float64(s01bu)
4932 s01a := float64(s01au)
4933 s11ru, s11gu, s11bu, s11au := src.At(sx1, sy1).RGBA()
4934 s11r := float64(s11ru)
4935 s11g := float64(s11gu)
4936 s11b := float64(s11bu)
4937 s11a := float64(s11au)
4938 s11r = xFrac1*s01r + xFrac0*s11r
4939 s11g = xFrac1*s01g + xFrac0*s11g
4940 s11b = xFrac1*s01b + xFrac0*s11b
4941 s11a = xFrac1*s01a + xFrac0*s11a
4942 s11r = yFrac1*s10r + yFrac0*s11r
4943 s11g = yFrac1*s10g + yFrac0*s11g
4944 s11b = yFrac1*s10b + yFrac0*s11b
4945 s11a = yFrac1*s10a + yFrac0*s11a
4946 pr := uint32(s11r)
4947 pg := uint32(s11g)
4948 pb := uint32(s11b)
4949 pa := uint32(s11a)
4950 pa1 := (0xffff - pa) * 0x101
4951 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr) >> 8)
4952 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg) >> 8)
4953 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb) >> 8)
4954 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa) >> 8)
4955 }
4956 }
4957 }
4958
4959 func (ablInterpolator) transform_RGBA_Image_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, opts *Options) {
4960 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
4961 dyf := float64(dr.Min.Y+int(dy)) + 0.5
4962 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
4963 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
4964 dxf := float64(dr.Min.X+int(dx)) + 0.5
4965 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
4966 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
4967 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
4968 continue
4969 }
4970
4971 sx -= 0.5
4972 sx0 := int(sx)
4973 xFrac0 := sx - float64(sx0)
4974 xFrac1 := 1 - xFrac0
4975 sx0 += bias.X
4976 sx1 := sx0 + 1
4977 if sx0 < sr.Min.X {
4978 sx0, sx1 = sr.Min.X, sr.Min.X
4979 xFrac0, xFrac1 = 0, 1
4980 } else if sx1 >= sr.Max.X {
4981 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
4982 xFrac0, xFrac1 = 1, 0
4983 }
4984
4985 sy -= 0.5
4986 sy0 := int(sy)
4987 yFrac0 := sy - float64(sy0)
4988 yFrac1 := 1 - yFrac0
4989 sy0 += bias.Y
4990 sy1 := sy0 + 1
4991 if sy0 < sr.Min.Y {
4992 sy0, sy1 = sr.Min.Y, sr.Min.Y
4993 yFrac0, yFrac1 = 0, 1
4994 } else if sy1 >= sr.Max.Y {
4995 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
4996 yFrac0, yFrac1 = 1, 0
4997 }
4998
4999 s00ru, s00gu, s00bu, s00au := src.At(sx0, sy0).RGBA()
5000 s00r := float64(s00ru)
5001 s00g := float64(s00gu)
5002 s00b := float64(s00bu)
5003 s00a := float64(s00au)
5004 s10ru, s10gu, s10bu, s10au := src.At(sx1, sy0).RGBA()
5005 s10r := float64(s10ru)
5006 s10g := float64(s10gu)
5007 s10b := float64(s10bu)
5008 s10a := float64(s10au)
5009 s10r = xFrac1*s00r + xFrac0*s10r
5010 s10g = xFrac1*s00g + xFrac0*s10g
5011 s10b = xFrac1*s00b + xFrac0*s10b
5012 s10a = xFrac1*s00a + xFrac0*s10a
5013 s01ru, s01gu, s01bu, s01au := src.At(sx0, sy1).RGBA()
5014 s01r := float64(s01ru)
5015 s01g := float64(s01gu)
5016 s01b := float64(s01bu)
5017 s01a := float64(s01au)
5018 s11ru, s11gu, s11bu, s11au := src.At(sx1, sy1).RGBA()
5019 s11r := float64(s11ru)
5020 s11g := float64(s11gu)
5021 s11b := float64(s11bu)
5022 s11a := float64(s11au)
5023 s11r = xFrac1*s01r + xFrac0*s11r
5024 s11g = xFrac1*s01g + xFrac0*s11g
5025 s11b = xFrac1*s01b + xFrac0*s11b
5026 s11a = xFrac1*s01a + xFrac0*s11a
5027 s11r = yFrac1*s10r + yFrac0*s11r
5028 s11g = yFrac1*s10g + yFrac0*s11g
5029 s11b = yFrac1*s10b + yFrac0*s11b
5030 s11a = yFrac1*s10a + yFrac0*s11a
5031 pr := uint32(s11r)
5032 pg := uint32(s11g)
5033 pb := uint32(s11b)
5034 pa := uint32(s11a)
5035 dst.Pix[d+0] = uint8(pr >> 8)
5036 dst.Pix[d+1] = uint8(pg >> 8)
5037 dst.Pix[d+2] = uint8(pb >> 8)
5038 dst.Pix[d+3] = uint8(pa >> 8)
5039 }
5040 }
5041 }
5042
5043 func (ablInterpolator) transform_RGBA64Image_RGBA64Image_Over(dst RGBA64Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, opts *Options) {
5044 srcMask, smp := opts.SrcMask, opts.SrcMaskP
5045 dstMask, dmp := opts.DstMask, opts.DstMaskP
5046 dstColorRGBA64 := color.RGBA64{}
5047
5048 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
5049 dyf := float64(dr.Min.Y+int(dy)) + 0.5
5050 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
5051 dxf := float64(dr.Min.X+int(dx)) + 0.5
5052 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
5053 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
5054 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
5055 continue
5056 }
5057
5058 sx -= 0.5
5059 sx0 := int(sx)
5060 xFrac0 := sx - float64(sx0)
5061 xFrac1 := 1 - xFrac0
5062 sx0 += bias.X
5063 sx1 := sx0 + 1
5064 if sx0 < sr.Min.X {
5065 sx0, sx1 = sr.Min.X, sr.Min.X
5066 xFrac0, xFrac1 = 0, 1
5067 } else if sx1 >= sr.Max.X {
5068 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
5069 xFrac0, xFrac1 = 1, 0
5070 }
5071
5072 sy -= 0.5
5073 sy0 := int(sy)
5074 yFrac0 := sy - float64(sy0)
5075 yFrac1 := 1 - yFrac0
5076 sy0 += bias.Y
5077 sy1 := sy0 + 1
5078 if sy0 < sr.Min.Y {
5079 sy0, sy1 = sr.Min.Y, sr.Min.Y
5080 yFrac0, yFrac1 = 0, 1
5081 } else if sy1 >= sr.Max.Y {
5082 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
5083 yFrac0, yFrac1 = 1, 0
5084 }
5085
5086 s00u := src.RGBA64At(sx0, sy0)
5087 if srcMask != nil {
5088 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy0).RGBA()
5089 s00u.R = uint16(uint32(s00u.R) * ma / 0xffff)
5090 s00u.G = uint16(uint32(s00u.G) * ma / 0xffff)
5091 s00u.B = uint16(uint32(s00u.B) * ma / 0xffff)
5092 s00u.A = uint16(uint32(s00u.A) * ma / 0xffff)
5093 }
5094 s00r := float64(s00u.R)
5095 s00g := float64(s00u.G)
5096 s00b := float64(s00u.B)
5097 s00a := float64(s00u.A)
5098 s10u := src.RGBA64At(sx1, sy0)
5099 if srcMask != nil {
5100 _, _, _, ma := srcMask.At(smp.X+sx1, smp.Y+sy0).RGBA()
5101 s10u.R = uint16(uint32(s10u.R) * ma / 0xffff)
5102 s10u.G = uint16(uint32(s10u.G) * ma / 0xffff)
5103 s10u.B = uint16(uint32(s10u.B) * ma / 0xffff)
5104 s10u.A = uint16(uint32(s10u.A) * ma / 0xffff)
5105 }
5106 s10r := float64(s10u.R)
5107 s10g := float64(s10u.G)
5108 s10b := float64(s10u.B)
5109 s10a := float64(s10u.A)
5110 s10r = xFrac1*s00r + xFrac0*s10r
5111 s10g = xFrac1*s00g + xFrac0*s10g
5112 s10b = xFrac1*s00b + xFrac0*s10b
5113 s10a = xFrac1*s00a + xFrac0*s10a
5114 s01u := src.RGBA64At(sx0, sy1)
5115 if srcMask != nil {
5116 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy1).RGBA()
5117 s01u.R = uint16(uint32(s01u.R) * ma / 0xffff)
5118 s01u.G = uint16(uint32(s01u.G) * ma / 0xffff)
5119 s01u.B = uint16(uint32(s01u.B) * ma / 0xffff)
5120 s01u.A = uint16(uint32(s01u.A) * ma / 0xffff)
5121 }
5122 s01r := float64(s01u.R)
5123 s01g := float64(s01u.G)
5124 s01b := float64(s01u.B)
5125 s01a := float64(s01u.A)
5126 s11u := src.RGBA64At(sx1, sy1)
5127 if srcMask != nil {
5128 _, _, _, ma := srcMask.At(smp.X+sx1, smp.Y+sy1).RGBA()
5129 s11u.R = uint16(uint32(s11u.R) * ma / 0xffff)
5130 s11u.G = uint16(uint32(s11u.G) * ma / 0xffff)
5131 s11u.B = uint16(uint32(s11u.B) * ma / 0xffff)
5132 s11u.A = uint16(uint32(s11u.A) * ma / 0xffff)
5133 }
5134 s11r := float64(s11u.R)
5135 s11g := float64(s11u.G)
5136 s11b := float64(s11u.B)
5137 s11a := float64(s11u.A)
5138 s11r = xFrac1*s01r + xFrac0*s11r
5139 s11g = xFrac1*s01g + xFrac0*s11g
5140 s11b = xFrac1*s01b + xFrac0*s11b
5141 s11a = xFrac1*s01a + xFrac0*s11a
5142 s11r = yFrac1*s10r + yFrac0*s11r
5143 s11g = yFrac1*s10g + yFrac0*s11g
5144 s11b = yFrac1*s10b + yFrac0*s11b
5145 s11a = yFrac1*s10a + yFrac0*s11a
5146 p := color.RGBA64{uint16(s11r), uint16(s11g), uint16(s11b), uint16(s11a)}
5147 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(dy))
5148 if dstMask != nil {
5149 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
5150 p.R = uint16(uint32(p.R) * ma / 0xffff)
5151 p.G = uint16(uint32(p.G) * ma / 0xffff)
5152 p.B = uint16(uint32(p.B) * ma / 0xffff)
5153 p.A = uint16(uint32(p.A) * ma / 0xffff)
5154 }
5155 pa1 := 0xffff - uint32(p.A)
5156 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + uint32(p.R))
5157 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + uint32(p.G))
5158 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + uint32(p.B))
5159 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + uint32(p.A))
5160 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColorRGBA64)
5161 }
5162 }
5163 }
5164
5165 func (ablInterpolator) transform_RGBA64Image_RGBA64Image_Src(dst RGBA64Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, opts *Options) {
5166 srcMask, smp := opts.SrcMask, opts.SrcMaskP
5167 dstMask, dmp := opts.DstMask, opts.DstMaskP
5168 dstColorRGBA64 := color.RGBA64{}
5169
5170 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
5171 dyf := float64(dr.Min.Y+int(dy)) + 0.5
5172 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
5173 dxf := float64(dr.Min.X+int(dx)) + 0.5
5174 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
5175 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
5176 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
5177 continue
5178 }
5179
5180 sx -= 0.5
5181 sx0 := int(sx)
5182 xFrac0 := sx - float64(sx0)
5183 xFrac1 := 1 - xFrac0
5184 sx0 += bias.X
5185 sx1 := sx0 + 1
5186 if sx0 < sr.Min.X {
5187 sx0, sx1 = sr.Min.X, sr.Min.X
5188 xFrac0, xFrac1 = 0, 1
5189 } else if sx1 >= sr.Max.X {
5190 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
5191 xFrac0, xFrac1 = 1, 0
5192 }
5193
5194 sy -= 0.5
5195 sy0 := int(sy)
5196 yFrac0 := sy - float64(sy0)
5197 yFrac1 := 1 - yFrac0
5198 sy0 += bias.Y
5199 sy1 := sy0 + 1
5200 if sy0 < sr.Min.Y {
5201 sy0, sy1 = sr.Min.Y, sr.Min.Y
5202 yFrac0, yFrac1 = 0, 1
5203 } else if sy1 >= sr.Max.Y {
5204 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
5205 yFrac0, yFrac1 = 1, 0
5206 }
5207
5208 s00u := src.RGBA64At(sx0, sy0)
5209 if srcMask != nil {
5210 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy0).RGBA()
5211 s00u.R = uint16(uint32(s00u.R) * ma / 0xffff)
5212 s00u.G = uint16(uint32(s00u.G) * ma / 0xffff)
5213 s00u.B = uint16(uint32(s00u.B) * ma / 0xffff)
5214 s00u.A = uint16(uint32(s00u.A) * ma / 0xffff)
5215 }
5216 s00r := float64(s00u.R)
5217 s00g := float64(s00u.G)
5218 s00b := float64(s00u.B)
5219 s00a := float64(s00u.A)
5220 s10u := src.RGBA64At(sx1, sy0)
5221 if srcMask != nil {
5222 _, _, _, ma := srcMask.At(smp.X+sx1, smp.Y+sy0).RGBA()
5223 s10u.R = uint16(uint32(s10u.R) * ma / 0xffff)
5224 s10u.G = uint16(uint32(s10u.G) * ma / 0xffff)
5225 s10u.B = uint16(uint32(s10u.B) * ma / 0xffff)
5226 s10u.A = uint16(uint32(s10u.A) * ma / 0xffff)
5227 }
5228 s10r := float64(s10u.R)
5229 s10g := float64(s10u.G)
5230 s10b := float64(s10u.B)
5231 s10a := float64(s10u.A)
5232 s10r = xFrac1*s00r + xFrac0*s10r
5233 s10g = xFrac1*s00g + xFrac0*s10g
5234 s10b = xFrac1*s00b + xFrac0*s10b
5235 s10a = xFrac1*s00a + xFrac0*s10a
5236 s01u := src.RGBA64At(sx0, sy1)
5237 if srcMask != nil {
5238 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy1).RGBA()
5239 s01u.R = uint16(uint32(s01u.R) * ma / 0xffff)
5240 s01u.G = uint16(uint32(s01u.G) * ma / 0xffff)
5241 s01u.B = uint16(uint32(s01u.B) * ma / 0xffff)
5242 s01u.A = uint16(uint32(s01u.A) * ma / 0xffff)
5243 }
5244 s01r := float64(s01u.R)
5245 s01g := float64(s01u.G)
5246 s01b := float64(s01u.B)
5247 s01a := float64(s01u.A)
5248 s11u := src.RGBA64At(sx1, sy1)
5249 if srcMask != nil {
5250 _, _, _, ma := srcMask.At(smp.X+sx1, smp.Y+sy1).RGBA()
5251 s11u.R = uint16(uint32(s11u.R) * ma / 0xffff)
5252 s11u.G = uint16(uint32(s11u.G) * ma / 0xffff)
5253 s11u.B = uint16(uint32(s11u.B) * ma / 0xffff)
5254 s11u.A = uint16(uint32(s11u.A) * ma / 0xffff)
5255 }
5256 s11r := float64(s11u.R)
5257 s11g := float64(s11u.G)
5258 s11b := float64(s11u.B)
5259 s11a := float64(s11u.A)
5260 s11r = xFrac1*s01r + xFrac0*s11r
5261 s11g = xFrac1*s01g + xFrac0*s11g
5262 s11b = xFrac1*s01b + xFrac0*s11b
5263 s11a = xFrac1*s01a + xFrac0*s11a
5264 s11r = yFrac1*s10r + yFrac0*s11r
5265 s11g = yFrac1*s10g + yFrac0*s11g
5266 s11b = yFrac1*s10b + yFrac0*s11b
5267 s11a = yFrac1*s10a + yFrac0*s11a
5268 p := color.RGBA64{uint16(s11r), uint16(s11g), uint16(s11b), uint16(s11a)}
5269 if dstMask != nil {
5270 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(dy))
5271 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
5272 p.R = uint16(uint32(p.R) * ma / 0xffff)
5273 p.G = uint16(uint32(p.G) * ma / 0xffff)
5274 p.B = uint16(uint32(p.B) * ma / 0xffff)
5275 p.A = uint16(uint32(p.A) * ma / 0xffff)
5276 pa1 := 0xffff - ma
5277 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + uint32(p.R))
5278 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + uint32(p.G))
5279 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + uint32(p.B))
5280 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + uint32(p.A))
5281 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColorRGBA64)
5282 } else {
5283 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), p)
5284 }
5285 }
5286 }
5287 }
5288
5289 func (ablInterpolator) transform_Image_Image_Over(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, opts *Options) {
5290 srcMask, smp := opts.SrcMask, opts.SrcMaskP
5291 dstMask, dmp := opts.DstMask, opts.DstMaskP
5292 dstColorRGBA64 := &color.RGBA64{}
5293 dstColor := color.Color(dstColorRGBA64)
5294 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
5295 dyf := float64(dr.Min.Y+int(dy)) + 0.5
5296 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
5297 dxf := float64(dr.Min.X+int(dx)) + 0.5
5298 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
5299 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
5300 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
5301 continue
5302 }
5303
5304 sx -= 0.5
5305 sx0 := int(sx)
5306 xFrac0 := sx - float64(sx0)
5307 xFrac1 := 1 - xFrac0
5308 sx0 += bias.X
5309 sx1 := sx0 + 1
5310 if sx0 < sr.Min.X {
5311 sx0, sx1 = sr.Min.X, sr.Min.X
5312 xFrac0, xFrac1 = 0, 1
5313 } else if sx1 >= sr.Max.X {
5314 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
5315 xFrac0, xFrac1 = 1, 0
5316 }
5317
5318 sy -= 0.5
5319 sy0 := int(sy)
5320 yFrac0 := sy - float64(sy0)
5321 yFrac1 := 1 - yFrac0
5322 sy0 += bias.Y
5323 sy1 := sy0 + 1
5324 if sy0 < sr.Min.Y {
5325 sy0, sy1 = sr.Min.Y, sr.Min.Y
5326 yFrac0, yFrac1 = 0, 1
5327 } else if sy1 >= sr.Max.Y {
5328 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
5329 yFrac0, yFrac1 = 1, 0
5330 }
5331
5332 s00ru, s00gu, s00bu, s00au := src.At(sx0, sy0).RGBA()
5333 if srcMask != nil {
5334 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy0).RGBA()
5335 s00ru = s00ru * ma / 0xffff
5336 s00gu = s00gu * ma / 0xffff
5337 s00bu = s00bu * ma / 0xffff
5338 s00au = s00au * ma / 0xffff
5339 }
5340 s00r := float64(s00ru)
5341 s00g := float64(s00gu)
5342 s00b := float64(s00bu)
5343 s00a := float64(s00au)
5344 s10ru, s10gu, s10bu, s10au := src.At(sx1, sy0).RGBA()
5345 if srcMask != nil {
5346 _, _, _, ma := srcMask.At(smp.X+sx1, smp.Y+sy0).RGBA()
5347 s10ru = s10ru * ma / 0xffff
5348 s10gu = s10gu * ma / 0xffff
5349 s10bu = s10bu * ma / 0xffff
5350 s10au = s10au * ma / 0xffff
5351 }
5352 s10r := float64(s10ru)
5353 s10g := float64(s10gu)
5354 s10b := float64(s10bu)
5355 s10a := float64(s10au)
5356 s10r = xFrac1*s00r + xFrac0*s10r
5357 s10g = xFrac1*s00g + xFrac0*s10g
5358 s10b = xFrac1*s00b + xFrac0*s10b
5359 s10a = xFrac1*s00a + xFrac0*s10a
5360 s01ru, s01gu, s01bu, s01au := src.At(sx0, sy1).RGBA()
5361 if srcMask != nil {
5362 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy1).RGBA()
5363 s01ru = s01ru * ma / 0xffff
5364 s01gu = s01gu * ma / 0xffff
5365 s01bu = s01bu * ma / 0xffff
5366 s01au = s01au * ma / 0xffff
5367 }
5368 s01r := float64(s01ru)
5369 s01g := float64(s01gu)
5370 s01b := float64(s01bu)
5371 s01a := float64(s01au)
5372 s11ru, s11gu, s11bu, s11au := src.At(sx1, sy1).RGBA()
5373 if srcMask != nil {
5374 _, _, _, ma := srcMask.At(smp.X+sx1, smp.Y+sy1).RGBA()
5375 s11ru = s11ru * ma / 0xffff
5376 s11gu = s11gu * ma / 0xffff
5377 s11bu = s11bu * ma / 0xffff
5378 s11au = s11au * ma / 0xffff
5379 }
5380 s11r := float64(s11ru)
5381 s11g := float64(s11gu)
5382 s11b := float64(s11bu)
5383 s11a := float64(s11au)
5384 s11r = xFrac1*s01r + xFrac0*s11r
5385 s11g = xFrac1*s01g + xFrac0*s11g
5386 s11b = xFrac1*s01b + xFrac0*s11b
5387 s11a = xFrac1*s01a + xFrac0*s11a
5388 s11r = yFrac1*s10r + yFrac0*s11r
5389 s11g = yFrac1*s10g + yFrac0*s11g
5390 s11b = yFrac1*s10b + yFrac0*s11b
5391 s11a = yFrac1*s10a + yFrac0*s11a
5392 pr := uint32(s11r)
5393 pg := uint32(s11g)
5394 pb := uint32(s11b)
5395 pa := uint32(s11a)
5396 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(dy)).RGBA()
5397 if dstMask != nil {
5398 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
5399 pr = pr * ma / 0xffff
5400 pg = pg * ma / 0xffff
5401 pb = pb * ma / 0xffff
5402 pa = pa * ma / 0xffff
5403 }
5404 pa1 := 0xffff - pa
5405 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr)
5406 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg)
5407 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb)
5408 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa)
5409 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
5410 }
5411 }
5412 }
5413
5414 func (ablInterpolator) transform_Image_Image_Src(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, opts *Options) {
5415 srcMask, smp := opts.SrcMask, opts.SrcMaskP
5416 dstMask, dmp := opts.DstMask, opts.DstMaskP
5417 dstColorRGBA64 := &color.RGBA64{}
5418 dstColor := color.Color(dstColorRGBA64)
5419 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
5420 dyf := float64(dr.Min.Y+int(dy)) + 0.5
5421 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
5422 dxf := float64(dr.Min.X+int(dx)) + 0.5
5423 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
5424 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
5425 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
5426 continue
5427 }
5428
5429 sx -= 0.5
5430 sx0 := int(sx)
5431 xFrac0 := sx - float64(sx0)
5432 xFrac1 := 1 - xFrac0
5433 sx0 += bias.X
5434 sx1 := sx0 + 1
5435 if sx0 < sr.Min.X {
5436 sx0, sx1 = sr.Min.X, sr.Min.X
5437 xFrac0, xFrac1 = 0, 1
5438 } else if sx1 >= sr.Max.X {
5439 sx0, sx1 = sr.Max.X-1, sr.Max.X-1
5440 xFrac0, xFrac1 = 1, 0
5441 }
5442
5443 sy -= 0.5
5444 sy0 := int(sy)
5445 yFrac0 := sy - float64(sy0)
5446 yFrac1 := 1 - yFrac0
5447 sy0 += bias.Y
5448 sy1 := sy0 + 1
5449 if sy0 < sr.Min.Y {
5450 sy0, sy1 = sr.Min.Y, sr.Min.Y
5451 yFrac0, yFrac1 = 0, 1
5452 } else if sy1 >= sr.Max.Y {
5453 sy0, sy1 = sr.Max.Y-1, sr.Max.Y-1
5454 yFrac0, yFrac1 = 1, 0
5455 }
5456
5457 s00ru, s00gu, s00bu, s00au := src.At(sx0, sy0).RGBA()
5458 if srcMask != nil {
5459 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy0).RGBA()
5460 s00ru = s00ru * ma / 0xffff
5461 s00gu = s00gu * ma / 0xffff
5462 s00bu = s00bu * ma / 0xffff
5463 s00au = s00au * ma / 0xffff
5464 }
5465 s00r := float64(s00ru)
5466 s00g := float64(s00gu)
5467 s00b := float64(s00bu)
5468 s00a := float64(s00au)
5469 s10ru, s10gu, s10bu, s10au := src.At(sx1, sy0).RGBA()
5470 if srcMask != nil {
5471 _, _, _, ma := srcMask.At(smp.X+sx1, smp.Y+sy0).RGBA()
5472 s10ru = s10ru * ma / 0xffff
5473 s10gu = s10gu * ma / 0xffff
5474 s10bu = s10bu * ma / 0xffff
5475 s10au = s10au * ma / 0xffff
5476 }
5477 s10r := float64(s10ru)
5478 s10g := float64(s10gu)
5479 s10b := float64(s10bu)
5480 s10a := float64(s10au)
5481 s10r = xFrac1*s00r + xFrac0*s10r
5482 s10g = xFrac1*s00g + xFrac0*s10g
5483 s10b = xFrac1*s00b + xFrac0*s10b
5484 s10a = xFrac1*s00a + xFrac0*s10a
5485 s01ru, s01gu, s01bu, s01au := src.At(sx0, sy1).RGBA()
5486 if srcMask != nil {
5487 _, _, _, ma := srcMask.At(smp.X+sx0, smp.Y+sy1).RGBA()
5488 s01ru = s01ru * ma / 0xffff
5489 s01gu = s01gu * ma / 0xffff
5490 s01bu = s01bu * ma / 0xffff
5491 s01au = s01au * ma / 0xffff
5492 }
5493 s01r := float64(s01ru)
5494 s01g := float64(s01gu)
5495 s01b := float64(s01bu)
5496 s01a := float64(s01au)
5497 s11ru, s11gu, s11bu, s11au := src.At(sx1, sy1).RGBA()
5498 if srcMask != nil {
5499 _, _, _, ma := srcMask.At(smp.X+sx1, smp.Y+sy1).RGBA()
5500 s11ru = s11ru * ma / 0xffff
5501 s11gu = s11gu * ma / 0xffff
5502 s11bu = s11bu * ma / 0xffff
5503 s11au = s11au * ma / 0xffff
5504 }
5505 s11r := float64(s11ru)
5506 s11g := float64(s11gu)
5507 s11b := float64(s11bu)
5508 s11a := float64(s11au)
5509 s11r = xFrac1*s01r + xFrac0*s11r
5510 s11g = xFrac1*s01g + xFrac0*s11g
5511 s11b = xFrac1*s01b + xFrac0*s11b
5512 s11a = xFrac1*s01a + xFrac0*s11a
5513 s11r = yFrac1*s10r + yFrac0*s11r
5514 s11g = yFrac1*s10g + yFrac0*s11g
5515 s11b = yFrac1*s10b + yFrac0*s11b
5516 s11a = yFrac1*s10a + yFrac0*s11a
5517 pr := uint32(s11r)
5518 pg := uint32(s11g)
5519 pb := uint32(s11b)
5520 pa := uint32(s11a)
5521 if dstMask != nil {
5522 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(dy)).RGBA()
5523 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
5524 pr = pr * ma / 0xffff
5525 pg = pg * ma / 0xffff
5526 pb = pb * ma / 0xffff
5527 pa = pa * ma / 0xffff
5528 pa1 := 0xffff - ma
5529 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr)
5530 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg)
5531 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb)
5532 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa)
5533 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
5534 } else {
5535 dstColorRGBA64.R = uint16(pr)
5536 dstColorRGBA64.G = uint16(pg)
5537 dstColorRGBA64.B = uint16(pb)
5538 dstColorRGBA64.A = uint16(pa)
5539 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
5540 }
5541 }
5542 }
5543 }
5544
5545 func (z *kernelScaler) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
5546 if z.dw != int32(dr.Dx()) || z.dh != int32(dr.Dy()) || z.sw != int32(sr.Dx()) || z.sh != int32(sr.Dy()) {
5547 z.kernel.Scale(dst, dr, src, sr, op, opts)
5548 return
5549 }
5550
5551 var o Options
5552 if opts != nil {
5553 o = *opts
5554 }
5555
5556
5557 adr := dst.Bounds().Intersect(dr)
5558 adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP)
5559 if adr.Empty() || sr.Empty() {
5560 return
5561 }
5562
5563 adr = adr.Sub(dr.Min)
5564 if op == Over && o.SrcMask == nil && opaque(src) {
5565 op = Src
5566 }
5567
5568 if _, ok := src.(*image.Uniform); ok && o.DstMask == nil && o.SrcMask == nil && sr.In(src.Bounds()) {
5569 Draw(dst, dr, src, src.Bounds().Min, op)
5570 return
5571 }
5572
5573
5574
5575
5576 var tmp [][4]float64
5577 if z.pool.New != nil {
5578 tmpp := z.pool.Get().(*[][4]float64)
5579 defer z.pool.Put(tmpp)
5580 tmp = *tmpp
5581 } else {
5582 tmp = z.makeTmpBuf()
5583 }
5584
5585
5586
5587
5588
5589
5590 if o.SrcMask != nil || !sr.In(src.Bounds()) {
5591 z.scaleX_Image(tmp, src, sr, &o)
5592 } else {
5593 switch src := src.(type) {
5594 case *image.Gray:
5595 z.scaleX_Gray(tmp, src, sr, &o)
5596 case *image.NRGBA:
5597 z.scaleX_NRGBA(tmp, src, sr, &o)
5598 case *image.RGBA:
5599 z.scaleX_RGBA(tmp, src, sr, &o)
5600 case *image.YCbCr:
5601 switch src.SubsampleRatio {
5602 default:
5603 z.scaleX_Image(tmp, src, sr, &o)
5604 case image.YCbCrSubsampleRatio444:
5605 z.scaleX_YCbCr444(tmp, src, sr, &o)
5606 case image.YCbCrSubsampleRatio422:
5607 z.scaleX_YCbCr422(tmp, src, sr, &o)
5608 case image.YCbCrSubsampleRatio420:
5609 z.scaleX_YCbCr420(tmp, src, sr, &o)
5610 case image.YCbCrSubsampleRatio440:
5611 z.scaleX_YCbCr440(tmp, src, sr, &o)
5612 }
5613 case image.RGBA64Image:
5614 z.scaleX_RGBA64Image(tmp, src, sr, &o)
5615 default:
5616 z.scaleX_Image(tmp, src, sr, &o)
5617 }
5618 }
5619
5620 if o.DstMask != nil {
5621 switch op {
5622 case Over:
5623 z.scaleY_Image_Over(dst, dr, adr, tmp, &o)
5624 case Src:
5625 z.scaleY_Image_Src(dst, dr, adr, tmp, &o)
5626 }
5627 } else {
5628 switch op {
5629 case Over:
5630 switch dst := dst.(type) {
5631 case *image.RGBA:
5632 z.scaleY_RGBA_Over(dst, dr, adr, tmp, &o)
5633 case RGBA64Image:
5634 z.scaleY_RGBA64Image_Over(dst, dr, adr, tmp, &o)
5635 default:
5636 z.scaleY_Image_Over(dst, dr, adr, tmp, &o)
5637 }
5638 case Src:
5639 switch dst := dst.(type) {
5640 case *image.RGBA:
5641 z.scaleY_RGBA_Src(dst, dr, adr, tmp, &o)
5642 case RGBA64Image:
5643 z.scaleY_RGBA64Image_Src(dst, dr, adr, tmp, &o)
5644 default:
5645 z.scaleY_Image_Src(dst, dr, adr, tmp, &o)
5646 }
5647 }
5648 }
5649 }
5650
5651 func (q *Kernel) Transform(dst Image, s2d f64.Aff3, src image.Image, sr image.Rectangle, op Op, opts *Options) {
5652 var o Options
5653 if opts != nil {
5654 o = *opts
5655 }
5656
5657 dr := transformRect(&s2d, &sr)
5658
5659 adr := dst.Bounds().Intersect(dr)
5660 adr, o.DstMask = clipAffectedDestRect(adr, o.DstMask, o.DstMaskP)
5661 if adr.Empty() || sr.Empty() {
5662 return
5663 }
5664 if op == Over && o.SrcMask == nil && opaque(src) {
5665 op = Src
5666 }
5667 d2s := invert(&s2d)
5668
5669
5670
5671
5672
5673
5674
5675 bias := transformRect(&d2s, &adr).Min
5676 bias.X--
5677 bias.Y--
5678 d2s[2] -= float64(bias.X)
5679 d2s[5] -= float64(bias.Y)
5680
5681 adr = adr.Sub(dr.Min)
5682
5683 if u, ok := src.(*image.Uniform); ok && o.DstMask != nil && o.SrcMask != nil && sr.In(src.Bounds()) {
5684 transform_Uniform(dst, dr, adr, &d2s, u, sr, bias, op)
5685 return
5686 }
5687
5688 xscale := abs(d2s[0])
5689 if s := abs(d2s[1]); xscale < s {
5690 xscale = s
5691 }
5692 yscale := abs(d2s[3])
5693 if s := abs(d2s[4]); yscale < s {
5694 yscale = s
5695 }
5696
5697
5698
5699
5700
5701
5702 if o.DstMask != nil || o.SrcMask != nil || !sr.In(src.Bounds()) {
5703 switch op {
5704 case Over:
5705 q.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5706 case Src:
5707 q.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5708 }
5709 } else {
5710 switch op {
5711 case Over:
5712 switch dst := dst.(type) {
5713 case *image.RGBA:
5714 switch src := src.(type) {
5715 case *image.NRGBA:
5716 q.transform_RGBA_NRGBA_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5717 case *image.RGBA:
5718 q.transform_RGBA_RGBA_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5719 case image.RGBA64Image:
5720 q.transform_RGBA_RGBA64Image_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5721 default:
5722 q.transform_RGBA_Image_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5723 }
5724 case RGBA64Image:
5725 switch src := src.(type) {
5726 case image.RGBA64Image:
5727 q.transform_RGBA64Image_RGBA64Image_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5728 }
5729 default:
5730 switch src := src.(type) {
5731 default:
5732 q.transform_Image_Image_Over(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5733 }
5734 }
5735 case Src:
5736 switch dst := dst.(type) {
5737 case *image.RGBA:
5738 switch src := src.(type) {
5739 case *image.Gray:
5740 q.transform_RGBA_Gray_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5741 case *image.NRGBA:
5742 q.transform_RGBA_NRGBA_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5743 case *image.RGBA:
5744 q.transform_RGBA_RGBA_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5745 case *image.YCbCr:
5746 switch src.SubsampleRatio {
5747 default:
5748 q.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5749 case image.YCbCrSubsampleRatio444:
5750 q.transform_RGBA_YCbCr444_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5751 case image.YCbCrSubsampleRatio422:
5752 q.transform_RGBA_YCbCr422_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5753 case image.YCbCrSubsampleRatio420:
5754 q.transform_RGBA_YCbCr420_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5755 case image.YCbCrSubsampleRatio440:
5756 q.transform_RGBA_YCbCr440_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5757 }
5758 case image.RGBA64Image:
5759 q.transform_RGBA_RGBA64Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5760 default:
5761 q.transform_RGBA_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5762 }
5763 case RGBA64Image:
5764 switch src := src.(type) {
5765 case image.RGBA64Image:
5766 q.transform_RGBA64Image_RGBA64Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5767 }
5768 default:
5769 switch src := src.(type) {
5770 default:
5771 q.transform_Image_Image_Src(dst, dr, adr, &d2s, src, sr, bias, xscale, yscale, &o)
5772 }
5773 }
5774 }
5775 }
5776 }
5777
5778 func (z *kernelScaler) scaleX_Gray(tmp [][4]float64, src *image.Gray, sr image.Rectangle, opts *Options) {
5779 t := 0
5780 for y := int32(0); y < z.sh; y++ {
5781 for _, s := range z.horizontal.sources {
5782 var pr float64
5783 for _, c := range z.horizontal.contribs[s.i:s.j] {
5784 pi := (sr.Min.Y+int(y)-src.Rect.Min.Y)*src.Stride + (sr.Min.X + int(c.coord) - src.Rect.Min.X)
5785 pru := uint32(src.Pix[pi]) * 0x101
5786 pr += float64(pru) * c.weight
5787 }
5788 pr *= s.invTotalWeightFFFF
5789 tmp[t] = [4]float64{
5790 pr,
5791 pr,
5792 pr,
5793 1,
5794 }
5795 t++
5796 }
5797 }
5798 }
5799
5800 func (z *kernelScaler) scaleX_NRGBA(tmp [][4]float64, src *image.NRGBA, sr image.Rectangle, opts *Options) {
5801 t := 0
5802 for y := int32(0); y < z.sh; y++ {
5803 for _, s := range z.horizontal.sources {
5804 var pr, pg, pb, pa float64
5805 for _, c := range z.horizontal.contribs[s.i:s.j] {
5806 pi := (sr.Min.Y+int(y)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(c.coord)-src.Rect.Min.X)*4
5807 pau := uint32(src.Pix[pi+3]) * 0x101
5808 pru := uint32(src.Pix[pi+0]) * pau / 0xff
5809 pgu := uint32(src.Pix[pi+1]) * pau / 0xff
5810 pbu := uint32(src.Pix[pi+2]) * pau / 0xff
5811 pr += float64(pru) * c.weight
5812 pg += float64(pgu) * c.weight
5813 pb += float64(pbu) * c.weight
5814 pa += float64(pau) * c.weight
5815 }
5816 tmp[t] = [4]float64{
5817 pr * s.invTotalWeightFFFF,
5818 pg * s.invTotalWeightFFFF,
5819 pb * s.invTotalWeightFFFF,
5820 pa * s.invTotalWeightFFFF,
5821 }
5822 t++
5823 }
5824 }
5825 }
5826
5827 func (z *kernelScaler) scaleX_RGBA(tmp [][4]float64, src *image.RGBA, sr image.Rectangle, opts *Options) {
5828 t := 0
5829 for y := int32(0); y < z.sh; y++ {
5830 for _, s := range z.horizontal.sources {
5831 var pr, pg, pb, pa float64
5832 for _, c := range z.horizontal.contribs[s.i:s.j] {
5833 pi := (sr.Min.Y+int(y)-src.Rect.Min.Y)*src.Stride + (sr.Min.X+int(c.coord)-src.Rect.Min.X)*4
5834 pru := uint32(src.Pix[pi+0]) * 0x101
5835 pgu := uint32(src.Pix[pi+1]) * 0x101
5836 pbu := uint32(src.Pix[pi+2]) * 0x101
5837 pau := uint32(src.Pix[pi+3]) * 0x101
5838 pr += float64(pru) * c.weight
5839 pg += float64(pgu) * c.weight
5840 pb += float64(pbu) * c.weight
5841 pa += float64(pau) * c.weight
5842 }
5843 tmp[t] = [4]float64{
5844 pr * s.invTotalWeightFFFF,
5845 pg * s.invTotalWeightFFFF,
5846 pb * s.invTotalWeightFFFF,
5847 pa * s.invTotalWeightFFFF,
5848 }
5849 t++
5850 }
5851 }
5852 }
5853
5854 func (z *kernelScaler) scaleX_YCbCr444(tmp [][4]float64, src *image.YCbCr, sr image.Rectangle, opts *Options) {
5855 t := 0
5856 for y := int32(0); y < z.sh; y++ {
5857 for _, s := range z.horizontal.sources {
5858 var pr, pg, pb float64
5859 for _, c := range z.horizontal.contribs[s.i:s.j] {
5860 pi := (sr.Min.Y+int(y)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(c.coord) - src.Rect.Min.X)
5861 pj := (sr.Min.Y+int(y)-src.Rect.Min.Y)*src.CStride + (sr.Min.X + int(c.coord) - src.Rect.Min.X)
5862
5863
5864 pyy1 := int(src.Y[pi]) * 0x10101
5865 pcb1 := int(src.Cb[pj]) - 128
5866 pcr1 := int(src.Cr[pj]) - 128
5867 pru := (pyy1 + 91881*pcr1) >> 8
5868 pgu := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
5869 pbu := (pyy1 + 116130*pcb1) >> 8
5870 if pru < 0 {
5871 pru = 0
5872 } else if pru > 0xffff {
5873 pru = 0xffff
5874 }
5875 if pgu < 0 {
5876 pgu = 0
5877 } else if pgu > 0xffff {
5878 pgu = 0xffff
5879 }
5880 if pbu < 0 {
5881 pbu = 0
5882 } else if pbu > 0xffff {
5883 pbu = 0xffff
5884 }
5885
5886 pr += float64(pru) * c.weight
5887 pg += float64(pgu) * c.weight
5888 pb += float64(pbu) * c.weight
5889 }
5890 tmp[t] = [4]float64{
5891 pr * s.invTotalWeightFFFF,
5892 pg * s.invTotalWeightFFFF,
5893 pb * s.invTotalWeightFFFF,
5894 1,
5895 }
5896 t++
5897 }
5898 }
5899 }
5900
5901 func (z *kernelScaler) scaleX_YCbCr422(tmp [][4]float64, src *image.YCbCr, sr image.Rectangle, opts *Options) {
5902 t := 0
5903 for y := int32(0); y < z.sh; y++ {
5904 for _, s := range z.horizontal.sources {
5905 var pr, pg, pb float64
5906 for _, c := range z.horizontal.contribs[s.i:s.j] {
5907 pi := (sr.Min.Y+int(y)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(c.coord) - src.Rect.Min.X)
5908 pj := (sr.Min.Y+int(y)-src.Rect.Min.Y)*src.CStride + ((sr.Min.X+int(c.coord))/2 - src.Rect.Min.X/2)
5909
5910
5911 pyy1 := int(src.Y[pi]) * 0x10101
5912 pcb1 := int(src.Cb[pj]) - 128
5913 pcr1 := int(src.Cr[pj]) - 128
5914 pru := (pyy1 + 91881*pcr1) >> 8
5915 pgu := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
5916 pbu := (pyy1 + 116130*pcb1) >> 8
5917 if pru < 0 {
5918 pru = 0
5919 } else if pru > 0xffff {
5920 pru = 0xffff
5921 }
5922 if pgu < 0 {
5923 pgu = 0
5924 } else if pgu > 0xffff {
5925 pgu = 0xffff
5926 }
5927 if pbu < 0 {
5928 pbu = 0
5929 } else if pbu > 0xffff {
5930 pbu = 0xffff
5931 }
5932
5933 pr += float64(pru) * c.weight
5934 pg += float64(pgu) * c.weight
5935 pb += float64(pbu) * c.weight
5936 }
5937 tmp[t] = [4]float64{
5938 pr * s.invTotalWeightFFFF,
5939 pg * s.invTotalWeightFFFF,
5940 pb * s.invTotalWeightFFFF,
5941 1,
5942 }
5943 t++
5944 }
5945 }
5946 }
5947
5948 func (z *kernelScaler) scaleX_YCbCr420(tmp [][4]float64, src *image.YCbCr, sr image.Rectangle, opts *Options) {
5949 t := 0
5950 for y := int32(0); y < z.sh; y++ {
5951 for _, s := range z.horizontal.sources {
5952 var pr, pg, pb float64
5953 for _, c := range z.horizontal.contribs[s.i:s.j] {
5954 pi := (sr.Min.Y+int(y)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(c.coord) - src.Rect.Min.X)
5955 pj := ((sr.Min.Y+int(y))/2-src.Rect.Min.Y/2)*src.CStride + ((sr.Min.X+int(c.coord))/2 - src.Rect.Min.X/2)
5956
5957
5958 pyy1 := int(src.Y[pi]) * 0x10101
5959 pcb1 := int(src.Cb[pj]) - 128
5960 pcr1 := int(src.Cr[pj]) - 128
5961 pru := (pyy1 + 91881*pcr1) >> 8
5962 pgu := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
5963 pbu := (pyy1 + 116130*pcb1) >> 8
5964 if pru < 0 {
5965 pru = 0
5966 } else if pru > 0xffff {
5967 pru = 0xffff
5968 }
5969 if pgu < 0 {
5970 pgu = 0
5971 } else if pgu > 0xffff {
5972 pgu = 0xffff
5973 }
5974 if pbu < 0 {
5975 pbu = 0
5976 } else if pbu > 0xffff {
5977 pbu = 0xffff
5978 }
5979
5980 pr += float64(pru) * c.weight
5981 pg += float64(pgu) * c.weight
5982 pb += float64(pbu) * c.weight
5983 }
5984 tmp[t] = [4]float64{
5985 pr * s.invTotalWeightFFFF,
5986 pg * s.invTotalWeightFFFF,
5987 pb * s.invTotalWeightFFFF,
5988 1,
5989 }
5990 t++
5991 }
5992 }
5993 }
5994
5995 func (z *kernelScaler) scaleX_YCbCr440(tmp [][4]float64, src *image.YCbCr, sr image.Rectangle, opts *Options) {
5996 t := 0
5997 for y := int32(0); y < z.sh; y++ {
5998 for _, s := range z.horizontal.sources {
5999 var pr, pg, pb float64
6000 for _, c := range z.horizontal.contribs[s.i:s.j] {
6001 pi := (sr.Min.Y+int(y)-src.Rect.Min.Y)*src.YStride + (sr.Min.X + int(c.coord) - src.Rect.Min.X)
6002 pj := ((sr.Min.Y+int(y))/2-src.Rect.Min.Y/2)*src.CStride + (sr.Min.X + int(c.coord) - src.Rect.Min.X)
6003
6004
6005 pyy1 := int(src.Y[pi]) * 0x10101
6006 pcb1 := int(src.Cb[pj]) - 128
6007 pcr1 := int(src.Cr[pj]) - 128
6008 pru := (pyy1 + 91881*pcr1) >> 8
6009 pgu := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
6010 pbu := (pyy1 + 116130*pcb1) >> 8
6011 if pru < 0 {
6012 pru = 0
6013 } else if pru > 0xffff {
6014 pru = 0xffff
6015 }
6016 if pgu < 0 {
6017 pgu = 0
6018 } else if pgu > 0xffff {
6019 pgu = 0xffff
6020 }
6021 if pbu < 0 {
6022 pbu = 0
6023 } else if pbu > 0xffff {
6024 pbu = 0xffff
6025 }
6026
6027 pr += float64(pru) * c.weight
6028 pg += float64(pgu) * c.weight
6029 pb += float64(pbu) * c.weight
6030 }
6031 tmp[t] = [4]float64{
6032 pr * s.invTotalWeightFFFF,
6033 pg * s.invTotalWeightFFFF,
6034 pb * s.invTotalWeightFFFF,
6035 1,
6036 }
6037 t++
6038 }
6039 }
6040 }
6041
6042 func (z *kernelScaler) scaleX_RGBA64Image(tmp [][4]float64, src image.RGBA64Image, sr image.Rectangle, opts *Options) {
6043 t := 0
6044 srcMask, smp := opts.SrcMask, opts.SrcMaskP
6045 for y := int32(0); y < z.sh; y++ {
6046 for _, s := range z.horizontal.sources {
6047 var pr, pg, pb, pa float64
6048 for _, c := range z.horizontal.contribs[s.i:s.j] {
6049 pu := src.RGBA64At(sr.Min.X+int(c.coord), sr.Min.Y+int(y))
6050 if srcMask != nil {
6051 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(c.coord), smp.Y+sr.Min.Y+int(y)).RGBA()
6052 pu.R = uint16(uint32(pu.R) * ma / 0xffff)
6053 pu.G = uint16(uint32(pu.G) * ma / 0xffff)
6054 pu.B = uint16(uint32(pu.B) * ma / 0xffff)
6055 pu.A = uint16(uint32(pu.A) * ma / 0xffff)
6056 }
6057 pr += float64(pu.R) * c.weight
6058 pg += float64(pu.G) * c.weight
6059 pb += float64(pu.B) * c.weight
6060 pa += float64(pu.A) * c.weight
6061 }
6062 tmp[t] = [4]float64{
6063 pr * s.invTotalWeightFFFF,
6064 pg * s.invTotalWeightFFFF,
6065 pb * s.invTotalWeightFFFF,
6066 pa * s.invTotalWeightFFFF,
6067 }
6068 t++
6069 }
6070 }
6071 }
6072
6073 func (z *kernelScaler) scaleX_Image(tmp [][4]float64, src image.Image, sr image.Rectangle, opts *Options) {
6074 t := 0
6075 srcMask, smp := opts.SrcMask, opts.SrcMaskP
6076 for y := int32(0); y < z.sh; y++ {
6077 for _, s := range z.horizontal.sources {
6078 var pr, pg, pb, pa float64
6079 for _, c := range z.horizontal.contribs[s.i:s.j] {
6080 pru, pgu, pbu, pau := src.At(sr.Min.X+int(c.coord), sr.Min.Y+int(y)).RGBA()
6081 if srcMask != nil {
6082 _, _, _, ma := srcMask.At(smp.X+sr.Min.X+int(c.coord), smp.Y+sr.Min.Y+int(y)).RGBA()
6083 pru = pru * ma / 0xffff
6084 pgu = pgu * ma / 0xffff
6085 pbu = pbu * ma / 0xffff
6086 pau = pau * ma / 0xffff
6087 }
6088 pr += float64(pru) * c.weight
6089 pg += float64(pgu) * c.weight
6090 pb += float64(pbu) * c.weight
6091 pa += float64(pau) * c.weight
6092 }
6093 tmp[t] = [4]float64{
6094 pr * s.invTotalWeightFFFF,
6095 pg * s.invTotalWeightFFFF,
6096 pb * s.invTotalWeightFFFF,
6097 pa * s.invTotalWeightFFFF,
6098 }
6099 t++
6100 }
6101 }
6102 }
6103
6104 func (z *kernelScaler) scaleY_RGBA_Over(dst *image.RGBA, dr, adr image.Rectangle, tmp [][4]float64, opts *Options) {
6105 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
6106 d := (dr.Min.Y+adr.Min.Y-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+int(dx)-dst.Rect.Min.X)*4
6107 for _, s := range z.vertical.sources[adr.Min.Y:adr.Max.Y] {
6108 var pr, pg, pb, pa float64
6109 for _, c := range z.vertical.contribs[s.i:s.j] {
6110 p := &tmp[c.coord*z.dw+dx]
6111 pr += p[0] * c.weight
6112 pg += p[1] * c.weight
6113 pb += p[2] * c.weight
6114 pa += p[3] * c.weight
6115 }
6116
6117 if pr > pa {
6118 pr = pa
6119 }
6120 if pg > pa {
6121 pg = pa
6122 }
6123 if pb > pa {
6124 pb = pa
6125 }
6126
6127 pr0 := uint32(ftou(pr * s.invTotalWeight))
6128 pg0 := uint32(ftou(pg * s.invTotalWeight))
6129 pb0 := uint32(ftou(pb * s.invTotalWeight))
6130 pa0 := uint32(ftou(pa * s.invTotalWeight))
6131 pa1 := (0xffff - uint32(pa0)) * 0x101
6132 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr0) >> 8)
6133 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg0) >> 8)
6134 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb0) >> 8)
6135 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa0) >> 8)
6136 d += dst.Stride
6137 }
6138 }
6139 }
6140
6141 func (z *kernelScaler) scaleY_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, tmp [][4]float64, opts *Options) {
6142 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
6143 d := (dr.Min.Y+adr.Min.Y-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+int(dx)-dst.Rect.Min.X)*4
6144 for _, s := range z.vertical.sources[adr.Min.Y:adr.Max.Y] {
6145 var pr, pg, pb, pa float64
6146 for _, c := range z.vertical.contribs[s.i:s.j] {
6147 p := &tmp[c.coord*z.dw+dx]
6148 pr += p[0] * c.weight
6149 pg += p[1] * c.weight
6150 pb += p[2] * c.weight
6151 pa += p[3] * c.weight
6152 }
6153
6154 if pr > pa {
6155 pr = pa
6156 }
6157 if pg > pa {
6158 pg = pa
6159 }
6160 if pb > pa {
6161 pb = pa
6162 }
6163
6164 dst.Pix[d+0] = uint8(ftou(pr*s.invTotalWeight) >> 8)
6165 dst.Pix[d+1] = uint8(ftou(pg*s.invTotalWeight) >> 8)
6166 dst.Pix[d+2] = uint8(ftou(pb*s.invTotalWeight) >> 8)
6167 dst.Pix[d+3] = uint8(ftou(pa*s.invTotalWeight) >> 8)
6168 d += dst.Stride
6169 }
6170 }
6171 }
6172
6173 func (z *kernelScaler) scaleY_RGBA64Image_Over(dst RGBA64Image, dr, adr image.Rectangle, tmp [][4]float64, opts *Options) {
6174 dstMask, dmp := opts.DstMask, opts.DstMaskP
6175 dstColorRGBA64 := color.RGBA64{}
6176
6177 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
6178 for dy, s := range z.vertical.sources[adr.Min.Y:adr.Max.Y] {
6179 var pr, pg, pb, pa float64
6180 for _, c := range z.vertical.contribs[s.i:s.j] {
6181 p := &tmp[c.coord*z.dw+dx]
6182 pr += p[0] * c.weight
6183 pg += p[1] * c.weight
6184 pb += p[2] * c.weight
6185 pa += p[3] * c.weight
6186 }
6187
6188 if pr > pa {
6189 pr = pa
6190 }
6191 if pg > pa {
6192 pg = pa
6193 }
6194 if pb > pa {
6195 pb = pa
6196 }
6197
6198 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(adr.Min.Y+dy))
6199 pr0 := uint32(ftou(pr * s.invTotalWeight))
6200 pg0 := uint32(ftou(pg * s.invTotalWeight))
6201 pb0 := uint32(ftou(pb * s.invTotalWeight))
6202 pa0 := uint32(ftou(pa * s.invTotalWeight))
6203 if dstMask != nil {
6204 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(adr.Min.Y+dy)).RGBA()
6205 pr0 = pr0 * ma / 0xffff
6206 pg0 = pg0 * ma / 0xffff
6207 pb0 = pb0 * ma / 0xffff
6208 pa0 = pa0 * ma / 0xffff
6209 }
6210 pa1 := 0xffff - pa0
6211 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + pr0)
6212 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + pg0)
6213 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + pb0)
6214 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + pa0)
6215 dst.SetRGBA64(dr.Min.X+int(dx), dr.Min.Y+int(adr.Min.Y+dy), dstColorRGBA64)
6216 }
6217 }
6218 }
6219
6220 func (z *kernelScaler) scaleY_RGBA64Image_Src(dst RGBA64Image, dr, adr image.Rectangle, tmp [][4]float64, opts *Options) {
6221 dstMask, dmp := opts.DstMask, opts.DstMaskP
6222 dstColorRGBA64 := color.RGBA64{}
6223
6224 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
6225 for dy, s := range z.vertical.sources[adr.Min.Y:adr.Max.Y] {
6226 var pr, pg, pb, pa float64
6227 for _, c := range z.vertical.contribs[s.i:s.j] {
6228 p := &tmp[c.coord*z.dw+dx]
6229 pr += p[0] * c.weight
6230 pg += p[1] * c.weight
6231 pb += p[2] * c.weight
6232 pa += p[3] * c.weight
6233 }
6234
6235 if pr > pa {
6236 pr = pa
6237 }
6238 if pg > pa {
6239 pg = pa
6240 }
6241 if pb > pa {
6242 pb = pa
6243 }
6244
6245 if dstMask != nil {
6246 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(adr.Min.Y+dy))
6247 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(adr.Min.Y+dy)).RGBA()
6248 pr := uint32(ftou(pr*s.invTotalWeight)) * ma / 0xffff
6249 pg := uint32(ftou(pg*s.invTotalWeight)) * ma / 0xffff
6250 pb := uint32(ftou(pb*s.invTotalWeight)) * ma / 0xffff
6251 pa := uint32(ftou(pa*s.invTotalWeight)) * ma / 0xffff
6252 pa1 := 0xffff - ma
6253 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + pr)
6254 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + pg)
6255 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + pb)
6256 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + pa)
6257 dst.SetRGBA64(dr.Min.X+int(dx), dr.Min.Y+int(adr.Min.Y+dy), dstColorRGBA64)
6258 } else {
6259 dstColorRGBA64.R = ftou(pr * s.invTotalWeight)
6260 dstColorRGBA64.G = ftou(pg * s.invTotalWeight)
6261 dstColorRGBA64.B = ftou(pb * s.invTotalWeight)
6262 dstColorRGBA64.A = ftou(pa * s.invTotalWeight)
6263 dst.SetRGBA64(dr.Min.X+int(dx), dr.Min.Y+int(adr.Min.Y+dy), dstColorRGBA64)
6264 }
6265 }
6266 }
6267 }
6268
6269 func (z *kernelScaler) scaleY_Image_Over(dst Image, dr, adr image.Rectangle, tmp [][4]float64, opts *Options) {
6270 dstMask, dmp := opts.DstMask, opts.DstMaskP
6271 dstColorRGBA64 := &color.RGBA64{}
6272 dstColor := color.Color(dstColorRGBA64)
6273 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
6274 for dy, s := range z.vertical.sources[adr.Min.Y:adr.Max.Y] {
6275 var pr, pg, pb, pa float64
6276 for _, c := range z.vertical.contribs[s.i:s.j] {
6277 p := &tmp[c.coord*z.dw+dx]
6278 pr += p[0] * c.weight
6279 pg += p[1] * c.weight
6280 pb += p[2] * c.weight
6281 pa += p[3] * c.weight
6282 }
6283
6284 if pr > pa {
6285 pr = pa
6286 }
6287 if pg > pa {
6288 pg = pa
6289 }
6290 if pb > pa {
6291 pb = pa
6292 }
6293
6294 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(adr.Min.Y+dy)).RGBA()
6295 pr0 := uint32(ftou(pr * s.invTotalWeight))
6296 pg0 := uint32(ftou(pg * s.invTotalWeight))
6297 pb0 := uint32(ftou(pb * s.invTotalWeight))
6298 pa0 := uint32(ftou(pa * s.invTotalWeight))
6299 if dstMask != nil {
6300 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(adr.Min.Y+dy)).RGBA()
6301 pr0 = pr0 * ma / 0xffff
6302 pg0 = pg0 * ma / 0xffff
6303 pb0 = pb0 * ma / 0xffff
6304 pa0 = pa0 * ma / 0xffff
6305 }
6306 pa1 := 0xffff - pa0
6307 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr0)
6308 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg0)
6309 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb0)
6310 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa0)
6311 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(adr.Min.Y+dy), dstColor)
6312 }
6313 }
6314 }
6315
6316 func (z *kernelScaler) scaleY_Image_Src(dst Image, dr, adr image.Rectangle, tmp [][4]float64, opts *Options) {
6317 dstMask, dmp := opts.DstMask, opts.DstMaskP
6318 dstColorRGBA64 := &color.RGBA64{}
6319 dstColor := color.Color(dstColorRGBA64)
6320 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
6321 for dy, s := range z.vertical.sources[adr.Min.Y:adr.Max.Y] {
6322 var pr, pg, pb, pa float64
6323 for _, c := range z.vertical.contribs[s.i:s.j] {
6324 p := &tmp[c.coord*z.dw+dx]
6325 pr += p[0] * c.weight
6326 pg += p[1] * c.weight
6327 pb += p[2] * c.weight
6328 pa += p[3] * c.weight
6329 }
6330
6331 if pr > pa {
6332 pr = pa
6333 }
6334 if pg > pa {
6335 pg = pa
6336 }
6337 if pb > pa {
6338 pb = pa
6339 }
6340
6341 if dstMask != nil {
6342 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(adr.Min.Y+dy)).RGBA()
6343 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(adr.Min.Y+dy)).RGBA()
6344 pr := uint32(ftou(pr*s.invTotalWeight)) * ma / 0xffff
6345 pg := uint32(ftou(pg*s.invTotalWeight)) * ma / 0xffff
6346 pb := uint32(ftou(pb*s.invTotalWeight)) * ma / 0xffff
6347 pa := uint32(ftou(pa*s.invTotalWeight)) * ma / 0xffff
6348 pa1 := 0xffff - ma
6349 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr)
6350 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg)
6351 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb)
6352 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa)
6353 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(adr.Min.Y+dy), dstColor)
6354 } else {
6355 dstColorRGBA64.R = ftou(pr * s.invTotalWeight)
6356 dstColorRGBA64.G = ftou(pg * s.invTotalWeight)
6357 dstColorRGBA64.B = ftou(pb * s.invTotalWeight)
6358 dstColorRGBA64.A = ftou(pa * s.invTotalWeight)
6359 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(adr.Min.Y+dy), dstColor)
6360 }
6361 }
6362 }
6363 }
6364
6365 func (q *Kernel) transform_RGBA_Gray_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.Gray, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
6366
6367
6368 xHalfWidth, xKernelArgScale := q.Support, 1.0
6369 if xscale > 1 {
6370 xHalfWidth *= xscale
6371 xKernelArgScale = 1 / xscale
6372 }
6373 yHalfWidth, yKernelArgScale := q.Support, 1.0
6374 if yscale > 1 {
6375 yHalfWidth *= yscale
6376 yKernelArgScale = 1 / yscale
6377 }
6378
6379 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
6380 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
6381
6382 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
6383 dyf := float64(dr.Min.Y+int(dy)) + 0.5
6384 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
6385 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
6386 dxf := float64(dr.Min.X+int(dx)) + 0.5
6387 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
6388 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
6389 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
6390 continue
6391 }
6392
6393
6394
6395 sx += float64(bias.X)
6396 sx -= 0.5
6397 ix := int(math.Floor(sx - xHalfWidth))
6398 if ix < sr.Min.X {
6399 ix = sr.Min.X
6400 }
6401 jx := int(math.Ceil(sx + xHalfWidth))
6402 if jx > sr.Max.X {
6403 jx = sr.Max.X
6404 }
6405
6406 totalXWeight := 0.0
6407 for kx := ix; kx < jx; kx++ {
6408 xWeight := 0.0
6409 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
6410 xWeight = q.At(t)
6411 }
6412 xWeights[kx-ix] = xWeight
6413 totalXWeight += xWeight
6414 }
6415 for x := range xWeights[:jx-ix] {
6416 xWeights[x] /= totalXWeight
6417 }
6418
6419 sy += float64(bias.Y)
6420 sy -= 0.5
6421 iy := int(math.Floor(sy - yHalfWidth))
6422 if iy < sr.Min.Y {
6423 iy = sr.Min.Y
6424 }
6425 jy := int(math.Ceil(sy + yHalfWidth))
6426 if jy > sr.Max.Y {
6427 jy = sr.Max.Y
6428 }
6429
6430 totalYWeight := 0.0
6431 for ky := iy; ky < jy; ky++ {
6432 yWeight := 0.0
6433 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
6434 yWeight = q.At(t)
6435 }
6436 yWeights[ky-iy] = yWeight
6437 totalYWeight += yWeight
6438 }
6439 for y := range yWeights[:jy-iy] {
6440 yWeights[y] /= totalYWeight
6441 }
6442
6443 var pr float64
6444 for ky := iy; ky < jy; ky++ {
6445 if yWeight := yWeights[ky-iy]; yWeight != 0 {
6446 for kx := ix; kx < jx; kx++ {
6447 if w := xWeights[kx-ix] * yWeight; w != 0 {
6448 pi := (ky-src.Rect.Min.Y)*src.Stride + (kx - src.Rect.Min.X)
6449 pru := uint32(src.Pix[pi]) * 0x101
6450 pr += float64(pru) * w
6451 }
6452 }
6453 }
6454 }
6455 out := uint8(fffftou(pr) >> 8)
6456 dst.Pix[d+0] = out
6457 dst.Pix[d+1] = out
6458 dst.Pix[d+2] = out
6459 dst.Pix[d+3] = 0xff
6460 }
6461 }
6462 }
6463
6464 func (q *Kernel) transform_RGBA_NRGBA_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
6465
6466
6467 xHalfWidth, xKernelArgScale := q.Support, 1.0
6468 if xscale > 1 {
6469 xHalfWidth *= xscale
6470 xKernelArgScale = 1 / xscale
6471 }
6472 yHalfWidth, yKernelArgScale := q.Support, 1.0
6473 if yscale > 1 {
6474 yHalfWidth *= yscale
6475 yKernelArgScale = 1 / yscale
6476 }
6477
6478 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
6479 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
6480
6481 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
6482 dyf := float64(dr.Min.Y+int(dy)) + 0.5
6483 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
6484 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
6485 dxf := float64(dr.Min.X+int(dx)) + 0.5
6486 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
6487 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
6488 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
6489 continue
6490 }
6491
6492
6493
6494 sx += float64(bias.X)
6495 sx -= 0.5
6496 ix := int(math.Floor(sx - xHalfWidth))
6497 if ix < sr.Min.X {
6498 ix = sr.Min.X
6499 }
6500 jx := int(math.Ceil(sx + xHalfWidth))
6501 if jx > sr.Max.X {
6502 jx = sr.Max.X
6503 }
6504
6505 totalXWeight := 0.0
6506 for kx := ix; kx < jx; kx++ {
6507 xWeight := 0.0
6508 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
6509 xWeight = q.At(t)
6510 }
6511 xWeights[kx-ix] = xWeight
6512 totalXWeight += xWeight
6513 }
6514 for x := range xWeights[:jx-ix] {
6515 xWeights[x] /= totalXWeight
6516 }
6517
6518 sy += float64(bias.Y)
6519 sy -= 0.5
6520 iy := int(math.Floor(sy - yHalfWidth))
6521 if iy < sr.Min.Y {
6522 iy = sr.Min.Y
6523 }
6524 jy := int(math.Ceil(sy + yHalfWidth))
6525 if jy > sr.Max.Y {
6526 jy = sr.Max.Y
6527 }
6528
6529 totalYWeight := 0.0
6530 for ky := iy; ky < jy; ky++ {
6531 yWeight := 0.0
6532 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
6533 yWeight = q.At(t)
6534 }
6535 yWeights[ky-iy] = yWeight
6536 totalYWeight += yWeight
6537 }
6538 for y := range yWeights[:jy-iy] {
6539 yWeights[y] /= totalYWeight
6540 }
6541
6542 var pr, pg, pb, pa float64
6543 for ky := iy; ky < jy; ky++ {
6544 if yWeight := yWeights[ky-iy]; yWeight != 0 {
6545 for kx := ix; kx < jx; kx++ {
6546 if w := xWeights[kx-ix] * yWeight; w != 0 {
6547 pi := (ky-src.Rect.Min.Y)*src.Stride + (kx-src.Rect.Min.X)*4
6548 pau := uint32(src.Pix[pi+3]) * 0x101
6549 pru := uint32(src.Pix[pi+0]) * pau / 0xff
6550 pgu := uint32(src.Pix[pi+1]) * pau / 0xff
6551 pbu := uint32(src.Pix[pi+2]) * pau / 0xff
6552 pr += float64(pru) * w
6553 pg += float64(pgu) * w
6554 pb += float64(pbu) * w
6555 pa += float64(pau) * w
6556 }
6557 }
6558 }
6559 }
6560
6561 if pr > pa {
6562 pr = pa
6563 }
6564 if pg > pa {
6565 pg = pa
6566 }
6567 if pb > pa {
6568 pb = pa
6569 }
6570
6571 pr0 := uint32(fffftou(pr))
6572 pg0 := uint32(fffftou(pg))
6573 pb0 := uint32(fffftou(pb))
6574 pa0 := uint32(fffftou(pa))
6575 pa1 := (0xffff - uint32(pa0)) * 0x101
6576 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr0) >> 8)
6577 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg0) >> 8)
6578 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb0) >> 8)
6579 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa0) >> 8)
6580 }
6581 }
6582 }
6583
6584 func (q *Kernel) transform_RGBA_NRGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.NRGBA, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
6585
6586
6587 xHalfWidth, xKernelArgScale := q.Support, 1.0
6588 if xscale > 1 {
6589 xHalfWidth *= xscale
6590 xKernelArgScale = 1 / xscale
6591 }
6592 yHalfWidth, yKernelArgScale := q.Support, 1.0
6593 if yscale > 1 {
6594 yHalfWidth *= yscale
6595 yKernelArgScale = 1 / yscale
6596 }
6597
6598 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
6599 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
6600
6601 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
6602 dyf := float64(dr.Min.Y+int(dy)) + 0.5
6603 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
6604 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
6605 dxf := float64(dr.Min.X+int(dx)) + 0.5
6606 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
6607 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
6608 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
6609 continue
6610 }
6611
6612
6613
6614 sx += float64(bias.X)
6615 sx -= 0.5
6616 ix := int(math.Floor(sx - xHalfWidth))
6617 if ix < sr.Min.X {
6618 ix = sr.Min.X
6619 }
6620 jx := int(math.Ceil(sx + xHalfWidth))
6621 if jx > sr.Max.X {
6622 jx = sr.Max.X
6623 }
6624
6625 totalXWeight := 0.0
6626 for kx := ix; kx < jx; kx++ {
6627 xWeight := 0.0
6628 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
6629 xWeight = q.At(t)
6630 }
6631 xWeights[kx-ix] = xWeight
6632 totalXWeight += xWeight
6633 }
6634 for x := range xWeights[:jx-ix] {
6635 xWeights[x] /= totalXWeight
6636 }
6637
6638 sy += float64(bias.Y)
6639 sy -= 0.5
6640 iy := int(math.Floor(sy - yHalfWidth))
6641 if iy < sr.Min.Y {
6642 iy = sr.Min.Y
6643 }
6644 jy := int(math.Ceil(sy + yHalfWidth))
6645 if jy > sr.Max.Y {
6646 jy = sr.Max.Y
6647 }
6648
6649 totalYWeight := 0.0
6650 for ky := iy; ky < jy; ky++ {
6651 yWeight := 0.0
6652 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
6653 yWeight = q.At(t)
6654 }
6655 yWeights[ky-iy] = yWeight
6656 totalYWeight += yWeight
6657 }
6658 for y := range yWeights[:jy-iy] {
6659 yWeights[y] /= totalYWeight
6660 }
6661
6662 var pr, pg, pb, pa float64
6663 for ky := iy; ky < jy; ky++ {
6664 if yWeight := yWeights[ky-iy]; yWeight != 0 {
6665 for kx := ix; kx < jx; kx++ {
6666 if w := xWeights[kx-ix] * yWeight; w != 0 {
6667 pi := (ky-src.Rect.Min.Y)*src.Stride + (kx-src.Rect.Min.X)*4
6668 pau := uint32(src.Pix[pi+3]) * 0x101
6669 pru := uint32(src.Pix[pi+0]) * pau / 0xff
6670 pgu := uint32(src.Pix[pi+1]) * pau / 0xff
6671 pbu := uint32(src.Pix[pi+2]) * pau / 0xff
6672 pr += float64(pru) * w
6673 pg += float64(pgu) * w
6674 pb += float64(pbu) * w
6675 pa += float64(pau) * w
6676 }
6677 }
6678 }
6679 }
6680
6681 if pr > pa {
6682 pr = pa
6683 }
6684 if pg > pa {
6685 pg = pa
6686 }
6687 if pb > pa {
6688 pb = pa
6689 }
6690
6691 dst.Pix[d+0] = uint8(fffftou(pr) >> 8)
6692 dst.Pix[d+1] = uint8(fffftou(pg) >> 8)
6693 dst.Pix[d+2] = uint8(fffftou(pb) >> 8)
6694 dst.Pix[d+3] = uint8(fffftou(pa) >> 8)
6695 }
6696 }
6697 }
6698
6699 func (q *Kernel) transform_RGBA_RGBA_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
6700
6701
6702 xHalfWidth, xKernelArgScale := q.Support, 1.0
6703 if xscale > 1 {
6704 xHalfWidth *= xscale
6705 xKernelArgScale = 1 / xscale
6706 }
6707 yHalfWidth, yKernelArgScale := q.Support, 1.0
6708 if yscale > 1 {
6709 yHalfWidth *= yscale
6710 yKernelArgScale = 1 / yscale
6711 }
6712
6713 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
6714 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
6715
6716 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
6717 dyf := float64(dr.Min.Y+int(dy)) + 0.5
6718 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
6719 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
6720 dxf := float64(dr.Min.X+int(dx)) + 0.5
6721 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
6722 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
6723 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
6724 continue
6725 }
6726
6727
6728
6729 sx += float64(bias.X)
6730 sx -= 0.5
6731 ix := int(math.Floor(sx - xHalfWidth))
6732 if ix < sr.Min.X {
6733 ix = sr.Min.X
6734 }
6735 jx := int(math.Ceil(sx + xHalfWidth))
6736 if jx > sr.Max.X {
6737 jx = sr.Max.X
6738 }
6739
6740 totalXWeight := 0.0
6741 for kx := ix; kx < jx; kx++ {
6742 xWeight := 0.0
6743 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
6744 xWeight = q.At(t)
6745 }
6746 xWeights[kx-ix] = xWeight
6747 totalXWeight += xWeight
6748 }
6749 for x := range xWeights[:jx-ix] {
6750 xWeights[x] /= totalXWeight
6751 }
6752
6753 sy += float64(bias.Y)
6754 sy -= 0.5
6755 iy := int(math.Floor(sy - yHalfWidth))
6756 if iy < sr.Min.Y {
6757 iy = sr.Min.Y
6758 }
6759 jy := int(math.Ceil(sy + yHalfWidth))
6760 if jy > sr.Max.Y {
6761 jy = sr.Max.Y
6762 }
6763
6764 totalYWeight := 0.0
6765 for ky := iy; ky < jy; ky++ {
6766 yWeight := 0.0
6767 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
6768 yWeight = q.At(t)
6769 }
6770 yWeights[ky-iy] = yWeight
6771 totalYWeight += yWeight
6772 }
6773 for y := range yWeights[:jy-iy] {
6774 yWeights[y] /= totalYWeight
6775 }
6776
6777 var pr, pg, pb, pa float64
6778 for ky := iy; ky < jy; ky++ {
6779 if yWeight := yWeights[ky-iy]; yWeight != 0 {
6780 for kx := ix; kx < jx; kx++ {
6781 if w := xWeights[kx-ix] * yWeight; w != 0 {
6782 pi := (ky-src.Rect.Min.Y)*src.Stride + (kx-src.Rect.Min.X)*4
6783 pru := uint32(src.Pix[pi+0]) * 0x101
6784 pgu := uint32(src.Pix[pi+1]) * 0x101
6785 pbu := uint32(src.Pix[pi+2]) * 0x101
6786 pau := uint32(src.Pix[pi+3]) * 0x101
6787 pr += float64(pru) * w
6788 pg += float64(pgu) * w
6789 pb += float64(pbu) * w
6790 pa += float64(pau) * w
6791 }
6792 }
6793 }
6794 }
6795
6796 if pr > pa {
6797 pr = pa
6798 }
6799 if pg > pa {
6800 pg = pa
6801 }
6802 if pb > pa {
6803 pb = pa
6804 }
6805
6806 pr0 := uint32(fffftou(pr))
6807 pg0 := uint32(fffftou(pg))
6808 pb0 := uint32(fffftou(pb))
6809 pa0 := uint32(fffftou(pa))
6810 pa1 := (0xffff - uint32(pa0)) * 0x101
6811 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr0) >> 8)
6812 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg0) >> 8)
6813 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb0) >> 8)
6814 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa0) >> 8)
6815 }
6816 }
6817 }
6818
6819 func (q *Kernel) transform_RGBA_RGBA_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.RGBA, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
6820
6821
6822 xHalfWidth, xKernelArgScale := q.Support, 1.0
6823 if xscale > 1 {
6824 xHalfWidth *= xscale
6825 xKernelArgScale = 1 / xscale
6826 }
6827 yHalfWidth, yKernelArgScale := q.Support, 1.0
6828 if yscale > 1 {
6829 yHalfWidth *= yscale
6830 yKernelArgScale = 1 / yscale
6831 }
6832
6833 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
6834 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
6835
6836 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
6837 dyf := float64(dr.Min.Y+int(dy)) + 0.5
6838 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
6839 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
6840 dxf := float64(dr.Min.X+int(dx)) + 0.5
6841 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
6842 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
6843 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
6844 continue
6845 }
6846
6847
6848
6849 sx += float64(bias.X)
6850 sx -= 0.5
6851 ix := int(math.Floor(sx - xHalfWidth))
6852 if ix < sr.Min.X {
6853 ix = sr.Min.X
6854 }
6855 jx := int(math.Ceil(sx + xHalfWidth))
6856 if jx > sr.Max.X {
6857 jx = sr.Max.X
6858 }
6859
6860 totalXWeight := 0.0
6861 for kx := ix; kx < jx; kx++ {
6862 xWeight := 0.0
6863 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
6864 xWeight = q.At(t)
6865 }
6866 xWeights[kx-ix] = xWeight
6867 totalXWeight += xWeight
6868 }
6869 for x := range xWeights[:jx-ix] {
6870 xWeights[x] /= totalXWeight
6871 }
6872
6873 sy += float64(bias.Y)
6874 sy -= 0.5
6875 iy := int(math.Floor(sy - yHalfWidth))
6876 if iy < sr.Min.Y {
6877 iy = sr.Min.Y
6878 }
6879 jy := int(math.Ceil(sy + yHalfWidth))
6880 if jy > sr.Max.Y {
6881 jy = sr.Max.Y
6882 }
6883
6884 totalYWeight := 0.0
6885 for ky := iy; ky < jy; ky++ {
6886 yWeight := 0.0
6887 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
6888 yWeight = q.At(t)
6889 }
6890 yWeights[ky-iy] = yWeight
6891 totalYWeight += yWeight
6892 }
6893 for y := range yWeights[:jy-iy] {
6894 yWeights[y] /= totalYWeight
6895 }
6896
6897 var pr, pg, pb, pa float64
6898 for ky := iy; ky < jy; ky++ {
6899 if yWeight := yWeights[ky-iy]; yWeight != 0 {
6900 for kx := ix; kx < jx; kx++ {
6901 if w := xWeights[kx-ix] * yWeight; w != 0 {
6902 pi := (ky-src.Rect.Min.Y)*src.Stride + (kx-src.Rect.Min.X)*4
6903 pru := uint32(src.Pix[pi+0]) * 0x101
6904 pgu := uint32(src.Pix[pi+1]) * 0x101
6905 pbu := uint32(src.Pix[pi+2]) * 0x101
6906 pau := uint32(src.Pix[pi+3]) * 0x101
6907 pr += float64(pru) * w
6908 pg += float64(pgu) * w
6909 pb += float64(pbu) * w
6910 pa += float64(pau) * w
6911 }
6912 }
6913 }
6914 }
6915
6916 if pr > pa {
6917 pr = pa
6918 }
6919 if pg > pa {
6920 pg = pa
6921 }
6922 if pb > pa {
6923 pb = pa
6924 }
6925
6926 dst.Pix[d+0] = uint8(fffftou(pr) >> 8)
6927 dst.Pix[d+1] = uint8(fffftou(pg) >> 8)
6928 dst.Pix[d+2] = uint8(fffftou(pb) >> 8)
6929 dst.Pix[d+3] = uint8(fffftou(pa) >> 8)
6930 }
6931 }
6932 }
6933
6934 func (q *Kernel) transform_RGBA_YCbCr444_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
6935
6936
6937 xHalfWidth, xKernelArgScale := q.Support, 1.0
6938 if xscale > 1 {
6939 xHalfWidth *= xscale
6940 xKernelArgScale = 1 / xscale
6941 }
6942 yHalfWidth, yKernelArgScale := q.Support, 1.0
6943 if yscale > 1 {
6944 yHalfWidth *= yscale
6945 yKernelArgScale = 1 / yscale
6946 }
6947
6948 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
6949 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
6950
6951 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
6952 dyf := float64(dr.Min.Y+int(dy)) + 0.5
6953 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
6954 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
6955 dxf := float64(dr.Min.X+int(dx)) + 0.5
6956 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
6957 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
6958 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
6959 continue
6960 }
6961
6962
6963
6964 sx += float64(bias.X)
6965 sx -= 0.5
6966 ix := int(math.Floor(sx - xHalfWidth))
6967 if ix < sr.Min.X {
6968 ix = sr.Min.X
6969 }
6970 jx := int(math.Ceil(sx + xHalfWidth))
6971 if jx > sr.Max.X {
6972 jx = sr.Max.X
6973 }
6974
6975 totalXWeight := 0.0
6976 for kx := ix; kx < jx; kx++ {
6977 xWeight := 0.0
6978 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
6979 xWeight = q.At(t)
6980 }
6981 xWeights[kx-ix] = xWeight
6982 totalXWeight += xWeight
6983 }
6984 for x := range xWeights[:jx-ix] {
6985 xWeights[x] /= totalXWeight
6986 }
6987
6988 sy += float64(bias.Y)
6989 sy -= 0.5
6990 iy := int(math.Floor(sy - yHalfWidth))
6991 if iy < sr.Min.Y {
6992 iy = sr.Min.Y
6993 }
6994 jy := int(math.Ceil(sy + yHalfWidth))
6995 if jy > sr.Max.Y {
6996 jy = sr.Max.Y
6997 }
6998
6999 totalYWeight := 0.0
7000 for ky := iy; ky < jy; ky++ {
7001 yWeight := 0.0
7002 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
7003 yWeight = q.At(t)
7004 }
7005 yWeights[ky-iy] = yWeight
7006 totalYWeight += yWeight
7007 }
7008 for y := range yWeights[:jy-iy] {
7009 yWeights[y] /= totalYWeight
7010 }
7011
7012 var pr, pg, pb float64
7013 for ky := iy; ky < jy; ky++ {
7014 if yWeight := yWeights[ky-iy]; yWeight != 0 {
7015 for kx := ix; kx < jx; kx++ {
7016 if w := xWeights[kx-ix] * yWeight; w != 0 {
7017 pi := (ky-src.Rect.Min.Y)*src.YStride + (kx - src.Rect.Min.X)
7018 pj := (ky-src.Rect.Min.Y)*src.CStride + (kx - src.Rect.Min.X)
7019
7020
7021 pyy1 := int(src.Y[pi]) * 0x10101
7022 pcb1 := int(src.Cb[pj]) - 128
7023 pcr1 := int(src.Cr[pj]) - 128
7024 pru := (pyy1 + 91881*pcr1) >> 8
7025 pgu := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
7026 pbu := (pyy1 + 116130*pcb1) >> 8
7027 if pru < 0 {
7028 pru = 0
7029 } else if pru > 0xffff {
7030 pru = 0xffff
7031 }
7032 if pgu < 0 {
7033 pgu = 0
7034 } else if pgu > 0xffff {
7035 pgu = 0xffff
7036 }
7037 if pbu < 0 {
7038 pbu = 0
7039 } else if pbu > 0xffff {
7040 pbu = 0xffff
7041 }
7042
7043 pr += float64(pru) * w
7044 pg += float64(pgu) * w
7045 pb += float64(pbu) * w
7046 }
7047 }
7048 }
7049 }
7050 dst.Pix[d+0] = uint8(fffftou(pr) >> 8)
7051 dst.Pix[d+1] = uint8(fffftou(pg) >> 8)
7052 dst.Pix[d+2] = uint8(fffftou(pb) >> 8)
7053 dst.Pix[d+3] = 0xff
7054 }
7055 }
7056 }
7057
7058 func (q *Kernel) transform_RGBA_YCbCr422_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
7059
7060
7061 xHalfWidth, xKernelArgScale := q.Support, 1.0
7062 if xscale > 1 {
7063 xHalfWidth *= xscale
7064 xKernelArgScale = 1 / xscale
7065 }
7066 yHalfWidth, yKernelArgScale := q.Support, 1.0
7067 if yscale > 1 {
7068 yHalfWidth *= yscale
7069 yKernelArgScale = 1 / yscale
7070 }
7071
7072 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
7073 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
7074
7075 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
7076 dyf := float64(dr.Min.Y+int(dy)) + 0.5
7077 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
7078 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
7079 dxf := float64(dr.Min.X+int(dx)) + 0.5
7080 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
7081 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
7082 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
7083 continue
7084 }
7085
7086
7087
7088 sx += float64(bias.X)
7089 sx -= 0.5
7090 ix := int(math.Floor(sx - xHalfWidth))
7091 if ix < sr.Min.X {
7092 ix = sr.Min.X
7093 }
7094 jx := int(math.Ceil(sx + xHalfWidth))
7095 if jx > sr.Max.X {
7096 jx = sr.Max.X
7097 }
7098
7099 totalXWeight := 0.0
7100 for kx := ix; kx < jx; kx++ {
7101 xWeight := 0.0
7102 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
7103 xWeight = q.At(t)
7104 }
7105 xWeights[kx-ix] = xWeight
7106 totalXWeight += xWeight
7107 }
7108 for x := range xWeights[:jx-ix] {
7109 xWeights[x] /= totalXWeight
7110 }
7111
7112 sy += float64(bias.Y)
7113 sy -= 0.5
7114 iy := int(math.Floor(sy - yHalfWidth))
7115 if iy < sr.Min.Y {
7116 iy = sr.Min.Y
7117 }
7118 jy := int(math.Ceil(sy + yHalfWidth))
7119 if jy > sr.Max.Y {
7120 jy = sr.Max.Y
7121 }
7122
7123 totalYWeight := 0.0
7124 for ky := iy; ky < jy; ky++ {
7125 yWeight := 0.0
7126 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
7127 yWeight = q.At(t)
7128 }
7129 yWeights[ky-iy] = yWeight
7130 totalYWeight += yWeight
7131 }
7132 for y := range yWeights[:jy-iy] {
7133 yWeights[y] /= totalYWeight
7134 }
7135
7136 var pr, pg, pb float64
7137 for ky := iy; ky < jy; ky++ {
7138 if yWeight := yWeights[ky-iy]; yWeight != 0 {
7139 for kx := ix; kx < jx; kx++ {
7140 if w := xWeights[kx-ix] * yWeight; w != 0 {
7141 pi := (ky-src.Rect.Min.Y)*src.YStride + (kx - src.Rect.Min.X)
7142 pj := (ky-src.Rect.Min.Y)*src.CStride + ((kx)/2 - src.Rect.Min.X/2)
7143
7144
7145 pyy1 := int(src.Y[pi]) * 0x10101
7146 pcb1 := int(src.Cb[pj]) - 128
7147 pcr1 := int(src.Cr[pj]) - 128
7148 pru := (pyy1 + 91881*pcr1) >> 8
7149 pgu := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
7150 pbu := (pyy1 + 116130*pcb1) >> 8
7151 if pru < 0 {
7152 pru = 0
7153 } else if pru > 0xffff {
7154 pru = 0xffff
7155 }
7156 if pgu < 0 {
7157 pgu = 0
7158 } else if pgu > 0xffff {
7159 pgu = 0xffff
7160 }
7161 if pbu < 0 {
7162 pbu = 0
7163 } else if pbu > 0xffff {
7164 pbu = 0xffff
7165 }
7166
7167 pr += float64(pru) * w
7168 pg += float64(pgu) * w
7169 pb += float64(pbu) * w
7170 }
7171 }
7172 }
7173 }
7174 dst.Pix[d+0] = uint8(fffftou(pr) >> 8)
7175 dst.Pix[d+1] = uint8(fffftou(pg) >> 8)
7176 dst.Pix[d+2] = uint8(fffftou(pb) >> 8)
7177 dst.Pix[d+3] = 0xff
7178 }
7179 }
7180 }
7181
7182 func (q *Kernel) transform_RGBA_YCbCr420_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
7183
7184
7185 xHalfWidth, xKernelArgScale := q.Support, 1.0
7186 if xscale > 1 {
7187 xHalfWidth *= xscale
7188 xKernelArgScale = 1 / xscale
7189 }
7190 yHalfWidth, yKernelArgScale := q.Support, 1.0
7191 if yscale > 1 {
7192 yHalfWidth *= yscale
7193 yKernelArgScale = 1 / yscale
7194 }
7195
7196 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
7197 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
7198
7199 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
7200 dyf := float64(dr.Min.Y+int(dy)) + 0.5
7201 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
7202 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
7203 dxf := float64(dr.Min.X+int(dx)) + 0.5
7204 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
7205 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
7206 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
7207 continue
7208 }
7209
7210
7211
7212 sx += float64(bias.X)
7213 sx -= 0.5
7214 ix := int(math.Floor(sx - xHalfWidth))
7215 if ix < sr.Min.X {
7216 ix = sr.Min.X
7217 }
7218 jx := int(math.Ceil(sx + xHalfWidth))
7219 if jx > sr.Max.X {
7220 jx = sr.Max.X
7221 }
7222
7223 totalXWeight := 0.0
7224 for kx := ix; kx < jx; kx++ {
7225 xWeight := 0.0
7226 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
7227 xWeight = q.At(t)
7228 }
7229 xWeights[kx-ix] = xWeight
7230 totalXWeight += xWeight
7231 }
7232 for x := range xWeights[:jx-ix] {
7233 xWeights[x] /= totalXWeight
7234 }
7235
7236 sy += float64(bias.Y)
7237 sy -= 0.5
7238 iy := int(math.Floor(sy - yHalfWidth))
7239 if iy < sr.Min.Y {
7240 iy = sr.Min.Y
7241 }
7242 jy := int(math.Ceil(sy + yHalfWidth))
7243 if jy > sr.Max.Y {
7244 jy = sr.Max.Y
7245 }
7246
7247 totalYWeight := 0.0
7248 for ky := iy; ky < jy; ky++ {
7249 yWeight := 0.0
7250 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
7251 yWeight = q.At(t)
7252 }
7253 yWeights[ky-iy] = yWeight
7254 totalYWeight += yWeight
7255 }
7256 for y := range yWeights[:jy-iy] {
7257 yWeights[y] /= totalYWeight
7258 }
7259
7260 var pr, pg, pb float64
7261 for ky := iy; ky < jy; ky++ {
7262 if yWeight := yWeights[ky-iy]; yWeight != 0 {
7263 for kx := ix; kx < jx; kx++ {
7264 if w := xWeights[kx-ix] * yWeight; w != 0 {
7265 pi := (ky-src.Rect.Min.Y)*src.YStride + (kx - src.Rect.Min.X)
7266 pj := ((ky)/2-src.Rect.Min.Y/2)*src.CStride + ((kx)/2 - src.Rect.Min.X/2)
7267
7268
7269 pyy1 := int(src.Y[pi]) * 0x10101
7270 pcb1 := int(src.Cb[pj]) - 128
7271 pcr1 := int(src.Cr[pj]) - 128
7272 pru := (pyy1 + 91881*pcr1) >> 8
7273 pgu := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
7274 pbu := (pyy1 + 116130*pcb1) >> 8
7275 if pru < 0 {
7276 pru = 0
7277 } else if pru > 0xffff {
7278 pru = 0xffff
7279 }
7280 if pgu < 0 {
7281 pgu = 0
7282 } else if pgu > 0xffff {
7283 pgu = 0xffff
7284 }
7285 if pbu < 0 {
7286 pbu = 0
7287 } else if pbu > 0xffff {
7288 pbu = 0xffff
7289 }
7290
7291 pr += float64(pru) * w
7292 pg += float64(pgu) * w
7293 pb += float64(pbu) * w
7294 }
7295 }
7296 }
7297 }
7298 dst.Pix[d+0] = uint8(fffftou(pr) >> 8)
7299 dst.Pix[d+1] = uint8(fffftou(pg) >> 8)
7300 dst.Pix[d+2] = uint8(fffftou(pb) >> 8)
7301 dst.Pix[d+3] = 0xff
7302 }
7303 }
7304 }
7305
7306 func (q *Kernel) transform_RGBA_YCbCr440_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src *image.YCbCr, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
7307
7308
7309 xHalfWidth, xKernelArgScale := q.Support, 1.0
7310 if xscale > 1 {
7311 xHalfWidth *= xscale
7312 xKernelArgScale = 1 / xscale
7313 }
7314 yHalfWidth, yKernelArgScale := q.Support, 1.0
7315 if yscale > 1 {
7316 yHalfWidth *= yscale
7317 yKernelArgScale = 1 / yscale
7318 }
7319
7320 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
7321 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
7322
7323 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
7324 dyf := float64(dr.Min.Y+int(dy)) + 0.5
7325 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
7326 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
7327 dxf := float64(dr.Min.X+int(dx)) + 0.5
7328 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
7329 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
7330 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
7331 continue
7332 }
7333
7334
7335
7336 sx += float64(bias.X)
7337 sx -= 0.5
7338 ix := int(math.Floor(sx - xHalfWidth))
7339 if ix < sr.Min.X {
7340 ix = sr.Min.X
7341 }
7342 jx := int(math.Ceil(sx + xHalfWidth))
7343 if jx > sr.Max.X {
7344 jx = sr.Max.X
7345 }
7346
7347 totalXWeight := 0.0
7348 for kx := ix; kx < jx; kx++ {
7349 xWeight := 0.0
7350 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
7351 xWeight = q.At(t)
7352 }
7353 xWeights[kx-ix] = xWeight
7354 totalXWeight += xWeight
7355 }
7356 for x := range xWeights[:jx-ix] {
7357 xWeights[x] /= totalXWeight
7358 }
7359
7360 sy += float64(bias.Y)
7361 sy -= 0.5
7362 iy := int(math.Floor(sy - yHalfWidth))
7363 if iy < sr.Min.Y {
7364 iy = sr.Min.Y
7365 }
7366 jy := int(math.Ceil(sy + yHalfWidth))
7367 if jy > sr.Max.Y {
7368 jy = sr.Max.Y
7369 }
7370
7371 totalYWeight := 0.0
7372 for ky := iy; ky < jy; ky++ {
7373 yWeight := 0.0
7374 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
7375 yWeight = q.At(t)
7376 }
7377 yWeights[ky-iy] = yWeight
7378 totalYWeight += yWeight
7379 }
7380 for y := range yWeights[:jy-iy] {
7381 yWeights[y] /= totalYWeight
7382 }
7383
7384 var pr, pg, pb float64
7385 for ky := iy; ky < jy; ky++ {
7386 if yWeight := yWeights[ky-iy]; yWeight != 0 {
7387 for kx := ix; kx < jx; kx++ {
7388 if w := xWeights[kx-ix] * yWeight; w != 0 {
7389 pi := (ky-src.Rect.Min.Y)*src.YStride + (kx - src.Rect.Min.X)
7390 pj := ((ky)/2-src.Rect.Min.Y/2)*src.CStride + (kx - src.Rect.Min.X)
7391
7392
7393 pyy1 := int(src.Y[pi]) * 0x10101
7394 pcb1 := int(src.Cb[pj]) - 128
7395 pcr1 := int(src.Cr[pj]) - 128
7396 pru := (pyy1 + 91881*pcr1) >> 8
7397 pgu := (pyy1 - 22554*pcb1 - 46802*pcr1) >> 8
7398 pbu := (pyy1 + 116130*pcb1) >> 8
7399 if pru < 0 {
7400 pru = 0
7401 } else if pru > 0xffff {
7402 pru = 0xffff
7403 }
7404 if pgu < 0 {
7405 pgu = 0
7406 } else if pgu > 0xffff {
7407 pgu = 0xffff
7408 }
7409 if pbu < 0 {
7410 pbu = 0
7411 } else if pbu > 0xffff {
7412 pbu = 0xffff
7413 }
7414
7415 pr += float64(pru) * w
7416 pg += float64(pgu) * w
7417 pb += float64(pbu) * w
7418 }
7419 }
7420 }
7421 }
7422 dst.Pix[d+0] = uint8(fffftou(pr) >> 8)
7423 dst.Pix[d+1] = uint8(fffftou(pg) >> 8)
7424 dst.Pix[d+2] = uint8(fffftou(pb) >> 8)
7425 dst.Pix[d+3] = 0xff
7426 }
7427 }
7428 }
7429
7430 func (q *Kernel) transform_RGBA_RGBA64Image_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
7431
7432
7433 xHalfWidth, xKernelArgScale := q.Support, 1.0
7434 if xscale > 1 {
7435 xHalfWidth *= xscale
7436 xKernelArgScale = 1 / xscale
7437 }
7438 yHalfWidth, yKernelArgScale := q.Support, 1.0
7439 if yscale > 1 {
7440 yHalfWidth *= yscale
7441 yKernelArgScale = 1 / yscale
7442 }
7443
7444 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
7445 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
7446
7447 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
7448 dyf := float64(dr.Min.Y+int(dy)) + 0.5
7449 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
7450 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
7451 dxf := float64(dr.Min.X+int(dx)) + 0.5
7452 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
7453 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
7454 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
7455 continue
7456 }
7457
7458
7459
7460 sx += float64(bias.X)
7461 sx -= 0.5
7462 ix := int(math.Floor(sx - xHalfWidth))
7463 if ix < sr.Min.X {
7464 ix = sr.Min.X
7465 }
7466 jx := int(math.Ceil(sx + xHalfWidth))
7467 if jx > sr.Max.X {
7468 jx = sr.Max.X
7469 }
7470
7471 totalXWeight := 0.0
7472 for kx := ix; kx < jx; kx++ {
7473 xWeight := 0.0
7474 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
7475 xWeight = q.At(t)
7476 }
7477 xWeights[kx-ix] = xWeight
7478 totalXWeight += xWeight
7479 }
7480 for x := range xWeights[:jx-ix] {
7481 xWeights[x] /= totalXWeight
7482 }
7483
7484 sy += float64(bias.Y)
7485 sy -= 0.5
7486 iy := int(math.Floor(sy - yHalfWidth))
7487 if iy < sr.Min.Y {
7488 iy = sr.Min.Y
7489 }
7490 jy := int(math.Ceil(sy + yHalfWidth))
7491 if jy > sr.Max.Y {
7492 jy = sr.Max.Y
7493 }
7494
7495 totalYWeight := 0.0
7496 for ky := iy; ky < jy; ky++ {
7497 yWeight := 0.0
7498 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
7499 yWeight = q.At(t)
7500 }
7501 yWeights[ky-iy] = yWeight
7502 totalYWeight += yWeight
7503 }
7504 for y := range yWeights[:jy-iy] {
7505 yWeights[y] /= totalYWeight
7506 }
7507
7508 var pr, pg, pb, pa float64
7509 for ky := iy; ky < jy; ky++ {
7510 if yWeight := yWeights[ky-iy]; yWeight != 0 {
7511 for kx := ix; kx < jx; kx++ {
7512 if w := xWeights[kx-ix] * yWeight; w != 0 {
7513 pu := src.RGBA64At(kx, ky)
7514 pr += float64(pu.R) * w
7515 pg += float64(pu.G) * w
7516 pb += float64(pu.B) * w
7517 pa += float64(pu.A) * w
7518 }
7519 }
7520 }
7521 }
7522
7523 if pr > pa {
7524 pr = pa
7525 }
7526 if pg > pa {
7527 pg = pa
7528 }
7529 if pb > pa {
7530 pb = pa
7531 }
7532
7533 pr0 := uint32(fffftou(pr))
7534 pg0 := uint32(fffftou(pg))
7535 pb0 := uint32(fffftou(pb))
7536 pa0 := uint32(fffftou(pa))
7537 pa1 := (0xffff - uint32(pa0)) * 0x101
7538 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr0) >> 8)
7539 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg0) >> 8)
7540 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb0) >> 8)
7541 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa0) >> 8)
7542 }
7543 }
7544 }
7545
7546 func (q *Kernel) transform_RGBA_RGBA64Image_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
7547
7548
7549 xHalfWidth, xKernelArgScale := q.Support, 1.0
7550 if xscale > 1 {
7551 xHalfWidth *= xscale
7552 xKernelArgScale = 1 / xscale
7553 }
7554 yHalfWidth, yKernelArgScale := q.Support, 1.0
7555 if yscale > 1 {
7556 yHalfWidth *= yscale
7557 yKernelArgScale = 1 / yscale
7558 }
7559
7560 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
7561 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
7562
7563 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
7564 dyf := float64(dr.Min.Y+int(dy)) + 0.5
7565 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
7566 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
7567 dxf := float64(dr.Min.X+int(dx)) + 0.5
7568 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
7569 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
7570 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
7571 continue
7572 }
7573
7574
7575
7576 sx += float64(bias.X)
7577 sx -= 0.5
7578 ix := int(math.Floor(sx - xHalfWidth))
7579 if ix < sr.Min.X {
7580 ix = sr.Min.X
7581 }
7582 jx := int(math.Ceil(sx + xHalfWidth))
7583 if jx > sr.Max.X {
7584 jx = sr.Max.X
7585 }
7586
7587 totalXWeight := 0.0
7588 for kx := ix; kx < jx; kx++ {
7589 xWeight := 0.0
7590 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
7591 xWeight = q.At(t)
7592 }
7593 xWeights[kx-ix] = xWeight
7594 totalXWeight += xWeight
7595 }
7596 for x := range xWeights[:jx-ix] {
7597 xWeights[x] /= totalXWeight
7598 }
7599
7600 sy += float64(bias.Y)
7601 sy -= 0.5
7602 iy := int(math.Floor(sy - yHalfWidth))
7603 if iy < sr.Min.Y {
7604 iy = sr.Min.Y
7605 }
7606 jy := int(math.Ceil(sy + yHalfWidth))
7607 if jy > sr.Max.Y {
7608 jy = sr.Max.Y
7609 }
7610
7611 totalYWeight := 0.0
7612 for ky := iy; ky < jy; ky++ {
7613 yWeight := 0.0
7614 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
7615 yWeight = q.At(t)
7616 }
7617 yWeights[ky-iy] = yWeight
7618 totalYWeight += yWeight
7619 }
7620 for y := range yWeights[:jy-iy] {
7621 yWeights[y] /= totalYWeight
7622 }
7623
7624 var pr, pg, pb, pa float64
7625 for ky := iy; ky < jy; ky++ {
7626 if yWeight := yWeights[ky-iy]; yWeight != 0 {
7627 for kx := ix; kx < jx; kx++ {
7628 if w := xWeights[kx-ix] * yWeight; w != 0 {
7629 pu := src.RGBA64At(kx, ky)
7630 pr += float64(pu.R) * w
7631 pg += float64(pu.G) * w
7632 pb += float64(pu.B) * w
7633 pa += float64(pu.A) * w
7634 }
7635 }
7636 }
7637 }
7638
7639 if pr > pa {
7640 pr = pa
7641 }
7642 if pg > pa {
7643 pg = pa
7644 }
7645 if pb > pa {
7646 pb = pa
7647 }
7648
7649 dst.Pix[d+0] = uint8(fffftou(pr) >> 8)
7650 dst.Pix[d+1] = uint8(fffftou(pg) >> 8)
7651 dst.Pix[d+2] = uint8(fffftou(pb) >> 8)
7652 dst.Pix[d+3] = uint8(fffftou(pa) >> 8)
7653 }
7654 }
7655 }
7656
7657 func (q *Kernel) transform_RGBA_Image_Over(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
7658
7659
7660 xHalfWidth, xKernelArgScale := q.Support, 1.0
7661 if xscale > 1 {
7662 xHalfWidth *= xscale
7663 xKernelArgScale = 1 / xscale
7664 }
7665 yHalfWidth, yKernelArgScale := q.Support, 1.0
7666 if yscale > 1 {
7667 yHalfWidth *= yscale
7668 yKernelArgScale = 1 / yscale
7669 }
7670
7671 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
7672 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
7673
7674 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
7675 dyf := float64(dr.Min.Y+int(dy)) + 0.5
7676 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
7677 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
7678 dxf := float64(dr.Min.X+int(dx)) + 0.5
7679 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
7680 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
7681 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
7682 continue
7683 }
7684
7685
7686
7687 sx += float64(bias.X)
7688 sx -= 0.5
7689 ix := int(math.Floor(sx - xHalfWidth))
7690 if ix < sr.Min.X {
7691 ix = sr.Min.X
7692 }
7693 jx := int(math.Ceil(sx + xHalfWidth))
7694 if jx > sr.Max.X {
7695 jx = sr.Max.X
7696 }
7697
7698 totalXWeight := 0.0
7699 for kx := ix; kx < jx; kx++ {
7700 xWeight := 0.0
7701 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
7702 xWeight = q.At(t)
7703 }
7704 xWeights[kx-ix] = xWeight
7705 totalXWeight += xWeight
7706 }
7707 for x := range xWeights[:jx-ix] {
7708 xWeights[x] /= totalXWeight
7709 }
7710
7711 sy += float64(bias.Y)
7712 sy -= 0.5
7713 iy := int(math.Floor(sy - yHalfWidth))
7714 if iy < sr.Min.Y {
7715 iy = sr.Min.Y
7716 }
7717 jy := int(math.Ceil(sy + yHalfWidth))
7718 if jy > sr.Max.Y {
7719 jy = sr.Max.Y
7720 }
7721
7722 totalYWeight := 0.0
7723 for ky := iy; ky < jy; ky++ {
7724 yWeight := 0.0
7725 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
7726 yWeight = q.At(t)
7727 }
7728 yWeights[ky-iy] = yWeight
7729 totalYWeight += yWeight
7730 }
7731 for y := range yWeights[:jy-iy] {
7732 yWeights[y] /= totalYWeight
7733 }
7734
7735 var pr, pg, pb, pa float64
7736 for ky := iy; ky < jy; ky++ {
7737 if yWeight := yWeights[ky-iy]; yWeight != 0 {
7738 for kx := ix; kx < jx; kx++ {
7739 if w := xWeights[kx-ix] * yWeight; w != 0 {
7740 pru, pgu, pbu, pau := src.At(kx, ky).RGBA()
7741 pr += float64(pru) * w
7742 pg += float64(pgu) * w
7743 pb += float64(pbu) * w
7744 pa += float64(pau) * w
7745 }
7746 }
7747 }
7748 }
7749
7750 if pr > pa {
7751 pr = pa
7752 }
7753 if pg > pa {
7754 pg = pa
7755 }
7756 if pb > pa {
7757 pb = pa
7758 }
7759
7760 pr0 := uint32(fffftou(pr))
7761 pg0 := uint32(fffftou(pg))
7762 pb0 := uint32(fffftou(pb))
7763 pa0 := uint32(fffftou(pa))
7764 pa1 := (0xffff - uint32(pa0)) * 0x101
7765 dst.Pix[d+0] = uint8((uint32(dst.Pix[d+0])*pa1/0xffff + pr0) >> 8)
7766 dst.Pix[d+1] = uint8((uint32(dst.Pix[d+1])*pa1/0xffff + pg0) >> 8)
7767 dst.Pix[d+2] = uint8((uint32(dst.Pix[d+2])*pa1/0xffff + pb0) >> 8)
7768 dst.Pix[d+3] = uint8((uint32(dst.Pix[d+3])*pa1/0xffff + pa0) >> 8)
7769 }
7770 }
7771 }
7772
7773 func (q *Kernel) transform_RGBA_Image_Src(dst *image.RGBA, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
7774
7775
7776 xHalfWidth, xKernelArgScale := q.Support, 1.0
7777 if xscale > 1 {
7778 xHalfWidth *= xscale
7779 xKernelArgScale = 1 / xscale
7780 }
7781 yHalfWidth, yKernelArgScale := q.Support, 1.0
7782 if yscale > 1 {
7783 yHalfWidth *= yscale
7784 yKernelArgScale = 1 / yscale
7785 }
7786
7787 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
7788 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
7789
7790 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
7791 dyf := float64(dr.Min.Y+int(dy)) + 0.5
7792 d := (dr.Min.Y+int(dy)-dst.Rect.Min.Y)*dst.Stride + (dr.Min.X+adr.Min.X-dst.Rect.Min.X)*4
7793 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx, d = dx+1, d+4 {
7794 dxf := float64(dr.Min.X+int(dx)) + 0.5
7795 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
7796 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
7797 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
7798 continue
7799 }
7800
7801
7802
7803 sx += float64(bias.X)
7804 sx -= 0.5
7805 ix := int(math.Floor(sx - xHalfWidth))
7806 if ix < sr.Min.X {
7807 ix = sr.Min.X
7808 }
7809 jx := int(math.Ceil(sx + xHalfWidth))
7810 if jx > sr.Max.X {
7811 jx = sr.Max.X
7812 }
7813
7814 totalXWeight := 0.0
7815 for kx := ix; kx < jx; kx++ {
7816 xWeight := 0.0
7817 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
7818 xWeight = q.At(t)
7819 }
7820 xWeights[kx-ix] = xWeight
7821 totalXWeight += xWeight
7822 }
7823 for x := range xWeights[:jx-ix] {
7824 xWeights[x] /= totalXWeight
7825 }
7826
7827 sy += float64(bias.Y)
7828 sy -= 0.5
7829 iy := int(math.Floor(sy - yHalfWidth))
7830 if iy < sr.Min.Y {
7831 iy = sr.Min.Y
7832 }
7833 jy := int(math.Ceil(sy + yHalfWidth))
7834 if jy > sr.Max.Y {
7835 jy = sr.Max.Y
7836 }
7837
7838 totalYWeight := 0.0
7839 for ky := iy; ky < jy; ky++ {
7840 yWeight := 0.0
7841 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
7842 yWeight = q.At(t)
7843 }
7844 yWeights[ky-iy] = yWeight
7845 totalYWeight += yWeight
7846 }
7847 for y := range yWeights[:jy-iy] {
7848 yWeights[y] /= totalYWeight
7849 }
7850
7851 var pr, pg, pb, pa float64
7852 for ky := iy; ky < jy; ky++ {
7853 if yWeight := yWeights[ky-iy]; yWeight != 0 {
7854 for kx := ix; kx < jx; kx++ {
7855 if w := xWeights[kx-ix] * yWeight; w != 0 {
7856 pru, pgu, pbu, pau := src.At(kx, ky).RGBA()
7857 pr += float64(pru) * w
7858 pg += float64(pgu) * w
7859 pb += float64(pbu) * w
7860 pa += float64(pau) * w
7861 }
7862 }
7863 }
7864 }
7865
7866 if pr > pa {
7867 pr = pa
7868 }
7869 if pg > pa {
7870 pg = pa
7871 }
7872 if pb > pa {
7873 pb = pa
7874 }
7875
7876 dst.Pix[d+0] = uint8(fffftou(pr) >> 8)
7877 dst.Pix[d+1] = uint8(fffftou(pg) >> 8)
7878 dst.Pix[d+2] = uint8(fffftou(pb) >> 8)
7879 dst.Pix[d+3] = uint8(fffftou(pa) >> 8)
7880 }
7881 }
7882 }
7883
7884 func (q *Kernel) transform_RGBA64Image_RGBA64Image_Over(dst RGBA64Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
7885
7886
7887 xHalfWidth, xKernelArgScale := q.Support, 1.0
7888 if xscale > 1 {
7889 xHalfWidth *= xscale
7890 xKernelArgScale = 1 / xscale
7891 }
7892 yHalfWidth, yKernelArgScale := q.Support, 1.0
7893 if yscale > 1 {
7894 yHalfWidth *= yscale
7895 yKernelArgScale = 1 / yscale
7896 }
7897
7898 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
7899 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
7900
7901 srcMask, smp := opts.SrcMask, opts.SrcMaskP
7902 dstMask, dmp := opts.DstMask, opts.DstMaskP
7903 dstColorRGBA64 := color.RGBA64{}
7904
7905 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
7906 dyf := float64(dr.Min.Y+int(dy)) + 0.5
7907 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
7908 dxf := float64(dr.Min.X+int(dx)) + 0.5
7909 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
7910 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
7911 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
7912 continue
7913 }
7914
7915
7916
7917 sx += float64(bias.X)
7918 sx -= 0.5
7919 ix := int(math.Floor(sx - xHalfWidth))
7920 if ix < sr.Min.X {
7921 ix = sr.Min.X
7922 }
7923 jx := int(math.Ceil(sx + xHalfWidth))
7924 if jx > sr.Max.X {
7925 jx = sr.Max.X
7926 }
7927
7928 totalXWeight := 0.0
7929 for kx := ix; kx < jx; kx++ {
7930 xWeight := 0.0
7931 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
7932 xWeight = q.At(t)
7933 }
7934 xWeights[kx-ix] = xWeight
7935 totalXWeight += xWeight
7936 }
7937 for x := range xWeights[:jx-ix] {
7938 xWeights[x] /= totalXWeight
7939 }
7940
7941 sy += float64(bias.Y)
7942 sy -= 0.5
7943 iy := int(math.Floor(sy - yHalfWidth))
7944 if iy < sr.Min.Y {
7945 iy = sr.Min.Y
7946 }
7947 jy := int(math.Ceil(sy + yHalfWidth))
7948 if jy > sr.Max.Y {
7949 jy = sr.Max.Y
7950 }
7951
7952 totalYWeight := 0.0
7953 for ky := iy; ky < jy; ky++ {
7954 yWeight := 0.0
7955 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
7956 yWeight = q.At(t)
7957 }
7958 yWeights[ky-iy] = yWeight
7959 totalYWeight += yWeight
7960 }
7961 for y := range yWeights[:jy-iy] {
7962 yWeights[y] /= totalYWeight
7963 }
7964
7965 var pr, pg, pb, pa float64
7966 for ky := iy; ky < jy; ky++ {
7967 if yWeight := yWeights[ky-iy]; yWeight != 0 {
7968 for kx := ix; kx < jx; kx++ {
7969 if w := xWeights[kx-ix] * yWeight; w != 0 {
7970 pu := src.RGBA64At(kx, ky)
7971 if srcMask != nil {
7972 _, _, _, ma := srcMask.At(smp.X+kx, smp.Y+ky).RGBA()
7973 pu.R = uint16(uint32(pu.R) * ma / 0xffff)
7974 pu.G = uint16(uint32(pu.G) * ma / 0xffff)
7975 pu.B = uint16(uint32(pu.B) * ma / 0xffff)
7976 pu.A = uint16(uint32(pu.A) * ma / 0xffff)
7977 }
7978 pr += float64(pu.R) * w
7979 pg += float64(pu.G) * w
7980 pb += float64(pu.B) * w
7981 pa += float64(pu.A) * w
7982 }
7983 }
7984 }
7985 }
7986
7987 if pr > pa {
7988 pr = pa
7989 }
7990 if pg > pa {
7991 pg = pa
7992 }
7993 if pb > pa {
7994 pb = pa
7995 }
7996
7997 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(dy))
7998 pr0 := uint32(fffftou(pr))
7999 pg0 := uint32(fffftou(pg))
8000 pb0 := uint32(fffftou(pb))
8001 pa0 := uint32(fffftou(pa))
8002 if dstMask != nil {
8003 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
8004 pr0 = pr0 * ma / 0xffff
8005 pg0 = pg0 * ma / 0xffff
8006 pb0 = pb0 * ma / 0xffff
8007 pa0 = pa0 * ma / 0xffff
8008 }
8009 pa1 := 0xffff - pa0
8010 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + pr0)
8011 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + pg0)
8012 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + pb0)
8013 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + pa0)
8014 dst.SetRGBA64(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColorRGBA64)
8015 }
8016 }
8017 }
8018
8019 func (q *Kernel) transform_RGBA64Image_RGBA64Image_Src(dst RGBA64Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.RGBA64Image, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
8020
8021
8022 xHalfWidth, xKernelArgScale := q.Support, 1.0
8023 if xscale > 1 {
8024 xHalfWidth *= xscale
8025 xKernelArgScale = 1 / xscale
8026 }
8027 yHalfWidth, yKernelArgScale := q.Support, 1.0
8028 if yscale > 1 {
8029 yHalfWidth *= yscale
8030 yKernelArgScale = 1 / yscale
8031 }
8032
8033 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
8034 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
8035
8036 srcMask, smp := opts.SrcMask, opts.SrcMaskP
8037 dstMask, dmp := opts.DstMask, opts.DstMaskP
8038 dstColorRGBA64 := color.RGBA64{}
8039
8040 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
8041 dyf := float64(dr.Min.Y+int(dy)) + 0.5
8042 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
8043 dxf := float64(dr.Min.X+int(dx)) + 0.5
8044 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
8045 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
8046 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
8047 continue
8048 }
8049
8050
8051
8052 sx += float64(bias.X)
8053 sx -= 0.5
8054 ix := int(math.Floor(sx - xHalfWidth))
8055 if ix < sr.Min.X {
8056 ix = sr.Min.X
8057 }
8058 jx := int(math.Ceil(sx + xHalfWidth))
8059 if jx > sr.Max.X {
8060 jx = sr.Max.X
8061 }
8062
8063 totalXWeight := 0.0
8064 for kx := ix; kx < jx; kx++ {
8065 xWeight := 0.0
8066 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
8067 xWeight = q.At(t)
8068 }
8069 xWeights[kx-ix] = xWeight
8070 totalXWeight += xWeight
8071 }
8072 for x := range xWeights[:jx-ix] {
8073 xWeights[x] /= totalXWeight
8074 }
8075
8076 sy += float64(bias.Y)
8077 sy -= 0.5
8078 iy := int(math.Floor(sy - yHalfWidth))
8079 if iy < sr.Min.Y {
8080 iy = sr.Min.Y
8081 }
8082 jy := int(math.Ceil(sy + yHalfWidth))
8083 if jy > sr.Max.Y {
8084 jy = sr.Max.Y
8085 }
8086
8087 totalYWeight := 0.0
8088 for ky := iy; ky < jy; ky++ {
8089 yWeight := 0.0
8090 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
8091 yWeight = q.At(t)
8092 }
8093 yWeights[ky-iy] = yWeight
8094 totalYWeight += yWeight
8095 }
8096 for y := range yWeights[:jy-iy] {
8097 yWeights[y] /= totalYWeight
8098 }
8099
8100 var pr, pg, pb, pa float64
8101 for ky := iy; ky < jy; ky++ {
8102 if yWeight := yWeights[ky-iy]; yWeight != 0 {
8103 for kx := ix; kx < jx; kx++ {
8104 if w := xWeights[kx-ix] * yWeight; w != 0 {
8105 pu := src.RGBA64At(kx, ky)
8106 if srcMask != nil {
8107 _, _, _, ma := srcMask.At(smp.X+kx, smp.Y+ky).RGBA()
8108 pu.R = uint16(uint32(pu.R) * ma / 0xffff)
8109 pu.G = uint16(uint32(pu.G) * ma / 0xffff)
8110 pu.B = uint16(uint32(pu.B) * ma / 0xffff)
8111 pu.A = uint16(uint32(pu.A) * ma / 0xffff)
8112 }
8113 pr += float64(pu.R) * w
8114 pg += float64(pu.G) * w
8115 pb += float64(pu.B) * w
8116 pa += float64(pu.A) * w
8117 }
8118 }
8119 }
8120 }
8121
8122 if pr > pa {
8123 pr = pa
8124 }
8125 if pg > pa {
8126 pg = pa
8127 }
8128 if pb > pa {
8129 pb = pa
8130 }
8131
8132 if dstMask != nil {
8133 q := dst.RGBA64At(dr.Min.X+int(dx), dr.Min.Y+int(dy))
8134 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
8135 pr := uint32(fffftou(pr)) * ma / 0xffff
8136 pg := uint32(fffftou(pg)) * ma / 0xffff
8137 pb := uint32(fffftou(pb)) * ma / 0xffff
8138 pa := uint32(fffftou(pa)) * ma / 0xffff
8139 pa1 := 0xffff - ma
8140 dstColorRGBA64.R = uint16(uint32(q.R)*pa1/0xffff + pr)
8141 dstColorRGBA64.G = uint16(uint32(q.G)*pa1/0xffff + pg)
8142 dstColorRGBA64.B = uint16(uint32(q.B)*pa1/0xffff + pb)
8143 dstColorRGBA64.A = uint16(uint32(q.A)*pa1/0xffff + pa)
8144 dst.SetRGBA64(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColorRGBA64)
8145 } else {
8146 dstColorRGBA64.R = fffftou(pr)
8147 dstColorRGBA64.G = fffftou(pg)
8148 dstColorRGBA64.B = fffftou(pb)
8149 dstColorRGBA64.A = fffftou(pa)
8150 dst.SetRGBA64(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColorRGBA64)
8151 }
8152 }
8153 }
8154 }
8155
8156 func (q *Kernel) transform_Image_Image_Over(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
8157
8158
8159 xHalfWidth, xKernelArgScale := q.Support, 1.0
8160 if xscale > 1 {
8161 xHalfWidth *= xscale
8162 xKernelArgScale = 1 / xscale
8163 }
8164 yHalfWidth, yKernelArgScale := q.Support, 1.0
8165 if yscale > 1 {
8166 yHalfWidth *= yscale
8167 yKernelArgScale = 1 / yscale
8168 }
8169
8170 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
8171 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
8172
8173 srcMask, smp := opts.SrcMask, opts.SrcMaskP
8174 dstMask, dmp := opts.DstMask, opts.DstMaskP
8175 dstColorRGBA64 := &color.RGBA64{}
8176 dstColor := color.Color(dstColorRGBA64)
8177 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
8178 dyf := float64(dr.Min.Y+int(dy)) + 0.5
8179 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
8180 dxf := float64(dr.Min.X+int(dx)) + 0.5
8181 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
8182 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
8183 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
8184 continue
8185 }
8186
8187
8188
8189 sx += float64(bias.X)
8190 sx -= 0.5
8191 ix := int(math.Floor(sx - xHalfWidth))
8192 if ix < sr.Min.X {
8193 ix = sr.Min.X
8194 }
8195 jx := int(math.Ceil(sx + xHalfWidth))
8196 if jx > sr.Max.X {
8197 jx = sr.Max.X
8198 }
8199
8200 totalXWeight := 0.0
8201 for kx := ix; kx < jx; kx++ {
8202 xWeight := 0.0
8203 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
8204 xWeight = q.At(t)
8205 }
8206 xWeights[kx-ix] = xWeight
8207 totalXWeight += xWeight
8208 }
8209 for x := range xWeights[:jx-ix] {
8210 xWeights[x] /= totalXWeight
8211 }
8212
8213 sy += float64(bias.Y)
8214 sy -= 0.5
8215 iy := int(math.Floor(sy - yHalfWidth))
8216 if iy < sr.Min.Y {
8217 iy = sr.Min.Y
8218 }
8219 jy := int(math.Ceil(sy + yHalfWidth))
8220 if jy > sr.Max.Y {
8221 jy = sr.Max.Y
8222 }
8223
8224 totalYWeight := 0.0
8225 for ky := iy; ky < jy; ky++ {
8226 yWeight := 0.0
8227 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
8228 yWeight = q.At(t)
8229 }
8230 yWeights[ky-iy] = yWeight
8231 totalYWeight += yWeight
8232 }
8233 for y := range yWeights[:jy-iy] {
8234 yWeights[y] /= totalYWeight
8235 }
8236
8237 var pr, pg, pb, pa float64
8238 for ky := iy; ky < jy; ky++ {
8239 if yWeight := yWeights[ky-iy]; yWeight != 0 {
8240 for kx := ix; kx < jx; kx++ {
8241 if w := xWeights[kx-ix] * yWeight; w != 0 {
8242 pru, pgu, pbu, pau := src.At(kx, ky).RGBA()
8243 if srcMask != nil {
8244 _, _, _, ma := srcMask.At(smp.X+kx, smp.Y+ky).RGBA()
8245 pru = pru * ma / 0xffff
8246 pgu = pgu * ma / 0xffff
8247 pbu = pbu * ma / 0xffff
8248 pau = pau * ma / 0xffff
8249 }
8250 pr += float64(pru) * w
8251 pg += float64(pgu) * w
8252 pb += float64(pbu) * w
8253 pa += float64(pau) * w
8254 }
8255 }
8256 }
8257 }
8258
8259 if pr > pa {
8260 pr = pa
8261 }
8262 if pg > pa {
8263 pg = pa
8264 }
8265 if pb > pa {
8266 pb = pa
8267 }
8268
8269 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(dy)).RGBA()
8270 pr0 := uint32(fffftou(pr))
8271 pg0 := uint32(fffftou(pg))
8272 pb0 := uint32(fffftou(pb))
8273 pa0 := uint32(fffftou(pa))
8274 if dstMask != nil {
8275 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
8276 pr0 = pr0 * ma / 0xffff
8277 pg0 = pg0 * ma / 0xffff
8278 pb0 = pb0 * ma / 0xffff
8279 pa0 = pa0 * ma / 0xffff
8280 }
8281 pa1 := 0xffff - pa0
8282 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr0)
8283 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg0)
8284 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb0)
8285 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa0)
8286 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
8287 }
8288 }
8289 }
8290
8291 func (q *Kernel) transform_Image_Image_Src(dst Image, dr, adr image.Rectangle, d2s *f64.Aff3, src image.Image, sr image.Rectangle, bias image.Point, xscale, yscale float64, opts *Options) {
8292
8293
8294 xHalfWidth, xKernelArgScale := q.Support, 1.0
8295 if xscale > 1 {
8296 xHalfWidth *= xscale
8297 xKernelArgScale = 1 / xscale
8298 }
8299 yHalfWidth, yKernelArgScale := q.Support, 1.0
8300 if yscale > 1 {
8301 yHalfWidth *= yscale
8302 yKernelArgScale = 1 / yscale
8303 }
8304
8305 xWeights := make([]float64, 1+2*int(math.Ceil(xHalfWidth)))
8306 yWeights := make([]float64, 1+2*int(math.Ceil(yHalfWidth)))
8307
8308 srcMask, smp := opts.SrcMask, opts.SrcMaskP
8309 dstMask, dmp := opts.DstMask, opts.DstMaskP
8310 dstColorRGBA64 := &color.RGBA64{}
8311 dstColor := color.Color(dstColorRGBA64)
8312 for dy := int32(adr.Min.Y); dy < int32(adr.Max.Y); dy++ {
8313 dyf := float64(dr.Min.Y+int(dy)) + 0.5
8314 for dx := int32(adr.Min.X); dx < int32(adr.Max.X); dx++ {
8315 dxf := float64(dr.Min.X+int(dx)) + 0.5
8316 sx := d2s[0]*dxf + d2s[1]*dyf + d2s[2]
8317 sy := d2s[3]*dxf + d2s[4]*dyf + d2s[5]
8318 if !(image.Point{int(sx) + bias.X, int(sy) + bias.Y}).In(sr) {
8319 continue
8320 }
8321
8322
8323
8324 sx += float64(bias.X)
8325 sx -= 0.5
8326 ix := int(math.Floor(sx - xHalfWidth))
8327 if ix < sr.Min.X {
8328 ix = sr.Min.X
8329 }
8330 jx := int(math.Ceil(sx + xHalfWidth))
8331 if jx > sr.Max.X {
8332 jx = sr.Max.X
8333 }
8334
8335 totalXWeight := 0.0
8336 for kx := ix; kx < jx; kx++ {
8337 xWeight := 0.0
8338 if t := abs((sx - float64(kx)) * xKernelArgScale); t < q.Support {
8339 xWeight = q.At(t)
8340 }
8341 xWeights[kx-ix] = xWeight
8342 totalXWeight += xWeight
8343 }
8344 for x := range xWeights[:jx-ix] {
8345 xWeights[x] /= totalXWeight
8346 }
8347
8348 sy += float64(bias.Y)
8349 sy -= 0.5
8350 iy := int(math.Floor(sy - yHalfWidth))
8351 if iy < sr.Min.Y {
8352 iy = sr.Min.Y
8353 }
8354 jy := int(math.Ceil(sy + yHalfWidth))
8355 if jy > sr.Max.Y {
8356 jy = sr.Max.Y
8357 }
8358
8359 totalYWeight := 0.0
8360 for ky := iy; ky < jy; ky++ {
8361 yWeight := 0.0
8362 if t := abs((sy - float64(ky)) * yKernelArgScale); t < q.Support {
8363 yWeight = q.At(t)
8364 }
8365 yWeights[ky-iy] = yWeight
8366 totalYWeight += yWeight
8367 }
8368 for y := range yWeights[:jy-iy] {
8369 yWeights[y] /= totalYWeight
8370 }
8371
8372 var pr, pg, pb, pa float64
8373 for ky := iy; ky < jy; ky++ {
8374 if yWeight := yWeights[ky-iy]; yWeight != 0 {
8375 for kx := ix; kx < jx; kx++ {
8376 if w := xWeights[kx-ix] * yWeight; w != 0 {
8377 pru, pgu, pbu, pau := src.At(kx, ky).RGBA()
8378 if srcMask != nil {
8379 _, _, _, ma := srcMask.At(smp.X+kx, smp.Y+ky).RGBA()
8380 pru = pru * ma / 0xffff
8381 pgu = pgu * ma / 0xffff
8382 pbu = pbu * ma / 0xffff
8383 pau = pau * ma / 0xffff
8384 }
8385 pr += float64(pru) * w
8386 pg += float64(pgu) * w
8387 pb += float64(pbu) * w
8388 pa += float64(pau) * w
8389 }
8390 }
8391 }
8392 }
8393
8394 if pr > pa {
8395 pr = pa
8396 }
8397 if pg > pa {
8398 pg = pa
8399 }
8400 if pb > pa {
8401 pb = pa
8402 }
8403
8404 if dstMask != nil {
8405 qr, qg, qb, qa := dst.At(dr.Min.X+int(dx), dr.Min.Y+int(dy)).RGBA()
8406 _, _, _, ma := dstMask.At(dmp.X+dr.Min.X+int(dx), dmp.Y+dr.Min.Y+int(dy)).RGBA()
8407 pr := uint32(fffftou(pr)) * ma / 0xffff
8408 pg := uint32(fffftou(pg)) * ma / 0xffff
8409 pb := uint32(fffftou(pb)) * ma / 0xffff
8410 pa := uint32(fffftou(pa)) * ma / 0xffff
8411 pa1 := 0xffff - ma
8412 dstColorRGBA64.R = uint16(qr*pa1/0xffff + pr)
8413 dstColorRGBA64.G = uint16(qg*pa1/0xffff + pg)
8414 dstColorRGBA64.B = uint16(qb*pa1/0xffff + pb)
8415 dstColorRGBA64.A = uint16(qa*pa1/0xffff + pa)
8416 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
8417 } else {
8418 dstColorRGBA64.R = fffftou(pr)
8419 dstColorRGBA64.G = fffftou(pg)
8420 dstColorRGBA64.B = fffftou(pb)
8421 dstColorRGBA64.A = fffftou(pa)
8422 dst.Set(dr.Min.X+int(dx), dr.Min.Y+int(dy), dstColor)
8423 }
8424 }
8425 }
8426 }
8427
View as plain text