Blender  V3.3
transform.cc
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 <array>
9 #include <type_traits>
10 
11 #include "BLI_math.h"
12 #include "BLI_rect.h"
13 
14 #include "IMB_imbuf.h"
15 #include "IMB_imbuf_types.h"
16 
18 
21  const ImBuf *src;
25  float start_uv[2];
26 
31  float add_x[2];
32 
37  float add_y[2];
38 
43 
47  void init(const float transform_matrix[4][4])
48  {
49  init_start_uv(transform_matrix);
50  init_add_x(transform_matrix);
51  init_add_y(transform_matrix);
52  }
53 
54  private:
55  void init_start_uv(const float transform_matrix[4][4])
56  {
57  float start_uv_v3[3];
58  float orig[3];
59  zero_v3(orig);
60  mul_v3_m4v3(start_uv_v3, transform_matrix, orig);
61  copy_v2_v2(start_uv, start_uv_v3);
62  }
63 
64  void init_add_x(const float transform_matrix[4][4])
65  {
66  const int width = src->x;
67  float add_x_v3[3];
68  float uv_max_x[3];
69  zero_v3(uv_max_x);
70  uv_max_x[0] = width;
71  uv_max_x[1] = 0.0f;
72  mul_v3_m4v3(add_x_v3, transform_matrix, uv_max_x);
73  sub_v2_v2(add_x_v3, start_uv);
74  mul_v2_fl(add_x_v3, 1.0f / width);
75  copy_v2_v2(add_x, add_x_v3);
76  }
77 
78  void init_add_y(const float transform_matrix[4][4])
79  {
80  const int height = src->y;
81  float add_y_v3[3];
82  float uv_max_y[3];
83  zero_v3(uv_max_y);
84  uv_max_y[0] = 0.0f;
85  uv_max_y[1] = height;
86  mul_v3_m4v3(add_y_v3, transform_matrix, uv_max_y);
87  sub_v2_v2(add_y_v3, start_uv);
88  mul_v2_fl(add_y_v3, 1.0f / height);
89  copy_v2_v2(add_y, add_y_v3);
90  }
91 };
92 
100 class BaseDiscard {
101  public:
102  virtual ~BaseDiscard() = default;
103 
107  virtual bool should_discard(const TransformUserData &user_data, const float uv[2]) = 0;
108 };
109 
113 class CropSource : public BaseDiscard {
114  public:
120  bool should_discard(const TransformUserData &user_data, const float uv[2]) override
121  {
122  return uv[0] < user_data.src_crop.xmin || uv[0] >= user_data.src_crop.xmax ||
123  uv[1] < user_data.src_crop.ymin || uv[1] >= user_data.src_crop.ymax;
124  }
125 };
126 
130 class NoDiscard : public BaseDiscard {
131  public:
138  const float UNUSED(uv[2])) override
139  {
140  return false;
141  }
142 };
143 
147 template<
152  typename StorageType = float,
153 
157  int NumChannels = 4>
159  public:
160  static const int ChannelLen = NumChannels;
161 
162  private:
163  StorageType *pointer;
164 
165  public:
166  void init_pixel_pointer(const ImBuf *image_buffer, int x, int y)
167  {
168  const size_t offset = (y * (size_t)image_buffer->x + x) * NumChannels;
169 
170  if constexpr (std::is_same_v<StorageType, float>) {
171  pointer = image_buffer->rect_float + offset;
172  }
173  else if constexpr (std::is_same_v<StorageType, unsigned char>) {
174  pointer = const_cast<unsigned char *>(
175  static_cast<const unsigned char *>(static_cast<const void *>(image_buffer->rect)) +
176  offset);
177  }
178  else {
179  pointer = nullptr;
180  }
181  }
182 
186  StorageType *get_pointer()
187  {
188  return pointer;
189  }
190 
192  {
193  pointer += NumChannels;
194  }
195 };
196 
203  public:
207  virtual float modify_u(const ImBuf *source_buffer, float u) = 0;
208 
212  virtual float modify_v(const ImBuf *source_buffer, float v) = 0;
213 };
214 
219  public:
220  float modify_u(const ImBuf *UNUSED(source_buffer), float u) override
221  {
222  return u;
223  }
224 
225  float modify_v(const ImBuf *UNUSED(source_buffer), float v) override
226  {
227  return v;
228  }
229 };
230 
234 class WrapRepeatUV : public BaseUVWrapping {
235  public:
236  float modify_u(const ImBuf *source_buffer, float u) override
237 
238  {
239  int x = (int)floor(u);
240  x = x % source_buffer->x;
241  if (x < 0) {
242  x += source_buffer->x;
243  }
244  return x;
245  }
246 
247  float modify_v(const ImBuf *source_buffer, float v) override
248  {
249  int y = (int)floor(v);
250  y = y % source_buffer->y;
251  if (y < 0) {
252  y += source_buffer->y;
253  }
254  return y;
255  }
256 };
257 
264 template<
267 
269  typename StorageType,
275  int NumChannels,
281  typename UVWrapping>
282 class Sampler {
283  UVWrapping uv_wrapper;
284 
285  public:
286  using ChannelType = StorageType;
287  static const int ChannelLen = NumChannels;
288  using SampleType = std::array<StorageType, NumChannels>;
289 
290  void sample(const ImBuf *source, const float u, const float v, SampleType &r_sample)
291  {
292  if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<StorageType, float> &&
293  NumChannels == 4) {
294  const float wrapped_u = uv_wrapper.modify_u(source, u);
295  const float wrapped_v = uv_wrapper.modify_v(source, v);
296  bilinear_interpolation_color_fl(source, nullptr, r_sample.data(), wrapped_u, wrapped_v);
297  }
298  else if constexpr (Filter == IMB_FILTER_NEAREST &&
299  std::is_same_v<StorageType, unsigned char> && NumChannels == 4) {
300  const float wrapped_u = uv_wrapper.modify_u(source, u);
301  const float wrapped_v = uv_wrapper.modify_v(source, v);
302  nearest_interpolation_color_char(source, r_sample.data(), nullptr, wrapped_u, wrapped_v);
303  }
304  else if constexpr (Filter == IMB_FILTER_BILINEAR &&
305  std::is_same_v<StorageType, unsigned char> && NumChannels == 4) {
306  const float wrapped_u = uv_wrapper.modify_u(source, u);
307  const float wrapped_v = uv_wrapper.modify_v(source, v);
308  bilinear_interpolation_color_char(source, r_sample.data(), nullptr, wrapped_u, wrapped_v);
309  }
310  else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<StorageType, float>) {
311  if constexpr (std::is_same_v<UVWrapping, WrapRepeatUV>) {
313  r_sample.data(),
314  source->x,
315  source->y,
316  NumChannels,
317  u,
318  v,
319  true,
320  true);
321  }
322  else {
323  const float wrapped_u = uv_wrapper.modify_u(source, u);
324  const float wrapped_v = uv_wrapper.modify_v(source, v);
326  r_sample.data(),
327  source->x,
328  source->y,
329  NumChannels,
330  wrapped_u,
331  wrapped_v);
332  }
333  }
334  else if constexpr (Filter == IMB_FILTER_NEAREST && std::is_same_v<StorageType, float>) {
335  const float wrapped_u = uv_wrapper.modify_u(source, u);
336  const float wrapped_v = uv_wrapper.modify_v(source, v);
337  sample_nearest_float(source, wrapped_u, wrapped_v, r_sample);
338  }
339  else {
340  /* Unsupported sampler. */
342  }
343  }
344 
345  private:
346  void sample_nearest_float(const ImBuf *source,
347  const float u,
348  const float v,
349  SampleType &r_sample)
350  {
351  BLI_STATIC_ASSERT(std::is_same_v<StorageType, float>);
352 
353  /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
354  int x1 = (int)(u);
355  int y1 = (int)(v);
356 
357  /* Break when sample outside image is requested. */
358  if (x1 < 0 || x1 >= source->x || y1 < 0 || y1 >= source->y) {
359  for (int i = 0; i < NumChannels; i++) {
360  r_sample[i] = 0.0f;
361  }
362  return;
363  }
364 
365  const size_t offset = ((size_t)source->x * y1 + x1) * NumChannels;
366  const float *dataF = source->rect_float + offset;
367  for (int i = 0; i < NumChannels; i++) {
368  r_sample[i] = dataF[i];
369  }
370  }
371 };
372 
384 template<typename StorageType, int SourceNumChannels, int DestinationNumChannels>
386  public:
387  using SampleType = std::array<StorageType, SourceNumChannels>;
389 
394  void convert_and_store(const SampleType &sample, PixelType &pixel_pointer)
395  {
396  if constexpr (std::is_same_v<StorageType, unsigned char>) {
397  BLI_STATIC_ASSERT(SourceNumChannels == 4, "Unsigned chars always have 4 channels.");
398  BLI_STATIC_ASSERT(DestinationNumChannels == 4, "Unsigned chars always have 4 channels.");
399 
400  copy_v4_v4_uchar(pixel_pointer.get_pointer(), sample.data());
401  }
402  else if constexpr (std::is_same_v<StorageType, float> && SourceNumChannels == 4 &&
403  DestinationNumChannels == 4) {
404  copy_v4_v4(pixel_pointer.get_pointer(), sample.data());
405  }
406  else if constexpr (std::is_same_v<StorageType, float> && SourceNumChannels == 3 &&
407  DestinationNumChannels == 4) {
408  copy_v4_fl4(pixel_pointer.get_pointer(), sample[0], sample[1], sample[2], 1.0f);
409  }
410  else if constexpr (std::is_same_v<StorageType, float> && SourceNumChannels == 2 &&
411  DestinationNumChannels == 4) {
412  copy_v4_fl4(pixel_pointer.get_pointer(), sample[0], sample[1], 0.0f, 1.0f);
413  }
414  else if constexpr (std::is_same_v<StorageType, float> && SourceNumChannels == 1 &&
415  DestinationNumChannels == 4) {
416  copy_v4_fl4(pixel_pointer.get_pointer(), sample[0], sample[0], sample[0], 1.0f);
417  }
418  else {
420  }
421  }
422 };
423 
427 template<
433  typename Discard,
434 
438  typename Sampler,
439 
444  typename OutputPixelPointer>
446  Discard discarder;
447  OutputPixelPointer output;
448  Sampler sampler;
449 
456  OutputPixelPointer::ChannelLen>
457  channel_converter;
458 
459  public:
463  void process(const TransformUserData *user_data, int scanline)
464  {
465  const int width = user_data->dst->x;
466 
467  float uv[2];
468  madd_v2_v2v2fl(uv, user_data->start_uv, user_data->add_y, scanline);
469 
470  output.init_pixel_pointer(user_data->dst, 0, scanline);
471  for (int xi = 0; xi < width; xi++) {
472  if (!discarder.should_discard(*user_data, uv)) {
473  typename Sampler::SampleType sample;
474  sampler.sample(user_data->src, uv[0], uv[1], sample);
475  channel_converter.convert_and_store(sample, output);
476  }
477 
478  add_v2_v2(uv, user_data->add_x);
479  output.increase_pixel_pointer();
480  }
481  }
482 };
483 
487 template<typename Processor> void transform_scanline_function(void *custom_data, int scanline)
488 {
489  const TransformUserData *user_data = static_cast<const TransformUserData *>(custom_data);
490  Processor processor;
491  processor.process(user_data, scanline);
492 }
493 
494 template<eIMBInterpolationFilterMode Filter,
495  typename StorageType,
496  int SourceNumChannels,
497  int DestinationNumChannels>
499 
500 {
501  switch (mode) {
517  }
518 
520  return nullptr;
521 }
522 
523 template<eIMBInterpolationFilterMode Filter>
525  const eIMBTransformMode mode)
526 {
527  const ImBuf *src = user_data->src;
528  const ImBuf *dst = user_data->dst;
529 
530  if (src->channels == 4 && dst->channels == 4) {
531  return get_scanline_function<Filter, float, 4, 4>(mode);
532  }
533  if (src->channels == 3 && dst->channels == 4) {
534  return get_scanline_function<Filter, float, 3, 4>(mode);
535  }
536  if (src->channels == 2 && dst->channels == 4) {
537  return get_scanline_function<Filter, float, 2, 4>(mode);
538  }
539  if (src->channels == 1 && dst->channels == 4) {
540  return get_scanline_function<Filter, float, 1, 4>(mode);
541  }
542  return nullptr;
543 }
544 
545 template<eIMBInterpolationFilterMode Filter>
547 {
548  ScanlineThreadFunc scanline_func = nullptr;
549 
550  if (user_data->dst->rect_float && user_data->src->rect_float) {
551  scanline_func = get_scanline_function<Filter>(user_data, mode);
552  }
553  else if (user_data->dst->rect && user_data->src->rect) {
554  /* Number of channels is always 4 when using unsigned char buffers (sRGB + straight alpha). */
555  scanline_func = get_scanline_function<Filter, unsigned char, 4, 4>(mode);
556  }
557 
558  if (scanline_func != nullptr) {
560  }
561 }
562 
563 } // namespace blender::imbuf::transform
564 
565 extern "C" {
566 
567 using namespace blender::imbuf::transform;
568 
569 void IMB_transform(const struct ImBuf *src,
570  struct ImBuf *dst,
571  const eIMBTransformMode mode,
573  const float transform_matrix[4][4],
574  const struct rctf *src_crop)
575 {
576  BLI_assert_msg(mode != IMB_TRANSFORM_MODE_CROP_SRC || src_crop != nullptr,
577  "No source crop rect given, but crop source is requested. Or source crop rect "
578  "was given, but crop source was not requested.");
579 
581  user_data.src = src;
582  user_data.dst = dst;
583  if (mode == IMB_TRANSFORM_MODE_CROP_SRC) {
584  user_data.src_crop = *src_crop;
585  }
586  user_data.init(transform_matrix);
587 
588  if (filter == IMB_FILTER_NEAREST) {
589  transform_threaded<IMB_FILTER_NEAREST>(&user_data, mode);
590  }
591  else {
592  transform_threaded<IMB_FILTER_BILINEAR>(&user_data, mode);
593  }
594 }
595 }
typedef float(TangentPoint)[2]
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_STATIC_ASSERT(a, msg)
Definition: BLI_assert.h:83
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
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_wrap_fl(const float *buffer, float *output, int width, int height, int components, float u, float v, bool wrap_x, bool wrap_y)
Definition: math_interp.c:464
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
MINLINE void sub_v2_v2(float r[2], const float a[2])
MINLINE void copy_v4_v4_uchar(unsigned char r[4], const unsigned char a[4])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE void zero_v3(float r[3])
#define UNUSED(x)
_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 y1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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
_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 width
void bilinear_interpolation_color_fl(const struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
eIMBTransformMode
Transform modes to use for IMB_transform function.
Definition: IMB_imbuf.h:892
@ IMB_TRANSFORM_MODE_WRAP_REPEAT
Wrap repeat the source buffer. Only supported in with nearest filtering.
Definition: IMB_imbuf.h:898
@ IMB_TRANSFORM_MODE_REGULAR
Do not crop or repeat.
Definition: IMB_imbuf.h:894
@ IMB_TRANSFORM_MODE_CROP_SRC
Crop the source buffer.
Definition: IMB_imbuf.h:896
void IMB_processor_apply_threaded_scanlines(int total_scanlines, ScanlineThreadFunc do_thread, void *custom_data)
Definition: imageprocess.c:415
void bilinear_interpolation_color_char(const struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
void(* ScanlineThreadFunc)(void *custom_data, int scanline)
Definition: IMB_imbuf.h:882
eIMBInterpolationFilterMode
Definition: IMB_imbuf.h:349
@ IMB_FILTER_NEAREST
Definition: IMB_imbuf.h:350
@ IMB_FILTER_BILINEAR
Definition: IMB_imbuf.h:351
void nearest_interpolation_color_char(const struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
Contains defines and structs used throughout the imbuf module.
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define output
Base class for source discarding.
Definition: transform.cc:100
virtual bool should_discard(const TransformUserData &user_data, const float uv[2])=0
Should the source pixel at the given uv coordinate be discarded.
Wrapping mode for the uv coordinates.
Definition: transform.cc:202
virtual float modify_v(const ImBuf *source_buffer, float v)=0
modify the given v coordinate.
virtual float modify_u(const ImBuf *source_buffer, float u)=0
modify the given u coordinate.
Change the number of channels and store it.
Definition: transform.cc:385
std::array< StorageType, SourceNumChannels > SampleType
Definition: transform.cc:387
void convert_and_store(const SampleType &sample, PixelType &pixel_pointer)
Convert the number of channels of the given sample to match the pixel pointer and store it at the loc...
Definition: transform.cc:394
Crop uv-coordinates that are outside the user data src_crop rect.
Definition: transform.cc:113
bool should_discard(const TransformUserData &user_data, const float uv[2]) override
Should the source pixel at the given uv coordinate be discarded.
Definition: transform.cc:120
Discard that does not discard anything.
Definition: transform.cc:130
bool should_discard(const TransformUserData &UNUSED(user_data), const float UNUSED(uv[2])) override
Should the source pixel at the given uv coordinate be discarded.
Definition: transform.cc:137
UVWrapping method that does not modify the UV coordinates.
Definition: transform.cc:218
float modify_v(const ImBuf *UNUSED(source_buffer), float v) override
Definition: transform.cc:225
float modify_u(const ImBuf *UNUSED(source_buffer), float u) override
Definition: transform.cc:220
Pointer to a pixel to write to in serial.
Definition: transform.cc:158
StorageType * get_pointer()
Get pointer to the current pixel to write to.
Definition: transform.cc:186
void init_pixel_pointer(const ImBuf *image_buffer, int x, int y)
Definition: transform.cc:166
Read a sample from an image buffer.
Definition: transform.cc:282
void sample(const ImBuf *source, const float u, const float v, SampleType &r_sample)
Definition: transform.cc:290
std::array< StorageType, NumChannels > SampleType
Definition: transform.cc:288
void process(const TransformUserData *user_data, int scanline)
Inner loop of the transformations, processing a full scanline.
Definition: transform.cc:463
UVWrapping method that wrap repeats the UV coordinates.
Definition: transform.cc:234
float modify_v(const ImBuf *source_buffer, float v) override
modify the given v coordinate.
Definition: transform.cc:247
float modify_u(const ImBuf *source_buffer, float u) override
modify the given u coordinate.
Definition: transform.cc:236
void * user_data
SyclQueue void void * src
depth_tx sampler(1, ImageType::FLOAT_2D, "combined_tx") .sampler(2
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void transform_scanline_function(void *custom_data, int scanline)
callback function for threaded transformation.
Definition: transform.cc:487
ScanlineThreadFunc get_scanline_function(const eIMBTransformMode mode)
Definition: transform.cc:498
static void transform_threaded(TransformUserData *user_data, const eIMBTransformMode mode)
Definition: transform.cc:546
T floor(const T &a)
int channels
unsigned int * rect
float * rect_float
float add_y[2]
delta UV coordinate along the source image buffer, when moving a single pixel in the Y axes of the ds...
Definition: transform.cc:37
float start_uv[2]
UV coordinates at the origin (0,0) in source image space.
Definition: transform.cc:25
rctf src_crop
Cropping region in source image pixel space.
Definition: transform.cc:42
const ImBuf * src
Source image buffer to read from.
Definition: transform.cc:21
ImBuf * dst
Destination image buffer to write to.
Definition: transform.cc:23
void init(const float transform_matrix[4][4])
Initialize the start_uv, add_x and add_y fields based on the given transform matrix.
Definition: transform.cc:47
float add_x[2]
delta UV coordinates along the source image buffer, when moving a single pixel in the X axis of the d...
Definition: transform.cc:31
void IMB_transform(const struct ImBuf *src, struct ImBuf *dst, const eIMBTransformMode mode, const eIMBInterpolationFilterMode filter, const float transform_matrix[4][4], const struct rctf *src_crop)
Transform source image buffer onto destination image buffer using a transform matrix.
Definition: transform.cc:569