# OpenColorIO

## Open Source Color Management

Home Compatible Software Configurations Installation User Guide Developer guide Getting started Coding guidelines Submitting Changes Issues Usage Examples C++ API C++ Transforms C++ Types Python API Python Transforms Python Types Internal Architecture Overview FAQ Downloads ChangeLog License ### Quick search | # C++ API Usage Example: Compositing plugin that converts from “log” to “lin”
    #include <OpenColorIO/OpenColorIO.h>
    namespace OCIO = OCIO_NAMESPACE;

    try
    {
        // Get the global OpenColorIO config
        // This will auto-initialize (using $OCIO) on first use
        OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();

        // Get the processor corresponding to this transform.
        OCIO::ConstProcessorRcPtr processor = config->getProcessor(OCIO::ROLE_COMPOSITING_LOG,
                                                                   OCIO::ROLE_SCENE_LINEAR);

        // Wrap the image in a light-weight ImageDescription
        OCIO::PackedImageDesc img(imageData, w, h, 4);

        // Apply the color transformation (in place)
        processor->apply(img);
    }
    catch(OCIO::Exception & exception)
    {
        std::cerr << "OpenColorIO Error: " << exception.what() << std::endl;
    }
## Exceptions class `Exception` An exception class to throw for errors detected at runtime. Warning All functions in the Config class can potentially throw this exception. `Exception::``Exception`(const char* None) Constructor that takes a string as the exception message. `Exception::``Exception`(const Exception& None) Constructor that takes an exception pointer. Exception& `Exception::``operator=`(const Exception& None) Constructor that takes an exception pointer and returns an exception pointer (???). `Exception::``~Exception`() const char* `Exception::``what`()`const` class `ExceptionMissingFile` An exception class for errors detected at runtime, thrown when OCIO cannot find a file that is expected to exist. This is provided as a custom type to distinguish cases where one wants to continue looking for missing files, but wants to properly fail for other error conditions. `ExceptionMissingFile::``ExceptionMissingFile`(const char* None) `ExceptionMissingFile::``ExceptionMissingFile`(const ExceptionMissingFile& None) ## Global void `ClearAllCaches`() OpenColorIO, during normal usage, tends to cache certain information (such as the contents of LUTs on disk, intermediate results, etc.). Calling this function will flush all such information. Under normal usage, this is not necessary, but it can be helpful in particular instances, such as designing OCIO profiles, and wanting to re-read luts without restarting. const char* `GetVersion`() Get the version number for the library, as a dot-delimited string (e.g., “1.0.0”). This is also available at compile time as OCIO_VERSION. int `GetVersionHex`() Get the version number for the library, as a single 4-byte hex number (e.g., 0x01050200 for “1.5.2”), to be used for numeric comparisons. This is also available at compile time as OCIO_VERSION_HEX. LoggingLevel `GetLoggingLevel`() Get the global logging level. You can override this at runtime using the `OCIO_LOGGING_LEVEL` environment variable. The client application that sets this should use `SetLoggingLevel()`, and not the environment variable. The default value is INFO. void `SetLoggingLevel`(LoggingLevel level) Set the global logging level. ## Config A config defines all the color spaces to be available at runtime. The color configuration (`Config`) is the main object for interacting with this library. It encapsulates all of the information necessary to use customized `ColorSpaceTransform` and `DisplayTransform` operations. See the User Guide for more information on selecting, creating, and working with custom color configurations. For applications interested in using only one color config at a time (this is the vast majority of apps), their API would traditionally get the global configuration and use that, as opposed to creating a new one. This simplifies the use case for plugins and bindings, as it alleviates the need to pass around configuration handles. An example of an application where this would not be sufficient would be a multi-threaded image proxy server (daemon), which wished to handle multiple show configurations in a single process concurrently. This app would need to keep multiple configurations alive, and to manage them appropriately. Roughly speaking, a novice user should select a default configuration that most closely approximates the use case (animation, visual effects, etc.), and set the `OCIO` environment variable to point at the root of that configuration. Note Initialization using environment variables is typically preferable in a multi-app ecosystem, as it allows all applications to be consistently configured. See Usage Examples ConstConfigRcPtr `GetCurrentConfig`() Get the current configuration. void `SetCurrentConfig`(const ConstConfigRcPtr& config) Set the current configuration. This will then store a copy of the specified config. class `Config` ### Initialization static ConfigRcPtr `Config::``Create`() Constructor...ELABORATE static ConstConfigRcPtr `Config::``CreateFromEnv`() static ConstConfigRcPtr `Config::``CreateFromFile`(const char* filename) static ConstConfigRcPtr `Config::``CreateFromStream`(std::istream& istream) ConfigRcPtr `Config::``createEditableCopy`()`const` void `Config::``sanityCheck`()`const` This will throw an exception if the config is malformed. The most common error occurs when references are made to colorspaces that do not exist. const char* `Config::``getDescription`()`const` void `Config::``setDescription`(const char* description) void `Config::``serialize`(std::ostream& os)`const` Returns the string representation of the Config in YAML text form. This is typically stored on disk in a file with the extension .ocio. const char* `Config::``getCacheID`()`const` This will produce a hash of the all colorspace definitions, etc. All external references, such as files used in FileTransforms, etc., will be incorporated into the cacheID. While the contents of the files are not read, the file system is queried for relavent information (mtime, inode) so that the config’s cacheID will change when the underlying luts are updated. If a context is not provided, the current Context will be used. If a null context is provided, file references will not be taken into account (this is essentially a hash of Config::serialize). const char* `Config::``getCacheID`(const ConstContextRcPtr& context)`const` ### Resources Given a lut src name, where should we find it? ConstContextRcPtr `Config::``getCurrentContext`()`const` const char* `Config::``getSearchPath`()`const` const char* `Config::``getWorkingDir`()`const` ### ColorSpaces int `Config::``getNumColorSpaces`()`const` const char* `Config::``getColorSpaceNameByIndex`(int index)`const` This will null if an invalid index is specified Note These fcns all accept either a color space OR role name. (Colorspace names take precedence over roles.) ConstColorSpaceRcPtr `Config::``getColorSpace`(const char* name)`const` This will return null if the specified name is not found. int `Config::``getIndexForColorSpace`(const char* name)`const` void `Config::``addColorSpace`(const ConstColorSpaceRcPtr& cs) Note If another color space is already registered with the same name, this will overwrite it. This stores a copy of the specified color space. void `Config::``clearColorSpaces`() const char* `Config::``parseColorSpaceFromString`(const char* str)`const` Given the specified string, get the longest, right-most, colorspace substring that appears. If strict parsing is enabled, and no color space is found, return an empty string. If strict parsing is disabled, return ROLE_DEFAULT (if defined). If the default role is not defined, return an empty string. bool `Config::``isStrictParsingEnabled`()`const` void `Config::``setStrictParsingEnabled`(bool enabled) ### Roles A role is like an alias for a colorspace. You can query the colorspace corresponding to a role using the normal getColorSpace fcn. void `Config::``setRole`(const char* role, const char* colorSpaceName) Note Setting the `colorSpaceName` name to a null string unsets it. int `Config::``getNumRoles`()`const` bool `Config::``hasRole`(const char* role)`const` Return true if the role has been defined. const char* `Config::``getRoleName`(int index)`const` Get the role name at index, this will return values like ‘scene_linear’, ‘compositing_log’. Return empty string if index is out of range. ### Display/View Registration Looks is a potentially comma (or colon) delimited list of lookNames, Where +/- prefixes are optionally allowed to denote forward/inverse look specification. (And forward is assumed in the absense of either) const char* `Config::``getDefaultDisplay`()`const` int `Config::``getNumDisplays`()`const` const char* `Config::``getDisplay`(int index)`const` const char* `Config::``getDefaultView`(const char* display)`const` int `Config::``getNumViews`(const char* display)`const` const char* `Config::``getView`(const char* display, int index)`const` const char* `Config::``getDisplayColorSpaceName`(const char* display, const char* view)`const` const char* `Config::``getDisplayLooks`(const char* display, const char* view)`const` void `Config::``addDisplay`(const char* display, const char* view, const char* colorSpaceName, const char* looks) For the (display,view) combination, specify which colorSpace and look to use. If a look is not desired, then just pass an empty string void `Config::``clearDisplays`() void `Config::``setActiveDisplays`(const char* displays) Comma-delimited list of display names. const char* `Config::``getActiveDisplays`()`const` void `Config::``setActiveViews`(const char* views) Comma-delimited list of view names. const char* `Config::``getActiveViews`()`const` ### Luma Get the default coefficients for computing luma. Note There is no “1 size fits all” set of luma coefficients. (The values are typically different for each colorspace, and the application of them may be nonsensical depending on the intensity coding anyways). Thus, the ‘right’ answer is to make these functions on the `Config` class. However, it’s often useful to have a config-wide default so here it is. We will add the colorspace specific luma call if/when another client is interesting in using it. void `Config::``getDefaultLumaCoefs`(float* rgb)`const` void `Config::``setDefaultLumaCoefs`(const float* rgb) These should be normalized (sum to 1.0 exactly). ### Look Manager per-shot look settings. ConstLookRcPtr `Config::``getLook`(const char* name)`const` int `Config::``getNumLooks`()`const` const char* `Config::``getLookNameByIndex`(int index)`const` void `Config::``addLook`(const ConstLookRcPtr& look) void `Config::``clearLooks`() ### Processors Convert from inputColorSpace to outputColorSpace Note This may provide higher fidelity than anticipated due to internal optimizations. For example, if the inputcolorspace and the outputColorSpace are members of the same family, no conversion will be applied, even though strictly speaking quantization should be added. If you wish to test these calls for quantization characteristics, apply in two steps; the image must contain RGB triples (though arbitrary numbers of additional channels can be supported (ignored) using the pixelStrideBytes arg). ConstProcessorRcPtr `Config::``getProcessor`(const ConstContextRcPtr& context, const ConstColorSpaceRcPtr& srcColorSpace, const ConstColorSpaceRcPtr& dstColorSpace)`const` ConstProcessorRcPtr `Config::``getProcessor`(const ConstColorSpaceRcPtr& srcColorSpace, const ConstColorSpaceRcPtr& dstColorSpace)`const` ConstProcessorRcPtr `Config::``getProcessor`(const char* srcName, const char* dstName)`const` Note Names can be colorspace name, role name, or a combination of both. ConstProcessorRcPtr `Config::``getProcessor`(const ConstContextRcPtr& context, const char* srcName, const char* dstName)`const` Get the processor for the specified transform. Not often needed, but will allow for the re-use of atomic OCIO functionality (such as to apply an individual LUT file). ConstProcessorRcPtr `Config::``getProcessor`(const ConstTransformRcPtr& transform)`const` ConstProcessorRcPtr `Config::``getProcessor`(const ConstTransformRcPtr& transform, TransformDirection direction)`const` ConstProcessorRcPtr `Config::``getProcessor`(const ConstContextRcPtr& context, const ConstTransformRcPtr& transform, TransformDirection direction)`const` ## ColorSpace The ColorSpace is the state of an image with respect to colorimetry and color encoding. Transforming images between different ColorSpaces is the primary motivation for this library. While a complete discussion of colorspaces is beyond the scope of header documentation, traditional uses would be to have ColorSpaces corresponding to: physical capture devices (known cameras, scanners), and internal ‘convenience’ spaces (such as scene linear, logarithmic). ColorSpaces are specific to a particular image precision (float32, uint8, etc.), and the set of ColorSpaces that provide equivalent mappings (at different precisions) are referred to as a ‘family’. class `ColorSpace` static ColorSpaceRcPtr `ColorSpace::``Create`() ColorSpaceRcPtr `ColorSpace::``createEditableCopy`()`const` const char* `ColorSpace::``getName`()`const` void `ColorSpace::``setName`(const char* name) const char* `ColorSpace::``getFamily`()`const` Get the family, for use in user interfaces (optional) void `ColorSpace::``setFamily`(const char* family) Set the family, for use in user interfaces (optional) const char* `ColorSpace::``getEqualityGroup`()`const` Get the ColorSpace group name (used for equality comparisons) This allows no-op transforms between different colorspaces. If an equalityGroup is not defined (an empty string), it will be considered unique (i.e., it will not compare as equal to other ColorSpaces with an empty equality group). This is often, though not always, set to the same value as ‘family’. void `ColorSpace::``setEqualityGroup`(const char* equalityGroup) const char* `ColorSpace::``getDescription`()`const` void `ColorSpace::``setDescription`(const char* description) BitDepth `ColorSpace::``getBitDepth`()`const` void `ColorSpace::``setBitDepth`(BitDepth bitDepth) ### Data ColorSpaces that are data are treated a bit special. Basically, any colorspace transforms you try to apply to them are ignored. (Think of applying a gamut mapping transform to an ID pass). Also, the `DisplayTransform` process obeys special ‘data min’ and ‘data max’ args. This is traditionally used for pixel data that represents non-color pixel data, such as normals, point positions, ID information, etc. bool `ColorSpace::``isData`()`const` void `ColorSpace::``setIsData`(bool isData) ### Allocation If this colorspace needs to be transferred to a limited dynamic range coding space (such as during display with a GPU path), use this allocation to maximize bit efficiency. Allocation `ColorSpace::``getAllocation`()`const` void `ColorSpace::``setAllocation`(Allocation allocation) Specify the optional variable values to configure the allocation. If no variables are specified, the defaults are used. ALLOCATION_UNIFORM:
    2 vars: [min, max]
