OpenColorIO

Open Source Color Management

OpenColorIO 1.1.1 documentation

Config syntax

OpenColorIO is primarily controlled by a central configuration file, usually named config.ocio. This page will only describe how to syntactically write this OCIO config - e.g. what transforms are available, or what sections are optional.

This page alone will not help you to write a useful config file! See the Configurations section for examples of complete, practical configs, and discussion of how they fit within a facilities workflow.

YAML basics

This config file is a YAML document, so it is important to have some basic knowledge of this format.

The Wikipedia article on YAML has a good overview.

OCIO configs typically use a small subset of YAML, so looking at existing configs is probably the quickest way to familiarise yourself (just remember the indentation is important!)

Checking for errors

Use the ociocheck command line tool to validate your config. It will inform you of YAML-syntax errors, but more importantly it performs various OCIO-specific “sanity checks”.

For more information, see the overview of ociocheck

Config sections

ocio_profile_version

Required.

By convention, the profile starts with ocio_profile_version.

This is an integer, specifying which version of the OCIO config syntax is used.

Currently there is only one OCIO profile version, so the value is always 1 (one)

ocio_profile_version: 1

search_path

Optional. Default is an empty search path.

search_path is a colon-separated list of directories. Each directory is checked in order to locate a file (e.g. a LUT).

This works is very similar to how the UNIX $PATH env-var works for executables.

A common directory structure for a config is:

config.ocio
luts/
  lg10_to_lnf.spi1d
  lg10_to_p3.3dl

For this, we would set search_path as follows:

search_path: "luts"

In a colorspace definition, we might have a FileTransform which refers to the LUT lg10_to_lnf.spi1d. It will look in the luts directory, relative to the config.ocio file’s location.

Paths can be relative (to the directory containing config.ocio), or absolute (e.g. /mnt/path/to/my/luts)

Multiple paths can be specified, including a mix of relative and absolute paths. Each path is separated with a colon :

search_path: "/mnt/path/to/my/luts:luts"

Finally, paths can reference OCIO’s context variables:

search_path: "/shots/show/$SHOT/cc/data:luts"

This allows for some clever setups, for example per-shot LUT’s with fallbacks to a default. For more information, see the examples in Looks

strictparsing

Optional. Valid values are true and false. Default is true (assuming a config is present):

strictparsing: true

OCIO provides a mechanism for applications to extract the colorspace from a filename (the parseColorSpaceFromString API method)

So for a file like example_render_v001_lnf.0001.exr it will determine the colorspace lnf (it being the right-most substring containing a colorspace name)

However, if the colorspace cannot be determined and strictparsing: true, it will produce an error.

If the colorspace cannot be determined and strictparsing: false, the default role will be used. This allows unhandled images to operate in “non-color managed” mode.

Application authors should note: when no config is present (e.g. via $OCIO), the default internal profile specifies strictparsing=false, and the default color space role is raw. This means that ANY string passed to OCIO will be parsed as the default raw. This is nice because in the absence of a config, the behavior from your application perspective is that the library essentially falls back to “non-color managed”.

luma

Deprecated. Optional. Default is the Rec.709 primaries specified by the ASC:

luma: [0.2126, 0.7152, 0.0722]

These are the luminance coefficients, which can be used by OCIO-supporting applications when adjusting saturation (e.g. in an image-viewer when displaying a single channel)

Note

While the API method is not yet officially deprecated, luma is a legacy option from Imageworks’ internal, closed-source predecessor to OCIO.

The luma value is not respected anywhere within the OCIO library. Also very few (if any) applications supporting OCIO will respect the value either.

roles

Required.

A “role” is an alias to a colorspaces, which can be used by applications to perform task-specific color transforms without requiring the user to select a colorspace by name.

For example, the Nuke node OCIOLogConvert: instead of requiring the user to select the appropriate log colorspace, the node performs a transform between scene_linear and compositing_log, and the OCIO config specifies the project-appropriate colorspaces. This simplifies life for artists, as they don’t have to remember which is the correct log colorspace for the current project - the OCIOLogConvert always does the correct thing.

A typical role definition looks like this, taken from the spi-vfx example configuration:

