bool GenericOCIO::isIdentity(double time) { assert(_created); #ifdef OFX_IO_USING_OCIO if (!_config) { return true; } std::string inputSpace; getInputColorspaceAtTime(time, inputSpace); std::string outputSpace; getOutputColorspaceAtTime(time, outputSpace); if (inputSpace == outputSpace) { return true; } // must clear persistent message in isIdentity, or render() is not called by Nuke after an error _parent->clearPersistentMessage(); try { // maybe the names are not the same, but it's still a no-op (e.g. "scene_linear" and "linear") OCIO::ConstContextRcPtr context = getLocalContext(time);//_config->getCurrentContext(); OCIO_NAMESPACE::ConstProcessorRcPtr proc = _config->getProcessor(context, inputSpace.c_str(), outputSpace.c_str()); return proc->isNoOp(); } catch (const std::exception& e) { _parent->setPersistentMessage(OFX::Message::eMessageError, "", e.what()); OFX::throwSuiteStatusException(kOfxStatFailed); return false; } #else return true; #endif }
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 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 GenericOCIO::apply(double time, const OfxRectI& renderWindow, float *pixelData, const OfxRectI& bounds, OFX::PixelComponentEnum pixelComponents, int pixelComponentCount, int rowBytes) { assert(_created); #ifdef OFX_IO_USING_OCIO if (!_config) { return; } if (isIdentity(time)) { return; } // are we in the image bounds if(renderWindow.x1 < bounds.x1 || renderWindow.x1 >= bounds.x2 || renderWindow.y1 < bounds.y1 || renderWindow.y1 >= bounds.y2 || renderWindow.x2 <= bounds.x1 || renderWindow.x2 > bounds.x2 || renderWindow.y2 <= bounds.y1 || renderWindow.y2 > bounds.y2) { _parent->setPersistentMessage(OFX::Message::eMessageError, "","OCIO: render window outside of image bounds"); OFX::throwSuiteStatusException(kOfxStatFailed); } if (pixelComponents != OFX::ePixelComponentRGBA && pixelComponents != OFX::ePixelComponentRGB) { _parent->setPersistentMessage(OFX::Message::eMessageError, "","OCIO: invalid components (only RGB and RGBA are supported)"); OFX::throwSuiteStatusException(kOfxStatFailed); } OCIOProcessor processor(*_parent); // set the images processor.setDstImg(pixelData, bounds, pixelComponents, pixelComponentCount, OFX::eBitDepthFloat, rowBytes); std::string inputSpace; getInputColorspaceAtTime(time, inputSpace); std::string outputSpace; getOutputColorspaceAtTime(time, outputSpace); OCIO::ConstContextRcPtr context = getLocalContext(time);//_config->getCurrentContext(); processor.setValues(_config, context, inputSpace, outputSpace); // set the render window processor.setRenderWindow(renderWindow); // Call the base class process member, this will call the derived templated process code processor.process(); #endif }
void OCIOLookTransform::_validate(bool 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 { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char * inputName = config->getColorSpaceNameByIndex(m_inputColorSpaceIndex); const char * outputName = config->getColorSpaceNameByIndex(m_outputColorSpaceIndex); OCIO::LookTransformRcPtr transform = OCIO::LookTransform::Create(); const char * look = m_lookCstrNames[m_lookIndex]; if(look != NULL) { transform->setLooks(look); } OCIO::ConstContextRcPtr context = getLocalContext(); OCIO::TransformDirection direction = OCIO::TRANSFORM_DIR_UNKNOWN; bool invertTransform = (m_dirIndex == 0) ? false : true; // Forward if(!invertTransform) { transform->setSrc(inputName); transform->setDst(outputName); direction = OCIO::TRANSFORM_DIR_FORWARD; } else { // 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(outputName); transform->setDst(inputName); direction = OCIO::TRANSFORM_DIR_INVERSE; } try { m_processor = config->getProcessor(context, transform, direction); } // We only catch the exceptions for missing files, and try to succeed // in this case. All other errors represent more serious problems and // should fail through. catch(const OCIO::ExceptionMissingFile &e) { if(!m_ignoreErrors) throw; m_processor = config->getProcessor(context, inputName, outputName); } } catch(const OCIO::Exception &e) { error(e.what()); return; } catch (...) { error("OCIOLookTransform: Unknown exception during _validate."); 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); }