Merged changes in the trunk up to revision 55546.
[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 "BLO_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         int 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                 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         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                 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 int 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, do_rect = FALSE, do_float = FALSE;
1134
1135         val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
1136         val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
1137         val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
1138         val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
1139         if (ibuf == NULL) return(NULL);
1140         if (ibuf->rect == NULL && ibuf->rect_float == NULL) return (ibuf);
1141
1142         if (ibuf->rect) {
1143                 do_rect = TRUE;
1144                 _newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaleupx");
1145                 if (_newrect == NULL) return(ibuf);
1146         }
1147         if (ibuf->rect_float) {
1148                 do_float = TRUE;
1149                 _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaleupxf");
1150                 if (_newrectf == NULL) {
1151                         if (_newrect) MEM_freeN(_newrect);
1152                         return(ibuf);
1153                 }
1154         }
1155
1156         add = (ibuf->x - 1.001) / (newx - 1.0);
1157
1158         rect = (uchar *) ibuf->rect;
1159         rectf = (float *) ibuf->rect_float;
1160         newrect = _newrect;
1161         newrectf = _newrectf;
1162
1163         for (y = ibuf->y; y > 0; y--) {
1164
1165                 sample = 0;
1166                 
1167                 if (do_rect) {
1168                         val_a = rect[0];
1169                         nval_a = rect[4];
1170                         diff_a = nval_a - val_a;
1171                         val_a += 0.5f;
1172
1173                         val_b = rect[1];
1174                         nval_b = rect[5];
1175                         diff_b = nval_b - val_b;
1176                         val_b += 0.5f;
1177
1178                         val_g = rect[2];
1179                         nval_g = rect[6];
1180                         diff_g = nval_g - val_g;
1181                         val_g += 0.5f;
1182
1183                         val_r = rect[3];
1184                         nval_r = rect[7];
1185                         diff_r = nval_r - val_r;
1186                         val_r += 0.5f;
1187
1188                         rect += 8;
1189                 }
1190                 if (do_float) {
1191                         val_af = rectf[0];
1192                         nval_af = rectf[4];
1193                         diff_af = nval_af - val_af;
1194         
1195                         val_bf = rectf[1];
1196                         nval_bf = rectf[5];
1197                         diff_bf = nval_bf - val_bf;
1198
1199                         val_gf = rectf[2];
1200                         nval_gf = rectf[6];
1201                         diff_gf = nval_gf - val_gf;
1202
1203                         val_rf = rectf[3];
1204                         nval_rf = rectf[7];
1205                         diff_rf = nval_rf - val_rf;
1206
1207                         rectf += 8;
1208                 }
1209                 for (x = newx; x > 0; x--) {
1210                         if (sample >= 1.0f) {
1211                                 sample -= 1.0f;
1212
1213                                 if (do_rect) {
1214                                         val_a = nval_a;
1215                                         nval_a = rect[0];
1216                                         diff_a = nval_a - val_a;
1217                                         val_a += 0.5f;
1218
1219                                         val_b = nval_b;
1220                                         nval_b = rect[1];
1221                                         diff_b = nval_b - val_b;
1222                                         val_b += 0.5f;
1223
1224                                         val_g = nval_g;
1225                                         nval_g = rect[2];
1226                                         diff_g = nval_g - val_g;
1227                                         val_g += 0.5f;
1228
1229                                         val_r = nval_r;
1230                                         nval_r = rect[3];
1231                                         diff_r = nval_r - val_r;
1232                                         val_r += 0.5f;
1233                                         rect += 4;
1234                                 }
1235                                 if (do_float) {
1236                                         val_af = nval_af;
1237                                         nval_af = rectf[0];
1238                                         diff_af = nval_af - val_af;
1239         
1240                                         val_bf = nval_bf;
1241                                         nval_bf = rectf[1];
1242                                         diff_bf = nval_bf - val_bf;
1243
1244                                         val_gf = nval_gf;
1245                                         nval_gf = rectf[2];
1246                                         diff_gf = nval_gf - val_gf;
1247
1248                                         val_rf = nval_rf;
1249                                         nval_rf = rectf[3];
1250                                         diff_rf = nval_rf - val_rf;
1251                                         rectf += 4;
1252                                 }
1253                         }
1254                         if (do_rect) {
1255                                 newrect[0] = val_a + sample * diff_a;
1256                                 newrect[1] = val_b + sample * diff_b;
1257                                 newrect[2] = val_g + sample * diff_g;
1258                                 newrect[3] = val_r + sample * diff_r;
1259                                 newrect += 4;
1260                         }
1261                         if (do_float) {
1262                                 newrectf[0] = val_af + sample * diff_af;
1263                                 newrectf[1] = val_bf + sample * diff_bf;
1264                                 newrectf[2] = val_gf + sample * diff_gf;
1265                                 newrectf[3] = val_rf + sample * diff_rf;
1266                                 newrectf += 4;
1267                         }
1268                         sample += add;
1269                 }
1270         }
1271
1272         if (do_rect) {
1273                 imb_freerectImBuf(ibuf);
1274                 ibuf->mall |= IB_rect;
1275                 ibuf->rect = (unsigned int *) _newrect;
1276         }
1277         if (do_float) {
1278                 imb_freerectfloatImBuf(ibuf);
1279                 ibuf->mall |= IB_rectfloat;
1280                 ibuf->rect_float = (float *) _newrectf;
1281         }
1282         
1283         ibuf->x = newx;
1284         return(ibuf);
1285 }
1286
1287 static ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
1288 {
1289         uchar *rect, *_newrect = NULL, *newrect;
1290         float *rectf, *_newrectf = NULL, *newrectf;
1291         float sample, add;
1292         float val_a, nval_a, diff_a;
1293         float val_b, nval_b, diff_b;
1294         float val_g, nval_g, diff_g;
1295         float val_r, nval_r, diff_r;
1296         float val_af, nval_af, diff_af;
1297         float val_bf, nval_bf, diff_bf;
1298         float val_gf, nval_gf, diff_gf;
1299         float val_rf, nval_rf, diff_rf;
1300         int x, y, do_rect = FALSE, do_float = FALSE, skipx;
1301
1302         val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0;
1303         val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0;
1304         val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0;
1305         val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0;
1306         if (ibuf == NULL) return(NULL);
1307         if (ibuf->rect == NULL && ibuf->rect_float == NULL) return (ibuf);
1308
1309         if (ibuf->rect) {
1310                 do_rect = TRUE;
1311                 _newrect = MEM_mallocN(ibuf->x * newy * sizeof(int), "scaleupy");
1312                 if (_newrect == NULL) return(ibuf);
1313         }
1314         if (ibuf->rect_float) {
1315                 do_float = TRUE;
1316                 _newrectf = MEM_mallocN(ibuf->x * newy * sizeof(float) * 4, "scaleupyf");
1317                 if (_newrectf == NULL) {
1318                         if (_newrect) MEM_freeN(_newrect);
1319                         return(ibuf);
1320                 }
1321         }
1322
1323         add = (ibuf->y - 1.001) / (newy - 1.0);
1324         skipx = 4 * ibuf->x;
1325
1326         rect = (uchar *) ibuf->rect;
1327         rectf = (float *) ibuf->rect_float;
1328         newrect = _newrect;
1329         newrectf = _newrectf;
1330
1331         for (x = ibuf->x; x > 0; x--) {
1332
1333                 sample = 0;
1334                 if (do_rect) {
1335                         rect = ((uchar *)ibuf->rect) + 4 * (x - 1);
1336                         newrect = _newrect + 4 * (x - 1);
1337
1338                         val_a = rect[0];
1339                         nval_a = rect[skipx];
1340                         diff_a = nval_a - val_a;
1341                         val_a += 0.5f;
1342
1343                         val_b = rect[1];
1344                         nval_b = rect[skipx + 1];
1345                         diff_b = nval_b - val_b;
1346                         val_b += 0.5f;
1347
1348                         val_g = rect[2];
1349                         nval_g = rect[skipx + 2];
1350                         diff_g = nval_g - val_g;
1351                         val_g += 0.5f;
1352
1353                         val_r = rect[3];
1354                         nval_r = rect[skipx + 4];
1355                         diff_r = nval_r - val_r;
1356                         val_r += 0.5f;
1357
1358                         rect += 2 * skipx;
1359                 }
1360                 if (do_float) {
1361                         rectf = ibuf->rect_float + 4 * (x - 1);
1362                         newrectf = _newrectf + 4 * (x - 1);
1363
1364                         val_af = rectf[0];
1365                         nval_af = rectf[skipx];
1366                         diff_af = nval_af - val_af;
1367         
1368                         val_bf = rectf[1];
1369                         nval_bf = rectf[skipx + 1];
1370                         diff_bf = nval_bf - val_bf;
1371
1372                         val_gf = rectf[2];
1373                         nval_gf = rectf[skipx + 2];
1374                         diff_gf = nval_gf - val_gf;
1375
1376                         val_rf = rectf[3];
1377                         nval_rf = rectf[skipx + 3];
1378                         diff_rf = nval_rf - val_rf;
1379
1380                         rectf += 2 * skipx;
1381                 }
1382                 
1383                 for (y = newy; y > 0; y--) {
1384                         if (sample >= 1.0f) {
1385                                 sample -= 1.0f;
1386
1387                                 if (do_rect) {
1388                                         val_a = nval_a;
1389                                         nval_a = rect[0];
1390                                         diff_a = nval_a - val_a;
1391                                         val_a += 0.5f;
1392
1393                                         val_b = nval_b;
1394                                         nval_b = rect[1];
1395                                         diff_b = nval_b - val_b;
1396                                         val_b += 0.5f;
1397
1398                                         val_g = nval_g;
1399                                         nval_g = rect[2];
1400                                         diff_g = nval_g - val_g;
1401                                         val_g += 0.5f;
1402
1403                                         val_r = nval_r;
1404                                         nval_r = rect[3];
1405                                         diff_r = nval_r - val_r;
1406                                         val_r += 0.5f;
1407                                         rect += skipx;
1408                                 }
1409                                 if (do_float) {
1410                                         val_af = nval_af;
1411                                         nval_af = rectf[0];
1412                                         diff_af = nval_af - val_af;
1413         
1414                                         val_bf = nval_bf;
1415                                         nval_bf = rectf[1];
1416                                         diff_bf = nval_bf - val_bf;
1417
1418                                         val_gf = nval_gf;
1419                                         nval_gf = rectf[2];
1420                                         diff_gf = nval_gf - val_gf;
1421
1422                                         val_rf = nval_rf;
1423                                         nval_rf = rectf[3];
1424                                         diff_rf = nval_rf - val_rf;
1425                                         rectf += skipx;
1426                                 }
1427                         }
1428                         if (do_rect) {
1429                                 newrect[0] = val_a + sample * diff_a;
1430                                 newrect[1] = val_b + sample * diff_b;
1431                                 newrect[2] = val_g + sample * diff_g;
1432                                 newrect[3] = val_r + sample * diff_r;
1433                                 newrect += skipx;
1434                         }
1435                         if (do_float) {
1436                                 newrectf[0] = val_af + sample * diff_af;
1437                                 newrectf[1] = val_bf + sample * diff_bf;
1438                                 newrectf[2] = val_gf + sample * diff_gf;
1439                                 newrectf[3] = val_rf + sample * diff_rf;
1440                                 newrectf += skipx;
1441                         }
1442                         sample += add;
1443                 }
1444         }
1445
1446         if (do_rect) {
1447                 imb_freerectImBuf(ibuf);
1448                 ibuf->mall |= IB_rect;
1449                 ibuf->rect = (unsigned int *) _newrect;
1450         }
1451         if (do_float) {
1452                 imb_freerectfloatImBuf(ibuf);
1453                 ibuf->mall |= IB_rectfloat;
1454                 ibuf->rect_float = (float *) _newrectf;
1455         }
1456         
1457         ibuf->y = newy;
1458         return(ibuf);
1459 }
1460
1461
1462 /* no float buf needed here! */
1463 static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy)
1464 {
1465         unsigned int *rect, *_newrect, *newrect;
1466         int x, y;
1467         int ofsx, ofsy, stepx, stepy;
1468
1469         if (ibuf->zbuf) {
1470                 _newrect = MEM_mallocN(newx * newy * sizeof(int), "z rect");
1471                 if (_newrect == NULL) return;
1472                 
1473                 stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5;
1474                 stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5;
1475                 ofsy = 32768;
1476
1477                 newrect = _newrect;
1478         
1479                 for (y = newy; y > 0; y--) {
1480                         rect = (unsigned int *) ibuf->zbuf;
1481                         rect += (ofsy >> 16) * ibuf->x;
1482                         ofsy += stepy;
1483                         ofsx = 32768;
1484                         for (x = newx; x > 0; x--) {
1485                                 *newrect++ = rect[ofsx >> 16];
1486                                 ofsx += stepx;
1487                         }
1488                 }
1489         
1490                 IMB_freezbufImBuf(ibuf);
1491                 ibuf->mall |= IB_zbuf;
1492                 ibuf->zbuf = (int *) _newrect;
1493         }
1494 }
1495
1496 struct ImBuf *IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
1497 {
1498         if (ibuf == NULL) return (NULL);
1499         if (ibuf->rect == NULL && ibuf->rect_float == NULL) return (ibuf);
1500         
1501         if (newx == ibuf->x && newy == ibuf->y) { return ibuf; }
1502
1503         /* scaleup / scaledown functions below change ibuf->x and ibuf->y
1504          * so we first scale the Z-buffer (if any) */
1505         scalefast_Z_ImBuf(ibuf, newx, newy);
1506
1507         /* try to scale common cases in a fast way */
1508         /* disabled, quality loss is unacceptable, see report #18609  (ton) */
1509         if (0 && q_scale_linear_interpolation(ibuf, newx, newy)) {
1510                 return ibuf;
1511         }
1512
1513         if (newx && (newx < ibuf->x)) scaledownx(ibuf, newx);
1514         if (newy && (newy < ibuf->y)) scaledowny(ibuf, newy);
1515         if (newx && (newx > ibuf->x)) scaleupx(ibuf, newx);
1516         if (newy && (newy > ibuf->y)) scaleupy(ibuf, newy);
1517         
1518         return(ibuf);
1519 }
1520
1521 struct imbufRGBA {
1522         float r, g, b, a;
1523 };
1524
1525 struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
1526 {
1527         unsigned int *rect, *_newrect, *newrect;
1528         struct imbufRGBA *rectf, *_newrectf, *newrectf;
1529         int x, y, do_float = FALSE, do_rect = FALSE;
1530         int ofsx, ofsy, stepx, stepy;
1531
1532         rect = NULL; _newrect = NULL; newrect = NULL;
1533         rectf = NULL; _newrectf = NULL; newrectf = NULL;
1534
1535         if (ibuf == NULL) return(NULL);
1536         if (ibuf->rect) do_rect = TRUE;
1537         if (ibuf->rect_float) do_float = TRUE;
1538         if (do_rect == FALSE && do_float == FALSE) return(ibuf);
1539         
1540         if (newx == ibuf->x && newy == ibuf->y) return(ibuf);
1541         
1542         if (do_rect) {
1543                 _newrect = MEM_mallocN(newx * newy * sizeof(int), "scalefastimbuf");
1544                 if (_newrect == NULL) return(ibuf);
1545                 newrect = _newrect;
1546         }
1547         
1548         if (do_float) {
1549                 _newrectf = MEM_mallocN(newx * newy * sizeof(float) * 4, "scalefastimbuf f");
1550                 if (_newrectf == NULL) {
1551                         if (_newrect) MEM_freeN(_newrect);
1552                         return(ibuf);
1553                 }
1554                 newrectf = _newrectf;
1555         }
1556
1557         stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5;
1558         stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5;
1559         ofsy = 32768;
1560
1561         for (y = newy; y > 0; y--) {
1562                 if (do_rect) {
1563                         rect = ibuf->rect;
1564                         rect += (ofsy >> 16) * ibuf->x;
1565                 }
1566                 if (do_float) {
1567                         rectf = (struct imbufRGBA *)ibuf->rect_float;
1568                         rectf += (ofsy >> 16) * ibuf->x;
1569                 }
1570                 ofsy += stepy;
1571                 ofsx = 32768;
1572                 
1573                 if (do_rect) {
1574                         for (x = newx; x > 0; x--) {
1575                                 *newrect++ = rect[ofsx >> 16];
1576                                 ofsx += stepx;
1577                         }
1578                 }
1579
1580                 if (do_float) {
1581                         ofsx = 32768;
1582                         for (x = newx; x > 0; x--) {
1583                                 *newrectf++ = rectf[ofsx >> 16];
1584                                 ofsx += stepx;
1585                         }
1586                 }
1587         }
1588
1589         if (do_rect) {
1590                 imb_freerectImBuf(ibuf);
1591                 ibuf->mall |= IB_rect;
1592                 ibuf->rect = _newrect;
1593         }
1594         
1595         if (do_float) {
1596                 imb_freerectfloatImBuf(ibuf);
1597                 ibuf->mall |= IB_rectfloat;
1598                 ibuf->rect_float = (float *)_newrectf;
1599         }
1600         
1601         scalefast_Z_ImBuf(ibuf, newx, newy);
1602         
1603         ibuf->x = newx;
1604         ibuf->y = newy;
1605         return(ibuf);
1606 }
1607
1608 /* ******** threaded scaling ******** */
1609
1610 typedef struct ScaleTreadInitData {
1611         ImBuf *ibuf;
1612
1613         unsigned int newx;
1614         unsigned int newy;
1615
1616         unsigned char *byte_buffer;
1617         float *float_buffer;
1618 } ScaleTreadInitData;
1619
1620 typedef struct ScaleThreadData {
1621         ImBuf *ibuf;
1622
1623         unsigned int newx;
1624         unsigned int newy;
1625
1626         int start_line;
1627         int tot_line;
1628
1629         unsigned char *byte_buffer;
1630         float *float_buffer;
1631 } ScaleThreadData;
1632
1633 static void scale_thread_init(void *data_v, int start_line, int tot_line, void *init_data_v)
1634 {
1635         ScaleThreadData *data = (ScaleThreadData *) data_v;
1636         ScaleTreadInitData *init_data = (ScaleTreadInitData *) init_data_v;
1637
1638         data->ibuf = init_data->ibuf;
1639
1640         data->newx = init_data->newx;
1641         data->newy = init_data->newy;
1642
1643         data->start_line = start_line;
1644         data->tot_line = tot_line;
1645
1646         data->byte_buffer = init_data->byte_buffer;
1647         data->float_buffer = init_data->float_buffer;
1648 }
1649
1650 static void *do_scale_thread(void *data_v)
1651 {
1652         ScaleThreadData *data = (ScaleThreadData *) data_v;
1653         ImBuf *ibuf = data->ibuf;
1654         int i;
1655         float factor_x = (float) ibuf->x / data->newx;
1656         float factor_y = (float) ibuf->y / data->newy;
1657
1658         for (i = 0; i < data->tot_line; i++) {
1659                 int y = data->start_line + i;
1660                 int x;
1661
1662                 for (x = 0; x < data->newx; x++) {
1663                         float u = (float) x * factor_x;
1664                         float v = (float) y * factor_y;
1665                         int offset = y * data->newx + x;
1666
1667                         if (data->byte_buffer) {
1668                                 unsigned char *pixel = data->byte_buffer + 4 * offset;
1669                                 BLI_bilinear_interpolation_char((unsigned char *) ibuf->rect, pixel, ibuf->x, ibuf->y, 4, u, v);
1670                         }
1671
1672                         if (data->float_buffer) {
1673                                 float *pixel = data->float_buffer + ibuf->channels * offset;
1674                                 BLI_bilinear_interpolation_fl(ibuf->rect_float, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v);
1675                         }
1676                 }
1677         }
1678
1679         return NULL;
1680 }
1681
1682 void IMB_scaleImBuf_threaded(ImBuf *ibuf, unsigned int newx, unsigned int newy)
1683 {
1684         ScaleTreadInitData init_data = {NULL};
1685
1686         /* prepare initialization data */
1687         init_data.ibuf = ibuf;
1688
1689         init_data.newx = newx;
1690         init_data.newy = newy;
1691
1692         if (ibuf->rect)
1693                 init_data.byte_buffer = MEM_mallocN(4 * newx * newy * sizeof(char), "threaded scale byte buffer");
1694
1695         if (ibuf->rect_float)
1696                 init_data.float_buffer = MEM_mallocN(ibuf->channels * newx * newy * sizeof(float), "threaded scale float buffer");
1697
1698         /* actual scaling threads */
1699         IMB_processor_apply_threaded(newy, sizeof(ScaleThreadData), &init_data,
1700                                      scale_thread_init, do_scale_thread);
1701
1702         /* alter image buffer */
1703         ibuf->x = newx;
1704         ibuf->y = newy;
1705
1706         if (ibuf->rect) {
1707                 imb_freerectImBuf(ibuf);
1708                 ibuf->mall |= IB_rect;
1709                 ibuf->rect = (unsigned int *) init_data.byte_buffer;
1710         }
1711
1712         if (ibuf->rect_float) {
1713                 imb_freerectfloatImBuf(ibuf);
1714                 ibuf->mall |= IB_rectfloat;
1715                 ibuf->rect_float = init_data.float_buffer;
1716         }
1717 }