Exemple #1
0
    def test_constructor_with_keyword(self):
        """
        Test DisplayViewTransform constructor with keywords and validate its values.
        """

        # With keywords in their proper order.
        dv_tr = OCIO.DisplayViewTransform(src=self.TEST_SRC[0],
                                          display=self.TEST_DISPLAY[0],
                                          view=self.TEST_VIEW[0],
                                          looksBypass=True,
                                          dataBypass=False,
                                          direction=OCIO.TRANSFORM_DIR_INVERSE)

        self.assertEqual(self.TEST_SRC[0], dv_tr.getSrc())
        self.assertEqual(self.TEST_DISPLAY[0], dv_tr.getDisplay())
        self.assertEqual(self.TEST_VIEW[0], dv_tr.getView())
        self.assertEqual(True, dv_tr.getLooksBypass())
        self.assertEqual(False, dv_tr.getDataBypass())
        self.assertEqual(OCIO.TRANSFORM_DIR_INVERSE, dv_tr.getDirection())

        # With keyword not in their proper order.
        dv_tr2 = OCIO.DisplayViewTransform(
            direction=OCIO.TRANSFORM_DIR_FORWARD,
            view=self.TEST_VIEW[1],
            src=self.TEST_SRC[1],
            looksBypass=True,
            display=self.TEST_DISPLAY[1],
            dataBypass=True)

        self.assertEqual(self.TEST_SRC[1], dv_tr2.getSrc())
        self.assertEqual(self.TEST_DISPLAY[1], dv_tr2.getDisplay())
        self.assertEqual(self.TEST_VIEW[1], dv_tr2.getView())
        self.assertEqual(True, dv_tr2.getLooksBypass())
        self.assertEqual(True, dv_tr2.getDataBypass())
        self.assertEqual(OCIO.TRANSFORM_DIR_FORWARD, dv_tr2.getDirection())
    def test_get_processor_errors(self):
        """
        Test the getProcessor function failures.
        """
        cfg = OCIO.Config().CreateRaw()
        pipeline = OCIO.LegacyViewingPipeline()

        # No DisplayViewTransform.
        with self.assertRaises(OCIO.Exception):
            pipeline.getProcessor(cfg)

        # DisplayViewTransform refers to elements that are not part of config.

        dvt = OCIO.DisplayViewTransform(src='colorspace1',
                                        display='sRGB',
                                        view='view1')
        pipeline.setDisplayViewTransform(dvt)
        with self.assertRaises(OCIO.Exception):
            pipeline.getProcessor(cfg)

        # Add display and view.
        cfg.addDisplayView(display='sRGB',
                           view='view1',
                           colorSpaceName='colorspace1')

        with self.assertRaises(OCIO.Exception):
            pipeline.getProcessor(cfg)

        # Add color space.
        cs = OCIO.ColorSpace(name='colorspace1')
        cfg.addColorSpace(cs)

        # Processor can now be created.
        pipeline.getProcessor(cfg)

        mat = OCIO.MatrixTransform()
        mat.setOffset([0.1, 0.2, 0.3, 0.])
        pipeline.setLinearCC(mat)

        # Scene_linear role is missing.
        with self.assertRaises(OCIO.Exception):
            pipeline.getProcessor(cfg)

        cfg.setRole(role='scene_linear', colorSpaceName='colorspace1')
        # Processor can now be created.
        pipeline.getProcessor(cfg)

        # Print the pipeline.
        self.assertEqual(str(pipeline), (
            'DisplayViewTransform: <DisplayViewTransform direction=forward, '
            'src=colorspace1, display=sRGB, view=view1, , looksBypass=1>, '
            'LinearCC: <MatrixTransform direction=forward, fileindepth=unknown, '
            'fileoutdepth=unknown, matrix=1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1, offset=0.1 0.2 0.3 0>'
        ))
Exemple #3
0
def build_output_transform_from_id_elem(config, gt, id_elem, msg, transform_dir):
    """ Add an OCIO transform to the supplied group transform using a transform ID. """
    aces_id = id_elem.text

    dcs_name = search_colorspaces(config, aces_id)
    vt_name = search_viewtransforms(config, aces_id)

    if dcs_name is not None and vt_name is not None:
        print( msg % (dcs_name, vt_name) )
        gt.appendTransform( ocio.DisplayViewTransform(ACES, dcs_name, vt_name, direction=transform_dir) )
    else:
        raise ValueError("Could not process transformId element: " + aces_id)
