Blender V4.3
source/blender/blenkernel/intern/image_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_listbase.h"
6#include "BLI_path_utils.hh"
7#include "BLI_string.h"
8#include "BLI_string_ref.hh"
9#include "BLI_vector.hh"
10
11#include "BKE_global.hh"
12#include "BKE_idtype.hh"
13#include "BKE_image.hh"
14#include "BKE_main.hh"
15
16#include "MEM_guardedalloc.h"
17
18#include "testing/testing.h"
19#include "gmock/gmock.h"
20
21#include "IMB_moviecache.hh"
22
23#include "DNA_image_types.h"
24
25#include "RE_pipeline.h"
26
27#include "CLG_log.h"
28
29namespace blender::bke::tests {
30
31using testing::Eq;
32using testing::Pointwise;
33
34TEST(udim, image_ensure_tile_token)
35{
36 auto verify = [](const char *original, const char *expected) {
37 char result[FILE_MAX];
38
39 STRNCPY(result, original);
40 BKE_image_ensure_tile_token_filename_only(result, sizeof(result));
41 EXPECT_STREQ(result, expected);
42 };
43
44 /* Already present tokens. */
45 verify("test.<UDIM>.png", "test.<UDIM>.png");
46 verify("test.<UVTILE>.png", "test.<UVTILE>.png");
47
48 /* UDIM pattern detection. */
49 verify("test.1002.png", "test.<UDIM>.png");
50 verify("test-1002-ao.png", "test-<UDIM>-ao.png");
51 verify("test_1002_ao.png", "test_<UDIM>_ao.png");
52 verify("test.1002.ver0023.png", "test.<UDIM>.ver0023.png");
53 verify("test.ver0023.1002.png", "test.ver0023.<UDIM>.png");
54 verify("test.1002.1.png", "test.<UDIM>.1.png");
55 verify("test.1.1002.png", "test.1.<UDIM>.png");
56 verify("test-2022-01-01.1002.png", "test-2022-01-01.<UDIM>.png");
57 verify("1111_11.1002.png", "1111_11.<UDIM>.png");
58 verify("2111_01.1002.png", "2111_01.<UDIM>.png");
59 verify("2022_1002_100200.1002.png", "2022_1002_100200.<UDIM>.png");
60
61 /* UVTILE pattern detection. */
62 verify("uv-test.u2_v10.png", "uv-test.<UVTILE>.png");
63 verify("uv-test-u2_v10-ao.png", "uv-test-<UVTILE>-ao.png");
64 verify("uv-test_u2_v10_ao.png", "uv-test_<UVTILE>_ao.png");
65 verify("uv-test.u10_v100.png", "uv-test.<UVTILE>.png");
66 verify("u_v-test.u2_v10.png", "u_v-test.<UVTILE>.png");
67 verify("u2_v10uv-test.png", "<UVTILE>uv-test.png");
68 verify("u2_v10u_v-test.png", "<UVTILE>u_v-test.png");
69
70 /* Patterns which should not be detected as UDIMs. */
71 for (const char *incorrect : {"1002.png",
72 "1002test.png",
73 "test1002.png",
74 "test(1002).png",
75 "(1002)test.png",
76 "test-1080p.png",
77 "test-1920x1080.png",
78 "test.123.png",
79 "test.12345.png",
80 "test.uv.png",
81 "test.u1v.png",
82 "test.uv1.png",
83 "test.u_v.png",
84 "test.u1_v.png",
85 "test.u_v2.png",
86 "test.u2v3.png",
87 "test.u123_v1.png",
88 "test.u1_v12345.png"})
89 {
90 /* These should not result in modifications happening. */
91 verify(incorrect, incorrect);
92 }
93}
94
95TEST(udim, image_get_tile_strformat)
96{
97 eUDIM_TILE_FORMAT tile_format;
98 char *udim_pattern;
99
100 /* Parameter validation. */
101 udim_pattern = BKE_image_get_tile_strformat(nullptr, &tile_format);
102 EXPECT_EQ(udim_pattern, nullptr);
103
104 udim_pattern = BKE_image_get_tile_strformat("", nullptr);
105 EXPECT_EQ(udim_pattern, nullptr);
106
107 /* Typical usage. */
108 udim_pattern = BKE_image_get_tile_strformat("", &tile_format);
109 EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_NONE);
110 EXPECT_EQ(udim_pattern, nullptr);
111
112 udim_pattern = BKE_image_get_tile_strformat("test.<UNKNOWN>.png", &tile_format);
113 EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_NONE);
114 EXPECT_EQ(udim_pattern, nullptr);
115
116 udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format);
117 EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM);
118 EXPECT_STREQ(udim_pattern, "test.%d.png");
119 MEM_freeN(udim_pattern);
120
121 udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format);
123 EXPECT_STREQ(udim_pattern, "test.u%d_v%d.png");
124 MEM_freeN(udim_pattern);
125}
126
127TEST(udim, image_get_tile_number_from_filepath)
128{
129 eUDIM_TILE_FORMAT tile_format;
130 char *udim_pattern;
131 int tile_number;
132
133 udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format);
134 EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM);
135 EXPECT_NE(udim_pattern, nullptr);
136
137 /* Parameter validation. */
138 EXPECT_FALSE(
139 BKE_image_get_tile_number_from_filepath(nullptr, udim_pattern, tile_format, &tile_number));
141 "test.1004.png", nullptr, tile_format, &tile_number));
143 "test.1004.png", udim_pattern, UDIM_TILE_FORMAT_NONE, &tile_number));
145 "test.1004.png", udim_pattern, tile_format, nullptr));
146
147 /* UDIM tile format tests. */
149 "test.1004.png", udim_pattern, tile_format, &tile_number));
150 EXPECT_EQ(tile_number, 1004);
151
153 "has_no_number.png", udim_pattern, tile_format, &tile_number));
155 "test.X.png", udim_pattern, tile_format, &tile_number));
157 "wrong.1004.png", udim_pattern, tile_format, &tile_number));
158
159 MEM_freeN(udim_pattern);
160
161 /* UVTILE tile format tests. */
162 udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format);
164 EXPECT_NE(udim_pattern, nullptr);
165
167 "test.u2_v2.png", udim_pattern, tile_format, &tile_number));
168 EXPECT_EQ(tile_number, 1012);
169
171 "has_no_number.png", udim_pattern, tile_format, &tile_number));
173 "test.u1_vX.png", udim_pattern, tile_format, &tile_number));
175 "test.uX_v1.png", udim_pattern, tile_format, &tile_number));
177 "wrong.u2_v2.png", udim_pattern, tile_format, &tile_number));
178
179 MEM_freeN(udim_pattern);
180}
181
182TEST(udim, image_set_filepath_from_tile_number)
183{
184 eUDIM_TILE_FORMAT tile_format;
185 char *udim_pattern;
186
187 udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format);
188 EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM);
189 EXPECT_NE(udim_pattern, nullptr);
190
191 char filepath[FILE_MAX];
192
193 /* Parameter validation. */
194 STRNCPY(filepath, "xxxx");
195
196 BKE_image_set_filepath_from_tile_number(nullptr, udim_pattern, tile_format, 1028);
197 BKE_image_set_filepath_from_tile_number(filepath, nullptr, tile_format, 1028);
198 EXPECT_STREQ(filepath, "xxxx");
200 EXPECT_STREQ(filepath, "xxxx");
201
202 /* UDIM tile format tests. */
203 BKE_image_set_filepath_from_tile_number(filepath, udim_pattern, tile_format, 1028);
204 EXPECT_STREQ(filepath, "test.1028.png");
205 MEM_freeN(udim_pattern);
206
207 /* UVTILE tile format tests. */
208 udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format);
210 EXPECT_NE(udim_pattern, nullptr);
211
212 BKE_image_set_filepath_from_tile_number(filepath, udim_pattern, tile_format, 1028);
213 EXPECT_STREQ(filepath, "test.u8_v3.png");
214 MEM_freeN(udim_pattern);
215}
216
217class ImageTest : public ::testing::Test {
218 Main *bmain_ = nullptr;
219
220 RenderResult *get_image_render_result(Image &image)
221 {
222 ImageUser iuser{};
223 BKE_imageuser_default(&iuser);
224
225 ImBuf *temp_ibuf = BKE_image_acquire_ibuf(&image, &iuser, nullptr);
226 BKE_image_release_ibuf(&image, temp_ibuf, nullptr);
227
228 return image.rr;
229 }
230
231 protected:
232 static void SetUpTestSuite()
233 {
234 CLG_init();
236 }
237
238 static void TearDownTestSuite()
239 {
240 CLG_exit();
241 }
242
243 void SetUp() override
244 {
246
247 bmain_ = BKE_main_new();
248 G_MAIN = bmain_;
249 }
250
251 void TearDown() override
252 {
253 BKE_main_free(bmain_);
254 G_MAIN = nullptr;
255
257 }
258
259 Image *load_image(const char *path)
260 {
261 const std::string asset_dir = blender::tests::flags_test_asset_dir().c_str();
262 return BKE_image_load(bmain_, (asset_dir + SEP_STR + "imbuf_io" + SEP_STR + path).c_str());
263 }
264
266 {
267 RenderResult *render_result = get_image_render_result(image);
268 if (!render_result) {
269 ADD_FAILURE() << "Missing image RenderResult";
270 return {};
271 }
272
273 Vector<std::string> layer_names;
274 LISTBASE_FOREACH (const RenderLayer *, layer, &render_result->layers) {
275 layer_names.append(layer->name);
276 }
277
278 return layer_names;
279 }
280
282 {
283 RenderResult *render_result = get_image_render_result(image);
284 if (!render_result) {
285 ADD_FAILURE() << "Missing image RenderResult";
286 return {};
287 }
288
289 LISTBASE_FOREACH (const RenderLayer *, layer, &render_result->layers) {
290 if (layer->name == layer_name) {
291 Vector<std::string> pass_names;
292 LISTBASE_FOREACH (const RenderPass *, pass, &layer->passes) {
293 pass_names.append(pass->name);
294 }
295 return pass_names;
296 }
297 }
298
299 return {};
300 }
301};
302
303TEST_F(ImageTest, multilayer)
304{
305 /* Multi-layer file from another DCC originally reported as #108980.
306 * The expected passes are obtained from Blender 4.2 Beta f069692caf8, with the
307 * !118867 reverted. File Scene_RenderLayer_000.exr from the report was used. */
308 {
309 Image *image = load_image("multilayer" SEP_STR "108980.exr");
310 ASSERT_NE(image, nullptr);
311
312 EXPECT_THAT(get_image_layer_names(*image), Pointwise(Eq(), {""}));
313 EXPECT_THAT(get_image_pass_names_for_layer(*image, ""),
314 Pointwise(Eq(),
315 {"Combined",
316 "Albedo",
317 "Nsx",
318 "Nsy",
319 "Nsz",
320 "Nx",
321 "Ny",
322 "Nz",
323 "Px",
324 "Py",
325 "Pz",
326 "RelativeVariance",
327 "Variance",
328 "dzdx",
329 "dzdy",
330 "u"}));
331 }
332
333 /* Multi-layer file from another DCC originally reported as #124217.
334 * The expected passes are obtained from Blender 4.2 Beta f069692caf8, with the
335 * !118867 reverted. File test.exr from the report was used. */
336 {
337 Image *image = load_image("multilayer" SEP_STR "124217.exr");
338 ASSERT_NE(image, nullptr);
339
340 EXPECT_THAT(get_image_layer_names(*image), Pointwise(Eq(), {""}));
341 EXPECT_THAT(get_image_pass_names_for_layer(*image, ""),
342 Pointwise(Eq(),
343 {"Combined",
344 "Depth",
345 "AO",
346 "ID",
347 "crypto_material",
348 "crypto_material00",
349 "crypto_material01",
350 "crypto_material02",
351 "crypto_material03",
352 "crypto_material04",
353 "crypto_material05",
354 "crypto_material06",
355 "crypto_object",
356 "crypto_object00",
357 "crypto_object01",
358 "crypto_object02",
359 "crypto_object03",
360 "crypto_object04",
361 "crypto_object05",
362 "crypto_object06",
363 "diffuse",
364 "opacity",
365 "specular",
366 "v"}));
367 }
368
369 /* Multi-part file from another DCC, originally reported as #101227.
370 * The expected passes are obtained from Blender 4.2 Beta f069692caf8, with the
371 * !118867 landed. */
372 {
373 Image *image = load_image("multilayer" SEP_STR "101227.exr");
374 ASSERT_NE(image, nullptr);
375
376 EXPECT_THAT(get_image_layer_names(*image), Pointwise(Eq(), {""}));
377 EXPECT_THAT(get_image_pass_names_for_layer(*image, ""),
378 Pointwise(Eq(), {"C", "N", "albedo", "depth"}));
379 }
380}
381
382} // namespace blender::bke::tests
#define G_MAIN
void BKE_idtype_init()
Definition idtype.cc:127
eUDIM_TILE_FORMAT
Definition BKE_image.hh:422
@ UDIM_TILE_FORMAT_UVTILE
Definition BKE_image.hh:425
@ UDIM_TILE_FORMAT_NONE
Definition BKE_image.hh:423
@ UDIM_TILE_FORMAT_UDIM
Definition BKE_image.hh:424
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
char * BKE_image_get_tile_strformat(const char *filepath, eUDIM_TILE_FORMAT *r_tile_format)
Image * BKE_image_load(Main *bmain, const char *filepath)
void BKE_image_set_filepath_from_tile_number(char *filepath, const char *pattern, eUDIM_TILE_FORMAT tile_format, int tile_number)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
bool BKE_image_get_tile_number_from_filepath(const char *filepath, const char *pattern, eUDIM_TILE_FORMAT tile_format, int *r_tile_number)
void BKE_image_ensure_tile_token_filename_only(char *filename, size_t filename_maxncpy)
void BKE_imageuser_default(ImageUser *iuser)
Main * BKE_main_new(void)
Definition main.cc:45
void BKE_main_free(Main *bmain)
Definition main.cc:175
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
#define LISTBASE_FOREACH(type, var, list)
#define FILE_MAX
#define STRNCPY(dst, src)
Definition BLI_string.h:593
void CLG_exit(void)
Definition clog.c:706
void CLG_init(void)
Definition clog.c:699
void IMB_moviecache_destruct()
void IMB_moviecache_init()
Read Guarded memory(de)allocation.
void append(const T &value)
Vector< std::string > get_image_pass_names_for_layer(Image &image, StringRefNull layer_name)
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
TEST_F(BKE_armature_find_selected_bones_test, some_bones_selected)
TEST(action_groups, ReconstructGroupsWithReordering)
ListBase layers
#define SEP_STR
Definition unit.cc:39