roles:
  color_picking: cpf
  color_timing: lg10
  compositing_log: lgf
  data: ncf
  default: ncf
  matte_paint: vd8
  reference: lnf
  scene_linear: lnf
  texture_paint: dt16

All values in this example (such as cpf, lg10 and ncf) refer to colorspaces defined later the config, in the colorspaces section.

A description of all roles. Note that applications may interpret or use these differently.

  • color_picking - colors in a color-selection UI can be displayed in this space, while selecting colors in a different working space (e.g. scene_linear or texture_paint)
  • color_timing - colorspace used for applying color corrections, e.g. user-specified grade within an image viewer (if the application uses the DisplayTransform::setDisplayCC API method)
  • compositing_log - a log colorspace used for certain processing operations (plate resizing, pulling keys, degrain, etc). Used by the OCIOLogConvert Nuke node
  • data - used when writing data outputs such as normals, depth data, and other “non color” data. The colorspace in this role should typically have data: true specified, so no color transforms are applied
  • default - when strictparsing: false, this colorspace is used as a fallback. If not defined, the scene_linear role is used
  • matte_paint - colorspace which matte-paintings are created in (for more information, see the guide on baking ICC profiles for Photoshop, and spi-vfx)
  • reference - the colorspace against which the other colorspaces are defined
  • scene_linear - the scene-referred linear-to-light colorspace, often the same as the reference space (see:ref:faq-terminology)
  • texture_paint - similar to matte_paint but for painting textures for 3D objects (see the description of texture painting in SPI’s pipeline)

displays

Required.

This section defines all the display devices which will be used. For example you might have a sRGB display device for artist workstations, a DCIP3 display device for the screening room projector.

Each display device has a number of “views”. These views provide different ways to display the image on the selected display device. Examples of common views are:

  • “Film” to emulate the final projected result on the current display
  • “Log” to send log-space pixel values directly to the display, resulting in a “lifted” image useful for checking black-levels.
  • “Raw” when assigned a colorspace with raw: yes set will show the unaltered image, useful for tech-checking images

An example of the displays section from the spi-vfx config:

displays:
  DCIP3:
    - !<View> {name: Film, colorspace: p3dci8}
    - !<View> {name: Log, colorspace: lg10}
    - !<View> {name: Raw, colorspace: nc10}
  sRGB:
    - !<View> {name: Film, colorspace: srgb8}
    - !<View> {name: Log, colorspace: lg10}
    - !<View> {name: Raw, colorspace: nc10}
    - !<View> {name: Film, colorspace: srgb8}

All the colorspaces (p3dci8, srgb8 etc) refer to colorspaces defined later in the config.

Unless the active_displays and active_views sections are defined, the first display and first view will be the default.

active_displays

Optional. Default is for all displays to be visible, and to respect order of items in displays section.

You can choose what display devices to make visible in UI’s, and change the order in which they appear.

Given the example displays block in the previous section - to make the sRGB device appear first:

active_displays: [sRGB, DCIP3]

To display only the DCIP3 device, simply remove sRGB:

active_displays: [DCIP3]

The value can be overridden by the OCIO_ACTIVE_DISPLAYS env-var. This allows you to make the sRGB the only active display, like so:

active_displays: [sRGB]

Then on a review machine with a DCI P3 projector, set the following environment variable, making DCIP3 the only visible display device:

export OCIO_ACTIVE_DISPLAYS="DCIP3"

Or specify multiple active displays, by separating each with a colon:

export OCIO_ACTIVE_DISPLAYS="DCIP3:sRGB"

active_views

Optional. Default is for all views to be visible, and to respect order of the views under the display.

Works identically to active_displays, but controls which views are visible.

Overridden by the OCIO_ACTIVE_VIEWS env-var:

export OCIO_ACTIVE_VIEWS="Film:Log:Raw"

looks

Optional.

This section defines a list of “looks”. A look is a color transform defined similarly to a colorspace, with a few important differences.

For example, a look could be defined for a “first pass DI beauty grade”, which is used to view shots with a rough approximation of the final grade.

When the look is defined in the config, you must specify a name, the color transform, and the colorspace in which the grade is performed (the “process space”). You can optionally specify an inverse transform for when the look transform is not trivially invertable (e.g. it applies a 3D LUT)

