Blender V5.0
BLI_math_interp_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "testing/testing.h"
6
7#include "BLI_color.hh"
8#include "BLI_math_interp.hh"
9
10using namespace blender;
11using namespace blender::math;
12
13static constexpr float float_tolerance = 0.00005f;
14static constexpr int image_width = 3;
15static constexpr int image_height = 3;
16static constexpr uchar image_char[image_height][image_width][4] = {
17 {{255, 254, 217, 216}, {230, 230, 230, 230}, {240, 160, 90, 20}},
18 {{0, 1, 2, 3}, {62, 72, 82, 92}, {126, 127, 128, 129}},
19 {{1, 2, 3, 4}, {73, 108, 153, 251}, {128, 129, 130, 131}},
20};
21static constexpr float image_fl[image_height][image_width][4] = {
22 {{255, 254, 217, 216}, {230, 230, 230, 230}, {240, 160, 90, 20}},
23 {{0, 1, 2, 3}, {62, 72, 82, 92}, {126, 127, 128, 129}},
24 {{1, 2, 3, 4}, {73, 108, 153, 251}, {128, 129, 130, 131}},
25};
26
27TEST(math_interp, NearestCharExactSamples)
28{
29 uchar4 res;
30 uchar4 exp1 = {73, 108, 153, 251};
32 EXPECT_EQ(exp1, res);
33 uchar4 exp2 = {240, 160, 90, 20};
35 EXPECT_EQ(exp2, res);
36}
37
38TEST(math_interp, NearestCharHalfwaySamples)
39{
40 uchar4 res;
41 uchar4 exp1 = {0, 1, 2, 3};
43 EXPECT_EQ(exp1, res);
44 uchar4 exp2 = {255, 254, 217, 216};
46 EXPECT_EQ(exp2, res);
47}
48
49TEST(math_interp, NearestFloatExactSamples)
50{
51 float4 res;
52 float4 exp1 = {73.0f, 108.0f, 153.0f, 251.0f};
54 EXPECT_EQ(exp1, res);
55 float4 exp2 = {240.0f, 160.0f, 90.0f, 20.0f};
57 EXPECT_EQ(exp2, res);
58}
59
60TEST(math_interp, NearestFloatHalfwaySamples)
61{
62 float4 res;
63 float4 exp1 = {0.0f, 1.0f, 2.0f, 3.0f};
65 EXPECT_EQ(exp1, res);
66 float4 exp2 = {255.0f, 254.0f, 217.0f, 216.0f};
68 EXPECT_EQ(exp2, res);
69}
70
71TEST(math_interp, BilinearCharExactSamples)
72{
73 uchar4 res;
74 uchar4 exp1 = {73, 108, 153, 251};
76 EXPECT_EQ(exp1, res);
77 uchar4 exp2 = {240, 160, 90, 20};
79 EXPECT_EQ(exp2, res);
80}
81
82TEST(math_interp, BilinearCharHalfwayUSamples)
83{
84 uchar4 res;
85 uchar4 exp1 = {31, 37, 42, 48};
87 EXPECT_EQ(exp1, res);
88 uchar4 exp2 = {243, 242, 224, 223};
90 EXPECT_EQ(exp2, res);
91}
92
93TEST(math_interp, BilinearCharHalfwayVSamples)
94{
95 uchar4 res;
96 uchar4 exp1 = {1, 2, 3, 4};
98 EXPECT_EQ(exp1, res);
99 uchar4 exp2 = {127, 128, 129, 130};
101 EXPECT_EQ(exp2, res);
102}
103
104TEST(math_interp, BilinearCharSamples)
105{
106 uchar4 res;
107 uchar4 exp1 = {136, 133, 132, 130};
109 image_char[0][0], image_width, image_height, 1.25f, 0.625f);
110 EXPECT_EQ(exp1, res);
111 uchar4 exp2 = {219, 191, 167, 142};
113 EXPECT_EQ(exp2, res);
114}
115
116TEST(math_interp, BilinearFloatSamples)
117{
118 float4 res;
119 float4 exp1 = {135.9375f, 133.28125f, 131.5625f, 129.84375f};
121 EXPECT_V4_NEAR(exp1, res, float_tolerance);
122 float4 exp2 = {219.36f, 191.2f, 166.64f, 142.08f};
124 EXPECT_V4_NEAR(exp2, res, float_tolerance);
125}
126
127TEST(math_interp, BilinearCharPartiallyOutsideImageBorder)
128{
129 uchar4 res;
130 uchar4 exp1 = {1, 1, 2, 2};
132 EXPECT_EQ(exp1, res);
133 uchar4 exp2 = {9, 11, 15, 22};
135 EXPECT_EQ(exp2, res);
136 uchar4 exp3 = {173, 115, 65, 14};
138 EXPECT_EQ(exp3, res);
139}
140
141TEST(math_interp, BilinearCharPartiallyOutsideImage)
142{
143 uchar4 res;
144 uint4 exp1 = {1, 2, 3, 4};
146 EXPECT_EQ(exp1, uint4(res));
147 uint4 exp2 = {87, 113, 147, 221};
149 EXPECT_EQ(exp2, uint4(res));
150 uint4 exp3 = {240, 160, 90, 20};
152 EXPECT_EQ(exp3, uint4(res));
153}
154
155TEST(math_interp, BilinearCharPartiallyOutsideImageWrap)
156{
157 uchar4 res;
158 uchar4 exp1 = {65, 66, 67, 68};
160 EXPECT_EQ(exp1, res);
161 uchar4 exp2 = {218, 203, 190, 182};
163 EXPECT_EQ(exp2, res);
164 uchar4 exp3 = {229, 171, 114, 64};
166 EXPECT_EQ(exp3, res);
167}
168
169TEST(math_interp, BilinearFloatPartiallyOutsideImageBorder)
170{
171 float4 res;
172 float4 exp1 = {0.5f, 1, 1.5f, 2};
174 EXPECT_V4_NEAR(exp1, res, float_tolerance);
175 float4 exp2 = {8.675f, 11.325f, 14.725f, 22.1f};
177 EXPECT_V4_NEAR(exp2, res, float_tolerance);
178 float4 exp3 = {172.8f, 115.2f, 64.8f, 14.4f};
180 EXPECT_V4_NEAR(exp3, res, float_tolerance);
181}
182
183TEST(math_interp, BilinearFloatPartiallyOutsideImage)
184{
185 float4 res;
186 float4 exp1 = {1.0f, 2.0f, 3.0f, 4.0f};
187 res = interpolate_bilinear_fl(image_fl[0][0], image_width, image_height, -0.5f, 2.0f);
188 EXPECT_V4_NEAR(exp1, res, float_tolerance);
189 float4 exp2 = {86.75f, 113.25f, 147.25f, 221.0f};
190 res = interpolate_bilinear_fl(image_fl[0][0], image_width, image_height, 1.25f, 2.9f);
191 EXPECT_V4_NEAR(exp2, res, float_tolerance);
192 float4 exp3 = {240.0f, 160.0f, 90.0f, 20.0f};
193 res = interpolate_bilinear_fl(image_fl[0][0], image_width, image_height, 2.2f, -0.1f);
194 EXPECT_V4_NEAR(exp3, res, float_tolerance);
195}
196
197TEST(math_interp, BilinearFloatPartiallyOutsideImageWrap)
198{
199 float4 res;
200 float4 exp1 = {64.5f, 65.5f, 66.5f, 67.5f};
202 res,
205 4,
206 -0.5f,
207 2.0f,
210 EXPECT_V4_NEAR(exp1, res, float_tolerance);
212 EXPECT_V4_NEAR(exp1, res, float_tolerance);
213
214 float4 exp2 = {217.92502f, 202.57501f, 190.22501f, 181.85f};
216 res,
219 4,
220 1.25f,
221 2.9f,
224 EXPECT_V4_NEAR(exp2, res, float_tolerance);
226 EXPECT_V4_NEAR(exp2, res, float_tolerance);
227
228 float4 exp3 = {228.96f, 171.27998f, 114.32f, 63.84f};
230 res,
233 4,
234 2.2f,
235 -0.1f,
238 EXPECT_V4_NEAR(exp3, res, float_tolerance);
240 EXPECT_V4_NEAR(exp3, res, float_tolerance);
241
242 /* Wrap only V axis. */
243 float4 exp4 = {191.5f, 191.0f, 163.5f, 163.0f};
245 res,
248 4,
249 -0.5f,
250 2.75f,
253 EXPECT_V4_NEAR(exp4, res, float_tolerance);
255 res,
258 4,
259 -0.5f,
260 5.75f,
263 EXPECT_V4_NEAR(exp4, res, float_tolerance);
264}
265
266TEST(math_interp, BilinearCharFullyOutsideImage)
267{
268 uchar4 res;
269 uchar4 exp = {0, 0, 0, 0};
270 /* Out of range on U */
272 EXPECT_EQ(exp, res);
274 EXPECT_EQ(exp, res);
276 EXPECT_EQ(exp, res);
278 EXPECT_EQ(exp, res);
279
280 /* Out of range on V */
282 EXPECT_EQ(exp, res);
284 EXPECT_EQ(exp, res);
286 EXPECT_EQ(exp, res);
288 EXPECT_EQ(exp, res);
289}
290
291TEST(math_interp, BilinearFloatFullyOutsideImage)
292{
293 float4 res;
294 float4 exp = {0, 0, 0, 0};
295 /* Out of range on U */
297 EXPECT_EQ(exp, res);
299 EXPECT_EQ(exp, res);
301 EXPECT_EQ(exp, res);
303 EXPECT_EQ(exp, res);
304
305 /* Out of range on V */
307 EXPECT_EQ(exp, res);
309 EXPECT_EQ(exp, res);
311 EXPECT_EQ(exp, res);
313 EXPECT_EQ(exp, res);
314}
315
316TEST(math_interp, CubicBSplineCharExactSamples)
317{
318 uchar4 res;
319 uchar4 exp1 = {69, 90, 116, 172};
321 EXPECT_EQ(exp1, res);
322 uchar4 exp2 = {218, 163, 115, 66};
324 EXPECT_EQ(exp2, res);
325}
326
327TEST(math_interp, CubicBSplineCharSamples)
328{
329 uchar4 res;
330 uchar4 exp1 = {142, 136, 131, 128};
332 EXPECT_EQ(exp1, res);
333 uchar4 exp2 = {202, 177, 154, 132};
335 EXPECT_EQ(exp2, res);
336}
337
338TEST(math_interp, CubicBSplineFloatSamples)
339{
340 float4 res;
341 float4 exp1 = {142.14418f, 136.255798f, 130.87924f, 127.85243f};
343 EXPECT_V4_NEAR(exp1, res, float_tolerance);
344 float4 exp2 = {202.36082f, 177.13397f, 154.21078f, 132.30153f};
346 EXPECT_V4_NEAR(exp2, res, float_tolerance);
347}
348
349TEST(math_interp, CubicBSplineCharPartiallyOutsideImage)
350{
351 uchar4 res;
352 uchar4 exp1 = {2, 4, 6, 8};
354 EXPECT_EQ(exp1, res);
355 uchar4 exp2 = {85, 107, 135, 195};
357 EXPECT_EQ(exp2, res);
358 uchar4 exp3 = {225, 161, 105, 49};
360 EXPECT_EQ(exp3, res);
361}
362
363TEST(math_interp, CubicBSplineFloatPartiallyOutsideImage)
364{
365 float4 res;
366 float4 exp1 = {2.29861f, 3.92014f, 5.71528f, 8.430554f};
368 EXPECT_V4_NEAR(exp1, res, float_tolerance);
370 res,
373 4,
374 -0.5f,
375 2.0f,
378 EXPECT_V4_NEAR(exp1, res, float_tolerance);
379
380 float4 exp2 = {85.41022f, 107.21497f, 135.13849f, 195.49146f};
382 EXPECT_V4_NEAR(exp2, res, float_tolerance);
384 res,
387 4,
388 1.25f,
389 2.9f,
392 EXPECT_V4_NEAR(exp2, res, float_tolerance);
393
394 float4 exp3 = {224.73579f, 160.66783f, 104.63521f, 48.60260f};
396 EXPECT_V4_NEAR(exp3, res, float_tolerance);
398 res,
401 4,
402 2.2f,
403 -0.1f,
406 EXPECT_V4_NEAR(exp3, res, float_tolerance);
407
408 /* Different wrap modes. */
409 float4 exp4 = {122.66441f, 89.68848f, 60.85706f, 32.02566f};
411 res,
414 4,
415 2.2f,
416 -0.1f,
419 EXPECT_V4_NEAR(exp4, res, float_tolerance);
420
421 float4 exp5 = {189.57422f, 157.32167f, 122.71796f, 95.81750f};
423 res,
426 4,
427 2.2f,
428 -0.1f,
431 EXPECT_V4_NEAR(exp5, res, float_tolerance);
432}
433
434TEST(math_interp, CubicMitchellCharExactSamples)
435{
436 uchar4 res;
437 uchar4 exp1 = {72, 101, 140, 223};
439 EXPECT_EQ(int4(exp1), int4(res));
440 uchar4 exp2 = {233, 162, 99, 37};
442 EXPECT_EQ(int4(exp2), int4(res));
443}
444
445TEST(math_interp, CubicMitchellCharSamples)
446{
447 uchar4 res;
448 uchar4 exp1 = {135, 132, 130, 127};
450 image_char[0][0], image_width, image_height, 1.25f, 0.625f);
451 EXPECT_EQ(int4(exp1), int4(res));
452 uchar4 exp2 = {216, 189, 167, 143};
454 EXPECT_EQ(int4(exp2), int4(res));
455}
456
457TEST(math_interp, CubicMitchellFloatSamples)
458{
459 float4 res;
460 float4 exp1 = {134.5659f, 131.91309f, 130.17685f, 126.66989f};
462 EXPECT_V4_NEAR(exp1, res, float_tolerance);
463 float4 exp2 = {216.27115f, 189.30673f, 166.93599f, 143.31964f};
465 EXPECT_V4_NEAR(exp2, res, float_tolerance);
466}
467
468TEST(math_interp, CubicMitchellCharPartiallyOutsideImage)
469{
470 uchar4 res;
471 uchar4 exp1 = {0, 0, 0, 0};
473 EXPECT_EQ(int4(exp1), int4(res));
474 uchar4 exp2 = {88, 116, 151, 228};
476 EXPECT_EQ(int4(exp2), int4(res));
477 uchar4 exp3 = {239, 159, 89, 19};
479 EXPECT_EQ(int4(exp3), int4(res));
480}
481
482TEST(math_interp, CubicMitchellFloatPartiallyOutsideImage)
483{
484 float4 res;
485 float4 exp1 = {0, 0, 0, 0};
487 EXPECT_V4_NEAR(exp1, res, float_tolerance);
488 float4 exp2 = {87.98676f, 115.63634f, 151.13014f, 228.19823f};
490 EXPECT_V4_NEAR(exp2, res, float_tolerance);
491 float4 exp3 = {238.6136f, 158.58293f, 88.55761f, 18.53225f};
493 EXPECT_V4_NEAR(exp3, res, float_tolerance);
494}
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
static constexpr float float_tolerance
static constexpr int image_width
static constexpr uchar image_char[image_height][image_width][4]
static constexpr float image_fl[image_height][image_width][4]
static constexpr int image_height
unsigned char uchar
#define exp2
#define exp
uchar4 interpolate_cubic_mitchell_byte(const uchar *buffer, int width, int height, float u, float v)
uchar4 interpolate_bilinear_wrap_byte(const uchar *buffer, int width, int height, float u, float v)
uchar4 interpolate_bilinear_byte(const uchar *buffer, int width, int height, float u, float v)
void interpolate_nearest_border_fl(const float *buffer, float *output, int width, int height, int components, float u, float v)
float4 interpolate_bilinear_border_fl(const float *buffer, int width, int height, float u, float v)
float4 interpolate_bilinear_wrap_fl(const float *buffer, int width, int height, float u, float v)
float4 interpolate_cubic_bspline_fl(const float *buffer, int width, int height, float u, float v)
float4 interpolate_bilinear_fl(const float *buffer, int width, int height, float u, float v)
float4 interpolate_cubic_mitchell_fl(const float *buffer, int width, int height, float u, float v)
void interpolate_bilinear_wrapmode_fl(const float *buffer, float *output, int width, int height, int components, float u, float v, InterpWrapMode wrap_u, InterpWrapMode wrap_v)
uchar4 interpolate_cubic_bspline_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)
void interpolate_nearest_border_byte(const uchar *buffer, uchar *output, int width, int height, float u, float v)
void interpolate_cubic_bspline_wrapmode_fl(const float *buffer, float *output, int width, int height, int components, float u, float v, InterpWrapMode wrap_u, InterpWrapMode wrap_v)
VecBase< int32_t, 4 > int4
VecBase< uint32_t, 4 > uint4
TEST(compression, filter_transpose_delta)