ImBuf: Use vector types in transform.cc.

Replace array types with the vector types. No functional changes.
This commit is contained in:
Jeroen Bakker 2023-01-26 09:56:32 +01:00
parent f7dd7d5454
commit 6d79bc0073
1 changed files with 48 additions and 59 deletions

View File

@ -9,6 +9,7 @@
#include <type_traits>
#include "BLI_math.h"
#include "BLI_math_vector.hh"
#include "BLI_rect.h"
#include "IMB_imbuf.h"
@ -22,19 +23,19 @@ struct TransformUserData {
/** \brief Destination image buffer to write to. */
ImBuf *dst;
/** \brief UV coordinates at the origin (0,0) in source image space. */
double start_uv[2];
double2 start_uv;
/**
* \brief delta UV coordinates along the source image buffer, when moving a single pixel in the X
* axis of the dst image buffer.
*/
double add_x[2];
double2 add_x;
/**
* \brief delta UV coordinate along the source image buffer, when moving a single pixel in the Y
* axes of the dst image buffer.
*/
double add_y[2];
double2 add_y;
/**
* \brief Cropping region in source image pixel space.
@ -54,45 +55,33 @@ struct TransformUserData {
private:
void init_start_uv(const float transform_matrix[4][4])
{
double start_uv_v3[3];
double orig[3];
double3 start_uv_v3;
double3 orig(0.0);
double transform_matrix_double[4][4];
copy_m4d_m4(transform_matrix_double, transform_matrix);
zero_v3_db(orig);
mul_v3_m4v3_db(start_uv_v3, transform_matrix_double, orig);
copy_v2_v2_db(start_uv, start_uv_v3);
start_uv = double2(start_uv_v3);
}
void init_add_x(const float transform_matrix[4][4])
{
double transform_matrix_double[4][4];
copy_m4d_m4(transform_matrix_double, transform_matrix);
const int width = src->x;
double add_x_v3[3];
double uv_max_x[3];
zero_v3_db(uv_max_x);
uv_max_x[0] = width;
uv_max_x[1] = 0.0f;
mul_v3_m4v3_db(add_x_v3, transform_matrix_double, uv_max_x);
sub_v2_v2_db(add_x_v3, start_uv);
mul_v3db_db(add_x_v3, 1.0f / width);
copy_v2_v2_db(add_x, add_x_v3);
const double width = src->x;
double3 add_x_v3;
mul_v3_m4v3_db(add_x_v3, transform_matrix_double, double3(width, 0.0, 0.0));
add_x = double2((add_x_v3 - double3(start_uv)) * (1.0 / width));
}
void init_add_y(const float transform_matrix[4][4])
{
double transform_matrix_double[4][4];
copy_m4d_m4(transform_matrix_double, transform_matrix);
const int height = src->y;
double add_y_v3[3];
double uv_max_y[3];
zero_v3_db(uv_max_y);
uv_max_y[0] = 0.0f;
uv_max_y[1] = height;
mul_v3_m4v3_db(add_y_v3, transform_matrix_double, uv_max_y);
sub_v2_v2_db(add_y_v3, start_uv);
mul_v3db_db(add_y_v3, 1.0f / height);
copy_v2_v2_db(add_y, add_y_v3);
const double height = src->y;
double3 add_y_v3;
double3 uv_max_y(0.0, height, 0.0);
mul_v3_m4v3_db(add_y_v3, transform_matrix_double, double3(0.0, height, 0.0));
add_y = double2((add_y_v3 - double3(start_uv)) * (1.0 / height));
}
};
@ -110,7 +99,7 @@ class BaseDiscard {
/**
* \brief Should the source pixel at the given uv coordinate be discarded.
*/
virtual bool should_discard(const TransformUserData &user_data, const double uv[2]) = 0;
virtual bool should_discard(const TransformUserData &user_data, const double2 uv) = 0;
};
/**
@ -123,10 +112,10 @@ class CropSource : public BaseDiscard {
*
* Uses user_data.src_crop to determine if the uv coordinate should be skipped.
*/
bool should_discard(const TransformUserData &user_data, const double uv[2]) override
bool should_discard(const TransformUserData &user_data, const double2 uv) override
{
return uv[0] < user_data.src_crop.xmin || uv[0] >= user_data.src_crop.xmax ||
uv[1] < user_data.src_crop.ymin || uv[1] >= user_data.src_crop.ymax;
return uv.x < user_data.src_crop.xmin || uv.x >= user_data.src_crop.xmax ||
uv.y < user_data.src_crop.ymin || uv.y >= user_data.src_crop.ymax;
}
};
@ -140,7 +129,7 @@ class NoDiscard : public BaseDiscard {
*
* Will never discard any pixels.
*/
bool should_discard(const TransformUserData & /*user_data*/, const double /*uv*/[2]) override
bool should_discard(const TransformUserData & /*user_data*/, const double2 /*uv*/) override
{
return false;
}
@ -168,9 +157,10 @@ class PixelPointer {
StorageType *pointer;
public:
void init_pixel_pointer(const ImBuf *image_buffer, int x, int y)
void init_pixel_pointer(const ImBuf *image_buffer, int2 start_coordinate)
{
const size_t offset = (y * size_t(image_buffer->x) + x) * NumChannels;
const size_t offset = (start_coordinate.y * size_t(image_buffer->x) + start_coordinate.x) *
NumChannels;
if constexpr (std::is_same_v<StorageType, float>) {
pointer = image_buffer->rect_float + offset;
@ -214,6 +204,14 @@ class BaseUVWrapping {
* \brief modify the given v coordinate.
*/
virtual double modify_v(const ImBuf *source_buffer, double v) = 0;
/**
* \brief modify the given uv coordinate.
*/
double2 modify_uv(const ImBuf *source_buffer, double2 uv)
{
return double2(modify_u(source_buffer, uv.x), modify_v(source_buffer, uv.y));
}
};
/**
@ -290,25 +288,22 @@ class Sampler {
static const int ChannelLen = NumChannels;
using SampleType = std::array<StorageType, NumChannels>;
void sample(const ImBuf *source, const double u, const double v, SampleType &r_sample)
void sample(const ImBuf *source, const double2 uv, SampleType &r_sample)
{
if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<StorageType, float> &&
NumChannels == 4) {
const double wrapped_u = uv_wrapper.modify_u(source, u);
const double wrapped_v = uv_wrapper.modify_v(source, v);
bilinear_interpolation_color_fl(source, nullptr, r_sample.data(), wrapped_u, wrapped_v);
const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv);
bilinear_interpolation_color_fl(source, nullptr, r_sample.data(), UNPACK2(wrapped_uv));
}
else if constexpr (Filter == IMB_FILTER_NEAREST && std::is_same_v<StorageType, uchar> &&
NumChannels == 4) {
const double wrapped_u = uv_wrapper.modify_u(source, u);
const double wrapped_v = uv_wrapper.modify_v(source, v);
nearest_interpolation_color_char(source, r_sample.data(), nullptr, wrapped_u, wrapped_v);
const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv);
nearest_interpolation_color_char(source, r_sample.data(), nullptr, UNPACK2(wrapped_uv));
}
else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<StorageType, uchar> &&
NumChannels == 4) {
const double wrapped_u = uv_wrapper.modify_u(source, u);
const double wrapped_v = uv_wrapper.modify_v(source, v);
bilinear_interpolation_color_char(source, r_sample.data(), nullptr, wrapped_u, wrapped_v);
const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv);
bilinear_interpolation_color_char(source, r_sample.data(), nullptr, UNPACK2(wrapped_uv));
}
else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<StorageType, float>) {
if constexpr (std::is_same_v<UVWrapping, WrapRepeatUV>) {
@ -317,27 +312,23 @@ class Sampler {
source->x,
source->y,
NumChannels,
u,
v,
UNPACK2(uv),
true,
true);
}
else {
const double wrapped_u = uv_wrapper.modify_u(source, u);
const double wrapped_v = uv_wrapper.modify_v(source, v);
const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv);
BLI_bilinear_interpolation_fl(source->rect_float,
r_sample.data(),
source->x,
source->y,
NumChannels,
wrapped_u,
wrapped_v);
UNPACK2(wrapped_uv));
}
}
else if constexpr (Filter == IMB_FILTER_NEAREST && std::is_same_v<StorageType, float>) {
const double wrapped_u = uv_wrapper.modify_u(source, u);
const double wrapped_v = uv_wrapper.modify_v(source, v);
sample_nearest_float(source, wrapped_u, wrapped_v, r_sample);
const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv);
sample_nearest_float(source, UNPACK2(wrapped_uv), r_sample);
}
else {
/* Unsupported sampler. */
@ -466,19 +457,17 @@ class ScanlineProcessor {
void process(const TransformUserData *user_data, int scanline)
{
const int width = user_data->dst->x;
double2 uv = user_data->start_uv + user_data->add_y * scanline;
double uv[2];
madd_v2_v2db_db(uv, user_data->start_uv, user_data->add_y, scanline);
output.init_pixel_pointer(user_data->dst, 0, scanline);
output.init_pixel_pointer(user_data->dst, int2(0, scanline));
for (int xi = 0; xi < width; xi++) {
if (!discarder.should_discard(*user_data, uv)) {
typename Sampler::SampleType sample;
sampler.sample(user_data->src, uv[0], uv[1], sample);
sampler.sample(user_data->src, uv, sample);
channel_converter.convert_and_store(sample, output);
}
add_v2_v2_db(uv, user_data->add_x);
uv += user_data->add_x;
output.increase_pixel_pointer();
}
}