Merge branch 'blender-v2.81-release'
[blender.git] / source / blender / imbuf / intern / scaling.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  * allocimbuf.c
19  */
20
21 /** \file
22  * \ingroup imbuf
23  */
24
25 #include "BLI_utildefines.h"
26 #include "BLI_math_color.h"
27 #include "BLI_math_interp.h"
28 #include "MEM_guardedalloc.h"
29
30 #include "imbuf.h"
31 #include "IMB_imbuf_types.h"
32 #include "IMB_imbuf.h"
33
34 #include "IMB_filter.h"
35
36 #include "BLI_sys_types.h"  // for intptr_t support
37
38 static void imb_half_x_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
39 {
40   uchar *p1, *_p1, *dest;
41   short a, r, g, b;
42   int x, y;
43   float af, rf, gf, bf, *p1f, *_p1f, *destf;
44   bool do_rect, do_float;
45
46   do_rect = (ibuf1->rect != NULL);
47   do_float = (ibuf1->rect_float != NULL && ibuf2->rect_float != NULL);
48
49   _p1 = (uchar *)ibuf1->rect;
50   dest = (uchar *)ibuf2->rect;
51
52   _p1f = ibuf1->rect_float;
53   destf = ibuf2->rect_float;
54
55   for (y = ibuf2->y; y > 0; y--) {
56     p1 = _p1;
57     p1f = _p1f;
58     for (x = ibuf2->x; x > 0; x--) {
59       if (do_rect) {
60         a = *(p1++);
61         b = *(p1++);
62         g = *(p1++);
63         r = *(p1++);
64         a += *(p1++);
65         b += *(p1++);
66         g += *(p1++);
67         r += *(p1++);
68         *(dest++) = a >> 1;
69         *(dest++) = b >> 1;
70         *(dest++) = g >> 1;
71         *(dest++) = r >> 1;
72       }
73       if (do_float) {
74         af = *(p1f++);
75         bf = *(p1f++);
76         gf = *(p1f++);
77         rf = *(p1f++);
78         af += *(p1f++);
79         bf += *(p1f++);
80         gf += *(p1f++);
81         rf += *(p1f++);
82         *(destf++) = 0.5f * af;
83         *(destf++) = 0.5f * bf;
84         *(destf++) = 0.5f * gf;
85         *(destf++) = 0.5f * rf;
86       }
87     }
88     if (do_rect) {
89       _p1 += (ibuf1->x << 2);
90     }
91     if (do_float) {
92       _p1f += (ibuf1->x << 2);
93     }
94   }
95 }
96
97 struct ImBuf *IMB_half_x(struct ImBuf *ibuf1)
98 {
99   struct ImBuf *ibuf2;
100
101   if (ibuf1 == NULL) {
102     return (NULL);
103   }
104   if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) {
105     return (NULL);
106   }
107
108   if (ibuf1->x <= 1) {
109     return (IMB_dupImBuf(ibuf1));
110   }
111
112   ibuf2 = IMB_allocImBuf((ibuf1->x) / 2, ibuf1->y, ibuf1->planes, ibuf1->flags);
113   if (ibuf2 == NULL) {
114     return (NULL);
115   }
116
117   imb_half_x_no_alloc(ibuf2, ibuf1);
118
119   return (ibuf2);
120 }
121
122 struct ImBuf *IMB_double_fast_x(struct ImBuf *ibuf1)
123 {
124   struct ImBuf *ibuf2;
125   int *p1, *dest, i, col, do_rect, do_float;
126   float *p1f, *destf;
127
128   if (ibuf1 == NULL) {
129     return (NULL);
130   }
131   if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) {
132     return (NULL);
133   }
134
135   do_rect = (ibuf1->rect != NULL);
136   do_float = (ibuf1->rect_float != NULL);
137
138   ibuf2 = IMB_allocImBuf(2 * ibuf1->x, ibuf1->y, ibuf1->planes, ibuf1->flags);
139   if (ibuf2 == NULL) {
140     return (NULL);
141   }
142
143   p1 = (int *)ibuf1->rect;
144   dest = (int *)ibuf2->rect;
145   p1f = (float *)ibuf1->rect_float;
146   destf = (float *)ibuf2->rect_float;
147
148   for (i = ibuf1->y * ibuf1->x; i > 0; i--) {
149     if (do_rect) {
150       col = *p1++;
151       *dest++ = col;
152       *dest++ = col;
153     }
154     if (do_float) {
155       destf[0] = destf[4] = p1f[0];
156       destf[1] = destf[5] = p1f[1];
157       destf[2] = destf[6] = p1f[2];
158       destf[3] = destf[7] = p1f[3];
159       destf += 8;
160       p1f += 4;
161     }
162   }
163
164   return (ibuf2);
165 }
166
167 struct ImBuf *IMB_double_x(struct ImBuf *ibuf1)
168 {
169   struct ImBuf *ibuf2;
170
171   if (ibuf1 == NULL) {
172     return (NULL);
173   }
174   if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) {
175     return (NULL);
176   }
177
178   ibuf2 = IMB_double_fast_x(ibuf1);
179
180   imb_filterx(ibuf2);
181   return (ibuf2);
182 }
183
184 static void imb_half_y_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
185 {
186   uchar *p1, *p2, *_p1, *dest;
187   short a, r, g, b;
188   int x, y;
189   int do_rect, do_float;
190   float af, rf, gf, bf, *p1f, *p2f, *_p1f, *destf;
191
192   p1 = p2 = NULL;
193   p1f = p2f = NULL;
194
195   do_rect = (ibuf1->rect != NULL);
196   do_float = (ibuf1->rect_float != NULL && ibuf2->rect_float != NULL);
197
198   _p1 = (uchar *)ibuf1->rect;
199   dest = (uchar *)ibuf2->rect;
200   _p1f = (float *)ibuf1->rect_float;
201   destf = (float *)ibuf2->rect_float;
202
203   for (y = ibuf2->y; y > 0; y--) {
204     if (do_rect) {
205       p1 = _p1;
206       p2 = _p1 + (ibuf1->x << 2);
207     }
208     if (do_float) {
209       p1f = _p1f;
210       p2f = _p1f + (ibuf1->x << 2);
211     }
212     for (x = ibuf2->x; x > 0; x--) {
213       if (do_rect) {
214         a = *(p1++);
215         b = *(p1++);
216         g = *(p1++);
217         r = *(p1++);
218         a += *(p2++);
219         b += *(p2++);
220         g += *(p2++);
221         r += *(p2++);
222         *(dest++) = a >> 1;
223         *(dest++) = b >> 1;
224         *(dest++) = g >> 1;
225         *(dest++) = r >> 1;
226       }
227       if (do_float) {
228         af = *(p1f++);
229         bf = *(p1f++);
230         gf = *(p1f++);
231         rf = *(p1f++);
232         af += *(p2f++);
233         bf += *(p2f++);
234         gf += *(p2f++);
235         rf += *(p2f++);
236         *(destf++) = 0.5f * af;
237         *(destf++) = 0.5f * bf;
238         *(destf++) = 0.5f * gf;
239         *(destf++) = 0.5f * rf;
240       }
241     }
242     if (do_rect) {
243       _p1 += (ibuf1->x << 3);
244     }
245     if (do_float) {
246       _p1f += (ibuf1->x << 3);
247     }
248   }
249 }
250
251 struct ImBuf *IMB_half_y(struct ImBuf *ibuf1)
252 {
253   struct ImBuf *ibuf2;
254
255   if (ibuf1 == NULL) {
256     return (NULL);
257   }
258   if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) {
259     return (NULL);
260   }
261
262   if (ibuf1->y <= 1) {
263     return (IMB_dupImBuf(ibuf1));
264   }
265
266   ibuf2 = IMB_allocImBuf(ibuf1->x, (ibuf1->y) / 2, ibuf1->planes, ibuf1->flags);
267   if (ibuf2 == NULL) {
268     return (NULL);
269   }
270
271   imb_half_y_no_alloc(ibuf2, ibuf1);
272
273   return (ibuf2);
274 }
275
276 struct ImBuf *IMB_double_fast_y(struct ImBuf *ibuf1)
277 {
278   struct ImBuf *ibuf2;
279   int *p1, *dest1, *dest2;
280   float *p1f, *dest1f, *dest2f;
281   int x, y;
282   int do_rect, do_float;
283
284   if (ibuf1 == NULL) {
285     return (NULL);
286   }
287   if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) {
288     return (NULL);
289   }
290
291   do_rect = (ibuf1->rect != NULL);
292   do_float = (ibuf1->rect_float != NULL);
293
294   ibuf2 = IMB_allocImBuf(ibuf1->x, 2 * ibuf1->y, ibuf1->planes, ibuf1->flags);
295   if (ibuf2 == NULL) {
296     return (NULL);
297   }
298
299   p1 = (int *)ibuf1->rect;
300   dest1 = (int *)ibuf2->rect;
301   p1f = (float *)ibuf1->rect_float;
302   dest1f = (float *)ibuf2->rect_float;
303
304   for (y = ibuf1->y; y > 0; y--) {
305     if (do_rect) {
306       dest2 = dest1 + ibuf2->x;
307       for (x = ibuf2->x; x > 0; x--) {
308         *dest1++ = *dest2++ = *p1++;
309       }
310       dest1 = dest2;
311     }
312     if (do_float) {
313       dest2f = dest1f + (4 * ibuf2->x);
314       for (x = ibuf2->x * 4; x > 0; x--) {
315         *dest1f++ = *dest2f++ = *p1f++;
316       }
317       dest1f = dest2f;
318     }
319   }
320
321   return (ibuf2);
322 }
323
324 struct ImBuf *IMB_double_y(struct ImBuf *ibuf1)
325 {
326   struct ImBuf *ibuf2;
327
328   if (ibuf1 == NULL) {
329     return (NULL);
330   }
331   if (ibuf1->rect == NULL) {
332     return (NULL);
333   }
334
335   ibuf2 = IMB_double_fast_y(ibuf1);
336
337   IMB_filtery(ibuf2);
338   return (ibuf2);
339 }
340
341 /* pretty much specific functions which converts uchar <-> ushort but assumes
342  * ushort range of 255*255 which is more convenient here
343  */
344 MINLINE void straight_uchar_to_premul_ushort(unsigned short result[4],
345                                              const unsigned char color[4])
346 {
347   unsigned short alpha = color[3];
348
349   result[0] = color[0] * alpha;
350   result[1] = color[1] * alpha;
351   result[2] = color[2] * alpha;
352   result[3] = alpha * 256;
353 }
354
355 MINLINE void premul_ushort_to_straight_uchar(unsigned char *result, const unsigned short color[4])
356 {
357   if (color[3] <= 255) {
358     result[0] = unit_ushort_to_uchar(color[0]);
359     result[1] = unit_ushort_to_uchar(color[1]);
360     result[2] = unit_ushort_to_uchar(color[2]);
361     result[3] = unit_ushort_to_uchar(color[3]);
362   }
363   else {
364     unsigned short alpha = color[3] / 256;
365
366     result[0] = unit_ushort_to_uchar((ushort)(color[0] / alpha * 256));
367     result[1] = unit_ushort_to_uchar((ushort)(color[1] / alpha * 256));
368     result[2] = unit_ushort_to_uchar((ushort)(color[2] / alpha * 256));
369     result[3] = unit_ushort_to_uchar(color[3]);
370   }
371 }
372
373 /* result in ibuf2, scaling should be done correctly */
374 void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1)
375 {
376   int x, y;
377   const short do_rect = (ibuf1->rect != NULL);
378   const short do_float = (ibuf1->rect_float != NULL) && (ibuf2->rect_float != NULL);
379
380   if (do_rect && (ibuf2->rect == NULL)) {
381     imb_addrectImBuf(ibuf2);
382   }
383
384   if (ibuf1->x <= 1) {
385     imb_half_y_no_alloc(ibuf2, ibuf1);
386     return;
387   }
388   if (ibuf1->y <= 1) {
389     imb_half_x_no_alloc(ibuf2, ibuf1);
390     return;
391   }
392
393   if (do_rect) {
394     unsigned char *cp1, *cp2, *dest;
395
396     cp1 = (unsigned char *)ibuf1->rect;
397     dest = (unsigned char *)ibuf2->rect;
398
399     for (y = ibuf2->y; y > 0; y--) {
400       cp2 = cp1 + (ibuf1->x << 2);
401       for (x = ibuf2->x; x > 0; x--) {
402         unsigned short p1i[8], p2i[8], desti[4];
403
404         straight_uchar_to_premul_ushort(p1i, cp1);
405         straight_uchar_to_premul_ushort(p2i, cp2);
406         straight_uchar_to_premul_ushort(p1i + 4, cp1 + 4);
407         straight_uchar_to_premul_ushort(p2i + 4, cp2 + 4);
408
409         desti[0] = ((unsigned int)p1i[0] + p2i[0] + p1i[4] + p2i[4]) >> 2;
410         desti[1] = ((unsigned int)p1i[1] + p2i[1] + p1i[5] + p2i[5]) >> 2;
411         desti[2] = ((unsigned int)p1i[2] + p2i[2] + p1i[6] + p2i[6]) >> 2;
412         desti[3] = ((unsigned int)p1i[3] + p2i[3] + p1i[7] + p2i[7]) >> 2;
413
414         premul_ushort_to_straight_uchar(dest, desti);
415
416         cp1 += 8;
417         cp2 += 8;
418         dest += 4;
419       }
420       cp1 = cp2;
421       if (ibuf1->x & 1) {
422         cp1 += 4;
423       }
424     }
425   }
426
427   if (do_float) {
428     float *p1f, *p2f, *destf;
429
430     p1f = ibuf1->rect_float;
431     destf = ibuf2->rect_float;
432     for (y = ibuf2->y; y > 0; y--) {
433       p2f = p1f + (ibuf1->x << 2);
434       for (x = ibuf2->x; x > 0; x--) {
435         destf[0] = 0.25f * (p1f[0] + p2f[0] + p1f[4] + p2f[4]);
436         destf[1] = 0.25f * (p1f[1] + p2f[1] + p1f[5] + p2f[5]);
437         destf[2] = 0.25f * (p1f[2] + p2f[2] + p1f[6] + p2f[6]);
438         destf[3] = 0.25f * (p1f[3] + p2f[3] + p1f[7] + p2f[7]);
439         p1f += 8;
440         p2f += 8;
441         destf += 4;
442       }
443       p1f = p2f;
444       if (ibuf1->x & 1) {
445         p1f += 4;
446       }
447     }
448   }
449 }
450
451 ImBuf *IMB_onehalf(struct ImBuf *ibuf1)
452 {
453   struct ImBuf *ibuf2;
454
455   if (ibuf1 == NULL) {
456     return (NULL);
457   }
458   if (ibuf1->rect == NULL && ibuf1->rect_float == NULL) {
459     return (NULL);
460   }
461
462   if (ibuf1->x <= 1) {
463     return (IMB_half_y(ibuf1));
464   }
465   if (ibuf1->y <= 1) {
466     return (IMB_half_x(ibuf1));
467   }
468
469   ibuf2 = IMB_allocImBuf((ibuf1->x) / 2, (ibuf1->y) / 2, ibuf1->planes, ibuf1->flags);
470   if (ibuf2 == NULL) {
471     return (NULL);
472   }
473
474   imb_onehalf_no_alloc(ibuf2, ibuf1);
475
476   return (ibuf2);
477 }
478
479 /* q_scale_linear_interpolation helper functions */
480
481 static void enlarge_picture_byte(unsigned char *src,
482                                  unsigned char *dst,
483                                  int src_width,
484                                  int src_height,
485                                  int dst_width,
486                                  int dst_height)
487 {
488   double ratiox = (double)(dst_width - 1.0) / (double)(src_width - 1.001);
489   double ratioy = (double)(dst_height - 1.0) / (double)(src_height - 1.001);
490   uintptr_t x_src, dx_src, x_dst;
491   uintptr_t y_src, dy_src, y_dst;
492
493   dx_src = 65536.0 / ratiox;
494   dy_src = 65536.0 / ratioy;
495
496   y_src = 0;
497   for (y_dst = 0; y_dst < dst_height; y_dst++) {
498     unsigned char *line1 = src + (y_src >> 16) * 4 * src_width;
499     unsigned char *line2 = line1 + 4 * src_width;
500     uintptr_t weight1y = 65536 - (y_src & 0xffff);
501     uintptr_t weight2y = 65536 - weight1y;
502
503     if ((y_src >> 16) == src_height - 1) {
504       line2 = line1;
505     }
506
507     x_src = 0;
508     for (x_dst = 0; x_dst < dst_width; x_dst++) {
509       uintptr_t weight1x = 65536 - (x_src & 0xffff);
510       uintptr_t weight2x = 65536 - weight1x;
511
512       unsigned long x = (x_src >> 16) * 4;
513
514       *dst++ = ((((line1[x] * weight1y) >> 16) * weight1x) >> 16) +
515                ((((line2[x] * weight2y) >> 16) * weight1x) >> 16) +
516                ((((line1[4 + x] * weight1y) >> 16) * weight2x) >> 16) +
517                ((((line2[4 + x] * weight2y) >> 16) * weight2x) >> 16);
518
519       *dst++ = ((((line1[x + 1] * weight1y) >> 16) * weight1x) >> 16) +
520                ((((line2[x + 1] * weight2y) >> 16) * weight1x) >> 16) +
521                ((((line1[4 + x + 1] * weight1y) >> 16) * weight2x) >> 16) +
522                ((((line2[4 + x + 1] * weight2y) >> 16) * weight2x) >> 16);
523
524       *dst++ = ((((line1[x + 2] * weight1y) >> 16) * weight1x) >> 16) +
525                ((((line2[x + 2] * weight2y) >> 16) * weight1x) >> 16) +
526                ((((line1[4 + x + 2] * weight1y) >> 16) * weight2x) >> 16) +
527                ((((line2[4 + x + 2] * weight2y) >> 16) * weight2x) >> 16);
528
529       *dst++ = ((((line1[x + 3] * weight1y) >> 16) * weight1x) >> 16) +
530                ((((line2[x + 3] * weight2y) >> 16) * weight1x) >> 16) +
531                ((((line1[4 + x + 3] * weight1y) >> 16) * weight2x) >> 16) +
532                ((((line2[4 + x + 3] * weight2y) >> 16) * weight2x) >> 16);
533
534       x_src += dx_src;
535     }
536     y_src += dy_src;
537   }
538 }
539
540 struct scale_outpix_byte {
541   uintptr_t r;
542   uintptr_t g;
543   uintptr_t b;
544   uintptr_t a;
545
546   uintptr_t weight;
547 };
548
549 static void shrink_picture_byte(unsigned char *src,
550                                 unsigned char *dst,
551                                 int src_width,
552                                 int src_height,
553                                 int dst_width,
554                                 int dst_height)
555 {
556   double ratiox = (double)(dst_width) / (double)(src_width);
557   double ratioy = (double)(dst_height) / (double)(src_height);
558   uintptr_t x_src, dx_dst, x_dst;
559   uintptr_t y_src, dy_dst, y_dst;
560   intptr_t y_counter;
561   unsigned char *dst_begin = dst;
562
563   struct scale_outpix_byte *dst_line1 = NULL;
564   struct scale_outpix_byte *dst_line2 = NULL;
565
566   dst_line1 = (struct scale_outpix_byte *)MEM_callocN(
567       (dst_width + 1) * sizeof(struct scale_outpix_byte), "shrink_picture_byte 1");
568   dst_line2 = (struct scale_outpix_byte *)MEM_callocN(
569       (dst_width + 1) * sizeof(struct scale_outpix_byte), "shrink_picture_byte 2");
570
571   dx_dst = 65536.0 * ratiox;
572   dy_dst = 65536.0 * ratioy;
573
574   y_dst = 0;
575   y_counter = 65536;
576   for (y_src = 0; y_src < src_height; y_src++) {
577     unsigned char *line = src + y_src * 4 * src_width;
578     uintptr_t weight1y = 65535 - (y_dst & 0xffff);
579     uintptr_t weight2y = 65535 - weight1y;
580     x_dst = 0;
581     for (x_src = 0; x_src < src_width; x_src++) {
582       uintptr_t weight1x = 65535 - (x_dst & 0xffff);
583       uintptr_t weight2x = 65535 - weight1x;
584
585       uintptr_t x = x_dst >> 16;
586
587       uintptr_t w;
588
589       w = (weight1y * weight1x) >> 16;
590
591       /* Ensure correct rounding, without this you get ugly banding,
592        * or too low color values (ton). */
593       dst_line1[x].r += (line[0] * w + 32767) >> 16;
594       dst_line1[x].g += (line[1] * w + 32767) >> 16;
595       dst_line1[x].b += (line[2] * w + 32767) >> 16;
596       dst_line1[x].a += (line[3] * w + 32767) >> 16;
597       dst_line1[x].weight += w;
598
599       w = (weight2y * weight1x) >> 16;
600
601       dst_line2[x].r += (line[0] * w + 32767) >> 16;
602       dst_line2[x].g += (line[1] * w + 32767) >> 16;
603       dst_line2[x].b += (line[2] * w + 32767) >> 16;
604       dst_line2[x].a += (line[3] * w + 32767) >> 16;
605       dst_line2[x].weight += w;
606
607       w = (weight1y * weight2x) >> 16;
608
609       dst_line1[x + 1].r += (line[0] * w + 32767) >> 16;
610       dst_line1[x + 1].g += (line[1] * w + 32767) >> 16;
611       dst_line1[x + 1].b += (line[2] * w + 32767) >> 16;
612       dst_line1[x + 1].a += (line[3] * w + 32767) >> 16;
613       dst_line1[x + 1].weight += w;
614
615       w = (weight2y * weight2x) >> 16;
616
617       dst_line2[x + 1].r += (line[0] * w + 32767) >> 16;
618       dst_line2[x + 1].g += (line[1] * w + 32767) >> 16;
619       dst_line2[x + 1].b += (line[2] * w + 32767) >> 16;
620       dst_line2[x + 1].a += (line[3] * w + 32767) >> 16;
621       dst_line2[x + 1].weight += w;
622
623       x_dst += dx_dst;
624       line += 4;
625     }
626
627     y_dst += dy_dst;
628     y_counter -= dy_dst;
629     if (y_counter < 0) {
630       int val;
631       uintptr_t x;
632       struct scale_outpix_byte *temp;
633
634       y_counter += 65536;
635
636       for (x = 0; x < dst_width; x++) {
637         uintptr_t f = 0x80000000UL / dst_line1[x].weight;
638         *dst++ = (val = (dst_line1[x].r * f) >> 15) > 255 ? 255 : val;
639         *dst++ = (val = (dst_line1[x].g * f) >> 15) > 255 ? 255 : val;
640         *dst++ = (val = (dst_line1[x].b * f) >> 15) > 255 ? 255 : val;
641         *dst++ = (val = (dst_line1[x].a * f) >> 15) > 255 ? 255 : val;
642       }
643       memset(dst_line1, 0, dst_width * sizeof(struct scale_outpix_byte));
644       temp = dst_line1;
645       dst_line1 = dst_line2;
646       dst_line2 = temp;
647     }
648   }
649   if (dst - dst_begin < dst_width * dst_height * 4) {
650     int val;
651     uintptr_t x;
652     for (x = 0; x < dst_width; x++) {
653       uintptr_t f = 0x80000000UL / dst_line1[x].weight;
654       *dst++ = (val = (dst_line1[x].r * f) >> 15) > 255 ? 255 : val;
655       *dst++ = (val = (dst_line1[x].g * f) >> 15) > 255 ? 255 : val;
656       *dst++ = (val = (dst_line1[x].b * f) >> 15) > 255 ? 255 : val;
657       *dst++ = (val = (dst_line1[x].a * f) >> 15) > 255 ? 255 : val;
658     }
659   }
660   MEM_freeN(dst_line1);
661   MEM_freeN(dst_line2);
662 }
663
664 static void q_scale_byte(unsigned char *in,
665                          unsigned char *out,
666                          int in_width,
667                          int in_height,
668                          int dst_width,
669                          int dst_height)
670 {
671   if (dst_width > in_width && dst_height > in_height) {
672     enlarge_picture_byte(in, out, in_width, in_height, dst_width, dst_height);
673   }
674   else if (dst_width < in_width && dst_height < in_height) {
675     shrink_picture_byte(in, out, in_width, in_height, dst_width, dst_height);
676   }
677 }
678
679 static void enlarge_picture_float(
680     float *src, float *dst, int src_width, int src_height, int dst_width, int dst_height)
681 {
682   double ratiox = (double)(dst_width - 1.0) / (double)(src_width - 1.001);
683   double ratioy = (double)(dst_height - 1.0) / (double)(src_height - 1.001);
684   uintptr_t x_dst;
685   uintptr_t y_dst;
686   double x_src, dx_src;
687   double y_src, dy_src;
688
689   dx_src = 1.0 / ratiox;
690   dy_src = 1.0 / ratioy;
691
692   y_src = 0;
693   for (y_dst = 0; y_dst < dst_height; y_dst++) {
694     float *line1 = src + ((int)y_src) * 4 * src_width;
695     const float *line2 = line1 + 4 * src_width;
696     const float weight1y = (float)(1.0 - (y_src - (int)y_src));
697     const float weight2y = 1.0f - weight1y;
698
699     if ((int)y_src == src_height - 1) {
700       line2 = line1;
701     }
702
703     x_src = 0;
704     for (x_dst = 0; x_dst < dst_width; x_dst++) {
705       const float weight1x = (float)(1.0 - (x_src - (int)x_src));
706       const float weight2x = (float)(1.0f - weight1x);
707
708       const float w11 = weight1y * weight1x;
709       const float w21 = weight2y * weight1x;
710       const float w12 = weight1y * weight2x;
711       const float w22 = weight2y * weight2x;
712
713       uintptr_t x = ((int)x_src) * 4;
714
715       *dst++ = line1[x] * w11 + line2[x] * w21 + line1[4 + x] * w12 + line2[4 + x] * w22;
716
717       *dst++ = line1[x + 1] * w11 + line2[x + 1] * w21 + line1[4 + x + 1] * w12 +
718                line2[4 + x + 1] * w22;
719
720       *dst++ = line1[x + 2] * w11 + line2[x + 2] * w21 + line1[4 + x + 2] * w12 +
721                line2[4 + x + 2] * w22;
722
723       *dst++ = line1[x + 3] * w11 + line2[x + 3] * w21 + line1[4 + x + 3] * w12 +
724                line2[4 + x + 3] * w22;
725
726       x_src += dx_src;
727     }
728     y_src += dy_src;
729   }
730 }
731
732 struct scale_outpix_float {
733   float r;
734   float g;
735   float b;
736   float a;
737
738   float weight;
739 };
740
741 static void shrink_picture_float(
742     const float *src, float *dst, int src_width, int src_height, int dst_width, int dst_height)
743 {
744   double ratiox = (double)(dst_width) / (double)(src_width);
745   double ratioy = (double)(dst_height) / (double)(src_height);
746   uintptr_t x_src;
747   uintptr_t y_src;
748   float dx_dst, x_dst;
749   float dy_dst, y_dst;
750   float y_counter;
751   const float *dst_begin = dst;
752
753   struct scale_outpix_float *dst_line1;
754   struct scale_outpix_float *dst_line2;
755
756   dst_line1 = (struct scale_outpix_float *)MEM_callocN(
757       (dst_width + 1) * sizeof(struct scale_outpix_float), "shrink_picture_float 1");
758   dst_line2 = (struct scale_outpix_float *)MEM_callocN(
759       (dst_width + 1) * sizeof(struct scale_outpix_float), "shrink_picture_float 2");
760
761   dx_dst = ratiox;
762   dy_dst = ratioy;
763
764   y_dst = 0;
765   y_counter = 1.0;
766   for (y_src = 0; y_src < src_height; y_src++) {
767     const float *line = src + y_src * 4 * src_width;
768     uintptr_t weight1y = 1.0f - (y_dst - (int)y_dst);
769     uintptr_t weight2y = 1.0f - weight1y;
770     x_dst = 0;
771     for (x_src = 0; x_src < src_width; x_src++) {
772       uintptr_t weight1x = 1.0f - (x_dst - (int)x_dst);
773       uintptr_t weight2x = 1.0f - weight1x;
774
775       uintptr_t x = (int)x_dst;
776
777       float w;
778
779       w = weight1y * weight1x;
780
781       dst_line1[x].r += line[0] * w;
782       dst_line1[x].g += line[1] * w;
783       dst_line1[x].b += line[2] * w;
784       dst_line1[x].a += line[3] * w;
785       dst_line1[x].weight += w;
786
787       w = weight2y * weight1x;
788
789       dst_line2[x].r += line[0] * w;
790       dst_line2[x].g += line[1] * w;
791       dst_line2[x].b += line[2] * w;
792       dst_line2[x].a += line[3] * w;
793       dst_line2[x].weight += w;
794
795       w = weight1y * weight2x;
796
797       dst_line1[x + 1].r += line[0] * w;
798       dst_line1[x + 1].g += line[1] * w;
799       dst_line1[x + 1].b += line[2] * w;
800       dst_line1[x + 1].a += line[3] * w;
801       dst_line1[x + 1].weight += w;
802
803       w = weight2y * weight2x;
804
805       dst_line2[x + 1].r += line[0] * w;
806       dst_line2[x + 1].g += line[1] * w;
807       dst_line2[x + 1].b += line[2] * w;
808       dst_line2[x + 1].a += line[3] * w;
809       dst_line2[x + 1].weight += w;
810
811       x_dst += dx_dst;
812       line += 4;
813     }
814
815     y_dst += dy_dst;
816     y_counter -= dy_dst;
817     if (y_counter < 0) {
818       uintptr_t x;
819       struct scale_outpix_float *temp;
820
821       y_counter += 1.0f;
822
823       for (x = 0; x < dst_width; x++) {
824         float f = 1.0f / dst_line1[x].weight;
825         *dst++ = dst_line1[x].r * f;
826         *dst++ = dst_line1[x].g * f;
827         *dst++ = dst_line1[x].b * f;
828         *dst++ = dst_line1[x].a * f;
829       }
830       memset(dst_line1, 0, dst_width * sizeof(struct scale_outpix_float));
831       temp = dst_line1;
832       dst_line1 = dst_line2;
833       dst_line2 = temp;
834     }
835   }
836   if (dst - dst_begin < dst_width * dst_height * 4) {
837     uintptr_t x;
838     for (x = 0; x < dst_width; x++) {
839       float f = 1.0f / dst_line1[x].weight;
840       *dst++ = dst_line1[x].r * f;
841       *dst++ = dst_line1[x].g * f;
842       *dst++ = dst_line1[x].b * f;
843       *dst++ = dst_line1[x].a * f;
844     }
845   }
846   MEM_freeN(dst_line1);
847   MEM_freeN(dst_line2);
848 }
849
850 static void q_scale_float(
851     float *in, float *out, int in_width, int in_height, int dst_width, int dst_height)
852 {
853   if (dst_width > in_width && dst_height > in_height) {
854     enlarge_picture_float(in, out, in_width, in_height, dst_width, dst_height);
855   }
856   else if (dst_width < in_width && dst_height < in_height) {
857     shrink_picture_float(in, out, in_width, in_height, dst_width, dst_height);
858   }
859 }
860
861 /**
862  * q_scale_linear_interpolation (derived from ppmqscale, http://libdv.sf.net)
863  *
864  * q stands for quick _and_ quality :)
865  *
866  * only handles common cases when we either
867  *
868  * scale  both, x and y or
869  * shrink both, x and y
870  *
871  * but that is pretty fast:
872  * - does only blit once instead of two passes like the old code
873  *   (fewer cache misses)
874  * - uses fixed point integer arithmetic for byte buffers
875  * - doesn't branch in tight loops
876  *
877  * Should be comparable in speed to the ImBuf ..._fast functions at least
878  * for byte-buffers.
879  *
880  * NOTE: disabled, due to unacceptable inaccuracy and quality loss, see bug #18609 (ton)
881  */
882 static bool q_scale_linear_interpolation(struct ImBuf *ibuf, int newx, int newy)
883 {
884   if ((newx >= ibuf->x && newy <= ibuf->y) || (newx <= ibuf->x && newy >= ibuf->y)) {
885     return false;
886   }
887
888   if (ibuf->rect) {
889     unsigned char *newrect = MEM_mallocN(newx * newy * sizeof(int), "q_scale rect");
890     q_scale_byte((unsigned char *)ibuf->rect, newrect, ibuf->x, ibuf->y, newx, newy);
891
892     imb_freerectImBuf(ibuf);
893     ibuf->mall |= IB_rect;
894     ibuf->rect = (unsigned int *)newrect;
895   }
896   if (ibuf->rect_float) {
897     float *newrect = MEM_mallocN(newx * newy * 4 * sizeof(float), "q_scale rectfloat");
898     q_scale_float(ibuf->rect_float, newrect, ibuf->x, ibuf->y, newx, newy);
899     imb_freerectfloatImBuf(ibuf);
900     ibuf->mall |= IB_rectfloat;
901     ibuf->rect_float = newrect;
902   }
903   ibuf->x = newx;
904   ibuf->y = newy;
905
906   return true;
907 }
908
909 static ImBuf *scaledownx(struct ImBuf *ibuf, int newx)
910 {
911   const int do_rect = (ibuf->rect != NULL);
912   const int do_float = (ibuf->rect_float != NULL);
913   const size_t rect_size = ibuf->x * ibuf->y * 4;
914
915   uchar *rect, *_newrect, *newrect;
916   float *rectf, *_newrectf, *newrectf;
917   float sample, add, val[4], nval[4], valf[4], nvalf[4];
918   int x, y;
919
920   rectf = _newrectf = newrectf = NULL;
921   rect = _newrect = newrect = NULL;
922   nval[0] = nval[1] = nval[2] = nval[3] = 0.0f;
923   nvalf[0] = nvalf[1] = nvalf[2] = nvalf[3] = 0.0f;
924
925   if (!do_rect && !do_float) {
926     return (ibuf);
927   }
928
929   if (do_rect) {
930     _newrect = MEM_mallocN(newx * ibuf->y * sizeof(uchar) * 4, "scaledownx");
931     if (_newrect == NULL) {
932       return (ibuf);
933     }
934   }
935   if (do_float) {
936     _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaledownxf");
937     if (_newrectf == NULL) {
938       if (_newrect) {
939         MEM_freeN(_newrect);
940       }
941       return (ibuf);
942     }
943   }
944
945   add = (ibuf->x - 0.01) / newx;
946
947   if (do_rect) {
948     rect = (uchar *)ibuf->rect;
949     newrect = _newrect;
950   }
951   if (do_float) {
952     rectf = ibuf->rect_float;
953     newrectf = _newrectf;
954   }
955
956   for (y = ibuf->y; y > 0; y--) {
957     sample = 0.0f;
958     val[0] = val[1] = val[2] = val[3] = 0.0f;
959     valf[0] = valf[1] = valf[2] = valf[3] = 0.0f;
960
961     for (x = newx; x > 0; x--) {
962       if (do_rect) {
963         nval[0] = -val[0] * sample;
964         nval[1] = -val[1] * sample;
965         nval[2] = -val[2] * sample;
966         nval[3] = -val[3] * sample;
967       }
968       if (do_float) {
969         nvalf[0] = -valf[0] * sample;
970         nvalf[1] = -valf[1] * sample;
971         nvalf[2] = -valf[2] * sample;
972         nvalf[3] = -valf[3] * sample;
973       }
974
975       sample += add;
976
977       while (sample >= 1.0f) {
978         sample -= 1.0f;
979
980         if (do_rect) {
981           nval[0] += rect[0];
982           nval[1] += rect[1];
983           nval[2] += rect[2];
984           nval[3] += rect[3];
985           rect += 4;
986         }
987         if (do_float) {
988           nvalf[0] += rectf[0];
989           nvalf[1] += rectf[1];
990           nvalf[2] += rectf[2];
991           nvalf[3] += rectf[3];
992           rectf += 4;
993         }
994       }
995
996       if (do_rect) {
997         val[0] = rect[0];
998         val[1] = rect[1];
999         val[2] = rect[2];
1000         val[3] = rect[3];
1001         rect += 4;
1002
1003         newrect[0] = ((nval[0] + sample * val[0]) / add + 0.5f);
1004         newrect[1] = ((nval[1] + sample * val[1]) / add + 0.5f);
1005         newrect[2] = ((nval[2] + sample * val[2]) / add + 0.5f);
1006         newrect[3] = ((nval[3] + sample * val[3]) / add + 0.5f);
1007
1008         newrect += 4;
1009       }
1010       if (do_float) {
1011
1012         valf[0] = rectf[0];
1013         valf[1] = rectf[1];
1014         valf[2] = rectf[2];
1015         valf[3] = rectf[3];
1016         rectf += 4;
1017
1018         newrectf[0] = ((nvalf[0] + sample * valf[0]) / add);
1019         newrectf[1] = ((nvalf[1] + sample * valf[1]) / add);
1020         newrectf[2] = ((nvalf[2] + sample * valf[2]) / add);
1021         newrectf[3] = ((nvalf[3] + sample * valf[3]) / add);
1022
1023         newrectf += 4;
1024       }
1025
1026       sample -= 1.0f;
1027     }
1028   }
1029
1030   if (do_rect) {
1031     // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size);
1032     BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug [#26502] */
1033     imb_freerectImBuf(ibuf);
1034     ibuf->mall |= IB_rect;
1035     ibuf->rect = (unsigned int *)_newrect;
1036   }
1037   if (do_float) {
1038     // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size);
1039     BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug [#26502] */
1040     imb_freerectfloatImBuf(ibuf);
1041     ibuf->mall |= IB_rectfloat;
1042     ibuf->rect_float = _newrectf;
1043   }
1044   (void)rect_size; /* UNUSED in release builds */
1045
1046   ibuf->x = newx;
1047   return (ibuf);
1048 }
1049
1050 static ImBuf *scaledowny(struct ImBuf *ibuf, int newy)
1051 {
1052   const int do_rect = (ibuf->rect != NULL);
1053   const int do_float = (ibuf->rect_float != NULL);
1054   const size_t rect_size = ibuf->x * ibuf->y * 4;
1055
1056   uchar *rect, *_newrect, *newrect;
1057   float *rectf, *_newrectf, *newrectf;
1058   float sample, add, val[4], nval[4], valf[4], nvalf[4];
1059   int x, y, skipx;
1060
1061   rectf = _newrectf = newrectf = NULL;
1062   rect = _newrect = newrect = NULL;
1063   nval[0] = nval[1] = nval[2] = nval[3] = 0.0f;
1064   nvalf[0] = nvalf[1] = nvalf[2] = nvalf[3] = 0.0f;
1065
1066   if (!do_rect && !do_float) {
1067     return (ibuf);
1068   }
1069
1070   if (do_rect) {
1071     _newrect = MEM_mallocN(newy * ibuf->x * sizeof(uchar) * 4, "scaledowny");
1072     if (_newrect == NULL) {
1073       return (ibuf);
1074     }
1075   }
1076   if (do_float) {
1077     _newrectf = MEM_mallocN(newy * ibuf->x * sizeof(float) * 4, "scaledownyf");
1078     if (_newrectf == NULL) {
1079       if (_newrect) {
1080         MEM_freeN(_newrect);
1081       }
1082       return (ibuf);
1083     }
1084   }
1085
1086   add = (ibuf->y - 0.01) / newy;
1087   skipx = 4 * ibuf->x;
1088
1089   for (x = skipx - 4; x >= 0; x -= 4) {
1090     if (do_rect) {
1091       rect = ((uchar *)ibuf->rect) + x;
1092       newrect = _newrect + x;
1093     }
1094     if (do_float) {
1095       rectf = ibuf->rect_float + x;
1096       newrectf = _newrectf + x;
1097     }
1098
1099     sample = 0.0f;
1100     val[0] = val[1] = val[2] = val[3] = 0.0f;
1101     valf[0] = valf[1] = valf[2] = valf[3] = 0.0f;
1102
1103     for (y = newy; y > 0; y--) {
1104       if (do_rect) {
1105         nval[0] = -val[0] * sample;
1106         nval[1] = -val[1] * sample;
1107         nval[2] = -val[2] * sample;
1108         nval[3] = -val[3] * sample;
1109       }
1110       if (do_float) {
1111         nvalf[0] = -valf[0] * sample;
1112         nvalf[1] = -valf[1] * sample;
1113         nvalf[2] = -valf[2] * sample;
1114         nvalf[3] = -valf[3] * sample;
1115       }
1116
1117       sample += add;
1118
1119       while (sample >= 1.0f) {
1120         sample -= 1.0f;
1121
1122         if (do_rect) {
1123           nval[0] += rect[0];
1124           nval[1] += rect[1];
1125           nval[2] += rect[2];
1126           nval[3] += rect[3];
1127           rect += skipx;
1128         }
1129         if (do_float) {
1130           nvalf[0] += rectf[0];
1131           nvalf[1] += rectf[1];
1132           nvalf[2] += rectf[2];
1133           nvalf[3] += rectf[3];
1134           rectf += skipx;
1135         }
1136       }
1137
1138       if (do_rect) {
1139         val[0] = rect[0];
1140         val[1] = rect[1];
1141         val[2] = rect[2];
1142         val[3] = rect[3];
1143         rect += skipx;
1144
1145         newrect[0] = ((nval[0] + sample * val[0]) / add + 0.5f);
1146         newrect[1] = ((nval[1] + sample * val[1]) / add + 0.5f);
1147         newrect[2] = ((nval[2] + sample * val[2]) / add + 0.5f);
1148         newrect[3] = ((nval[3] + sample * val[3]) / add + 0.5f);
1149
1150         newrect += skipx;
1151       }
1152       if (do_float) {
1153
1154         valf[0] = rectf[0];
1155         valf[1] = rectf[1];
1156         valf[2] = rectf[2];
1157         valf[3] = rectf[3];
1158         rectf += skipx;
1159
1160         newrectf[0] = ((nvalf[0] + sample * valf[0]) / add);
1161         newrectf[1] = ((nvalf[1] + sample * valf[1]) / add);
1162         newrectf[2] = ((nvalf[2] + sample * valf[2]) / add);
1163         newrectf[3] = ((nvalf[3] + sample * valf[3]) / add);
1164
1165         newrectf += skipx;
1166       }
1167
1168       sample -= 1.0f;
1169     }
1170   }
1171
1172   if (do_rect) {
1173     // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size);
1174     BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug [#26502] */
1175     imb_freerectImBuf(ibuf);
1176     ibuf->mall |= IB_rect;
1177     ibuf->rect = (unsigned int *)_newrect;
1178   }
1179   if (do_float) {
1180     // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size);
1181     BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug [#26502] */
1182     imb_freerectfloatImBuf(ibuf);
1183     ibuf->mall |= IB_rectfloat;
1184     ibuf->rect_float = (float *)_newrectf;
1185   }
1186   (void)rect_size; /* UNUSED in release builds */
1187
1188   ibuf->y = newy;
1189   return (ibuf);
1190 }
1191
1192 static ImBuf *scaleupx(struct ImBuf *ibuf, int newx)
1193 {
1194   uchar *rect, *_newrect = NULL, *newrect;
1195   float *rectf, *_newrectf = NULL, *newrectf;
1196   float sample, add;
1197   float val_a, nval_a, diff_a;
1198   float val_b, nval_b, diff_b;
1199   float val_g, nval_g, diff_g;
1200   float val_r, nval_r, diff_r;
1201   float val_af, nval_af, diff_af;
1202   float val_bf, nval_bf, diff_bf;
1203   float val_gf, nval_gf, diff_gf;
1204   float val_rf, nval_rf, diff_rf;
1205   int x, y;
1206   bool do_rect = false, do_float = false;
1207
1208   val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
1209   val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
1210   val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
1211   val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
1212   if (ibuf == NULL) {
1213     return (NULL);
1214   }
1215   if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
1216     return (ibuf);
1217   }
1218
1219   if (ibuf->rect) {
1220     do_rect = true;
1221     _newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaleupx");
1222     if (_newrect == NULL) {
1223       return (ibuf);
1224     }
1225   }
1226   if (ibuf->rect_float) {
1227     do_float = true;
1228     _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaleupxf");
1229     if (_newrectf == NULL) {
1230       if (_newrect) {
1231         MEM_freeN(_newrect);
1232       }
1233       return (ibuf);
1234     }
1235   }
1236
1237   add = (ibuf->x - 1.001) / (newx - 1.0);
1238
1239   rect = (uchar *)ibuf->rect;
1240   rectf = (float *)ibuf->rect_float;
1241   newrect = _newrect;
1242   newrectf = _newrectf;
1243
1244   for (y = ibuf->y; y > 0; y--) {
1245
1246     sample = 0;
1247
1248     if (do_rect) {
1249       val_a = rect[0];
1250       nval_a = rect[4];
1251       diff_a = nval_a - val_a;
1252       val_a += 0.5f;
1253
1254       val_b = rect[1];
1255       nval_b = rect[5];
1256       diff_b = nval_b - val_b;
1257       val_b += 0.5f;
1258
1259       val_g = rect[2];
1260       nval_g = rect[6];
1261       diff_g = nval_g - val_g;
1262       val_g += 0.5f;
1263
1264       val_r = rect[3];
1265       nval_r = rect[7];
1266       diff_r = nval_r - val_r;
1267       val_r += 0.5f;
1268
1269       rect += 8;
1270     }
1271     if (do_float) {
1272       val_af = rectf[0];
1273       nval_af = rectf[4];
1274       diff_af = nval_af - val_af;
1275
1276       val_bf = rectf[1];
1277       nval_bf = rectf[5];
1278       diff_bf = nval_bf - val_bf;
1279
1280       val_gf = rectf[2];
1281       nval_gf = rectf[6];
1282       diff_gf = nval_gf - val_gf;
1283
1284       val_rf = rectf[3];
1285       nval_rf = rectf[7];
1286       diff_rf = nval_rf - val_rf;
1287
1288       rectf += 8;
1289     }
1290     for (x = newx; x > 0; x--) {
1291       if (sample >= 1.0f) {
1292         sample -= 1.0f;
1293
1294         if (do_rect) {
1295           val_a = nval_a;
1296           nval_a = rect[0];
1297           diff_a = nval_a - val_a;
1298           val_a += 0.5f;
1299
1300           val_b = nval_b;
1301           nval_b = rect[1];
1302           diff_b = nval_b - val_b;
1303           val_b += 0.5f;
1304
1305           val_g = nval_g;
1306           nval_g = rect[2];
1307           diff_g = nval_g - val_g;
1308           val_g += 0.5f;
1309
1310           val_r = nval_r;
1311           nval_r = rect[3];
1312           diff_r = nval_r - val_r;
1313           val_r += 0.5f;
1314           rect += 4;
1315         }
1316         if (do_float) {
1317           val_af = nval_af;
1318           nval_af = rectf[0];
1319           diff_af = nval_af - val_af;
1320
1321           val_bf = nval_bf;
1322           nval_bf = rectf[1];
1323           diff_bf = nval_bf - val_bf;
1324
1325           val_gf = nval_gf;
1326           nval_gf = rectf[2];
1327           diff_gf = nval_gf - val_gf;
1328
1329           val_rf = nval_rf;
1330           nval_rf = rectf[3];
1331           diff_rf = nval_rf - val_rf;
1332           rectf += 4;
1333         }
1334       }
1335       if (do_rect) {
1336         newrect[0] = val_a + sample * diff_a;
1337         newrect[1] = val_b + sample * diff_b;
1338         newrect[2] = val_g + sample * diff_g;
1339         newrect[3] = val_r + sample * diff_r;
1340         newrect += 4;
1341       }
1342       if (do_float) {
1343         newrectf[0] = val_af + sample * diff_af;
1344         newrectf[1] = val_bf + sample * diff_bf;
1345         newrectf[2] = val_gf + sample * diff_gf;
1346         newrectf[3] = val_rf + sample * diff_rf;
1347         newrectf += 4;
1348       }
1349       sample += add;
1350     }
1351   }
1352
1353   if (do_rect) {
1354     imb_freerectImBuf(ibuf);
1355     ibuf->mall |= IB_rect;
1356     ibuf->rect = (unsigned int *)_newrect;
1357   }
1358   if (do_float) {
1359     imb_freerectfloatImBuf(ibuf);
1360     ibuf->mall |= IB_rectfloat;
1361     ibuf->rect_float = (float *)_newrectf;
1362   }
1363
1364   ibuf->x = newx;
1365   return (ibuf);
1366 }
1367
1368 static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
1369 {
1370   uchar *rect, *_newrect = NULL, *newrect;
1371   float *rectf, *_newrectf = NULL, *newrectf;
1372   float sample, add;
1373   float val_a, nval_a, diff_a;
1374   float val_b, nval_b, diff_b;
1375   float val_g, nval_g, diff_g;
1376   float val_r, nval_r, diff_r;
1377   float val_af, nval_af, diff_af;
1378   float val_bf, nval_bf, diff_bf;
1379   float val_gf, nval_gf, diff_gf;
1380   float val_rf, nval_rf, diff_rf;
1381   int x, y, skipx;
1382   bool do_rect = false, do_float = false;
1383
1384   val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
1385   val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
1386   val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
1387   val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
1388   if (ibuf == NULL) {
1389     return (NULL);
1390   }
1391   if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
1392     return (ibuf);
1393   }
1394
1395   if (ibuf->rect) {
1396     do_rect = true;
1397     _newrect = MEM_mallocN(ibuf->x * newy * sizeof(int), "scaleupy");
1398     if (_newrect == NULL) {
1399       return (ibuf);
1400     }
1401   }
1402   if (ibuf->rect_float) {
1403     do_float = true;
1404     _newrectf = MEM_mallocN(ibuf->x * newy * sizeof(float) * 4, "scaleupyf");
1405     if (_newrectf == NULL) {
1406       if (_newrect) {
1407         MEM_freeN(_newrect);
1408       }
1409       return (ibuf);
1410     }
1411   }
1412
1413   add = (ibuf->y - 1.001) / (newy - 1.0);
1414   skipx = 4 * ibuf->x;
1415
1416   rect = (uchar *)ibuf->rect;
1417   rectf = (float *)ibuf->rect_float;
1418   newrect = _newrect;
1419   newrectf = _newrectf;
1420
1421   for (x = ibuf->x; x > 0; x--) {
1422
1423     sample = 0;
1424     if (do_rect) {
1425       rect = ((uchar *)ibuf->rect) + 4 * (x - 1);
1426       newrect = _newrect + 4 * (x - 1);
1427
1428       val_a = rect[0];
1429       nval_a = rect[skipx];
1430       diff_a = nval_a - val_a;
1431       val_a += 0.5f;
1432
1433       val_b = rect[1];
1434       nval_b = rect[skipx + 1];
1435       diff_b = nval_b - val_b;
1436       val_b += 0.5f;
1437
1438       val_g = rect[2];
1439       nval_g = rect[skipx + 2];
1440       diff_g = nval_g - val_g;
1441       val_g += 0.5f;
1442
1443       val_r = rect[3];
1444       nval_r = rect[skipx + 3];
1445       diff_r = nval_r - val_r;
1446       val_r += 0.5f;
1447
1448       rect += 2 * skipx;
1449     }
1450     if (do_float) {
1451       rectf = ibuf->rect_float + 4 * (x - 1);
1452       newrectf = _newrectf + 4 * (x - 1);
1453
1454       val_af = rectf[0];
1455       nval_af = rectf[skipx];
1456       diff_af = nval_af - val_af;
1457
1458       val_bf = rectf[1];
1459       nval_bf = rectf[skipx + 1];
1460       diff_bf = nval_bf - val_bf;
1461
1462       val_gf = rectf[2];
1463       nval_gf = rectf[skipx + 2];
1464       diff_gf = nval_gf - val_gf;
1465
1466       val_rf = rectf[3];
1467       nval_rf = rectf[skipx + 3];
1468       diff_rf = nval_rf - val_rf;
1469
1470       rectf += 2 * skipx;
1471     }
1472
1473     for (y = newy; y > 0; y--) {
1474       if (sample >= 1.0f) {
1475         sample -= 1.0f;
1476
1477         if (do_rect) {
1478           val_a = nval_a;
1479           nval_a = rect[0];
1480           diff_a = nval_a - val_a;
1481           val_a += 0.5f;
1482
1483           val_b = nval_b;
1484           nval_b = rect[1];
1485           diff_b = nval_b - val_b;
1486           val_b += 0.5f;
1487
1488           val_g = nval_g;
1489           nval_g = rect[2];
1490           diff_g = nval_g - val_g;
1491           val_g += 0.5f;
1492
1493           val_r = nval_r;
1494           nval_r = rect[3];
1495           diff_r = nval_r - val_r;
1496           val_r += 0.5f;
1497           rect += skipx;
1498         }
1499         if (do_float) {
1500           val_af = nval_af;
1501           nval_af = rectf[0];
1502           diff_af = nval_af - val_af;
1503
1504           val_bf = nval_bf;
1505           nval_bf = rectf[1];
1506           diff_bf = nval_bf - val_bf;
1507
1508           val_gf = nval_gf;
1509           nval_gf = rectf[2];
1510           diff_gf = nval_gf - val_gf;
1511
1512           val_rf = nval_rf;
1513           nval_rf = rectf[3];
1514           diff_rf = nval_rf - val_rf;
1515           rectf += skipx;
1516         }
1517       }
1518       if (do_rect) {
1519         newrect[0] = val_a + sample * diff_a;
1520         newrect[1] = val_b + sample * diff_b;
1521         newrect[2] = val_g + sample * diff_g;
1522         newrect[3] = val_r + sample * diff_r;
1523         newrect += skipx;
1524       }
1525       if (do_float) {
1526         newrectf[0] = val_af + sample * diff_af;
1527         newrectf[1] = val_bf + sample * diff_bf;
1528         newrectf[2] = val_gf + sample * diff_gf;
1529         newrectf[3] = val_rf + sample * diff_rf;
1530         newrectf += skipx;
1531       }
1532       sample += add;
1533     }
1534   }
1535
1536   if (do_rect) {
1537     imb_freerectImBuf(ibuf);
1538     ibuf->mall |= IB_rect;
1539     ibuf->rect = (unsigned int *)_newrect;
1540   }
1541   if (do_float) {
1542     imb_freerectfloatImBuf(ibuf);
1543     ibuf->mall |= IB_rectfloat;
1544     ibuf->rect_float = (float *)_newrectf;
1545   }
1546
1547   ibuf->y = newy;
1548   return (ibuf);
1549 }
1550
1551 static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy)
1552 {
1553   int *zbuf, *newzbuf, *_newzbuf = NULL;
1554   float *zbuf_float, *newzbuf_float, *_newzbuf_float = NULL;
1555   int x, y;
1556   int ofsx, ofsy, stepx, stepy;
1557
1558   if (ibuf->zbuf) {
1559     _newzbuf = MEM_mallocN(newx * newy * sizeof(int), __func__);
1560     if (_newzbuf == NULL) {
1561       IMB_freezbufImBuf(ibuf);
1562     }
1563   }
1564
1565   if (ibuf->zbuf_float) {
1566     _newzbuf_float = MEM_mallocN((size_t)newx * newy * sizeof(float), __func__);
1567     if (_newzbuf_float == NULL) {
1568       IMB_freezbuffloatImBuf(ibuf);
1569     }
1570   }
1571
1572   if (!_newzbuf && !_newzbuf_float) {
1573     return;
1574   }
1575
1576   stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5;
1577   stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5;
1578   ofsy = 32768;
1579
1580   newzbuf = _newzbuf;
1581   newzbuf_float = _newzbuf_float;
1582
1583   for (y = newy; y > 0; y--, ofsy += stepy) {
1584     if (newzbuf) {
1585       zbuf = ibuf->zbuf;
1586       zbuf += (ofsy >> 16) * ibuf->x;
1587       ofsx = 32768;
1588       for (x = newx; x > 0; x--, ofsx += stepx) {
1589         *newzbuf++ = zbuf[ofsx >> 16];
1590       }
1591     }
1592
1593     if (newzbuf_float) {
1594       zbuf_float = ibuf->zbuf_float;
1595       zbuf_float += (ofsy >> 16) * ibuf->x;
1596       ofsx = 32768;
1597       for (x = newx; x > 0; x--, ofsx += stepx) {
1598         *newzbuf_float++ = zbuf_float[ofsx >> 16];
1599       }
1600     }
1601   }
1602
1603   if (_newzbuf) {
1604     IMB_freezbufImBuf(ibuf);
1605     ibuf->mall |= IB_zbuf;
1606     ibuf->zbuf = _newzbuf;
1607   }
1608
1609   if (_newzbuf_float) {
1610     IMB_freezbuffloatImBuf(ibuf);
1611     ibuf->mall |= IB_zbuffloat;
1612     ibuf->zbuf_float = _newzbuf_float;
1613   }
1614 }
1615
1616 /**
1617  * Return true if \a ibuf is modified.
1618  */
1619 bool IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
1620 {
1621   if (ibuf == NULL) {
1622     return false;
1623   }
1624   if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
1625     return false;
1626   }
1627
1628   if (newx == ibuf->x && newy == ibuf->y) {
1629     return false;
1630   }
1631
1632   /* Scale-up / scale-down functions below change ibuf->x and ibuf->y
1633    * so we first scale the Z-buffer (if any). */
1634   scalefast_Z_ImBuf(ibuf, newx, newy);
1635
1636   /* try to scale common cases in a fast way */
1637   /* disabled, quality loss is unacceptable, see report #18609  (ton) */
1638   if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) {
1639     return true;
1640   }
1641
1642   if (newx && (newx < ibuf->x)) {
1643     scaledownx(ibuf, newx);
1644   }
1645   if (newy && (newy < ibuf->y)) {
1646     scaledowny(ibuf, newy);
1647   }
1648   if (newx && (newx > ibuf->x)) {
1649     scaleupx(ibuf, newx);
1650   }
1651   if (newy && (newy > ibuf->y)) {
1652     scaleupy(ibuf, newy);
1653   }
1654
1655   return true;
1656 }
1657
1658 struct imbufRGBA {
1659   float r, g, b, a;
1660 };
1661
1662 /**
1663  * Return true if \a ibuf is modified.
1664  */
1665 bool IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
1666 {
1667   unsigned int *rect, *_newrect, *newrect;
1668   struct imbufRGBA *rectf, *_newrectf, *newrectf;
1669   int x, y;
1670   bool do_float = false, do_rect = false;
1671   size_t ofsx, ofsy, stepx, stepy;
1672
1673   rect = NULL;
1674   _newrect = NULL;
1675   newrect = NULL;
1676   rectf = NULL;
1677   _newrectf = NULL;
1678   newrectf = NULL;
1679
1680   if (ibuf == NULL) {
1681     return false;
1682   }
1683   if (ibuf->rect) {
1684     do_rect = true;
1685   }
1686   if (ibuf->rect_float) {
1687     do_float = true;
1688   }
1689   if (do_rect == false && do_float == false) {
1690     return false;
1691   }
1692
1693   if (newx == ibuf->x && newy == ibuf->y) {
1694     return false;
1695   }
1696
1697   if (do_rect) {
1698     _newrect = MEM_mallocN(newx * newy * sizeof(int), "scalefastimbuf");
1699     if (_newrect == NULL) {
1700       return false;
1701     }
1702     newrect = _newrect;
1703   }
1704
1705   if (do_float) {
1706     _newrectf = MEM_mallocN(newx * newy * sizeof(float) * 4, "scalefastimbuf f");
1707     if (_newrectf == NULL) {
1708       if (_newrect) {
1709         MEM_freeN(_newrect);
1710       }
1711       return false;
1712     }
1713     newrectf = _newrectf;
1714   }
1715
1716   stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5;
1717   stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5;
1718   ofsy = 32768;
1719
1720   for (y = newy; y > 0; y--, ofsy += stepy) {
1721     if (do_rect) {
1722       rect = ibuf->rect;
1723       rect += (ofsy >> 16) * ibuf->x;
1724       ofsx = 32768;
1725
1726       for (x = newx; x > 0; x--, ofsx += stepx) {
1727         *newrect++ = rect[ofsx >> 16];
1728       }
1729     }
1730
1731     if (do_float) {
1732       rectf = (struct imbufRGBA *)ibuf->rect_float;
1733       rectf += (ofsy >> 16) * ibuf->x;
1734       ofsx = 32768;
1735
1736       for (x = newx; x > 0; x--, ofsx += stepx) {
1737         *newrectf++ = rectf[ofsx >> 16];
1738       }
1739     }
1740   }
1741
1742   if (do_rect) {
1743     imb_freerectImBuf(ibuf);
1744     ibuf->mall |= IB_rect;
1745     ibuf->rect = _newrect;
1746   }
1747
1748   if (do_float) {
1749     imb_freerectfloatImBuf(ibuf);
1750     ibuf->mall |= IB_rectfloat;
1751     ibuf->rect_float = (float *)_newrectf;
1752   }
1753
1754   scalefast_Z_ImBuf(ibuf, newx, newy);
1755
1756   ibuf->x = newx;
1757   ibuf->y = newy;
1758   return true;
1759 }
1760
1761 /* ******** threaded scaling ******** */
1762
1763 typedef struct ScaleTreadInitData {
1764   ImBuf *ibuf;
1765
1766   unsigned int newx;
1767   unsigned int newy;
1768
1769   unsigned char *byte_buffer;
1770   float *float_buffer;
1771 } ScaleTreadInitData;
1772
1773 typedef struct ScaleThreadData {
1774   ImBuf *ibuf;
1775
1776   unsigned int newx;
1777   unsigned int newy;
1778
1779   int start_line;
1780   int tot_line;
1781
1782   unsigned char *byte_buffer;
1783   float *float_buffer;
1784 } ScaleThreadData;
1785
1786 static void scale_thread_init(void *data_v, int start_line, int tot_line, void *init_data_v)
1787 {
1788   ScaleThreadData *data = (ScaleThreadData *)data_v;
1789   ScaleTreadInitData *init_data = (ScaleTreadInitData *)init_data_v;
1790
1791   data->ibuf = init_data->ibuf;
1792
1793   data->newx = init_data->newx;
1794   data->newy = init_data->newy;
1795
1796   data->start_line = start_line;
1797   data->tot_line = tot_line;
1798
1799   data->byte_buffer = init_data->byte_buffer;
1800   data->float_buffer = init_data->float_buffer;
1801 }
1802
1803 static void *do_scale_thread(void *data_v)
1804 {
1805   ScaleThreadData *data = (ScaleThreadData *)data_v;
1806   ImBuf *ibuf = data->ibuf;
1807   int i;
1808   float factor_x = (float)ibuf->x / data->newx;
1809   float factor_y = (float)ibuf->y / data->newy;
1810
1811   for (i = 0; i < data->tot_line; i++) {
1812     int y = data->start_line + i;
1813     int x;
1814
1815     for (x = 0; x < data->newx; x++) {
1816       float u = (float)x * factor_x;
1817       float v = (float)y * factor_y;
1818       int offset = y * data->newx + x;
1819
1820       if (data->byte_buffer) {
1821         unsigned char *pixel = data->byte_buffer + 4 * offset;
1822         BLI_bilinear_interpolation_char(
1823             (unsigned char *)ibuf->rect, pixel, ibuf->x, ibuf->y, 4, u, v);
1824       }
1825
1826       if (data->float_buffer) {
1827         float *pixel = data->float_buffer + ibuf->channels * offset;
1828         BLI_bilinear_interpolation_fl(
1829             ibuf->rect_float, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v);
1830       }
1831     }
1832   }
1833
1834   return NULL;
1835 }
1836
1837 void IMB_scaleImBuf_threaded(ImBuf *ibuf, unsigned int newx, unsigned int newy)
1838 {
1839   ScaleTreadInitData init_data = {NULL};
1840
1841   /* prepare initialization data */
1842   init_data.ibuf = ibuf;
1843
1844   init_data.newx = newx;
1845   init_data.newy = newy;
1846
1847   if (ibuf->rect) {
1848     init_data.byte_buffer = MEM_mallocN(4 * newx * newy * sizeof(char),
1849                                         "threaded scale byte buffer");
1850   }
1851
1852   if (ibuf->rect_float) {
1853     init_data.float_buffer = MEM_mallocN(ibuf->channels * newx * newy * sizeof(float),
1854                                          "threaded scale float buffer");
1855   }
1856
1857   /* actual scaling threads */
1858   IMB_processor_apply_threaded(
1859       newy, sizeof(ScaleThreadData), &init_data, scale_thread_init, do_scale_thread);
1860
1861   /* alter image buffer */
1862   ibuf->x = newx;
1863   ibuf->y = newy;
1864
1865   if (ibuf->rect) {
1866     imb_freerectImBuf(ibuf);
1867     ibuf->mall |= IB_rect;
1868     ibuf->rect = (unsigned int *)init_data.byte_buffer;
1869   }
1870
1871   if (ibuf->rect_float) {
1872     imb_freerectfloatImBuf(ibuf);
1873     ibuf->mall |= IB_rectfloat;
1874     ibuf->rect_float = init_data.float_buffer;
1875   }
1876 }