Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/CMakeLists.txt1
-rw-r--r--source/blender/blenkernel/intern/image.cc79
-rw-r--r--source/blender/blenkernel/intern/image_test.cc186
3 files changed, 205 insertions, 61 deletions
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 3b5272aa600..268239ed7b5 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -818,6 +818,7 @@ if(WITH_GTESTS)
intern/cryptomatte_test.cc
intern/curves_geometry_test.cc
intern/fcurve_test.cc
+ intern/image_test.cc
intern/idprop_serialize_test.cc
intern/image_partial_update_test.cc
intern/lattice_deform_test.cc
diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc
index cfdd048495d..0e3c913189c 100644
--- a/source/blender/blenkernel/intern/image.cc
+++ b/source/blender/blenkernel/intern/image.cc
@@ -9,6 +9,7 @@
#include <cmath>
#include <cstdio>
#include <cstring>
+#include <ctime>
#include <fcntl.h>
#ifndef WIN32
# include <unistd.h>
@@ -16,7 +17,8 @@
# include <io.h>
#endif
-#include <ctime>
+#include <regex>
+#include <string>
#include "BLI_array.hh"
@@ -3316,69 +3318,24 @@ void BKE_image_ensure_tile_token(char *filename)
return;
}
- /* Is there a sequence of digits in the filename? */
- ushort digits;
- char head[FILE_MAX], tail[FILE_MAX];
- BLI_path_sequence_decode(filename, head, tail, &digits);
- if (digits == 4) {
- sprintf(filename, "%s<UDIM>%s", head, tail);
- return;
- }
-
- /* Is there a sequence like u##_v#### in the filename? */
- uint cur = 0;
- uint name_end = strlen(filename);
- uint u_digits = 0;
- uint v_digits = 0;
- uint u_start = (uint)-1;
- bool u_found = false;
- bool v_found = false;
- bool sep_found = false;
- while (cur < name_end) {
- if (filename[cur] == 'u') {
- u_found = true;
- u_digits = 0;
- u_start = cur;
- }
- else if (filename[cur] == 'v') {
- v_found = true;
- v_digits = 0;
- }
- else if (u_found && !v_found) {
- if (isdigit(filename[cur]) && u_digits < 2) {
- u_digits++;
- }
- else if (filename[cur] == '_') {
- sep_found = true;
- }
- else {
- u_found = false;
- }
- }
- else if (u_found && u_digits > 0 && v_found) {
- if (isdigit(filename[cur])) {
- if (v_digits < 4) {
- v_digits++;
- }
- else {
- u_found = false;
- v_found = false;
- }
- }
- else if (v_digits > 0) {
- break;
- }
- }
+ std::string path(filename);
+ std::smatch match;
- cur++;
+ /* General 4-digit "udim" pattern. As this format is susceptible to ambiguity
+ * with other digit sequences, we can leverage the supported range of roughly
+ * 1000 through 2000 to provide better detection.
+ */
+ std::regex pattern("(^|.*?\\D)([12]\\d{3})(\\D.*)");
+ if (std::regex_search(path, match, pattern)) {
+ BLI_strncpy(filename, match.format("$1<UDIM>$3").c_str(), FILE_MAX);
+ return;
}
- if (u_found && sep_found && v_found && (u_digits + v_digits > 1)) {
- const char *token = "<UVTILE>";
- const size_t token_length = strlen(token);
- memmove(filename + u_start + token_length, filename + cur, name_end - cur);
- memcpy(filename + u_start, token, token_length);
- filename[u_start + token_length + (name_end - cur)] = '\0';
+ /* General u##_v### "uvtile" pattern. */
+ pattern = std::regex("(.*)(u\\d{1,2}_v\\d{1,3})(\\D.*)");
+ if (std::regex_search(path, match, pattern)) {
+ BLI_strncpy(filename, match.format("$1<UVTILE>$3").c_str(), FILE_MAX);
+ return;
}
}
diff --git a/source/blender/blenkernel/intern/image_test.cc b/source/blender/blenkernel/intern/image_test.cc
new file mode 100644
index 00000000000..9c15fc62d21
--- /dev/null
+++ b/source/blender/blenkernel/intern/image_test.cc
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. */
+
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+
+#include "BKE_image.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "testing/testing.h"
+
+namespace blender::bke::tests {
+
+TEST(udim, image_ensure_tile_token)
+{
+ auto verify = [](const char *original, const char *expected) {
+ char result[FILE_MAX];
+
+ BLI_strncpy(result, original, sizeof(result));
+ BKE_image_ensure_tile_token(result);
+ EXPECT_STREQ(result, expected);
+ };
+
+ /* Already present tokens. */
+ verify("test.<UDIM>.png", "test.<UDIM>.png");
+ verify("test.<UVTILE>.png", "test.<UVTILE>.png");
+
+ /* UDIM pattern detection. */
+ verify("test.1002.png", "test.<UDIM>.png");
+ verify("test-1002-ao.png", "test-<UDIM>-ao.png");
+ verify("test_1002_ao.png", "test_<UDIM>_ao.png");
+ verify("test.1002.ver0023.png", "test.<UDIM>.ver0023.png");
+ verify("test.ver0023.1002.png", "test.ver0023.<UDIM>.png");
+ verify("1002test.png", "<UDIM>test.png");
+ verify("test1002.png", "test<UDIM>.png");
+
+ /* UVTILE pattern detection. */
+ verify("uv-test.u2_v10.png", "uv-test.<UVTILE>.png");
+ verify("uv-test-u2_v10-ao.png", "uv-test-<UVTILE>-ao.png");
+ verify("uv-test_u2_v10_ao.png", "uv-test_<UVTILE>_ao.png");
+ verify("uv-test.u10_v100.png", "uv-test.<UVTILE>.png");
+ verify("u_v-test.u2_v10.png", "u_v-test.<UVTILE>.png");
+ verify("u2_v10uv-test.png", "<UVTILE>uv-test.png");
+ verify("u2_v10u_v-test.png", "<UVTILE>u_v-test.png");
+
+ /* Incorrect patterns. */
+ for (const char *incorrect : {"test.123.png",
+ "test.12345.png",
+ "test.uv.png",
+ "test.u1v.png",
+ "test.uv1.png",
+ "test.u_v.png",
+ "test.u1_v.png",
+ "test.u_v2.png",
+ "test.u2v3.png",
+ "test.u123_v1.png",
+ "test.u1_v12345.png"}) {
+ /* These should not result in modifications happening. */
+ verify(incorrect, incorrect);
+ }
+}
+
+TEST(udim, image_get_tile_strformat)
+{
+ eUDIM_TILE_FORMAT tile_format;
+ char *udim_pattern;
+
+ /* Parameter validation. */
+ udim_pattern = BKE_image_get_tile_strformat(nullptr, &tile_format);
+ EXPECT_EQ(udim_pattern, nullptr);
+
+ udim_pattern = BKE_image_get_tile_strformat("", nullptr);
+ EXPECT_EQ(udim_pattern, nullptr);
+
+ /* Typical usage. */
+ udim_pattern = BKE_image_get_tile_strformat("", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_NONE);
+ EXPECT_EQ(udim_pattern, nullptr);
+
+ udim_pattern = BKE_image_get_tile_strformat("test.<UNKNOWN>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_NONE);
+ EXPECT_EQ(udim_pattern, nullptr);
+
+ udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM);
+ EXPECT_STREQ(udim_pattern, "test.%d.png");
+ MEM_freeN(udim_pattern);
+
+ udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UVTILE);
+ EXPECT_STREQ(udim_pattern, "test.u%d_v%d.png");
+ MEM_freeN(udim_pattern);
+}
+
+TEST(udim, image_get_tile_number_from_filepath)
+{
+ eUDIM_TILE_FORMAT tile_format;
+ char *udim_pattern;
+ int tile_number;
+
+ udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM);
+ EXPECT_NE(udim_pattern, nullptr);
+
+ /* Parameter validation. */
+ EXPECT_FALSE(
+ BKE_image_get_tile_number_from_filepath(nullptr, udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.1004.png", nullptr, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.1004.png", udim_pattern, UDIM_TILE_FORMAT_NONE, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.1004.png", udim_pattern, tile_format, nullptr));
+
+ /* UDIM tile format tests. */
+ EXPECT_TRUE(BKE_image_get_tile_number_from_filepath(
+ "test.1004.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_EQ(tile_number, 1004);
+
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "has_no_number.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.X.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "wrong.1004.png", udim_pattern, tile_format, &tile_number));
+
+ MEM_freeN(udim_pattern);
+
+ /* UVTILE tile format tests. */
+ udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UVTILE);
+ EXPECT_NE(udim_pattern, nullptr);
+
+ EXPECT_TRUE(BKE_image_get_tile_number_from_filepath(
+ "test.u2_v2.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_EQ(tile_number, 1012);
+
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "has_no_number.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.u1_vX.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.uX_v1.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "wrong.u2_v2.png", udim_pattern, tile_format, &tile_number));
+
+ MEM_freeN(udim_pattern);
+}
+
+TEST(udim, image_set_filepath_from_tile_number)
+{
+ eUDIM_TILE_FORMAT tile_format;
+ char *udim_pattern;
+
+ udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM);
+ EXPECT_NE(udim_pattern, nullptr);
+
+ char filepath[FILE_MAX];
+
+ /* Parameter validation. */
+ BLI_strncpy(filepath, "xxxx", FILE_MAX);
+
+ BKE_image_set_filepath_from_tile_number(nullptr, udim_pattern, tile_format, 1028);
+ BKE_image_set_filepath_from_tile_number(filepath, nullptr, tile_format, 1028);
+ EXPECT_STREQ(filepath, "xxxx");
+ BKE_image_set_filepath_from_tile_number(filepath, udim_pattern, UDIM_TILE_FORMAT_NONE, 1028);
+ EXPECT_STREQ(filepath, "xxxx");
+
+ /* UDIM tile format tests. */
+ BKE_image_set_filepath_from_tile_number(filepath, udim_pattern, tile_format, 1028);
+ EXPECT_STREQ(filepath, "test.1028.png");
+ MEM_freeN(udim_pattern);
+
+ /* UVTILE tile format tests. */
+ udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UVTILE);
+ EXPECT_NE(udim_pattern, nullptr);
+
+ BKE_image_set_filepath_from_tile_number(filepath, udim_pattern, tile_format, 1028);
+ EXPECT_STREQ(filepath, "test.u8_v3.png");
+ MEM_freeN(udim_pattern);
+}
+
+} // namespace blender::bke::tests