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