Exemple #4
0
    def test_constructor_without_keyword(self):
        """
        Test DisplayViewTransform constructor without keywords and validate its values.
        """

        dv_tr = OCIO.DisplayViewTransform(self.TEST_SRC[0],
                                          self.TEST_DISPLAY[0],
                                          self.TEST_VIEW[0], True, False,
                                          OCIO.TRANSFORM_DIR_INVERSE)

        self.assertEqual(self.TEST_SRC[0], dv_tr.getSrc())
        self.assertEqual(self.TEST_DISPLAY[0], dv_tr.getDisplay())
        self.assertEqual(self.TEST_VIEW[0], dv_tr.getView())
        self.assertEqual(True, dv_tr.getLooksBypass())
        self.assertEqual(False, dv_tr.getDataBypass())
        self.assertEqual(OCIO.TRANSFORM_DIR_INVERSE, dv_tr.getDirection())
    def test_display_view_transform(self):
        """
        Test the get/setDisplayViewTransform functions.
        """
        pipeline = OCIO.LegacyViewingPipeline()
        self.assertEqual(pipeline.getDisplayViewTransform(), None)
        dvt = OCIO.DisplayViewTransform(src='test', display='display', view='view')
        pipeline.setDisplayViewTransform(dvt)
        self.assertEqual(pipeline.getDisplayViewTransform().getSrc(), 'test')
        pipeline.setDisplayViewTransform(None)
        self.assertEqual(pipeline.getDisplayViewTransform(), None)

        with self.assertRaises(TypeError):
            pipeline.setDisplayViewTransform()
        with self.assertRaises(TypeError):
            pipeline.setDisplayViewTransform(OCIO.TRANSFORM_DIR_FORWARD)
        with self.assertRaises(TypeError):
            pipeline.setDisplayViewTransform(False)
def ocio_viewer(
    RGB=None,
    source=None,
    display=None,
    view=None,
    exposure=0.0,
    contrast=1.0,
    gamma=1.0,
    style=ocio.EXPOSURE_CONTRAST_LINEAR,
    use_gpu=False,
    config=None,
    context=None,
):

    cfg = config or create_new_config()
    context = context or cfg.getCurrentContext()

    exposure_contrast_transform = ocio.ExposureContrastTransform(
        exposure=exposure, gamma=gamma, contrast=contrast, style=style
    )

    processor = cfg.getProcessor(
        context=context,
        direction=ocio.TRANSFORM_DIR_FORWARD,
        transform=ocio.GroupTransform(
            [
                exposure_contrast_transform,
                ocio.DisplayViewTransform(
                    src=source or "scene_linear",
                    display=display or cfg.getDefaultDisplay(),
                    view=view or cfg.getDefaultView(),
                ),
            ]
        ),
    )

    if RGB is None:
        return processor
    else:
        RGB_out = np.copy(RGB)
        RGB_out = apply_ocio_processor(processor, RGB_out, use_gpu=use_gpu)

        return RGB_out
