VSE: bilinear upscaling no longer adds transparent border around the image #117717
|
@ -1316,7 +1316,7 @@ static void tracking_stabilize_frame_interpolation_cb(void *__restrict userdata,
|
|||
for (int x = 0; x < tmpibuf->x; x++, dst++) {
|
||||
vec[0] = float(x);
|
||||
mul_v3_m4v3(rvec, mat, vec);
|
||||
*dst = imbuf::interpolate_bilinear_fl(ibuf, rvec[0], rvec[1]);
|
||||
*dst = imbuf::interpolate_bilinear_border_fl(ibuf, rvec[0], rvec[1]);
|
||||
}
|
||||
}
|
||||
else if (data->tracking_filter == TRACKING_FILTER_BICUBIC) {
|
||||
|
@ -1342,7 +1342,7 @@ static void tracking_stabilize_frame_interpolation_cb(void *__restrict userdata,
|
|||
for (int x = 0; x < tmpibuf->x; x++, dst++) {
|
||||
vec[0] = float(x);
|
||||
mul_v3_m4v3(rvec, mat, vec);
|
||||
*dst = imbuf::interpolate_bilinear_byte(ibuf, rvec[0], rvec[1]);
|
||||
*dst = imbuf::interpolate_bilinear_border_byte(ibuf, rvec[0], rvec[1]);
|
||||
}
|
||||
}
|
||||
else if (data->tracking_filter == TRACKING_FILTER_BICUBIC) {
|
||||
|
|
|
@ -152,13 +152,13 @@ inline void interpolate_nearest_wrap_fl(
|
|||
* to get proper filtering.
|
||||
*/
|
||||
|
||||
[[nodiscard]] uchar4 interpolate_bilinear_byte(
|
||||
[[nodiscard]] uchar4 interpolate_bilinear_border_byte(
|
||||
const uchar *buffer, int width, int height, float u, float v);
|
||||
|
||||
[[nodiscard]] float4 interpolate_bilinear_fl(
|
||||
[[nodiscard]] float4 interpolate_bilinear_border_fl(
|
||||
const float *buffer, int width, int height, float u, float v);
|
||||
|
||||
void interpolate_bilinear_fl(
|
||||
void interpolate_bilinear_border_fl(
|
||||
const float *buffer, float *output, int width, int height, int components, float u, float v);
|
||||
|
||||
/**
|
||||
|
|
|
@ -357,7 +357,8 @@ BLI_INLINE void bilinear_fl_impl(const float *buffer,
|
|||
|
||||
namespace blender::math {
|
||||
|
||||
uchar4 interpolate_bilinear_byte(const uchar *buffer, int width, int height, float u, float v)
|
||||
uchar4 interpolate_bilinear_border_byte(
|
||||
const uchar *buffer, int width, int height, float u, float v)
|
||||
{
|
||||
BLI_assert(buffer);
|
||||
uchar4 res;
|
||||
|
@ -502,14 +503,14 @@ uchar4 interpolate_bilinear_byte(const uchar *buffer, int width, int height, flo
|
|||
return res;
|
||||
}
|
||||
|
||||
float4 interpolate_bilinear_fl(const float *buffer, int width, int height, float u, float v)
|
||||
float4 interpolate_bilinear_border_fl(const float *buffer, int width, int height, float u, float v)
|
||||
{
|
||||
float4 res;
|
||||
bilinear_fl_impl(buffer, res, width, height, 4, u, v);
|
||||
return res;
|
||||
}
|
||||
|
||||
void interpolate_bilinear_fl(
|
||||
void interpolate_bilinear_border_fl(
|
||||
const float *buffer, float *output, int width, int height, int components, float u, float v)
|
||||
{
|
||||
bilinear_fl_impl(buffer, output, width, height, components, u, v);
|
||||
|
|
|
@ -28,10 +28,10 @@ TEST(math_interp, BilinearCharExactSamples)
|
|||
{
|
||||
uchar4 res;
|
||||
uchar4 exp1 = {73, 108, 153, 251};
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 1.0f, 2.0f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 1.0f, 2.0f);
|
||||
EXPECT_EQ(exp1, res);
|
||||
uchar4 exp2 = {240, 160, 90, 20};
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 2.0f, 0.0f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 2.0f, 0.0f);
|
||||
EXPECT_EQ(exp2, res);
|
||||
}
|
||||
|
||||
|
@ -39,10 +39,10 @@ TEST(math_interp, BilinearCharHalfwayUSamples)
|
|||
{
|
||||
uchar4 res;
|
||||
uchar4 exp1 = {31, 37, 42, 48};
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 0.5f, 1.0f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 0.5f, 1.0f);
|
||||
EXPECT_EQ(exp1, res);
|
||||
uchar4 exp2 = {243, 242, 224, 223};
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 0.5f, 0.0f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 0.5f, 0.0f);
|
||||
EXPECT_EQ(exp2, res);
|
||||
}
|
||||
|
||||
|
@ -50,10 +50,10 @@ TEST(math_interp, BilinearCharHalfwayVSamples)
|
|||
{
|
||||
uchar4 res;
|
||||
uchar4 exp1 = {1, 2, 3, 4};
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 0.0f, 1.5f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 0.0f, 1.5f);
|
||||
EXPECT_EQ(exp1, res);
|
||||
uchar4 exp2 = {127, 128, 129, 130};
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 2.0f, 1.5f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 2.0f, 1.5f);
|
||||
EXPECT_EQ(exp2, res);
|
||||
}
|
||||
|
||||
|
@ -61,10 +61,11 @@ TEST(math_interp, BilinearCharSamples)
|
|||
{
|
||||
uchar4 res;
|
||||
uchar4 exp1 = {136, 133, 132, 130};
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 1.25f, 0.625f);
|
||||
res = interpolate_bilinear_border_byte(
|
||||
image_char[0][0], image_width, image_height, 1.25f, 0.625f);
|
||||
EXPECT_EQ(exp1, res);
|
||||
uchar4 exp2 = {219, 191, 167, 142};
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 1.4f, 0.1f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 1.4f, 0.1f);
|
||||
EXPECT_EQ(exp2, res);
|
||||
}
|
||||
|
||||
|
@ -72,10 +73,10 @@ TEST(math_interp, BilinearFloatSamples)
|
|||
{
|
||||
float4 res;
|
||||
float4 exp1 = {135.9375f, 133.28125f, 131.5625f, 129.84375f};
|
||||
res = interpolate_bilinear_fl(image_fl[0][0], image_width, image_height, 1.25f, 0.625f);
|
||||
res = interpolate_bilinear_border_fl(image_fl[0][0], image_width, image_height, 1.25f, 0.625f);
|
||||
EXPECT_V4_NEAR(exp1, res, float_tolerance);
|
||||
float4 exp2 = {219.36f, 191.2f, 166.64f, 142.08f};
|
||||
res = interpolate_bilinear_fl(image_fl[0][0], image_width, image_height, 1.4f, 0.1f);
|
||||
res = interpolate_bilinear_border_fl(image_fl[0][0], image_width, image_height, 1.4f, 0.1f);
|
||||
EXPECT_V4_NEAR(exp2, res, float_tolerance);
|
||||
}
|
||||
|
||||
|
@ -83,13 +84,13 @@ TEST(math_interp, BilinearCharPartiallyOutsideImage)
|
|||
{
|
||||
uchar4 res;
|
||||
uchar4 exp1 = {1, 1, 2, 2};
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, -0.5f, 2.0f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, -0.5f, 2.0f);
|
||||
EXPECT_EQ(exp1, res);
|
||||
uchar4 exp2 = {9, 11, 15, 22};
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 1.25f, 2.9f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 1.25f, 2.9f);
|
||||
EXPECT_EQ(exp2, res);
|
||||
uchar4 exp3 = {173, 115, 65, 14};
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 2.2f, -0.1f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 2.2f, -0.1f);
|
||||
EXPECT_EQ(exp3, res);
|
||||
}
|
||||
|
||||
|
@ -111,13 +112,13 @@ TEST(math_interp, BilinearFloatPartiallyOutsideImage)
|
|||
{
|
||||
float4 res;
|
||||
float4 exp1 = {0.5f, 1, 1.5f, 2};
|
||||
res = interpolate_bilinear_fl(image_fl[0][0], image_width, image_height, -0.5f, 2.0f);
|
||||
res = interpolate_bilinear_border_fl(image_fl[0][0], image_width, image_height, -0.5f, 2.0f);
|
||||
EXPECT_V4_NEAR(exp1, res, float_tolerance);
|
||||
float4 exp2 = {8.675f, 11.325f, 14.725f, 22.1f};
|
||||
res = interpolate_bilinear_fl(image_fl[0][0], image_width, image_height, 1.25f, 2.9f);
|
||||
res = interpolate_bilinear_border_fl(image_fl[0][0], image_width, image_height, 1.25f, 2.9f);
|
||||
EXPECT_V4_NEAR(exp2, res, float_tolerance);
|
||||
float4 exp3 = {172.8f, 115.2f, 64.8f, 14.4f};
|
||||
res = interpolate_bilinear_fl(image_fl[0][0], image_width, image_height, 2.2f, -0.1f);
|
||||
res = interpolate_bilinear_border_fl(image_fl[0][0], image_width, image_height, 2.2f, -0.1f);
|
||||
EXPECT_V4_NEAR(exp3, res, float_tolerance);
|
||||
}
|
||||
|
||||
|
@ -151,23 +152,23 @@ TEST(math_interp, BilinearCharFullyOutsideImage)
|
|||
uchar4 res;
|
||||
uchar4 exp = {0, 0, 0, 0};
|
||||
/* Out of range on U */
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, -1.5f, 0);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, -1.5f, 0);
|
||||
EXPECT_EQ(exp, res);
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, -1.1f, 0);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, -1.1f, 0);
|
||||
EXPECT_EQ(exp, res);
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 3, 0);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 3, 0);
|
||||
EXPECT_EQ(exp, res);
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 5, 0);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 5, 0);
|
||||
EXPECT_EQ(exp, res);
|
||||
|
||||
/* Out of range on V */
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 0, -3.2f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 0, -3.2f);
|
||||
EXPECT_EQ(exp, res);
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 0, -1.5f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 0, -1.5f);
|
||||
EXPECT_EQ(exp, res);
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 0, 3.1f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 0, 3.1f);
|
||||
EXPECT_EQ(exp, res);
|
||||
res = interpolate_bilinear_byte(image_char[0][0], image_width, image_height, 0, 500.0f);
|
||||
res = interpolate_bilinear_border_byte(image_char[0][0], image_width, image_height, 0, 500.0f);
|
||||
EXPECT_EQ(exp, res);
|
||||
}
|
||||
|
||||
|
|
|
@ -249,17 +249,17 @@ class MemoryBuffer {
|
|||
single_y = rel_y - last_y;
|
||||
}
|
||||
|
||||
math::interpolate_bilinear_fl(buffer_, out, 1, 1, num_channels_, single_x, single_y);
|
||||
math::interpolate_bilinear_border_fl(buffer_, out, 1, 1, num_channels_, single_x, single_y);
|
||||
return;
|
||||
}
|
||||
|
||||
math::interpolate_bilinear_fl(buffer_,
|
||||
out,
|
||||
get_width(),
|
||||
get_height(),
|
||||
num_channels_,
|
||||
get_relative_x(x),
|
||||
get_relative_y(y));
|
||||
math::interpolate_bilinear_border_fl(buffer_,
|
||||
out,
|
||||
get_width(),
|
||||
get_height(),
|
||||
num_channels_,
|
||||
get_relative_x(x),
|
||||
get_relative_y(y));
|
||||
}
|
||||
|
||||
void read_elem_sampled(float x, float y, PixelSampler sampler, float *out) const
|
||||
|
|
|
@ -104,7 +104,7 @@ static void sample_image_at_location(ImBuf *ibuf,
|
|||
imbuf::interpolate_nearest_fl(ibuf, color, x, y);
|
||||
break;
|
||||
case PixelSampler::Bilinear:
|
||||
imbuf::interpolate_bilinear_fl(ibuf, color, x, y);
|
||||
imbuf::interpolate_bilinear_border_fl(ibuf, color, x, y);
|
||||
break;
|
||||
case PixelSampler::Bicubic:
|
||||
imbuf::interpolate_cubic_bspline_fl(ibuf, color, x, y);
|
||||
|
@ -118,7 +118,7 @@ static void sample_image_at_location(ImBuf *ibuf,
|
|||
byte_color = imbuf::interpolate_nearest_byte(ibuf, x, y);
|
||||
break;
|
||||
case PixelSampler::Bilinear:
|
||||
byte_color = imbuf::interpolate_bilinear_byte(ibuf, x, y);
|
||||
byte_color = imbuf::interpolate_bilinear_border_byte(ibuf, x, y);
|
||||
break;
|
||||
case PixelSampler::Bicubic:
|
||||
byte_color = imbuf::interpolate_cubic_bspline_byte(ibuf, x, y);
|
||||
|
|
|
@ -85,7 +85,7 @@ void MovieClipBaseOperation::execute_pixel_sampled(float output[4],
|
|||
imbuf::interpolate_nearest_fl(ibuf, output, x, y);
|
||||
break;
|
||||
case PixelSampler::Bilinear:
|
||||
imbuf::interpolate_bilinear_fl(ibuf, output, x, y);
|
||||
imbuf::interpolate_bilinear_border_fl(ibuf, output, x, y);
|
||||
break;
|
||||
case PixelSampler::Bicubic:
|
||||
imbuf::interpolate_cubic_bspline_fl(ibuf, output, x, y);
|
||||
|
|
|
@ -91,7 +91,7 @@ void MultilayerColorOperation::execute_pixel_sampled(float output[4],
|
|||
imbuf::interpolate_nearest_fl(buffer_, output, x, y);
|
||||
break;
|
||||
case PixelSampler::Bilinear:
|
||||
imbuf::interpolate_bilinear_fl(buffer_, output, x, y);
|
||||
imbuf::interpolate_bilinear_border_fl(buffer_, output, x, y);
|
||||
break;
|
||||
case PixelSampler::Bicubic:
|
||||
imbuf::interpolate_cubic_bspline_fl(buffer_, output, x, y);
|
||||
|
|
|
@ -77,7 +77,8 @@ void RenderLayersProg::do_interpolation(float output[4], float x, float y, Pixel
|
|||
math::interpolate_nearest_fl(input_buffer_, output, width, height, elementsize_, x, y);
|
||||
break;
|
||||
case PixelSampler::Bilinear:
|
||||
math::interpolate_bilinear_fl(input_buffer_, output, width, height, elementsize_, x, y);
|
||||
math::interpolate_bilinear_border_fl(
|
||||
input_buffer_, output, width, height, elementsize_, x, y);
|
||||
break;
|
||||
case PixelSampler::Bicubic:
|
||||
math::interpolate_cubic_bspline_fl(input_buffer_, output, width, height, elementsize_, x, y);
|
||||
|
|
|
@ -44,22 +44,22 @@ inline void interpolate_nearest_fl(const ImBuf *in, float output[4], float u, fl
|
|||
return math::interpolate_nearest_wrap_fl(in->float_buffer.data, in->x, in->y, u, v);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline uchar4 interpolate_bilinear_byte(const ImBuf *in, float u, float v)
|
||||
[[nodiscard]] inline uchar4 interpolate_bilinear_border_byte(const ImBuf *in, float u, float v)
|
||||
{
|
||||
return math::interpolate_bilinear_byte(in->byte_buffer.data, in->x, in->y, u, v);
|
||||
return math::interpolate_bilinear_border_byte(in->byte_buffer.data, in->x, in->y, u, v);
|
||||
}
|
||||
[[nodiscard]] inline float4 interpolate_bilinear_fl(const ImBuf *in, float u, float v)
|
||||
[[nodiscard]] inline float4 interpolate_bilinear_border_fl(const ImBuf *in, float u, float v)
|
||||
{
|
||||
return math::interpolate_bilinear_fl(in->float_buffer.data, in->x, in->y, u, v);
|
||||
return math::interpolate_bilinear_border_fl(in->float_buffer.data, in->x, in->y, u, v);
|
||||
}
|
||||
inline void interpolate_bilinear_byte(const ImBuf *in, uchar output[4], float u, float v)
|
||||
inline void interpolate_bilinear_border_byte(const ImBuf *in, uchar output[4], float u, float v)
|
||||
{
|
||||
uchar4 col = math::interpolate_bilinear_byte(in->byte_buffer.data, in->x, in->y, u, v);
|
||||
uchar4 col = math::interpolate_bilinear_border_byte(in->byte_buffer.data, in->x, in->y, u, v);
|
||||
memcpy(output, &col, sizeof(col));
|
||||
}
|
||||
inline void interpolate_bilinear_fl(const ImBuf *in, float output[4], float u, float v)
|
||||
inline void interpolate_bilinear_border_fl(const ImBuf *in, float output[4], float u, float v)
|
||||
{
|
||||
float4 col = math::interpolate_bilinear_fl(in->float_buffer.data, in->x, in->y, u, v);
|
||||
float4 col = math::interpolate_bilinear_border_fl(in->float_buffer.data, in->x, in->y, u, v);
|
||||
memcpy(output, &col, sizeof(col));
|
||||
}
|
||||
|
||||
|
|
|
@ -1761,12 +1761,12 @@ static void *do_scale_thread(void *data_v)
|
|||
int offset = y * data->newx + x;
|
||||
|
||||
if (data->byte_buffer) {
|
||||
interpolate_bilinear_byte(ibuf, data->byte_buffer + 4 * offset, u, v);
|
||||
interpolate_bilinear_border_byte(ibuf, data->byte_buffer + 4 * offset, u, v);
|
||||
}
|
||||
|
||||
if (data->float_buffer) {
|
||||
float *pixel = data->float_buffer + ibuf->channels * offset;
|
||||
blender::math::interpolate_bilinear_fl(
|
||||
blender::math::interpolate_bilinear_border_fl(
|
||||
ibuf->float_buffer.data, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ static void sample_image(const ImBuf *source, float u, float v, T *r_sample)
|
|||
v -= 0.5f;
|
||||
}
|
||||
if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<T, float> && NumChannels == 4) {
|
||||
interpolate_bilinear_fl(source, r_sample, u, v);
|
||||
interpolate_bilinear_border_fl(source, r_sample, u, v);
|
||||
}
|
||||
else if constexpr (Filter == IMB_FILTER_NEAREST && std::is_same_v<T, uchar> && NumChannels == 4)
|
||||
{
|
||||
|
@ -144,7 +144,7 @@ static void sample_image(const ImBuf *source, float u, float v, T *r_sample)
|
|||
}
|
||||
else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<T, uchar> && NumChannels == 4)
|
||||
{
|
||||
interpolate_bilinear_byte(source, r_sample, u, v);
|
||||
interpolate_bilinear_border_byte(source, r_sample, u, v);
|
||||
}
|
||||
else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<T, float>) {
|
||||
if constexpr (WrapUV) {
|
||||
|
@ -159,7 +159,7 @@ static void sample_image(const ImBuf *source, float u, float v, T *r_sample)
|
|||
true);
|
||||
}
|
||||
else {
|
||||
math::interpolate_bilinear_fl(
|
||||
math::interpolate_bilinear_border_fl(
|
||||
source->float_buffer.data, r_sample, source->x, source->y, NumChannels, u, v);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,10 +274,12 @@ class TextureMarginMap {
|
|||
|
||||
if (found_pixel_in_polygon) {
|
||||
if (ibuf_ptr_fl) {
|
||||
ibuf_ptr_fl[pixel_index] = imbuf::interpolate_bilinear_fl(ibuf, destX, destY);
|
||||
ibuf_ptr_fl[pixel_index] = imbuf::interpolate_bilinear_border_fl(
|
||||
ibuf, destX, destY);
|
||||
}
|
||||
if (ibuf_ptr_ch) {
|
||||
ibuf_ptr_ch[pixel_index] = imbuf::interpolate_bilinear_byte(ibuf, destX, destY);
|
||||
ibuf_ptr_ch[pixel_index] = imbuf::interpolate_bilinear_border_byte(
|
||||
ibuf, destX, destY);
|
||||
}
|
||||
/* Add our new pixels to the assigned pixel map. */
|
||||
mask[pixel_index] = 1;
|
||||
|
|
|
@ -1584,10 +1584,10 @@ static void transform_image(int x,
|
|||
break;
|
||||
case 1:
|
||||
if (dst_fl) {
|
||||
dst_fl[offset] = imbuf::interpolate_bilinear_fl(ibuf, xt, yt);
|
||||
dst_fl[offset] = imbuf::interpolate_bilinear_border_fl(ibuf, xt, yt);
|
||||
}
|
||||
else {
|
||||
dst_ch[offset] = imbuf::interpolate_bilinear_byte(ibuf, xt, yt);
|
||||
dst_ch[offset] = imbuf::interpolate_bilinear_border_byte(ibuf, xt, yt);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
|
|
Loading…
Reference in New Issue