Skip to content

Commit 3444cf8

Browse files
lgritz1div0
authored andcommitted
fix(oiiotool): --autocc bugfix and color config inventory cleanup (AcademySoftwareFoundation#4060)
The important bug fix is in oiiotool image input when autocc is used, where we reversed the sense of a test and did the autocc-upon-input if the file's color space was equivalent to the scene_linear space (pointlessly), and skipped the conversion if they were different (oh no, big bug!). Along the way: * Add missing try/catch around OCIO call that should have had it. * Some very ugly SPI-specific recognize-by-name color space heuristics. I hate this, sorry, but it solves a really important problem for me. * A bunch of additional debugging messages during color space inventory, enabled only when debugging, so nobody should see these but me. * A couple places where we canonicalize the spelling of "oiio:ColorSpace". Note that there is still an issue with the color space classification using OCIO 2.3+'s identification of built-in equivalents by name. These are shockingly expensive. I will return to this later. Signed-off-by: Larry Gritz <[email protected]> Signed-off-by: Peter Kovář <[email protected]>
1 parent 9091e93 commit 3444cf8

File tree

5 files changed

+79
-29
lines changed

5 files changed

+79
-29
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ if (${PROJ_NAME}_NAMESPACE_INCLUDE_PATCH)
144144
endif ()
145145
message(STATUS "Setting Namespace to: ${PROJ_NAMESPACE_V}")
146146

147+
set (OIIO_SITE "" CACHE STRING "Site name for customization")
148+
if (OIIO_SITE)
149+
add_definitions (-DOIIO_SITE_${OIIO_SITE})
150+
endif ()
151+
147152
# Define OIIO_INTERNAL symbol only when building OIIO itself, will not be
148153
# defined for downstream projects using OIIO.
149154
add_definitions (-DOIIO_INTERNAL=1)

src/libOpenImageIO/color_ocio.cpp

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ static const Imath::C3f test_colors[n_test_colors]
4949
} // namespace
5050

5151

52-
#if 0 /* allow color configuration debugging */
52+
#if 0 || !defined(NDEBUG) /* allow color configuration debugging */
5353
static bool colordebug = Strutil::stoi(Sysutil::getenv("OIIO_COLOR_DEBUG"));
5454
# define DBG(...) \
5555
if (colordebug) \
@@ -403,6 +403,13 @@ class ColorConfig::Impl {
403403
}
404404
}
405405

406+
void debug_print_aliases()
407+
{
408+
DBG("Aliases: scene_linear={} lin_srgb={} srgb={} ACEScg={} Rec709={}\n",
409+
scene_linear_alias, lin_srgb_alias, srgb_alias, ACEScg_alias,
410+
Rec709_alias);
411+
}
412+
406413
// For OCIO 2.3+, we can ask for the equivalent of some built-in
407414
// color spaces.
408415
void identify_builtin_equivalents();
@@ -490,10 +497,15 @@ OCIO::ConstCPUProcessorRcPtr
490497
ColorConfig::Impl::get_to_builtin_cpu_proc(const char* my_from,
491498
const char* builtin_to) const
492499
{
493-
auto proc = OCIO::Config::GetProcessorToBuiltinColorSpace(config_, my_from,
494-
builtin_to);
495-
return proc ? proc->getDefaultCPUProcessor()
496-
: OCIO::ConstCPUProcessorRcPtr();
500+
try {
501+
auto proc = OCIO::Config::GetProcessorToBuiltinColorSpace(config_,
502+
my_from,
503+
builtin_to);
504+
return proc ? proc->getDefaultCPUProcessor()
505+
: OCIO::ConstCPUProcessorRcPtr();
506+
} catch (...) {
507+
return {};
508+
}
497509
}
498510

499511
#endif
@@ -592,6 +604,16 @@ ColorConfig::Impl::classify_by_name(CSInfo& cs)
592604
cs.setflag(CSInfo::is_ACEScg | CSInfo::is_linear_response,
593605
ACEScg_alias);
594606
}
607+
#ifdef OIIO_SITE_spi
608+
// Ugly SPI-specific hacks, so sorry
609+
else if (Strutil::starts_with(cs.name, "cgln")) {
610+
cs.setflag(CSInfo::is_ACEScg | CSInfo::is_linear_response,
611+
ACEScg_alias);
612+
} else if (cs.name == "srgbf" || cs.name == "srgbh" || cs.name == "srgb16"
613+
|| cs.name == "srgb8") {
614+
cs.setflag(CSInfo::is_srgb, srgb_alias);
615+
}
616+
#endif
595617

