Skip to content

Commit 49e4855

Browse files
committed
Improve RGB heuristics
Add unit tests
1 parent d8a9450 commit 49e4855

File tree

5 files changed

+91
-8
lines changed

5 files changed

+91
-8
lines changed

src/lib/OpenEXRCore/internal_ht_common.cpp

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ struct RGBChannelParams
2323
int r_index;
2424
int g_index;
2525
int b_index;
26+
const char* prefix;
27+
size_t prefix_len;
2628
};
2729

2830
static inline bool areEqual(const char* a, const char* b) {
@@ -54,9 +56,9 @@ make_channel_map (
5456
*/
5557

5658
RGBChannelParams params[] = {
57-
{"r", "g", "b", -1, -1, -1},
58-
{"red", "green", "blue", -1, -1, -1},
59-
{"red", "grn", "blu", -1, -1, -1}};
59+
{"r", "g", "b", -1, -1, -1, NULL, 0},
60+
{"red", "green", "blue", -1, -1, -1, NULL, 0},
61+
{"red", "grn", "blu", -1, -1, -1, NULL, 0}};
6062
constexpr size_t params_count = sizeof (params) / sizeof (params[0]);
6163

6264
cs_to_file_ch.resize (channel_count);
@@ -65,32 +67,53 @@ make_channel_map (
6567
{
6668
const char* channel_name = channels[i].channel_name;
6769
const char* suffix = strrchr (channel_name, '.');
68-
if (suffix) { suffix += 1; }
69-
else
70-
{
70+
const char* prefix = channel_name;
71+
size_t prefix_len = 0;
72+
if (suffix) {
73+
suffix += 1;
74+
prefix_len = suffix - prefix - 1;
75+
} else {
7176
suffix = channel_name;
7277
}
7378

7479
for (size_t j = 0; j < params_count; j++)
7580
{
81+
if (params[j].prefix != NULL &&
82+
(params[j].prefix_len != prefix_len ||
83+
strncmp (params[j].prefix, prefix, params[j].prefix_len)))
84+
{
85+
/* skip to the next potential match if a prefix has already been
86+
record and does not match the channel prefix */
87+
continue;
88+
}
89+
90+
bool match = false;
7691
if (areEqual (suffix, params[j].r_suffix) &&
7792
params[j].r_index < 0)
7893
{
7994
params[j].r_index = i;
80-
break;
95+
match = true;
8196
}
8297
else if (
8398
areEqual (suffix, params[j].g_suffix) &&
8499
params[j].g_index < 0)
85100
{
86101
params[j].g_index = i;
87-
break;
102+
match = true;
88103
}
89104
else if (
90105
areEqual (suffix, params[j].b_suffix) &&
91106
params[j].b_index < 0)
92107
{
93108
params[j].b_index = i;
109+
match = true;
110+
}
111+
112+
if (match) {
113+
/* record the prefix if one is not already recorded and move to
114+
the next channel */
115+
params[j].prefix = prefix;
116+
params[j].prefix_len = prefix_len;
94117
break;
95118
}
96119
}

src/test/OpenEXRCoreTest/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ define_openexrcore_tests(
118118
testB44ACompression
119119
testDWAACompression
120120
testDWABCompression
121+
testHTChannelMap
121122
testDeepNoCompression
122123
testDeepZIPCompression
123124
testDeepZIPSCompression

src/test/OpenEXRCoreTest/compression.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
#include <ImfOutputFile.h>
3737
#include <ImfTiledOutputFile.h>
3838
#include <half.h>
39+
40+
#include "internal_ht_common.cpp"
41+
3942
#ifdef __linux
4043
# include <sys/types.h>
4144
# include <sys/stat.h>
@@ -1693,6 +1696,60 @@ testDWABCompression (const std::string& tempdir)
16931696
testComp (tempdir, EXR_COMPRESSION_DWAB);
16941697
}
16951698

1699+
struct ht_channel_map_tests {
1700+
exr_coding_channel_info_t channels[6];
1701+
int channel_count;
1702+
bool pass;
1703+
int rgb_index[3];
1704+
};
1705+
1706+
void
1707+
testHTChannelMap (const std::string& tempdir)
1708+
{
1709+
std::vector<CodestreamChannelInfo> cs_to_file_ch;
1710+
ht_channel_map_tests tests[] = {
1711+
{{{"R"}, {"G"}, {"B"}}, 3, true, {0, 1, 2}},
1712+
{{{"r"}, {"G"}, {"b"}}, 3, true, {0, 1, 2}},
1713+
{{{"B"}, {"G"}, {"R"}}, 3, true, {2, 1, 0}},
1714+
{{{"red"}, {"green"}, {"blue"}}, 3, true, {0, 1, 2}},
1715+
{{{"Red"}, {"Green"}, {"Blue"}, {"alpha"}}, 4, true, {0, 1, 2}},
1716+
{{{"hello.R"}, {"hello.G"}, {"hello.B"}}, 3, true, {0, 1, 2}},
1717+
{{{"hello.R"}, {"bye.R"}, {"hello.G"}, {"bye.R"}, {"hello.B"}, {"bye.B"}}, 6, true, {0, 2, 4}},
1718+
{{{"red"}, {"green"}, {"blue"}}, 3, true, {0, 1, 2}},
1719+
/* the following are expected to fail */
1720+
{{{"redqueen"}, {"greens"}, {"blueberry"}}, 3, false, {0, 1, 2}},
1721+
{{{"hello.R"}, {"bye.G"}, {"hello.B"}}, 3, false, {0, 2, 4}},
1722+
};
1723+
int test_count = sizeof(tests) / sizeof(ht_channel_map_tests);
1724+
1725+
for (size_t i = 0; i < test_count; i++)
1726+
{
1727+
EXRCORE_TEST (
1728+
make_channel_map (
1729+
tests[i].channel_count, tests[i].channels, cs_to_file_ch) ==
1730+
tests[i].pass);
1731+
if (tests[i].pass)
1732+
{
1733+
for (size_t j = 0; j < 3; j++)
1734+
{
1735+
EXRCORE_TEST (
1736+
tests[i].rgb_index[j] == cs_to_file_ch[j].file_index);
1737+
}
1738+
}
1739+
}
1740+
1741+
exr_coding_channel_info_t channels_1[] = {
1742+
{ "R" }, { "G" }, { "B" }
1743+
};
1744+
1745+
exr_coding_channel_info_t channels_2[] = {
1746+
{ "R" }, { "G" }, { "1.B" }
1747+
};
1748+
1749+
EXRCORE_TEST (make_channel_map (3, channels_1, cs_to_file_ch));
1750+
EXRCORE_TEST (! make_channel_map (3, channels_2, cs_to_file_ch));
1751+
}
1752+
16961753
void
16971754
testDeepNoCompression (const std::string& tempdir)
16981755
{}

src/test/OpenEXRCoreTest/compression.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ void testB44Compression (const std::string& tempdir);
2222
void testB44ACompression (const std::string& tempdir);
2323
void testDWAACompression (const std::string& tempdir);
2424
void testDWABCompression (const std::string& tempdir);
25+
void testHTChannelMap (const std::string& tempdir);
2526

2627
void testDeepNoCompression (const std::string& tempdir);
2728
void testDeepZIPCompression (const std::string& tempdir);

src/test/OpenEXRCoreTest/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ main (int argc, char* argv[])
206206
TEST (testB44ACompression, "core_compression");
207207
TEST (testDWAACompression, "core_compression");
208208
TEST (testDWABCompression, "core_compression");
209+
TEST (testHTChannelMap, "core_compression");
209210

210211
TEST (testDeepNoCompression, "core_compression");
211212
TEST (testDeepZIPCompression, "core_compression");

0 commit comments

Comments
 (0)