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