596618
// Set up some canonical names
597619
if (cs.flags() & CSInfo::is_srgb)
@@ -602,13 +624,19 @@ ColorConfig::Impl::classify_by_name(CSInfo& cs)
602624
cs.canonical = "lin_srgb";
603625
else if (cs.flags() & CSInfo::is_ACEScg)
604626
cs.canonical = "ACEScg";
627+
if (cs.canonical.size()) {
628+
DBG("classify by name identified '{}' as canonical {}\n", cs.name,
629+
cs.canonical);
630+
cs.examined = true;
631+
}
605632
}
606633

607634

608635

609636
void
610637
ColorConfig::Impl::classify_by_conversions(CSInfo& cs)
611638
{
639+
DBG("classifying by conversions {}\n", cs.name);
612640
if (cs.examined)
613641
return; // Already classified
614642

@@ -698,26 +726,36 @@ void
698726
ColorConfig::Impl::identify_builtin_equivalents()
699727
{
700728
#if OCIO_VERSION_HEX >= MAKE_OCIO_VERSION_HEX(2, 3, 0)
729+
Timer timer;
701730
if (auto n = IdentifyBuiltinColorSpace("srgb_tx")) {
702731
if (CSInfo* cs = find(n)) {
703732
cs->setflag(CSInfo::is_srgb, srgb_alias);
704733
DBG("Identified {} = builtin '{}'\n", "srgb", cs->name);
705734
}
735+
} else {
736+
DBG("No config space identified as srgb\n");
706737
}
738+
DBG("identify_builtin_equivalents srgb took {:0.2f}s\n", timer.lap());
707739
if (auto n = IdentifyBuiltinColorSpace("lin_srgb")) {
708740
if (CSInfo* cs = find(n)) {
709741
cs->setflag(CSInfo::is_lin_srgb | CSInfo::is_linear_response,
710742
lin_srgb_alias);
711743
DBG("Identified {} = builtin '{}'\n", "lin_srgb", cs->name);
712744
}
745+
} else {
746+
DBG("No config space identified as lin_srgb\n");
713747
}
748+
DBG("identify_builtin_equivalents lin_srgb took {:0.2f}s\n", timer.lap());
714749
if (auto n = IdentifyBuiltinColorSpace("ACEScg")) {
715750
if (CSInfo* cs = find(n)) {
716751
cs->setflag(CSInfo::is_ACEScg | CSInfo::is_linear_response,
717752
ACEScg_alias);
718753
DBG("Identified {} = builtin '{}'\n", "ACEScg", cs->name);
719754
}
755+
} else {
756+
DBG("No config space identified as acescg\n");
720757
}
758+
DBG("identify_builtin_equivalents acescg took {:0.2f}s\n", timer.lap());
721759
#endif
722760
}
723761

@@ -798,23 +836,26 @@ ColorConfig::Impl::init(string_view filename)
798836

799837
ok = config_.get() != nullptr;
800838

801-
if (timer() > 0.1f)
802-
DBG("OCIO config {} loaded in {:0.2f} seconds\n", filename,
803-
timer.lap());
839+
DBG("OCIO config {} loaded in {:0.2f} seconds\n", filename, timer.lap());
804840
#endif
805841

806842
inventory();
807-
identify_builtin_equivalents();
843+
// NOTE: inventory already does classify_by_name
844+
808845
#if OCIO_VERSION_HEX < MAKE_OCIO_VERSION_HEX(2, 2, 0)
809846
// Prior to 2.2, there are some other heuristics we use
810847
for (auto&& cs : colorspaces)
811848
reclassify_heuristics(cs);
812849
#endif
813-
if (timer() > 0.1f)
814-
DBG("OCIO config classified in {:0.2f} seconds\n", timer.lap());
850+
#if OCIO_VERSION_HEX >= MAKE_OCIO_VERSION_HEX(2, 3, 0)
851+
DBG("\nIDENTIFY BUILTIN EQUIVALENTS\n");
852+
identify_builtin_equivalents(); // OCIO 2.3+ only
853+
DBG("OCIO 2.3+ builtin equivalents in {:0.2f} seconds\n", timer.lap());
854+
#endif
815855

816856
#if 1
817857
for (auto&& cs : colorspaces) {
858+
// examine(&cs);
818859
DBG("Color space '{}':\n", cs.name);
819860
if (cs.flags() & CSInfo::is_srgb)
820861
DBG("'{}' is srgb\n", cs.name);
@@ -832,9 +873,9 @@ ColorConfig::Impl::init(string_view filename)
832873
DBG("\n");
833874
}
834875
#endif
835-
DBG("Aliases: scene_linear={} lin_srgb={} srgb={} ACEScg={} Rec709={}\n",
836-
scene_linear_alias, lin_srgb_alias, srgb_alias, ACEScg_alias,
837-
Rec709_alias);
876+
debug_print_aliases();
877+
DBG("OCIO config {} classified in {:0.2f} seconds\n", filename,
878+
timer.lap());
838879

839880
return ok;
840881
}
@@ -845,7 +886,10 @@ bool
845886
ColorConfig::reset(string_view filename)
846887
{
847888
pvt::LoggedTimer logtime("ColorConfig::reset");
848-
if (m_impl && filename == getImpl()->configname()) {
889+
if (m_impl
890+
&& (filename == getImpl()->configname()
891+
|| (filename == ""
892+
&& getImpl()->configname() == "ocio://default"))) {
849893
// Request to reset to the config we're already using. Just return,
850894
// don't do anything expensive.
851895
return true;
@@ -1063,8 +1107,8 @@ ColorConfig::getColorSpaceNameByRole(string_view role) const
10631107
using Strutil::print;
10641108
OCIO::ConstColorSpaceRcPtr c = getImpl()->config_->getColorSpace(
10651109
std::string(role).c_str());
1066-
// print("looking first for named color space {} -> {}\n", role,
1067-
// c ? c->getName() : "not found");
1110+
// DBG("looking first for named color space {} -> {}\n", role,
1111+
// c ? c->getName() : "not found");
10681112
// Catch special case of obvious name synonyms
10691113
if (!c
10701114
&& (Strutil::iequals(role, "RGB")

src/oiiotool/oiiotool.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5381,30 +5381,31 @@ input_file(Oiiotool& ot, cspan<const char*> argv)
53815381
std::string colorspace(
53825382
ot.colorconfig.getColorSpaceFromFilepath(filename));
53835383
if (colorspace.size() && ot.debug)
5384-
std::cout << " From " << filename
5385-
<< ", we deduce color space \"" << colorspace
5386-
<< "\"\n";
5384+
print(" From {}, we deduce color space \"{}\"\n", filename,
5385+
colorspace);
53875386
if (colorspace.empty()) {
53885387
ot.read();
53895388
colorspace = ot.curimg->spec()->get_string_attribute(
53905389
"oiio:ColorSpace");
53915390
if (ot.debug)
5392-
std::cout << " Metadata of " << filename
5393-
<< " indicates color space \"" << colorspace
5394-
<< "\"\n";
5391+
print(" Metadata of {} indicates color space \"{}\"\n",
5392+
colorspace, filename);
53955393
}
53965394
std::string linearspace = ot.colorconfig.resolve("linear");
53975395
if (colorspace.size()
5398-
&& ot.colorconfig.equivalent(colorspace, linearspace)) {
5396+
&& !ot.colorconfig.equivalent(colorspace, linearspace)) {
53995397
std::string cmd = "colorconvert:strict=0";
54005398
if (autoccunpremult)
54015399
cmd += ":unpremult=1";
54025400
const char* argv[] = { cmd.c_str(), colorspace.c_str(),
54035401
linearspace.c_str() };
54045402
if (ot.debug)
5405-
std::cout << " Converting " << filename << " from "
5406-
<< colorspace << " to " << linearspace << "\n";
5403+
print(" Converting {} from {} to {}\n", filename,
5404+
colorspace, linearspace);
54075405
action_colorconvert(ot, argv);
5406+
} else if (ot.debug) {
5407+
print(" no auto conversion necessary for {}->{}\n", colorspace,
5408+
linearspace);
54085409
}
54095410
}
54105411

src/raw.imageio/rawinput.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,8 @@ RawInput::open_raw(bool unpack, const std::string& name,
662662
m_spec.attribute("raw:FilterPattern", filter);
663663

664664
// Also, any previously set demosaicing options are void, so remove them
665-
m_spec.erase_attribute("oiio:Colorspace");
666-
m_spec.erase_attribute("raw:Colorspace");
665+
m_spec.erase_attribute("oiio:ColorSpace");
666+
m_spec.erase_attribute("raw:ColorSpace");
667667
m_spec.erase_attribute("raw:Exposure");
668668
} else {
669669
errorf("raw:Demosaic set to unknown value");

src/term.imageio/termoutput.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ bool
128128
TermOutput::output()
129129
{
130130
// Color convert in place to sRGB, or it won't look right
131-
std::string cspace = m_buf.spec()["oiio:colorspace"].get();
131+
std::string cspace = m_buf.spec()["oiio:ColorSpace"].get();
132132
ImageBufAlgo::colorconvert(m_buf, m_buf, cspace, "sRGB");
133133

134134
string_view method(m_method);

0 commit comments

Comments
 (0)