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