When an application applies a look, OCIO ensures the grade is applied in the correct colorspace (by converting from the input colorspace to the process space, applies the look’s transform, and converts the image to the output colorspace)

Here is a simple looks: section, which defines two looks:

looks:
  - !<Look>
    name: beauty
    process_space: lnf
    transform: !<CDLTransform> {slope: [1, 2, 1]}

  - !<Look>
    name: neutral
    process_space: lg10
    transform: !<FileTransform> {src: 'neutral-${SHOT}-${SEQ}.csp', interpolation: linear }
    inverse_transform: !<FileTransform> {src: 'neutral-${SHOT}-${SEQ}-reverse.csp', interpolation: linear }

Here, the “beauty” look applies a simple, static ASC CDL grade, making the image very green (for some artistic reason!). The beauty look is appied in the scene-linear lnf colorspace (this colorspace is defined elsewhere in the config.

Next is a definition for a “neutral” look, which applies a shot-specific CSP LUT, dynamically finding the correct LUT based on the SEQ and SHOT context variables.

For example if SEQ=ab and SHOT=1234, this look will search for a LUT named neutral-ab-1234.csp in locations specified in search_path.

The process_space here is lg10. This means when the look is applied, OCIO will perform the following steps:

  • Transform the image from it’s current colorspace to the lg10 process space
  • Apply apply the FileTransform (which applies the grade LUT)
  • Transform the graded image from the process space to the output colorspace

The “beauty” look specifies the optional inverse_transform, because in this example the neutral CSP files contain a 3D LUT. For many transforms, OCIO will automatically calculate the inverse transform (as with the “beauty” look), however with a 3D LUT the inverse transform needs to be defined.

If the look was applied in reverse, and inverse_transform as not specified, then OCIO would give a helpful error message. This is commonly done for non-invertable looks

As in colorspace definitions, the transform can be specified as a series of transforms using the GroupTransform, for example:

looks:
  - !<Look>
    name: beauty
    process_space: lnf
    transform: !<GroupTransform>
      children:
        - !<CDLTransform> {slope: [1, 2, 1]}
        - !<FileTransform> {src: beauty.spi1d, interpolation: nearest}

colorspaces

Required.

This section is a list of all the colorspaces known to OCIO. A colorspace can be referred to elsewhere within the config (including other colorspace definitions), and are used within OCIO-supporting applications.

to_reference and from_reference

Here is a example of a very simple colorspaces section, modified from the spi-vfx example config:

colorspaces:
  - !<ColorSpace>
    name: lnf
    bitdepth: 32f
    description: |
      lnf : linear show space

  - !<ColorSpace>
    name: lg16
    bitdepth: 16ui
    description: |
      lg16 : conversion from film log
    to_reference: !<FileTransform> {src: lg16_to_lnf.spi1d, interpolation: nearest}

First the lnf colorspace (short for linear float) is used as our reference colorspace. The name can be anything, but the idea of a reference colorspace is an important convention within OCIO: all other colorspaces are defined as transforms either to or from this colorspace.

The lg16 colorspace is a 16-bit log colorspace (see spi-vfx for an explaination of this colorspace). It has a name, a bitdepth and a description.

The lg16 colorspace is defined as a transform from lg16 to the reference colorspace (lnf). That transform is to apply the LUT lg16_to_lnf.spi1d. This LUT has an input of lg16 integers and outputs linear 32-bit float values

Since the 1D LUT is automatically invertable by OCIO, we can use this colorspace both to convert lg16 images to lnf, and lnf images to lg16

Importantly, because of the reference colorspace concept, we can convert images from lg16 to the reference colorspace, and then on to any other colorspace.

Here is another example colorspace, which is defined using from_reference.

- !<ColorSpace>
  name: srgb8
  bitdepth: 8ui
  description: |
    srgb8 :rgb display space for the srgb standard.
  from_reference: !<FileTransform> {src: srgb8.spi3d, interpolation: linear}

We use from_reference here because we have a LUT which transforms from the reference colorspace (lnf in this example) to sRGB.

In this case srgb8.spi3d is a complex 3D LUT which cannot be inverted, so it is considered a “display only” colorspace. If we did have a second 3D LUT to apply the inverse transform, we can specify both to_reference and from_reference

- !<ColorSpace>
  name: srgb8
  bitdepth: 8ui
  description: |
    srgb8 :rgb display space for the srgb standard.
  from_reference: !<FileTransform> {src: lnf_to_srgb8.spi3d, interpolation: linear}
  to_reference: !<FileTransform> {src: srgb8_to_lnf.spi3d, interpolation: linear}

Using multiple transforms

The previous example colorspaces all used a single transform each, however it is often useful to use multiple transforms to define a colorspace.

- !<ColorSpace>
  name: srgb8
  bitdepth: 8ui
  description: |
    srgb8 :rgb display space for the srgb standard.
  from_reference: !<GroupTransform>
    children:
      - !<ColorSpaceTransform> {src: lnf, dst: lg16}
      - !<FileTransform> {src: lg16_to_srgb8.spi3d, interpolation: linear}

Here to get from the reference colorspace, we first use the ColorSpaceTransform to convert from lnf to lg16, then apply our 3D LUT on the log-encoded images.

This primarily demonstrates the meta-transform GroupTransform: a transform which simply composes two or more transforms together into one. Anything that accepts a transform like FileTransform or CDLTransform will also accept a GroupTransform

It is also worth noting the ColorSpaceTransform, which transforms between lnf and lg16 colorspaces (which are defined within the current config).

Example transform steps

This section explains how OCIO internally applies all the transforms. It can be skipped over if you understand how the reference colorspace works.

colorspaces:
  - !<ColorSpace>
    name: lnf
    bitdepth: 32f
    description: |
      lnf : linear show space

  - !<ColorSpace>
    name: lg16
    bitdepth: 16ui
    description: |
      lg16 : conversion from film log
    to_reference: !<FileTransform> {src: lg16.spi1d, interpolation: nearest}

  - !<ColorSpace>
    name: srgb8
    bitdepth: 8ui
    description: |
      srgb8 :rgb display space for the srgb standard.
    from_reference: !<GroupTransform>
      children:
        - !<ColorSpaceTransform> {src: lnf, dst: lg16}
        - !<FileTransform> {src: lg16_to_srgb8.spi3d, interpolation: linear}

To explain how this all ties together to display an image, say we have an image in the lnf colorspace (e.g. a linear EXR) and wish to convert it to srgb8 - the transform steps are:

  • ColorSpaceTransform is applied, converting from lnf to lg16
  • The FileTransform is applied, converting from lg16 to srgb8.

A more complex example: we have an image in the lg16 colorspace, and convert to srgb8 (using the lg16 definition from earlier, or the spi-vfx config):

First OCIO converts from lg16 to the reference space, using the transform defined in lg16’s to_reference:

  • FileTransform applies the lg16.spi1d

With the image now in the reference space, srgb8’s transform is applied:

  • ColorSpaceTransform to transform from lnf to lg16
  • FileTransform applies the lg16_to_srgb8.spi3d LUT.

Note

OCIO has an transform optimizer which removes redundant steps, and combines similar transforms into one operation.

In the previous example, the complete transform chain would be “lg16 -> lnf, lnf -> lg16, lg16 -> srgb8”. However the optimizer will reduce this to “lg16 -> srgb”.

bitdepth

Optional. Default: 32f

Specify an appropriate bitdepth for the colorspace, and applications can use this to automatically output images in the correct bit-depth.

Valid options are:

  • 8ui
  • 10ui
  • 12ui
  • 14ui
  • 16ui
  • 32ui
  • 16f
  • 32f

The number is in bits. ui stands for unsigned integer. f stands for floating point.

Example:

- !<ColorSpace>
  name: srgb8
  bitdepth: 8ui

  from_reference: [...]

isdata:

Optional. Default: false. Boolean.

The isdata key on a colorspace informs OCIO that this colorspace is used for non-color data channels, such as the “normals” output of a a multipass 3D render.

Here is example “non-color” colorspace from the spi-vfx config:

- !<ColorSpace>
  name: ncf
  family: nc
  equalitygroup:
  bitdepth: 32f
  description: |
    ncf :nc,Non-color used to store non-color data such as depth or surface normals
  isdata: true
  allocation: uniform

equalitygroup:

Optional.

If two colorspaces are in the “equality group”, transforms between them are considered non-operations.

You might have multiple colorspaces which are identical, but operate at different bit-depths.

For example, see the lg10 and lg16 colorspaces in the spi-vfx config. If loading a lg10 image and converting to lg16, no transform is required. This is of course faster, but may cause an unexpected increase in precision (e.g. it skip potential clamping caused by a LUT)

- !<ColorSpace>
  name: lg16
  equalitygroup: lg
  bitdepth: 16ui
  to_reference: !<FileTransform> {src: lg16.spi1d, interpolation: nearest}

- !<ColorSpace>
  name: lg10
  equalitygroup: lg
  bitdepth: 10ui
  to_reference: !<FileTransform> {src: lg10.spi1d, interpolation: nearest}
Do not put different colorspaces in the same equality group. For
logical grouping of “similar” colorspaces, use the family option.

family:

Optional.

Allows for logical grouping of colorspaces within a UI.

For example, a series of “log” colorspaces could be put in one “family”. Within a UI like the Nuke OCIOColorSpace node, these will be grouped together.

- !<ColorSpace>
  name: kodaklog
  family: log
  equalitygroup: kodaklog
  [...]

- !<ColorSpace>
  name: si2klog
  family: log
  equalitygroup: si2klog
  [...]

- !<ColorSpace>
  name: rec709
  family: display
  equalitygroup: rec709
  [...]

Unlike equalitygroup, the family has no impact on image processing.

allocation and allocationvars

Optional.

These two options are used when OCIO transforms are applied on the GPU.

It is also used to automatically generate a “shaper LUT” when baking LUT’s unless one is explicitly specified (not all output formats utilise this)

For a detailed description, see How to Configure ColorSpace Allocation

Example of a “0-1” colorspace

allocation: uniform
allocationvars: [0.0, 1.0]
allocation: lg2
allocationvars: [-15, 6]

description

Optional.

A human-readable description of the colorspace.

The YAML syntax allows for either single-line descriptions:

- !<ColorSpace>
  name: kodaklog
  [...]
  description: A concise description of the kodaklog colorspace.

Or multiple-lines:

- !<ColorSpace>
  name: kodaklog
  [...]
  description:
    This is a multi-line description of the kodaklog colorspace,
    to demonstrate the YAML syntax for doing so.

    Here is the second line. The first one will be unwrapped into
    a single line, as will this one.

It’s common to use literal | block syntax to preserve all newlines:

- !<ColorSpace>
  name: kodaklog
  [...]
  description: |
    This is one line.
    This is the second.

Available transforms

AllocationTransform

Transforms from reference space to the range specified by the vars:

Keys:

  • allocation
  • vars
  • direction

CDLTransform

Applies an ASC CDL compliant grade

Keys:

  • slope
  • offset
  • power
  • sat
  • direction

ColorSpaceTransform

Transforms from src colorspace to dst colorspace.

Keys:

  • src
  • dst
  • direction

ExponentTransform

Raises pixel values to a given power (often referred to as “gamma”)

!<ExponentTransform> {value: [1.8, 1.8, 1.8, 1]}

Keys:

  • value
  • direction

FileTransform

Applies a lookup table (LUT)

Keys:

  • src
  • cccid
  • interpolation
  • direction

GroupTransform

Combines multiple transforms into one.

colorspaces:

  - !<ColorSpace>
    name: adx10

    [...]

    to_reference: !<GroupTransform>
      children:
        - !<FileTransform> {src: adx_adx10_to_cdd.spimtx}
        - !<FileTransform> {src: adx_cdd_to_cid.spimtx}

A group transform is accepted anywhere a “regular” transform is.

LogTransform

Applies a mathematical logarithm with a given base to the pixel values.

Keys:

  • base

LookTransform

Applies a named look

MatrixTransform

Applies a matrix transform to the pixel values

Keys:

  • matrix
  • offset
  • direction

TruelightTransform

Applies a transform from a Truelight profile.

Keys:

  • config_root
  • profile
  • camera
  • input_display
  • recorder
  • print
  • lamp
  • output_camera
  • display
  • cube_input
  • direction

Note

This transform requires OCIO to be compiled with the Truelight SDK present.