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; }
void parseArguments(int argc, char **argv) { for(int i=1; i<argc; ++i) { if(0==strcmp(argv[i], "-v")) { g_verbose = true; } else if(0==strcmp(argv[i], "-gpulegacy")) { g_gpulegacy = true; } else if(0==strcmp(argv[i], "-gpuinfo")) { g_gpuinfo = true; } else if(0==strcmp(argv[i], "-h")) { std::cout << std::endl; std::cout << "help:" << std::endl; std::cout << " ociodisplay [OPTIONS] [image] where" << std::endl; std::cout << std::endl; std::cout << " OPTIONS:" << std::endl; std::cout << " -h : displays the help and exit" << std::endl; std::cout << " -v : displays the color space information" << std::endl; std::cout << " -gpulegacy : use the legacy (i.e. baked) GPU color processing" << std::endl; std::cout << " -gpuinfo : output the OCIO shader program" << std::endl; std::cout << std::endl; exit(0); } else { g_filename = argv[i]; } } if(g_verbose) { std::cout << std::endl; if(!g_filename.empty()) { std::cout << "Image:" << std::endl << "\t" << g_filename << std::endl; } std::cout << std::endl; std::cout << "OIIO: " << std::endl << "\tversion = " << OIIO_VERSION_STRING << std::endl; std::cout << std::endl; std::cout << "OCIO: " << std::endl << "\tversion = " << OCIO::GetVersion() << std::endl; if(getenv("OCIO")) { std::cout << "\tconfiguration = " << getenv("OCIO") << std::endl; OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); std::cout << "\tsearch_path = " << config->getSearchPath() << std::endl; } } }
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 }
OCIOColorSpace::OCIOColorSpace(Node *n) : DD::Image::PixelIop(n) { m_hasColorSpaces = false; m_inputColorSpaceIndex = 0; m_outputColorSpaceIndex = 0; m_layersToProcess = DD::Image::Mask_RGB; // Query the colorspace names from the current config // TODO (when to) re-grab the list of available colorspaces? How to save/load? try { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); std::string defaultColorSpaceName = config->getColorSpace(OCIO::ROLE_SCENE_LINEAR)->getName(); for(int i = 0; i < config->getNumColorSpaces(); i++) { std::string csname = config->getColorSpaceNameByIndex(i); m_colorSpaceNames.push_back(csname); if(csname == defaultColorSpaceName) { m_inputColorSpaceIndex = i; m_outputColorSpaceIndex = i; } } } catch (OCIO::Exception& e) { std::cerr << "OCIOColorSpace: " << e.what() << std::endl; } catch (...) { std::cerr << "OCIOColorSpace: Unknown exception during OCIO setup." << std::endl; } // Then, create a cstr array for passing to Nuke // This must be done in a second pass, lest the original m_colorSpaceNames // std::string be reallocated in the interim for(unsigned int i=0; i<m_colorSpaceNames.size(); ++i) { m_inputColorSpaceCstrNames.push_back(m_colorSpaceNames[i].c_str()); m_outputColorSpaceCstrNames.push_back(m_colorSpaceNames[i].c_str()); } m_inputColorSpaceCstrNames.push_back(NULL); m_outputColorSpaceCstrNames.push_back(NULL); m_hasColorSpaces = (!m_colorSpaceNames.empty()); if(!m_hasColorSpaces) { std::cerr << "OCIOColorSpace: No ColorSpaces available for input and/or output." << std::endl; } }
void OCIOColorSpace::_validate(bool for_real) { input0().validate(for_real); if(!m_hasColorSpaces) { error("No colorspaces available for input and/or output."); return; } int inputColorSpaceCount = static_cast<int>(m_inputColorSpaceCstrNames.size()) - 1; if(m_inputColorSpaceIndex < 0 || m_inputColorSpaceIndex >= inputColorSpaceCount) { std::ostringstream err; err << "Input colorspace index (" << m_inputColorSpaceIndex << ") out of range."; error(err.str().c_str()); return; } int outputColorSpaceCount = static_cast<int>(m_outputColorSpaceCstrNames.size()) - 1; if(m_outputColorSpaceIndex < 0 || m_outputColorSpaceIndex >= outputColorSpaceCount) { std::ostringstream err; err << "Output colorspace index (" << m_outputColorSpaceIndex << ") out of range."; error(err.str().c_str()); return; } try { const char * inputName = m_inputColorSpaceCstrNames[m_inputColorSpaceIndex]; const char * outputName = m_outputColorSpaceCstrNames[m_outputColorSpaceIndex]; OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); config->sanityCheck(); OCIO::ConstContextRcPtr context = getLocalContext(); m_processor = config->getProcessor(context, inputName, outputName); } catch(OCIO::Exception &e) { error(e.what()); return; } if(m_processor->isNoOp()) { // TODO or call disable() ? set_out_channels(DD::Image::Mask_None); // prevents engine() from being called copy_info(); return; } set_out_channels(DD::Image::Mask_All); DD::Image::PixelIop::_validate(for_real); }
void Generate(int cubesize, int maxwidth, const std::string & outputfile, const std::string & configfile, const std::string & incolorspace, const std::string & outcolorspace) { int width = 0; int height = 0; int numchannels = 3; GetLutImageSize(width, height, cubesize, maxwidth); std::vector<float> img; img.resize(width*height*numchannels, 0); GenerateIdentityLut3D(&img[0], cubesize, numchannels, LUT3DORDER_FAST_RED); if(!incolorspace.empty() || !outcolorspace.empty()) { OCIO::ConstConfigRcPtr config = OCIO::Config::Create(); if(!configfile.empty()) { config = OCIO::Config::CreateFromFile(configfile.c_str()); } else if(getenv("OCIO")) { config = OCIO::Config::CreateFromEnv(); } else { std::ostringstream os; os << "You must specify an ocio configuration "; os << "(either with --config or $OCIO)."; throw Exception(os.str().c_str()); } OCIO::ConstProcessorRcPtr processor = config->getProcessor(incolorspace.c_str(), outcolorspace.c_str()); OCIO::PackedImageDesc imgdesc(&img[0], width, height, 3); processor->apply(imgdesc); } OIIO::ImageOutput* f = OIIO::ImageOutput::create(outputfile); if(!f) { throw Exception( "Could not create output image."); } OIIO::ImageSpec spec(width, height, numchannels, OIIO::TypeDesc::TypeFloat); // TODO: If DPX, force 16-bit output? f->open(outputfile, spec); f->write_image(OIIO::TypeDesc::FLOAT, &img[0]); f->close(); delete f; }
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 }
void imageColorSpace_CB(int id) { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char * name = config->getColorSpaceNameByIndex(id); if(!name) return; g_inputColorSpace = name; UpdateOCIOGLState(); glutPostRedisplay(); }
static void buildLookChoiceMenu(OCIO::ConstConfigRcPtr config, ChoiceParamType* choice) { choice->resetOptions(); if (!config) { return; } for (int i = 0; i < config->getNumLooks(); ++i) { choice->appendOption(config->getLookNameByIndex(i)); } }
void transform_CB(int id) { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char * transform = config->getView(g_display.c_str(), id); if(!transform) return; g_transformName = transform; UpdateOCIOGLState(); glutPostRedisplay(); }
void look_CB(int id) { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char * look = config->getLookNameByIndex(id); if(!look || !*look) return; g_look = look; UpdateOCIOGLState(); glutPostRedisplay(); }
static void PopulateOCIOMenus() { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); int csMenuID = glutCreateMenu(imageColorSpace_CB); for(int i=0; i<config->getNumColorSpaces(); ++i) { glutAddMenuEntry(config->getColorSpaceNameByIndex(i), i); } int deviceMenuID = glutCreateMenu(displayDevice_CB); for(int i=0; i<config->getNumDisplays(); ++i) { glutAddMenuEntry(config->getDisplay(i), i); } int transformMenuID = glutCreateMenu(transform_CB); const char * defaultDisplay = config->getDefaultDisplay(); for(int i=0; i<config->getNumViews(defaultDisplay); ++i) { glutAddMenuEntry(config->getView(defaultDisplay, i), i); } glutCreateMenu(menuCallback); glutAddSubMenu("Image ColorSpace", csMenuID); glutAddSubMenu("Transform", transformMenuID); glutAddSubMenu("Device", deviceMenuID); glutAttachMenu(GLUT_RIGHT_BUTTON); }
void OCIOFileTransform::_validate(bool for_real) { if(!m_file) { error("The source file must be specified."); return; } try { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create(); transform->setSrc(m_file); transform->setCCCId(m_cccid.c_str()); if(m_dirindex == 0) transform->setDirection(OCIO::TRANSFORM_DIR_FORWARD); else transform->setDirection(OCIO::TRANSFORM_DIR_INVERSE); if(m_interpindex == 0) transform->setInterpolation(OCIO::INTERP_NEAREST); else if(m_interpindex == 1) transform->setInterpolation(OCIO::INTERP_LINEAR); else if(m_interpindex == 2) transform->setInterpolation(OCIO::INTERP_TETRAHEDRAL); else if(m_interpindex == 3) transform->setInterpolation(OCIO::INTERP_BEST); else { // Should never happen error("Interpolation value out of bounds"); return; } m_processor = config->getProcessor(transform, OCIO::TRANSFORM_DIR_FORWARD); } catch(OCIO::Exception &e) { error(e.what()); return; } if(m_processor->isNoOp()) { set_out_channels(DD::Image::Mask_None); // prevents engine() from being called } else { set_out_channels(DD::Image::Mask_All); } DD::Image::PixelIop::_validate(for_real); }
void OCIOFileTransform::_validate(bool for_real) { input0().validate(for_real); if(!src) { error("The source file must be specified."); return; } try { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); config->sanityCheck(); OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create(); transform->setSrc(src); // TODO: For some reason, cccid is NOT incorporated in this node's hash. // Until then, cccid is considered broken. Figure out why. transform->setCCCId(cccid.c_str()); if(dirindex == 0) transform->setDirection(OCIO::TRANSFORM_DIR_FORWARD); else transform->setDirection(OCIO::TRANSFORM_DIR_INVERSE); if(interpindex == 0) transform->setInterpolation(OCIO::INTERP_NEAREST); else transform->setInterpolation(OCIO::INTERP_LINEAR); processor = config->getProcessor(transform, OCIO::TRANSFORM_DIR_FORWARD); } catch(OCIO::Exception &e) { error(e.what()); return; } if(processor->isNoOp()) { // TODO or call disable() ? set_out_channels(DD::Image::Mask_None); // prevents engine() from being called copy_info(); return; } set_out_channels(DD::Image::Mask_All); DD::Image::PixelIop::_validate(for_real); }
void displayDevice_CB(int id) { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char * display = config->getDisplay(id); if(!display) return; g_display = display; const char * csname = config->getDisplayColorSpaceName(g_display.c_str(), g_transformName.c_str()); if(!csname) { g_transformName = config->getDefaultView(g_display.c_str()); } UpdateOCIOGLState(); glutPostRedisplay(); }
void OCIOColorSpace::append(DD::Image::Hash& localhash) { // TODO: Hang onto the context, what if getting it // (and querying getCacheID) is expensive? try { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); OCIO::ConstContextRcPtr context = getLocalContext(); std::string configCacheID = config->getCacheID(context); localhash.append(configCacheID); } catch(OCIO::Exception &e) { error(e.what()); return; } }
void OCIOLookTransform::append(DD::Image::Hash& localhash) { // TODO: Hang onto the context, what if getting it // (and querying getCacheID) is expensive? try { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); OCIO::ConstContextRcPtr context = getLocalContext(); std::string configCacheID = config->getCacheID(context); localhash.append(configCacheID); } catch(const OCIO::Exception &e) { error(e.what()); } catch (...) { error("OCIOLookTransform: Unknown exception during hash generation."); } }
void InitOCIO(const char * filename) { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); g_display = config->getDefaultDisplay(); g_transformName = config->getDefaultView(g_display.c_str()); g_inputColorSpace = OCIO::ROLE_SCENE_LINEAR; if(filename) { std::string cs = config->parseColorSpaceFromString(filename); if(!cs.empty()) { g_inputColorSpace = cs; std::cout << "colorspace: " << cs << std::endl; } else { std::cout << "colorspace: " << g_inputColorSpace << " \t(could not determine from filename, using default)" << std::endl; } } }
static std::string canonicalizeColorSpace(OCIO_NAMESPACE::ConstConfigRcPtr config, const std::string &csname) { if (!config) { return csname; } const int defaultcs = config->getIndexForColorSpace(OCIO_NAMESPACE::ROLE_DEFAULT); const int referencecs = config->getIndexForColorSpace(OCIO_NAMESPACE::ROLE_REFERENCE); const int datacs = config->getIndexForColorSpace(OCIO_NAMESPACE::ROLE_DATA); const int colorpickingcs = config->getIndexForColorSpace(OCIO_NAMESPACE::ROLE_COLOR_PICKING); const int scenelinearcs = config->getIndexForColorSpace(OCIO_NAMESPACE::ROLE_SCENE_LINEAR); const int compositinglogcs = config->getIndexForColorSpace(OCIO_NAMESPACE::ROLE_COMPOSITING_LOG); const int colortimingcs = config->getIndexForColorSpace(OCIO_NAMESPACE::ROLE_COLOR_TIMING); const int texturepaintcs = config->getIndexForColorSpace(OCIO_NAMESPACE::ROLE_TEXTURE_PAINT); const int mattepaintcs = config->getIndexForColorSpace(OCIO_NAMESPACE::ROLE_MATTE_PAINT); int inputSpaceIndex = config->getIndexForColorSpace(csname.c_str()); if (inputSpaceIndex == scenelinearcs) { return OCIO_NAMESPACE::ROLE_SCENE_LINEAR; } else if (inputSpaceIndex == defaultcs) { return OCIO_NAMESPACE::ROLE_DEFAULT; } else if (inputSpaceIndex == referencecs) { return OCIO_NAMESPACE::ROLE_REFERENCE; } else if (inputSpaceIndex == datacs) { return OCIO_NAMESPACE::ROLE_DATA; } else if (inputSpaceIndex == colorpickingcs) { return OCIO_NAMESPACE::ROLE_COLOR_PICKING; } else if (inputSpaceIndex == compositinglogcs) { return OCIO_NAMESPACE::ROLE_COMPOSITING_LOG; } else if (inputSpaceIndex == colortimingcs) { return OCIO_NAMESPACE::ROLE_COLOR_TIMING; } else if (inputSpaceIndex == texturepaintcs) { return OCIO_NAMESPACE::ROLE_TEXTURE_PAINT; } else if (inputSpaceIndex == mattepaintcs) { return OCIO_NAMESPACE::ROLE_MATTE_PAINT; } return csname; }
void OCIOCDLTransform::_validate(bool for_real) { input0().validate(for_real); try { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); config->sanityCheck(); OCIO::CDLTransformRcPtr cc = OCIO::CDLTransform::Create(); cc->setSlope(m_slope); cc->setOffset(m_offset); cc->setPower(m_power); cc->setSat(m_saturation); if(m_dirindex == 0) cc->setDirection(OCIO::TRANSFORM_DIR_FORWARD); else cc->setDirection(OCIO::TRANSFORM_DIR_INVERSE); m_processor = config->getProcessor(cc); } catch(OCIO::Exception &e) { error(e.what()); return; } if(m_processor->isNoOp()) { // TODO or call disable() ? set_out_channels(DD::Image::Mask_None); // prevents engine() from being called copy_info(); return; } set_out_channels(DD::Image::Mask_All); DD::Image::PixelIop::_validate(for_real); }
void OCIOLogConvert::_validate(bool for_real) { try { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char * src = 0; const char * dst = 0; if(modeindex == 0) { src = OCIO::ROLE_COMPOSITING_LOG; dst = OCIO::ROLE_SCENE_LINEAR; } else { src = OCIO::ROLE_SCENE_LINEAR; dst = OCIO::ROLE_COMPOSITING_LOG; } processor = config->getProcessor(src, dst); } catch(OCIO::Exception &e) { error(e.what()); return; } if(processor->isNoOp()) { set_out_channels(DD::Image::Mask_None); // prevents engine() from being called } else { set_out_channels(DD::Image::Mask_All); } DD::Image::PixelIop::_validate(for_real); }
ColorSpaceProcessor *ColorSpaceManager::get_processor(ustring colorspace) { #ifdef WITH_OCIO /* Only use this for OpenColorIO color spaces, not the builtin ones. */ assert(colorspace != u_colorspace_srgb && colorspace != u_colorspace_auto); if (colorspace == u_colorspace_raw) { return NULL; } OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); if (!config) { return NULL; } /* Cache processor until free_memory(), memory overhead is expected to be * small and the processor is likely to be reused. */ thread_scoped_lock cache_processors_lock(cache_processors_mutex); if (cached_processors.find(colorspace) == cached_processors.end()) { try { cached_processors[colorspace] = config->getProcessor(colorspace.c_str(), "scene_linear"); } catch (OCIO::Exception &exception) { cached_processors[colorspace] = OCIO::ConstProcessorRcPtr(); VLOG(1) << "Colorspace " << colorspace.c_str() << " can't be converted to scene_linear: " << exception.what(); } } const OCIO::Processor *processor = cached_processors[colorspace].get(); return (ColorSpaceProcessor *)processor; #else /* No OpenColorIO. */ (void)colorspace; return NULL; #endif }
bool ColorSpaceManager::colorspace_is_data(ustring colorspace) { if (colorspace == u_colorspace_auto || colorspace == u_colorspace_raw || colorspace == u_colorspace_srgb) { return false; } #ifdef WITH_OCIO OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); if (!config) { return false; } try { OCIO::ConstColorSpaceRcPtr space = config->getColorSpace(colorspace.c_str()); return space && space->isData(); } catch (OCIO::Exception &) { return false; } #else return false; #endif }
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 }
std::string HdxColorCorrectionTask::_CreateOpenColorIOResources() { #ifdef PXR_OCIO_PLUGIN_ENABLED // Use client provided OCIO values, or use default fallback values OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char* display = _displayOCIO.empty() ? config->getDefaultDisplay() : _displayOCIO.c_str(); const char* view = _viewOCIO.empty() ? config->getDefaultView(display) : _viewOCIO.c_str(); std::string inputColorSpace = _colorspaceOCIO; if (inputColorSpace.empty()) { OCIO::ConstColorSpaceRcPtr cs = config->getColorSpace("default"); if (cs) { inputColorSpace = cs->getName(); } else { inputColorSpace = OCIO::ROLE_SCENE_LINEAR; } } // Setup the transformation we need to apply OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create(); transform->setDisplay(display); transform->setView(view); transform->setInputColorSpaceName(inputColorSpace.c_str()); if (!_looksOCIO.empty()) { transform->setLooksOverride(_looksOCIO.c_str()); transform->setLooksOverrideEnabled(true); } else { transform->setLooksOverrideEnabled(false); } OCIO::ConstProcessorRcPtr processor = config->getProcessor(transform); // Create a GPU Shader Description OCIO::GpuShaderDesc shaderDesc; shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0); shaderDesc.setFunctionName("OCIODisplay"); shaderDesc.setLut3DEdgeLen(_lut3dSizeOCIO); // Compute and the 3D LUT int num3Dentries = 3 * _lut3dSizeOCIO*_lut3dSizeOCIO*_lut3dSizeOCIO; std::vector<float> lut3d; lut3d.resize(num3Dentries); processor->getGpuLut3D(&lut3d[0], shaderDesc); // Load the data into an OpenGL 3D Texture if (_texture3dLUT != 0) { glDeleteTextures(1, &_texture3dLUT); } GLint restoreTexture; glGetIntegerv(GL_TEXTURE_BINDING_3D, &restoreTexture); glGenTextures(1, &_texture3dLUT); glBindTexture(GL_TEXTURE_3D, _texture3dLUT); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F, _lut3dSizeOCIO, _lut3dSizeOCIO, _lut3dSizeOCIO, 0, GL_RGB, GL_FLOAT, &lut3d[0]); glBindTexture(GL_TEXTURE_3D, restoreTexture); const char* gpuShaderText = processor->getGpuShaderText(shaderDesc); GLF_POST_PENDING_GL_ERRORS(); return std::string(gpuShaderText); #else return std::string(); #endif }
int main(int argc, char **argv) { if(argc<5) { std::cerr << USAGE_TEXT << std::endl; exit(0); } const char * inputimage = argv[1]; const char * inputcolorspace = argv[2]; const char * outputimage = argv[3]; const char * outputcolorspace = argv[4]; OIIO::ImageSpec spec; std::vector<float> img; int imgwidth = 0; int imgheight = 0; int components = 0; // Load the image std::cerr << "Loading " << inputimage << std::endl; try { OIIO::ImageInput* f = OIIO::ImageInput::create(inputimage); if(!f) { std::cerr << "Could not create image input." << std::endl; exit(1); } f->open(inputimage, spec); std::string error = f->geterror(); if(!error.empty()) { std::cerr << "Error loading image " << error << std::endl; exit(1); } imgwidth = spec.width; imgheight = spec.height; components = spec.nchannels; img.resize(imgwidth*imgheight*components); memset(&img[0], 0, imgwidth*imgheight*components*sizeof(float)); f->read_image(OIIO::TypeDesc::TypeFloat, &img[0]); delete f; } catch(...) { std::cerr << "Error loading file."; exit(1); } // Process the image try { // Load the current config. OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); // Get the processor OCIO::ConstProcessorRcPtr processor = config->getProcessor(inputcolorspace, outputcolorspace); // Wrap the image in a light-weight ImageDescription OCIO::PackedImageDesc imageDesc(&img[0], imgwidth, imgheight, components); // Apply the color transformation (in place) processor->apply(imageDesc); } catch(OCIO::Exception & exception) { std::cerr << "OCIO Error: " << exception.what() << std::endl; } catch(...) { std::cerr << "Unknown OCIO error encountered." << std::endl; } // Write out the result try { OIIO::ImageOutput* f = OIIO::ImageOutput::create(outputimage); if(!f) { std::cerr << "Could not create output input." << std::endl; exit(1); } f->open(outputimage, spec); f->write_image(OIIO::TypeDesc::FLOAT, &img[0]); f->close(); delete f; } catch(...) { std::cerr << "Error loading file."; exit(1); } std::cerr << "Wrote " << outputimage << std::endl; return 0; }
void OCIOProcessor::setValues(const OCIO_NAMESPACE::ConstConfigRcPtr &config, const OCIO_NAMESPACE::ConstContextRcPtr &context, const OCIO_NAMESPACE::ConstTransformRcPtr& transform, OCIO_NAMESPACE::TransformDirection direction) { _proc = config->getProcessor(context, transform, direction); }
void OCIOProcessor::setValues(const OCIO_NAMESPACE::ConstConfigRcPtr &config, const OCIO_NAMESPACE::ConstTransformRcPtr& transform) { _proc = config->getProcessor(transform); }
void OCIOProcessor::setValues(const OCIO_NAMESPACE::ConstConfigRcPtr &config, const OCIO_NAMESPACE::ConstContextRcPtr &context, const std::string& inputSpace, const std::string& outputSpace) { _proc = config->getProcessor(context, inputSpace.c_str(), outputSpace.c_str()); }