Exemple #7
0
    def update_ocio_proc(self,
                         input_cs=None,
                         display=None,
                         view=None,
                         channel=None):
        """
        Update one or more aspects of the OCIO GPU renderer. Parameters
        are cached so not providing a parameter maintains the existing
        state. This will trigger a GL update IF the underlying OCIO ops
        in the processor have changed.

        :param str input_cs: Override the input color space name (how
            the image texture should be interpreted by OCIO). If this
            is wrong, the rendered results will look wrong in most
            cases.
        :param str display: OCIO display representing the current
            display device colors are being viewed on.
        :param str view: OCIO view defining the output transform for
            the given display.
        :param int channel: ImagePlaneChannels value to toggle channel
            isolation.
        """
        if input_cs:
            self._ocio_input_cs = input_cs
        if display:
            self._ocio_display = display
        if view:
            self._ocio_view = view
        if channel is not None:
            self._update_ocio_channel_hot(channel)

        # Can a processor be made?
        if not all((self._ocio_input_cs, self._ocio_display, self._ocio_view)):
            return

        config = ocio.GetCurrentConfig()

        # Build transforms needed for viewing pipeline
        exposure_tr = ocio.ExposureContrastTransform(
            exposure=self._ocio_exposure, dynamicExposure=True)
        channel_view_tr = ocio.MatrixTransform.View(
            channelHot=self._ocio_channel_hot,
            lumaCoef=config.getDefaultLumaCoefs())
        display_view_tr = ocio.DisplayViewTransform(src=self._ocio_input_cs,
                                                    display=self._ocio_display,
                                                    view=self._ocio_view)
        gamma_tr = ocio.ExposureContrastTransform(gamma=self._ocio_gamma,
                                                  pivot=1.0,
                                                  dynamicGamma=True)

        # Mimic OCIO v1 DisplayTransform for consistency with DCCs
        viewing_pipeline = ocio.LegacyViewingPipeline()
        viewing_pipeline.setLinearCC(exposure_tr)
        viewing_pipeline.setChannelView(channel_view_tr)
        viewing_pipeline.setDisplayViewTransform(display_view_tr)
        viewing_pipeline.setDisplayCC(gamma_tr)

        # Create processor
        proc = viewing_pipeline.getProcessor(config)

        if proc.getCacheID() != self._ocio_proc_cache_id:
            self._ocio_shader_desc = ocio.GpuShaderDesc.CreateShaderDesc(
                language=ocio.GPU_LANGUAGE_GLSL_4_0)
            self._ocio_proc_cache_id = proc.getCacheID()
            ocio_gpu_proc = proc.getDefaultGPUProcessor()
            ocio_gpu_proc.extractGpuShaderInfo(self._ocio_shader_desc)

            self._allocate_ocio_tex()
            self._build_program()

            # Set initial dynamic property state
            self._update_ocio_dyn_prop(ocio.DYNAMIC_PROPERTY_EXPOSURE,
                                       self._ocio_exposure)
            self._update_ocio_dyn_prop(ocio.DYNAMIC_PROPERTY_GAMMA,
                                       self._ocio_gamma)

            self.update()
