ColorProcessor* ColorConfig::createFileTransform (string_view name, bool inverse) const { #ifdef USE_OCIO // Ask OCIO to make a Processor that can handle the requested // transformation. if (getImpl()->config_) { OCIO::ConstConfigRcPtr config = getImpl()->config_; OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create(); transform->setSrc (name.c_str()); transform->setInterpolation (OCIO::INTERP_BEST); OCIO::TransformDirection dir = inverse ? OCIO::TRANSFORM_DIR_INVERSE : OCIO::TRANSFORM_DIR_FORWARD; OCIO::ConstContextRcPtr context = config->getCurrentContext(); OCIO::ConstProcessorRcPtr p; try { // Get the processor corresponding to this transform. p = getImpl()->config_->getProcessor (context, transform, dir); } catch(OCIO::Exception &e) { getImpl()->error_ = e.what(); return NULL; } catch(...) { getImpl()->error_ = "An unknown error occurred in OpenColorIO, getProcessor"; return NULL; } getImpl()->error_ = ""; return new ColorProcessor_OCIO(p); } #endif return NULL; // if we get this far, we've failed }
OCIO::ConstContextRcPtr OCIOColorSpace::getLocalContext() { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); OCIO::ConstContextRcPtr context = config->getCurrentContext(); OCIO::ContextRcPtr mutableContext; if(!m_contextKey1.empty()) { if(!mutableContext) mutableContext = context->createEditableCopy(); mutableContext->setStringVar(m_contextKey1.c_str(), m_contextValue1.c_str()); } if(!m_contextKey2.empty()) { if(!mutableContext) mutableContext = context->createEditableCopy(); mutableContext->setStringVar(m_contextKey2.c_str(), m_contextValue2.c_str()); } if(!m_contextKey3.empty()) { if(!mutableContext) mutableContext = context->createEditableCopy(); mutableContext->setStringVar(m_contextKey3.c_str(), m_contextValue3.c_str()); } if(!m_contextKey4.empty()) { if(!mutableContext) mutableContext = context->createEditableCopy(); mutableContext->setStringVar(m_contextKey4.c_str(), m_contextValue4.c_str()); } if(mutableContext) context = mutableContext; return context; }
ColorProcessor* ColorConfig::createLookTransform (string_view looks, string_view inputColorSpace, string_view outputColorSpace, bool inverse, string_view context_key, string_view context_val) const { #ifdef USE_OCIO // Ask OCIO to make a Processor that can handle the requested // transformation. if (getImpl()->config_) { OCIO::ConstConfigRcPtr config = getImpl()->config_; OCIO::LookTransformRcPtr transform = OCIO::LookTransform::Create(); transform->setLooks (looks.c_str()); OCIO::TransformDirection dir; if (inverse) { // The TRANSFORM_DIR_INVERSE applies an inverse for the // end-to-end transform, which would otherwise do dst->inv // look -> src. This is an unintuitive result for the // artist (who would expect in, out to remain unchanged), so // we account for that here by flipping src/dst transform->setSrc (outputColorSpace.c_str()); transform->setDst (inputColorSpace.c_str()); dir = OCIO::TRANSFORM_DIR_INVERSE; } else { // forward transform->setSrc (inputColorSpace.c_str()); transform->setDst (outputColorSpace.c_str()); dir = OCIO::TRANSFORM_DIR_FORWARD; } OCIO::ConstContextRcPtr context = config->getCurrentContext(); if (context_key.size() && context_val.size()) { OCIO::ContextRcPtr ctx = context->createEditableCopy(); ctx->setStringVar (context_key.c_str(), context_val.c_str()); context = ctx; } OCIO::ConstProcessorRcPtr p; try { // Get the processor corresponding to this transform. p = getImpl()->config_->getProcessor (context, transform, dir); } catch(OCIO::Exception &e) { getImpl()->error_ = e.what(); return NULL; } catch(...) { getImpl()->error_ = "An unknown error occurred in OpenColorIO, getProcessor"; return NULL; } getImpl()->error_ = ""; return new ColorProcessor_OCIO(p); } #endif return NULL; // if we get this far, we've failed }
ColorProcessor* ColorConfig::createDisplayTransform (string_view display, string_view view, string_view inputColorSpace, string_view looks, string_view context_key, string_view context_value) const { #ifdef USE_OCIO // Ask OCIO to make a Processor that can handle the requested // transformation. if (getImpl()->config_) { OCIO::ConstConfigRcPtr config = getImpl()->config_; OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create(); transform->setInputColorSpaceName (inputColorSpace.c_str()); transform->setDisplay(display.c_str()); transform->setView(view.c_str()); if (looks.size()) { transform->setLooksOverride(looks.c_str()); transform->setLooksOverrideEnabled(true); } else { transform->setLooksOverrideEnabled(false); } OCIO::ConstContextRcPtr context = config->getCurrentContext(); std::vector<string_view> keys, values; Strutil::split (context_key, keys, ","); Strutil::split (context_value, values, ","); if (keys.size() && values.size() && keys.size() == values.size()) { OCIO::ContextRcPtr ctx = context->createEditableCopy(); for (size_t i = 0; i < keys.size(); ++i) ctx->setStringVar (keys[i].c_str(), values[i].c_str()); context = ctx; } OCIO::ConstProcessorRcPtr p; try { // Get the processor corresponding to this transform. p = getImpl()->config_->getProcessor (context, transform, OCIO::TRANSFORM_DIR_FORWARD); } catch(OCIO::Exception &e) { getImpl()->error_ = e.what(); return NULL; } catch(...) { getImpl()->error_ = "An unknown error occurred in OpenColorIO, getProcessor"; return NULL; } getImpl()->error_ = ""; return new ColorProcessor_OCIO(p); } #endif return NULL; // if we get this far, we've failed }
ColorProcessor* ColorConfig::createColorProcessor (string_view inputColorSpace, string_view outputColorSpace, string_view context_key, string_view context_value) const { string_view inputrole, outputrole; std::string pending_error; #ifdef USE_OCIO // Ask OCIO to make a Processor that can handle the requested // transformation. OCIO::ConstProcessorRcPtr p; if (getImpl()->config_) { // If the names are roles, convert them to color space names string_view name; name = getColorSpaceNameByRole (inputColorSpace); if (! name.empty()) { inputrole = inputColorSpace; inputColorSpace = name; } name = getColorSpaceNameByRole (outputColorSpace); if (! name.empty()) { outputrole = outputColorSpace; outputColorSpace = name; } OCIO::ConstConfigRcPtr config = getImpl()->config_; OCIO::ConstContextRcPtr context = config->getCurrentContext(); std::vector<string_view> keys, values; Strutil::split (context_key, keys, ","); Strutil::split (context_value, values, ","); if (keys.size() && values.size() && keys.size() == values.size()) { OCIO::ContextRcPtr ctx = context->createEditableCopy(); for (size_t i = 0; i < keys.size(); ++i) ctx->setStringVar (keys[i].c_str(), values[i].c_str()); context = ctx; } try { // Get the processor corresponding to this transform. p = getImpl()->config_->getProcessor(context, inputColorSpace.c_str(), outputColorSpace.c_str()); } catch(OCIO::Exception &e) { // Don't quit yet, remember the error and see if any of our // built-in knowledge of some generic spaces will save us. p.reset(); pending_error = e.what(); } catch(...) { getImpl()->error_ = "An unknown error occurred in OpenColorIO, getProcessor"; return NULL; } getImpl()->error_ = ""; if (p && ! p->isNoOp()) { // If we got a valid processor that does something useful, // return it now. If it boils down to a no-op, give a second // chance below to recognize it as a special case. return new ColorProcessor_OCIO(p); } } #endif // Either not compiled with OCIO support, or no OCIO configuration // was found at all. There are a few color conversions we know // about even in such dire conditions. using namespace Strutil; if (iequals(inputColorSpace,outputColorSpace)) { return new ColorProcessor_Ident; } if ((iequals(inputColorSpace,"linear") || iequals(inputrole,"linear") || iequals(inputColorSpace,"lnf") || iequals(inputColorSpace,"lnh")) && iequals(outputColorSpace,"sRGB")) { return new ColorProcessor_linear_to_sRGB; } if (iequals(inputColorSpace,"sRGB") && (iequals(outputColorSpace,"linear") || iequals(outputrole,"linear") || iequals(outputColorSpace,"lnf") || iequals(outputColorSpace,"lnh"))) { return new ColorProcessor_sRGB_to_linear; } if ((iequals(inputColorSpace,"linear") || iequals(inputrole,"linear") || iequals(inputColorSpace,"lnf") || iequals(inputColorSpace,"lnh")) && iequals(outputColorSpace,"Rec709")) { return new ColorProcessor_linear_to_Rec709; } if (iequals(inputColorSpace,"Rec709") && (iequals(outputColorSpace,"linear") || iequals(outputrole,"linear") || iequals(outputColorSpace,"lnf") || iequals(outputColorSpace,"lnh"))) { return new ColorProcessor_Rec709_to_linear; } #ifdef USE_OCIO if (p) { // If we found a procesor from OCIO, even if it was a NoOp, and we // still don't have a better idea, return it. return new ColorProcessor_OCIO(p); } #endif if (pending_error.size()) getImpl()->error_ = pending_error; return NULL; // if we get this far, we've failed }