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