Exemple #8
0
 def setUp(self):
     self.dv_tr = OCIO.DisplayViewTransform()
    def test_get_processor(self):
        """
        Test the getProcessor function.
        """
        cfg = OCIO.Config().CreateFromStream(SAMPLE_CONFIG)
        dvt = OCIO.DisplayViewTransform(src='in_1', display='DISP_2', view='VIEW_2')
        pipeline = OCIO.LegacyViewingPipeline()
        pipeline.setDisplayViewTransform(dvt)

        mat = OCIO.MatrixTransform.Scale([1.1, 1.2, 1.1, 1.])
        pipeline.setChannelView(mat)
        ff = OCIO.FixedFunctionTransform()
        pipeline.setLinearCC(ff)

        proc = pipeline.getProcessor(cfg)
        grp = proc.createGroupTransform()
        self.assertEqual(len(grp), 8)

        # Color space conversion from in_1 to scene_linear role (lin_1 color space).

        t = grp[0]
        self.assertEqual(t.getTransformType(), OCIO.TRANSFORM_TYPE_EXPONENT)
        self.assertEqual(t.getDirection(), OCIO.TRANSFORM_DIR_FORWARD)
        self.assertEqual(t.getValue(), [2.6, 2.6, 2.6, 1.])

        # LinearCC transform.

        t = grp[1]
        self.assertEqual(t.getTransformType(), OCIO.TRANSFORM_TYPE_FIXED_FUNCTION)
        self.assertEqual(t.getDirection(), OCIO.TRANSFORM_DIR_FORWARD)

        # Apply the looks, channel view, and view transform.

        # Lin_1 to look3 process space (log_1).

        t = grp[2]
        self.assertEqual(t.getTransformType(), OCIO.TRANSFORM_TYPE_LOG)
        self.assertEqual(t.getDirection(), OCIO.TRANSFORM_DIR_FORWARD)
        self.assertEqual(t.getBase(), 2.)

        # Look_3 transform.

        t = grp[3]
        self.assertEqual(t.getTransformType(), OCIO.TRANSFORM_TYPE_CDL)
        self.assertEqual(t.getDirection(), OCIO.TRANSFORM_DIR_FORWARD)
        self.assertEqual(t.getSlope(), [1., 2., 1.])

        # Look_3 & look_4 have the same process space, no color space conversion.

        # Look_4 transform.

        t = grp[4]
        self.assertEqual(t.getTransformType(), OCIO.TRANSFORM_TYPE_CDL)
        self.assertEqual(t.getDirection(), OCIO.TRANSFORM_DIR_INVERSE)
        self.assertEqual(t.getSlope(), [1.2, 2.2, 1.2])

        # Channel View transform (no color space conversion).

        t = grp[5]
        self.assertEqual(t.getTransformType(), OCIO.TRANSFORM_TYPE_MATRIX)
        self.assertEqual(t.getDirection(), OCIO.TRANSFORM_DIR_FORWARD)
        m44 = t.getMatrix()
        self.assertEqual(m44[0],  1.1)
        self.assertEqual(m44[1],  0)
        self.assertEqual(m44[2],  0)
        self.assertEqual(m44[3],  0)
        self.assertEqual(m44[5],  1.2)
        self.assertEqual(m44[10],  1.1)

        # Look_4 process color space (log_1) to reference.

        t = grp[6]
        self.assertEqual(t.getTransformType(), OCIO.TRANSFORM_TYPE_LOG)
        self.assertEqual(t.getDirection(), OCIO.TRANSFORM_DIR_INVERSE)
        self.assertEqual(t.getBase(), 2.)

        # Reference to view_2 color space.

        t = grp[7]
        self.assertEqual(t.getTransformType(), OCIO.TRANSFORM_TYPE_EXPONENT)
        self.assertEqual(t.getDirection(), OCIO.TRANSFORM_DIR_INVERSE)
        self.assertEqual(t.getValue(), [2.4, 2.4, 2.4, 1.])
Exemple #10
0
    def test_processor(self):
        """
        Test creating a processor from a display view and a named transform.
        """
        SIMPLE_PROFILE = """ocio_profile_version: 2

roles:
  default: raw

displays:
  sRGB:
    - !<View> {name: Raw, colorspace: raw}
  display:
    - !<View> {name: view, view_transform: display_vt, display_colorspace: displayCSOut}
    - !<View> {name: viewCSNT, colorspace: nt_inverse}
    - !<View> {name: viewVTNT, view_transform: nt_forward, display_colorspace: displayCSOut}

view_transforms:
  - !<ViewTransform>
    name: display_vt
    to_display_reference: !<CDLTransform> {name: display vt to ref, sat: 1.5}
    from_display_reference: !<CDLTransform> {name: display vt from ref, sat: 1.5}

display_colorspaces:
  - !<ColorSpace>
    name: displayCSOut
    to_display_reference: !<CDLTransform> {name: out cs to ref, sat: 1.5}
    from_display_reference: !<CDLTransform> {name: out cs from ref, sat: 1.5}

colorspaces:
  - !<ColorSpace>
    name: raw
    isdata: true

  - !<ColorSpace>
    name: in
    to_reference: !<MatrixTransform> {offset: [0.11, 0.12, 0.13, 0]}

named_transforms:
  - !<NamedTransform>
    name: nt_forward
    transform: !<CDLTransform> {name: forward, sat: 1.5}

  - !<NamedTransform>
    name: nt_inverse
    inverse_transform: !<CDLTransform> {name: inverse, sat: 1.5}
"""
        # Create a config.
        cfg = OCIO.Config().CreateFromStream(SIMPLE_PROFILE)

        # Src can't be a named transform.
        dv_tr = OCIO.DisplayViewTransform(src='nt_forward',
                                          display='display',
                                          view='view')
        with self.assertRaises(OCIO.Exception):
            proc = cfg.getProcessor(dv_tr)

        # Dst is a named transform.
        dv_tr.setSrc('in')
        dv_tr.setView('viewCSNT')
        proc = cfg.getProcessor(dv_tr)
        group = proc.createGroupTransform()
        groupTransformsList = list(group)
        self.assertEqual(len(groupTransformsList), 1)
        self.assertIsInstance(groupTransformsList[0], OCIO.CDLTransform)
        metadata = groupTransformsList[0].getFormatMetadata()
        atts = metadata.getAttributes()
        self.assertEqual('inverse', next(atts)[1])

        # View transform is a named transform.
        dv_tr.setSrc('in')
        dv_tr.setView('viewVTNT')
        proc = cfg.getProcessor(dv_tr)
        group = proc.createGroupTransform()
        groupTransformsList = list(group)
        self.assertEqual(len(groupTransformsList), 2)
        self.assertIsInstance(groupTransformsList[0], OCIO.CDLTransform)
        metadata = groupTransformsList[0].getFormatMetadata()
        atts = metadata.getAttributes()
        self.assertEqual('forward', next(atts)[1])
        self.assertIsInstance(groupTransformsList[1], OCIO.CDLTransform)
        metadata = groupTransformsList[1].getFormatMetadata()
        atts = metadata.getAttributes()
        self.assertEqual('out cs from ref', next(atts)[1])
