Blender V5.0
cryptomatte_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "testing/testing.h"
6
7#include "BKE_cryptomatte.h"
8#include "BKE_cryptomatte.hh"
9#include "BKE_image.hh"
10
11#include "RE_pipeline.h"
12
13#include "MEM_guardedalloc.h"
14
16
17TEST(cryptomatte, meta_data_key)
18{
19 ASSERT_EQ("cryptomatte/c7dbf5e/key",
20 BKE_cryptomatte_meta_data_key("ViewLayer.CryptoMaterial", "key"));
21 ASSERT_EQ("cryptomatte/b990b65/𝓴𝓮𝔂",
22 BKE_cryptomatte_meta_data_key("𝖚𝖓𝖎𝖈𝖔𝖉𝖊.CryptoMaterial", "𝓴𝓮𝔂"));
23}
24
25TEST(cryptomatte, extract_layer_name)
26{
27 ASSERT_EQ("ViewLayer.CryptoMaterial",
28 BKE_cryptomatte_extract_layer_name("ViewLayer.CryptoMaterial00"));
29 ASSERT_EQ("𝖚𝖓𝖎𝖈𝖔𝖉𝖊", BKE_cryptomatte_extract_layer_name("𝖚𝖓𝖎𝖈𝖔𝖉𝖊13"));
30 ASSERT_EQ("NoTrailingSampleNumber",
31 BKE_cryptomatte_extract_layer_name("NoTrailingSampleNumber"));
32 ASSERT_EQ("W1thM1dd13Numb3rs", BKE_cryptomatte_extract_layer_name("W1thM1dd13Numb3rs09"));
33 ASSERT_EQ("", BKE_cryptomatte_extract_layer_name("0123"));
34 ASSERT_EQ("", BKE_cryptomatte_extract_layer_name(""));
35}
36
38{
40 ASSERT_EQ("{}", layer.manifest());
41
42 layer.add_hash("Object", 123);
43 ASSERT_EQ("{\"Object\":\"0000007b\"}", layer.manifest());
44
45 layer.add_hash("Object2", 123245678);
46 ASSERT_EQ("{\"Object\":\"0000007b\",\"Object2\":\"0758946e\"}", layer.manifest());
47}
48
49TEST(cryptomatte, layer_quoted)
50{
52 layer.add_hash("\"Object\"", 123);
53 ASSERT_EQ("{\"\\\"Object\\\"\":\"0000007b\"}", layer.manifest());
54}
55
56static void test_cryptomatte_manifest(std::string expected, std::string manifest)
57{
58 EXPECT_EQ(expected,
59 blender::bke::cryptomatte::CryptomatteLayer::read_from_manifest(manifest)->manifest());
60}
61
62TEST(cryptomatte, layer_from_manifest)
63{
64 test_cryptomatte_manifest("{}", "{}");
65 test_cryptomatte_manifest(R"({"Object":"12345678"})", R"({"Object": "12345678"})");
66 test_cryptomatte_manifest(R"({"Object":"12345678","Object2":"87654321"})",
67 R"({"Object":"12345678","Object2":"87654321"})");
68 test_cryptomatte_manifest(R"({"Object":"12345678","Object2":"87654321"})",
69 R"( { "Object" : "12345678" , "Object2" : "87654321" } )");
70 test_cryptomatte_manifest(R"({"Object\"01\"":"12345678"})", R"({"Object\"01\"": "12345678"})");
72 R"({"Object\"01\"":"12345678","Object":"12345678","Object2":"87654321"})",
73 R"({"Object\"01\"":"12345678","Object":"12345678", "Object2":"87654321"})");
74}
75
76TEST(cryptomatte, extract_layer_hash_from_metadata_key)
77{
78 EXPECT_EQ("eb4c67b",
80 "cryptomatte/eb4c67b/conversion"));
81 EXPECT_EQ("qwerty",
83 "cryptomatte/qwerty/name"));
84 /* Check if undefined behaviors are handled. */
85 EXPECT_EQ("",
87 "cryptomatte/name"));
88 EXPECT_EQ("",
90 "cryptomatte/"));
91}
92
94 const char *propname,
95 char *propvalue,
96 int /*propvalue_maxncpy*/)
97{
98 blender::StringRefNull prop_name(propname);
99 if (!prop_name.startswith("cryptomatte/")) {
100 return;
101 }
102
103 if (prop_name == "cryptomatte/67da54b/name") {
104 EXPECT_STREQ("layer1", propvalue);
105 }
106 else if (prop_name == "cryptomatte/67da54b/hash") {
107 EXPECT_STREQ("MurmurHash3_32", propvalue);
108 }
109 else if (prop_name == "cryptomatte/67da54b/conversion") {
110 EXPECT_STREQ("uint32_to_float32", propvalue);
111 }
112 else if (prop_name == "cryptomatte/67da54b/manifest") {
113 EXPECT_STREQ(R"({"Object":"12345678"})", propvalue);
114 }
115
116 else if (prop_name == "cryptomatte/79b2306/name") {
117 EXPECT_STREQ("layer2", propvalue);
118 }
119 else if (prop_name == "cryptomatte/79b2306/hash") {
120 EXPECT_STREQ("MurmurHash3_32", propvalue);
121 }
122 else if (prop_name == "cryptomatte/79b2306/conversion") {
123 EXPECT_STREQ("uint32_to_float32", propvalue);
124 }
125 else if (prop_name == "cryptomatte/79b2306/manifest") {
126 EXPECT_STREQ(R"({"Object2":"87654321"})", propvalue);
127 }
128
129 else {
130 EXPECT_EQ("Unhandled", std::string(propname) + ": " + propvalue);
131 }
132}
133
134TEST(cryptomatte, session_from_stamp_data)
135{
136 /* Create CryptomatteSession from stamp data. */
137 RenderResult *render_result = MEM_callocN<RenderResult>(__func__);
138 BKE_render_result_stamp_data(render_result, "cryptomatte/qwerty/name", "layer1");
140 render_result, "cryptomatte/qwerty/manifest", R"({"Object":"12345678"})");
141 BKE_render_result_stamp_data(render_result, "cryptomatte/uiop/name", "layer2");
143 render_result, "cryptomatte/uiop/manifest", R"({"Object2":"87654321"})");
145 EXPECT_NE(session.get(), nullptr);
146 RE_FreeRenderResult(render_result);
147
148 /* Create StampData from CryptomatteSession. */
149 RenderResult *render_result2 = MEM_callocN<RenderResult>(__func__);
150 BKE_cryptomatte_store_metadata(session.get(), render_result2);
151
152 /* Validate StampData. */
154 nullptr, render_result2->stamp_data, validate_cryptomatte_session_from_stamp_data, false);
155
156 RE_FreeRenderResult(render_result2);
157}
158
162TEST(cryptomatte, parsing_malformed_manifests)
163{
164 /* Manifest from `multilayer.exr` in the cryptomatte git-repository. */
166 R"({"/obj/instance1:instances:0":"0d54c6cc","/obj/instance1:instances:1":"293d9340","/obj/instance1:instances:110":"ccb9e1f2","/obj/instance1:instances:111":"f8dd3a48","/obj/instance1:instances:112":"a99e07a8","/obj/instance1:instances:113":"e75599a4","/obj/instance1:instances:114":"794200f3","/obj/instance1:instances:115":"2a3a1728","/obj/instance1:instances:116":"478544a1","/obj/instance1:instances:117":"b2bd969a","/obj/instance1:instances:10":"3a0c8681","/obj/instance1:instances:11":"01e5970d","/obj/box:polygons:1":"9d416418","/obj/instance1:instances:100":"2dcd2966","/obj/instance1:instances:101":"9331cd82","/obj/instance1:instances:102":"df50fccb","/obj/instance1:instances:103":"97f8590d","/obj/instance1:instances:104":"bbcd220d","/obj/instance1:instances:105":"4ae06139","/obj/instance1:instances:106":"8873d5ea","/obj/instance1:instances:107":"39d8af8d","/obj/instance1:instances:108":"bb11bd4e","/obj/instance1:instances:109":"a32bba35"})",
167 R"({"\/obj\/box:polygons:1":"9d416418","\/obj\/instance1:instances:0":"0d54c6cc","\/obj\/instance1:instances:1":"293d9340","\/obj\/instance1:instances:10":"3a0c8681","\/obj\/instance1:instances:100":"2dcd2966","\/obj\/instance1:instances:101":"9331cd82","\/obj\/instance1:instances:102":"df50fccb","\/obj\/instance1:instances:103":"97f8590d","\/obj\/instance1:instances:104":"bbcd220d","\/obj\/instance1:instances:105":"4ae06139","\/obj\/instance1:instances:106":"8873d5ea","\/obj\/instance1:instances:107":"39d8af8d","\/obj\/instance1:instances:108":"bb11bd4e","\/obj\/instance1:instances:109":"a32bba35","\/obj\/instance1:instances:11":"01e5970d","\/obj\/instance1:instances:110":"ccb9e1f2","\/obj\/instance1:instances:111":"f8dd3a48","\/obj\/instance1:instances:112":"a99e07a8","\/obj\/instance1:instances:113":"e75599a4","\/obj\/instance1:instances:114":"794200f3","\/obj\/instance1:instances:115":"2a3a1728","\/obj\/instance1:instances:116":"478544a1","\/obj\/instance1:instances:117":"b2bd969a","\/obj\/instance1:instance)");
168}
169} // namespace blender::bke::cryptomatte::tests
void BKE_cryptomatte_store_metadata(const struct CryptomatteSession *session, struct RenderResult *render_result)
struct CryptomatteSession * BKE_cryptomatte_init_from_render_result(const struct RenderResult *render_result)
void BKE_stamp_info_callback(void *data, StampData *stamp_data, StampCallback callback, bool noskip)
void BKE_render_result_stamp_data(RenderResult *rr, const char *key, const char *value)
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
Read Guarded memory(de)allocation.
constexpr bool startswith(StringRef prefix) const
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
static void test_cryptomatte_manifest(std::string expected, std::string manifest)
static void validate_cryptomatte_session_from_stamp_data(void *, const char *propname, char *propvalue, int)
TEST(cryptomatte, meta_data_key)
StringRef BKE_cryptomatte_extract_layer_name(StringRef render_pass_name)
std::unique_ptr< CryptomatteSession, CryptomatteSessionDeleter > CryptomatteSessionPtr
std::string BKE_cryptomatte_meta_data_key(StringRef layer_name, StringRefNull key_name)
void RE_FreeRenderResult(RenderResult *rr)
struct StampData * stamp_data
void add_hash(blender::StringRef name, CryptomatteHash cryptomatte_hash)
static blender::StringRef extract_layer_hash(blender::StringRefNull key)