ALLOCATION_LG2:
    2 vars: [lg2min, lg2max]
    3 vars: [lg2min, lg2max, linear_offset]
int `ColorSpace::``getAllocationNumVars`()`const` void `ColorSpace::``getAllocationVars`(float* vars)`const` void `ColorSpace::``setAllocationVars`(int numvars, const float* vars) ### Transform ConstTransformRcPtr `ColorSpace::``getTransform`(ColorSpaceDirection dir)`const` If a transform in the specified direction has been specified, return it. Otherwise return a null ConstTransformRcPtr void `ColorSpace::``setTransform`(const ConstTransformRcPtr& transform, ColorSpaceDirection dir) Specify the transform for the appropriate direction. Setting the transform to null will clear it. ## Look The Look is an ‘artistic’ image modification, in a specified image state. The processSpace defines the ColorSpace the image is required to be in, for the math to apply correctly. class `Look` static LookRcPtr `Look::``Create`() LookRcPtr `Look::``createEditableCopy`()`const` const char* `Look::``getName`()`const` void `Look::``setName`(const char* name) const char* `Look::``getProcessSpace`()`const` void `Look::``setProcessSpace`(const char* processSpace) ConstTransformRcPtr `Look::``getTransform`()`const` void `Look::``setTransform`(const ConstTransformRcPtr& transform) Setting a transform to a non-null call makes it allowed. ConstTransformRcPtr `Look::``getInverseTransform`()`const` void `Look::``setInverseTransform`(const ConstTransformRcPtr& transform) Setting a transform to a non-null call makes it allowed. ## Processor class `Processor` static ProcessorRcPtr `Processor::``Create`() bool `Processor::``isNoOp`()`const` bool `Processor::``hasChannelCrosstalk`()`const` does the processor represent an image transformation that introduces crosstalk between the image channels ConstProcessorMetadataRcPtr `Processor::``getMetadata`()`const` ### CPU Path void `Processor::``apply`(ImageDesc& img)`const` Apply to an image. Apply to a single pixel. Note This is not as efficient as applying to an entire image at once. If you are processing multiple pixels, and have the flexibility, use the above function instead. void `Processor::``applyRGB`(float* pixel)`const` void `Processor::``applyRGBA`(float* pixel)`const` const char* `Processor::``getCpuCacheID`()`const` ### GPU Path Get the 3d lut + cg shader for the specified `DisplayTransform`. cg signature will be:
    shaderFcnName(in half4 inPixel, const uniform sampler3D lut3d)
