Skip to content

Commit 5482ecd

Browse files
authored
fix(exr): improve attribute translation rules (#4946)
In exr output, we were doing attribute name substitutions using case-insensitive comparisions, whereas on the exr input side, we were using case-sensitive comparisons. This was leading to some strange behavior where certain attributes were not properly "round tripping" when reading and writing exr files, particularly when it involved attribute names that differed only in case from certain reserved/standard names. Also be a little more flexible in adjusting exr attributes that have the wrong type, by being able to convert int or float to a value that's required to be a string. Signed-off-by: Larry Gritz <[email protected]>
1 parent 1417836 commit 5482ecd

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

src/openexr.imageio/exroutput.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,8 +1140,7 @@ OpenEXROutput::put_parameter(const std::string& name, TypeDesc type,
11401140
TypeDesc exrtype = TypeUnknown;
11411141

11421142
for (const auto& e : exr_meta_translation) {
1143-
if (Strutil::iequals(xname, e.oiioname)
1144-
|| (e.exrname && Strutil::iequals(xname, e.exrname))) {
1143+
if (xname == e.oiioname || (e.exrname && xname == e.exrname)) {
11451144
xname = std::string(e.exrname ? e.exrname : "");
11461145
exrtype = e.exrtype;
11471146
// std::cerr << "exr put '" << name << "' -> '" << xname << "'\n";
@@ -1267,6 +1266,7 @@ OpenEXROutput::put_parameter(const std::string& name, TypeDesc type,
12671266
// OpenEXR expects, and we can make a good guess about how to translate.
12681267
float tmpfloat;
12691268
int tmpint;
1269+
ustring tmpstring;
12701270
if (exrtype == TypeFloat && type == TypeInt) {
12711271
tmpfloat = float(*(const int*)data);
12721272
data = &tmpfloat;
@@ -1278,10 +1278,19 @@ OpenEXROutput::put_parameter(const std::string& name, TypeDesc type,
12781278
} else if (exrtype == TypeMatrix && type == TypeDesc(TypeDesc::FLOAT, 16)) {
12791279
// Automatically translate float[16] to Matrix when expected
12801280
type = TypeMatrix;
1281+
} else if (exrtype == TypeString && type == TypeFloat) {
1282+
tmpstring = ustring::fmtformat("{}", *(const float*)data);
1283+
data = &tmpstring;
1284+
type = TypeString;
1285+
} else if (exrtype == TypeString && type == TypeInt) {
1286+
tmpstring = ustring::fmtformat("{}", *(const int*)data);
1287+
data = &tmpstring;
1288+
type = TypeString;
12811289
}
12821290

12831291
// Now if we still don't match a specific type OpenEXR is looking for,
1284-
// skip it.
1292+
// skip it. If we ever support warnings for ImageOutput, we should make
1293+
// this a warning.
12851294
if (exrtype != TypeDesc() && !exrtype.equivalent(type)) {
12861295
OIIO::debugfmt(
12871296
"OpenEXR output metadata \"{}\" type mismatch: expected {}, got {}\n",

0 commit comments

Comments
 (0)