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