lut3d should be size: 3 * edgeLen * edgeLen * edgeLen return 0 if unknown const char* `Processor::``getGpuShaderText`(const GpuShaderDesc& shaderDesc)`const` const char* `Processor::``getGpuShaderTextCacheID`(const GpuShaderDesc& shaderDesc)`const` void `Processor::``getGpuLut3D`(float* lut3d, const GpuShaderDesc& shaderDesc)`const` const char* `Processor::``getGpuLut3DCacheID`(const GpuShaderDesc& shaderDesc)`const` class `ProcessorMetadata` This class contains meta information about the process that generated this processor. The results of these functions do not impact the pixel processing. static ProcessorMetadataRcPtr `ProcessorMetadata::``Create`() int `ProcessorMetadata::``getNumFiles`()`const` const char* `ProcessorMetadata::``getFile`(int index)`const` int `ProcessorMetadata::``getNumLooks`()`const` const char* `ProcessorMetadata::``getLook`(int index)`const` void `ProcessorMetadata::``addFile`(const char* fname) void `ProcessorMetadata::``addLook`(const char* look) ## Baker In certain situations it is nessary to serilize transforms into a variety of application specific lut formats. The Baker can be used to create lut formats that ocio supports for writing. Usage Example: Bake a houdini sRGB viewer lut
    OCIO::ConstConfigRcPtr config = OCIO::Config::CreateFromEnv();
    OCIO::BakerRcPtr baker = OCIO::Baker::Create();
    baker->setConfig(config);
    baker->setFormat("houdini"); // set the houdini type
    baker->setType("3D"); // we want a 3D lut
    baker->setInputSpace("lnf");
    baker->setShaperSpace("log");
    baker->setTargetSpace("sRGB");
    std::ostringstream out;
    baker->bake(out); // fresh bread anyone!
    std::cout << out.str();
