OpenColorIO

Open Source Color Management

OpenColorIO v1.0.8 documentation

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.