Exemple #11
0
    def test_interface(self):

        ### AllocationTransform ###
        at = OCIO.AllocationTransform()
        self.assertEqual(OCIO.ALLOCATION_UNIFORM, at.getAllocation())
        at.setAllocation(OCIO.ALLOCATION_LG2)
        self.assertEqual(OCIO.ALLOCATION_LG2, at.getAllocation())
        self.assertEqual(0, at.getNumVars())
        at.setVars([0.1, 0.2, 0.3])
        self.assertEqual(3, at.getNumVars())
        newvars = at.getVars()
        self.assertAlmostEqual(0.2, newvars[1], delta=1e-8)

        at2 = OCIO.AllocationTransform(OCIO.ALLOCATION_LG2, [0.1, 0.2, 0.3],
                                       OCIO.TRANSFORM_DIR_INVERSE)
        self.assertEqual(OCIO.ALLOCATION_LG2, at2.getAllocation())
        self.assertEqual(3, at2.getNumVars())
        newvars2 = at2.getVars()
        for i in range(0, 3):
            self.assertAlmostEqual(float(i + 1) / 10.0,
                                   newvars2[i],
                                   delta=1e-7)
        self.assertEqual(OCIO.TRANSFORM_DIR_INVERSE, at2.getDirection())

        at3 = OCIO.AllocationTransform(allocation=OCIO.ALLOCATION_LG2,
                                       vars=[0.1, 0.2, 0.3],
                                       direction=OCIO.TRANSFORM_DIR_INVERSE)
        self.assertEqual(OCIO.ALLOCATION_LG2, at3.getAllocation())
        self.assertEqual(3, at3.getNumVars())
        newvars3 = at3.getVars()
        for i in range(0, 3):
            self.assertAlmostEqual(float(i + 1) / 10.0,
                                   newvars3[i],
                                   delta=1e-7)
        self.assertEqual(OCIO.TRANSFORM_DIR_INVERSE, at3.getDirection())

        ### Base Transform method tests ###
        self.assertEqual(OCIO.TRANSFORM_DIR_FORWARD, at.getDirection())
        at.setDirection(OCIO.TRANSFORM_DIR_UNKNOWN)
        self.assertEqual(OCIO.TRANSFORM_DIR_UNKNOWN, at.getDirection())

        ### CDLTransform ###
        cdl = OCIO.CDLTransform()
        CC = "<ColorCorrection id=\"foo\">\n"
        CC += "    <SOPNode>\n"
        CC += "        <Description>this is a description</Description>\n"
        CC += "        <Slope>1.1 1.2 1.3</Slope>\n"
        CC += "        <Offset>2.1 2.2 2.3</Offset>\n"
        CC += "        <Power>3.1 3.2 3.3</Power>\n"
        CC += "    </SOPNode>\n"
        CC += "    <SatNode>\n"
        CC += "        <Saturation>0.7</Saturation>\n"
        CC += "    </SatNode>\n"
        CC += "</ColorCorrection>"
        # Don't want to deal with getting the correct path so this runs
        #cdlfile = OCIO.CDLTransform().CreateFromFile("../OpenColorIO/src/jniglue/tests/org/OpenColorIO/test.cc", "foo")
        #self.assertEqual(CC, cdlfile.getXML())
        cdl.setXML(CC)
        self.assertEqual(CC, cdl.getXML())
        match = cdl.createEditableCopy()
        match.setOffset([1.0, 1.0, 1.0])
        self.assertEqual(False, cdl.equals(match))
        cdl.setSlope([0.1, 0.2, 0.3])
        cdl.setOffset([1.1, 1.2, 1.3])
        cdl.setPower([2.1, 2.2, 2.3])
        cdl.setSat(0.5)
        CC2 = "<ColorCorrection id=\"foo\">\n"
        CC2 += "    <SOPNode>\n"
        CC2 += "        <Description>this is a description</Description>\n"
        CC2 += "        <Slope>0.1 0.2 0.3</Slope>\n"
        CC2 += "        <Offset>1.1 1.2 1.3</Offset>\n"
        CC2 += "        <Power>2.1 2.2 2.3</Power>\n"
        CC2 += "    </SOPNode>\n"
        CC2 += "    <SatNode>\n"
        CC2 += "        <Saturation>0.5</Saturation>\n"
        CC2 += "    </SatNode>\n"
        CC2 += "</ColorCorrection>"
        self.assertEqual(CC2, cdl.getXML())
        cdl.setSOP([1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9])
        newsop = cdl.getSOP()
        self.assertAlmostEqual(1.5, newsop[4], delta=1e-8)
        slope = cdl.getSlope()
        self.assertAlmostEqual(1.2, slope[1], delta=1e-7)
        offset = cdl.getOffset()
        self.assertAlmostEqual(1.6, offset[2], delta=1e-7)
        power = cdl.getPower()
        self.assertAlmostEqual(1.7, power[0], delta=1e-7)
        self.assertAlmostEqual(0.5, cdl.getSat(), delta=1e-8)
        luma = cdl.getSatLumaCoefs()
        self.assertAlmostEqual(0.2126, luma[0], delta=1e-8)
        self.assertAlmostEqual(0.7152, luma[1], delta=1e-8)
        self.assertAlmostEqual(0.0722, luma[2], delta=1e-8)
        cdl.setID("foobar123")
        self.assertEqual("foobar123", cdl.getID())
        cdl.setDescription("bar")
        self.assertEqual("bar", cdl.getDescription())

        cdl2 = OCIO.CDLTransform([0.1, 0.2, 0.3], [1.1, 1.2, 1.3],
                                 [2.1, 2.2, 2.3], 0.5,
                                 OCIO.TRANSFORM_DIR_INVERSE, 'foobar123',
                                 'bar')
        slope2 = cdl2.getSlope()
        offset2 = cdl2.getOffset()
        power2 = cdl2.getPower()
        luma2 = cdl2.getSatLumaCoefs()
        for i in range(0, 3):
            self.assertAlmostEqual(float(i + 1) / 10.0, slope2[i], delta=1e-7)
            self.assertAlmostEqual(float(i + 1) / 10.0 + 1,
                                   offset2[i],
                                   delta=1e-7)
            self.assertAlmostEqual(float(i + 1) / 10.0 + 2,
                                   power2[i],
                                   delta=1e-7)
        self.assertAlmostEqual(0.5, cdl2.getSat(), delta=1e-8)
        self.assertAlmostEqual(0.2126, luma2[0], delta=1e-8)
        self.assertAlmostEqual(0.7152, luma2[1], delta=1e-8)
        self.assertAlmostEqual(0.0722, luma2[2], delta=1e-8)
        self.assertEqual(OCIO.TRANSFORM_DIR_INVERSE, cdl2.getDirection())
        self.assertEqual('foobar123', cdl2.getID())
        self.assertEqual('bar', cdl2.getDescription())

        cdl3 = OCIO.CDLTransform(slope=[0.1, 0.2, 0.3],
                                 offset=[1.1, 1.2, 1.3],
                                 power=[2.1, 2.2, 2.3],
                                 sat=0.5,
                                 direction=OCIO.TRANSFORM_DIR_INVERSE,
                                 id='foobar123',
                                 description='bar')
        slope3 = cdl2.getSlope()
        offset3 = cdl2.getOffset()
        power3 = cdl2.getPower()
        luma3 = cdl2.getSatLumaCoefs()
        for i in range(0, 3):
            self.assertAlmostEqual(float(i + 1) / 10.0, slope3[i], delta=1e-7)
            self.assertAlmostEqual(float(i + 1) / 10.0 + 1,
                                   offset3[i],
                                   delta=1e-7)
            self.assertAlmostEqual(float(i + 1) / 10.0 + 2,
                                   power3[i],
                                   delta=1e-7)
        self.assertAlmostEqual(0.5, cdl3.getSat(), delta=1e-8)
        self.assertAlmostEqual(0.2126, luma3[0], delta=1e-8)
        self.assertAlmostEqual(0.7152, luma3[1], delta=1e-8)
        self.assertAlmostEqual(0.0722, luma3[2], delta=1e-8)
        self.assertEqual(OCIO.TRANSFORM_DIR_INVERSE, cdl3.getDirection())
        self.assertEqual('foobar123', cdl3.getID())
        self.assertEqual('bar', cdl3.getDescription())

        ### ColorSpaceTransform ###
        ct = OCIO.ColorSpaceTransform()
        ct.setSrc("foo")
        self.assertEqual("foo", ct.getSrc())
        ct.setDst("bar")
        self.assertEqual("bar", ct.getDst())

        ### DisplayViewTransform ###
        dt = OCIO.DisplayViewTransform()
        dt.setInputColorSpaceName("lin18")
        self.assertEqual("lin18", dt.getInputColorSpaceName())
        dt.setLinearCC(ct)
        foo = dt.getLinearCC()
        dt.setColorTimingCC(cdl)
        blah = dt.getColorTimingCC()
        dt.setChannelView(at)
        wee = dt.getChannelView()
        dt.setDisplay("sRGB")
        self.assertEqual("sRGB", dt.getDisplay())
        dt.setView("foobar")
        self.assertEqual("foobar", dt.getView())
        cdl.setXML(CC)
        dt.setDisplayCC(cdl)
        cdldt = dt.getDisplayCC()
        self.assertEqual(CC, cdldt.getXML())
        dt.setLooksOverride("darkgrade")
        self.assertEqual("darkgrade", dt.getLooksOverride())
        dt.setLooksOverrideEnabled(True)
        self.assertEqual(True, dt.getLooksOverrideEnabled())

        dt2 = OCIO.DisplayViewTransform("lin18", "sRGB", "foobar",
                                        OCIO.TRANSFORM_DIR_INVERSE)
        self.assertEqual("lin18", dt2.getInputColorSpaceName())
        self.assertEqual("sRGB", dt2.getDisplay())
        self.assertEqual("foobar", dt2.getView())
        self.assertEqual(OCIO.TRANSFORM_DIR_INVERSE, dt2.getDirection())

        dt3 = OCIO.DisplayViewTransform(inputColorSpaceName="lin18",
                                        display="sRGB",
                                        view="foobar",
                                        direction=OCIO.TRANSFORM_DIR_INVERSE)
        self.assertEqual("lin18", dt3.getInputColorSpaceName())
        self.assertEqual("sRGB", dt3.getDisplay())
        self.assertEqual("foobar", dt3.getView())
        self.assertEqual(OCIO.TRANSFORM_DIR_INVERSE, dt3.getDirection())

        ### ExponentTransform ###
        et = OCIO.ExponentTransform()
        et.setValue([0.1, 0.2, 0.3, 0.4])
        evals = et.getValue()
        self.assertAlmostEqual(0.3, evals[2], delta=1e-7)

        ### FileTransform ###
        ft = OCIO.FileTransform()
        ft.setSrc("foo")
        self.assertEqual("foo", ft.getSrc())
        ft.setCCCId("foobar")
        self.assertEqual("foobar", ft.getCCCId())
        ft.setInterpolation(OCIO.INTERP_NEAREST)
        self.assertEqual(OCIO.INTERP_NEAREST, ft.getInterpolation())
        self.assertEqual(24, ft.getNumFormats())
        self.assertEqual("flame", ft.getFormatNameByIndex(0))
        self.assertEqual("3dl", ft.getFormatExtensionByIndex(0))

        ### GroupTransform ###
        gt = OCIO.GroupTransform()
        gt.appendTransform(et)
        gt.appendTransform(ft)
        self.assertEqual(2, gt.getNumTransforms())
        foo = gt.getTransform(0)
        self.assertEqual(OCIO.TRANSFORM_DIR_FORWARD, foo.getDirection())

        ### LogTransform ###
        lt = OCIO.LogTransform()
        lt.setBase(10.0)
        self.assertEqual(10.0, lt.getBase())

        ### LookTransform ###
        lkt = OCIO.LookTransform()
        lkt.setSrc("foo")
        self.assertEqual("foo", lkt.getSrc())
        lkt.setDst("bar")
        self.assertEqual("bar", lkt.getDst())
        lkt.setLooks("bar;foo")
        self.assertEqual("bar;foo", lkt.getLooks())

        ### MatrixTransform ###
        mt = OCIO.MatrixTransform()
        mmt = mt.createEditableCopy()
        mt.setMatrix([
            0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3,
            1.4, 1.5, 1.6
        ])
        mt.setOffset([0.1, 0.2, 0.3, 0.4])
        self.assertEqual(False, mt.equals(mmt))
        m44_1 = mt.getMatrix()
        offset_1 = mt.getOffset()
        self.assertAlmostEqual(0.3, m44_1[2], delta=1e-7)
        self.assertAlmostEqual(0.2, offset_1[1], delta=1e-7)
        m44_2, offset_2 = mt.Fit([0.1, 0.1, 0.1, 0.1], [0.9, 0.9, 0.9, 0.9],
                                 [0.0, 0.0, 0.0, 0.0], [1.1, 1.1, 1.1, 1.1])

        self.assertAlmostEqual(1.375, m44_2[0], delta=1e-7)
        m44_3, offset_2 = mt.Identity()
        self.assertAlmostEqual(0.0, m44_3[1], delta=1e-7)
        m44_2, offset_2 = mt.Sat(0.5, [0.2126, 0.7152, 0.0722])
        self.assertAlmostEqual(0.3576, m44_2[1], delta=1e-7)
        m44_2, offset_2 = mt.Scale([0.9, 0.8, 0.7, 1.])
        self.assertAlmostEqual(0.9, m44_2[0], delta=1e-7)
        m44_2, offset_2 = mt.View([1, 1, 1, 0], [0.2126, 0.7152, 0.0722])
        self.assertAlmostEqual(0.0722, m44_2[2], delta=1e-7)

        mt4 = OCIO.MatrixTransform([
            0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3,
            1.4, 1.5, 1.6
        ], [0.1, 0.2, 0.3, 0.4], OCIO.TRANSFORM_DIR_INVERSE)
        m44_4 = mt4.getMatrix()
        offset_4 = mt4.getOffset()
        for i in range(0, 16):
            self.assertAlmostEqual(float(i + 1) / 10.0, m44_4[i], delta=1e-7)
        for i in range(0, 4):
            self.assertAlmostEqual(float(i + 1) / 10.0,
                                   offset_4[i],
                                   delta=1e-7)
        self.assertEqual(mt4.getDirection(), OCIO.TRANSFORM_DIR_INVERSE)

        mt5 = OCIO.MatrixTransform(matrix=[
            0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3,
            1.4, 1.5, 1.6
        ],
                                   offset=[0.1, 0.2, 0.3, 0.4],
                                   direction=OCIO.TRANSFORM_DIR_INVERSE)
        m44_5 = mt5.getMatrix()
        offset_5 = mt5.getOffset()
        for i in range(0, 16):
            self.assertAlmostEqual(float(i + 1) / 10.0, m44_5[i], delta=1e-7)
        for i in range(0, 4):
            self.assertAlmostEqual(float(i + 1) / 10.0,
                                   offset_5[i],
                                   delta=1e-7)
        self.assertEqual(mt5.getDirection(), OCIO.TRANSFORM_DIR_INVERSE)