static BakerRcPtr `Create`() create a new Baker BakerRcPtr `createEditableCopy`()`const` create a copy of this Baker void `setConfig`(const ConstConfigRcPtr& config) set the config to use ConstConfigRcPtr `getConfig`()`const` get the config to use void `setFormat`(const char* formatName) set the lut output format const char* `getFormat`()`const` get the lut output format void `setType`(const char* type) set the lut output type (1D or 3D) const char* `getType`()`const` get the lut output type void `setMetadata`(const char* metadata) set optional meta data for luts that support it const char* `getMetadata`()`const` get the meta data that has been set void `setInputSpace`(const char* inputSpace) set the input ColorSpace that the lut will be applied to const char* `getInputSpace`()`const` get the input ColorSpace that has been set void `setShaperSpace`(const char* shaperSpace) set an optional ColorSpace to be used to shape / transfer the input colorspace. This is mostly used to allocate an HDR luminance range into an LDR one. If a shaper space is not explicitly specified, and the file format supports one, the ColorSpace Allocation will be used const char* `getShaperSpace`()`const` get the shaper colorspace that has been set void `setLooks`(const char* looks) set the looks to be applied during baking Looks is a potentially comma (or colon) delimited list of lookNames, Where +/- prefixes are optionally allowed to denote forward/inverse look specification. (And forward is assumed in the absense of either) const char* `getLooks`()`const` get the looks to be applied during baking void `setTargetSpace`(const char* targetSpace) set the target device colorspace for the lut const char* `getTargetSpace`()`const` get the target colorspace that has been set void `setShaperSize`(int shapersize) override the default the shaper sample size, default: <format specific> int `getShaperSize`()`const` get the shaper sample size void `setCubeSize`(int cubesize) override the default cube sample size default: <format specific> int `getCubeSize`()`const` get the cube sample size void `bake`(std::ostream& os)`const` bake the lut into the output stream static int `getNumFormats`() get the number of lut writers static const char* `getFormatNameByIndex`(int index) get the lut writer at index, return empty string if an invalid index is specified ## ImageDesc const ptrdiff_t `AutoStride` AutoStride class `ImageDesc` This is a light-weight wrapper around an image, that provides a context for pixel access. This does NOT claim ownership of the pixels or copy image data `ImageDesc::``~ImageDesc`() ### PackedImageDesc class `PackedImageDesc` `PackedImageDesc::``PackedImageDesc`(float* data, long width, long height, long numChannels, ptrdiff_t chanStrideBytes=AutoStride, ptrdiff_t xStrideBytes=AutoStride, ptrdiff_t yStrideBytes=AutoStride) Pass the pointer to packed image data: rgbrgbrgb, etc. The number of channels must be greater than or equal to 3 If a 4th channel is specified, it is assumed to be alpha information. Channels > 4 will be ignored. `PackedImageDesc::``~PackedImageDesc`() float* `PackedImageDesc::``getData`()`const` long `PackedImageDesc::``getWidth`()`const` long `PackedImageDesc::``getHeight`()`const` long `PackedImageDesc::``getNumChannels`()`const` ptrdiff_t `PackedImageDesc::``getChanStrideBytes`()`const` ptrdiff_t `PackedImageDesc::``getXStrideBytes`()`const` ptrdiff_t `PackedImageDesc::``getYStrideBytes`()`const` ### PlanarImageDesc class `PlanarImageDesc` `PlanarImageDesc::``PlanarImageDesc`(float* rData, float* gData, float* bData, float* aData, long width, long height, ptrdiff_t yStrideBytes=AutoStride) Pass the pointer to the specified image planes: rrrr gggg bbbb, etc. aData is optional, pass NULL if no alpha exists. {r,g,b} Data must be specified `PlanarImageDesc::``~PlanarImageDesc`() float* `PlanarImageDesc::``getRData`()`const` float* `PlanarImageDesc::``getGData`()`const` float* `PlanarImageDesc::``getBData`()`const` float* `PlanarImageDesc::``getAData`()`const` long `PlanarImageDesc::``getWidth`()`const` long `PlanarImageDesc::``getHeight`()`const` ptrdiff_t `PlanarImageDesc::``getYStrideBytes`()`const` ## GpuShaderDesc class `GpuShaderDesc` `GpuShaderDesc::``GpuShaderDesc`() `GpuShaderDesc::``~GpuShaderDesc`() void `GpuShaderDesc::``setLanguage`(GpuLanguage lang) GpuLanguage `GpuShaderDesc::``getLanguage`()`const` void `GpuShaderDesc::``setFunctionName`(const char* name) const char* `GpuShaderDesc::``getFunctionName`()`const` void `GpuShaderDesc::``setLut3DEdgeLen`(int len) int `GpuShaderDesc::``getLut3DEdgeLen`()`const` const char* `GpuShaderDesc::``getCacheID`()`const` ## Context class `Context` static ContextRcPtr `Context::``Create`() ContextRcPtr `Context::``createEditableCopy`()`const` const char* `Context::``getCacheID`()`const` void `Context::``setSearchPath`(const char* path) const char* `Context::``getSearchPath`()`const` void `Context::``setWorkingDir`(const char* dirname) const char* `Context::``getWorkingDir`()`const` void `Context::``setStringVar`(const char* name, const char* value) const char* `Context::``getStringVar`(const char* name)`const` void `Context::``loadEnvironment`() Seed all string vars with the current environment. const char* `Context::``resolveStringVar`(const char* val)`const` Do a file lookup. Evaluate the specified variable (as needed). Will not throw exceptions. const char* `Context::``resolveFileLocation`(const char* filename)`const` Do a file lookup. Evaluate all variables (as needed). Also, walk the full search path until the file is found. If the filename cannot be found, an exception will be thrown.