1
2import unittest, os, sys
3sys.path.append(os.path.join(sys.argv[1], "src", "pyglue"))
4import PyOpenColorIO as OCIO
5
6import platform
7osname = platform.system()
8
9class ConfigTest(unittest.TestCase):
10
11    SIMPLE_PROFILE = """ocio_profile_version: 1
12
13search_path: luts
14strictparsing: false
15luma: [0.2126, 0.7152, 0.0722]
16
17roles:
18  default: raw
19  scene_linear: lnh
20
21displays:
22  sRGB:
23    - !<View> {name: Film1D, colorspace: vd8}
24    - !<View> {name: Raw, colorspace: raw}
25
26active_displays: []
27active_views: []
28
29colorspaces:
30  - !<ColorSpace>
31    name: raw
32    family: raw
33    equalitygroup: ""
34    bitdepth: 32f
35    description: |
36      A raw color space. Conversions to and from this space are no-ops.
37
38    isdata: true
39    allocation: uniform
40
41  - !<ColorSpace>
42    name: lnh
43    family: ln
44    equalitygroup: ""
45    bitdepth: 16f
46    description: |
47      The show reference space. This is a sensor referred linear
48      representation of the scene with primaries that correspond to
49      scanned film. 0.18 in this space corresponds to a properly
50      exposed 18% grey card.
51
52    isdata: false
53    allocation: lg2
54
55  - !<ColorSpace>
56    name: vd8
57    family: vd8
58    equalitygroup: ""
59    bitdepth: 8ui
60    description: |
61      how many transforms can we use?
62
63    isdata: false
64    allocation: uniform
65    to_reference: !<GroupTransform>
66      children:
67        - !<ExponentTransform> {value: [2.2, 2.2, 2.2, 1]}
68        - !<MatrixTransform> {matrix: [1, 2, 3, 4, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], offset: [1, 2, 0, 0]}
69        - !<CDLTransform> {slope: [0.9, 1, 1], offset: [0.1, 0.3, 0.4], power: [1.1, 1.1, 1.1], sat: 0.9}
70"""
71
72    def setUp(self):
73
74        osx_hack = ''
75        if osname=="Darwin":
76            osx_hack = """
77// OSX segfault work-around: Force a no-op sampling of the 3d lut.
78texture3D(lut3d, 0.96875 * out_pixel.rgb + 0.015625).rgb;"""
79
80        self.GLSLResult = """
81// Generated by OpenColorIO
82
83vec4 pytestocio(in vec4 inPixel,
84    const sampler3D lut3d)
85{
86vec4 out_pixel = inPixel;
87out_pixel = out_pixel * mat4(1.08749, -0.0794667, -0.00802222, 0, -0.0236222, 1.03164, -0.00802222, 0, -0.0236222, -0.0794667, 1.10309, 0, 0, 0, 0, 1);
88out_pixel = pow(max(out_pixel, vec4(0, 0, 0, 0)), vec4(0.909091, 0.909091, 0.909091, 1));
89out_pixel = out_pixel * mat4(1.11111, -2, -3, -4, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
90out_pixel = vec4(4.68889, -2.3, -0.4, -0) + out_pixel;
91out_pixel = pow(max(out_pixel, vec4(0, 0, 0, 0)), vec4(0.454545, 0.454545, 0.454545, 1));""" \
92 + osx_hack + \
93"""
94return out_pixel;
95}
96
97"""
98
99    def test_is_editable(self):
100
101        cfg = OCIO.Config().CreateFromStream(self.SIMPLE_PROFILE)
102        self.assertEqual(cfg.isEditable(), False)
103        cfg = cfg.createEditableCopy()
104        self.assertEqual(cfg.isEditable(), True)
105        ctx = cfg.getCurrentContext()
106        self.assertEqual(ctx.isEditable(), False)
107        ctx = ctx.createEditableCopy()
108        self.assertEqual(ctx.isEditable(), True)
109        ctx.setEnvironmentMode(OCIO.Constants.ENV_ENVIRONMENT_LOAD_ALL)
110
111    def test_interface(self):
112
113        _cfg = OCIO.Config().CreateFromStream(self.SIMPLE_PROFILE)
114        _cfge = _cfg.createEditableCopy()
115        _cfge.clearEnvironmentVars()
116        self.assertEqual(0, _cfge.getNumEnvironmentVars())
117        _cfge.addEnvironmentVar("FOO", "test1")
118        _cfge.addEnvironmentVar("FOO2", "test2${FOO}")
119        self.assertEqual(2, _cfge.getNumEnvironmentVars())
120        self.assertEqual("FOO", _cfge.getEnvironmentVarNameByIndex(0))
121        self.assertEqual("FOO2", _cfge.getEnvironmentVarNameByIndex(1))
122        self.assertEqual("test1", _cfge.getEnvironmentVarDefault("FOO"))
123        self.assertEqual("test2${FOO}", _cfge.getEnvironmentVarDefault("FOO2"))
124        self.assertEqual("test2test1", _cfge.getCurrentContext().resolveStringVar("${FOO2}"))
125        self.assertEqual({'FOO': 'test1', 'FOO2': 'test2${FOO}'}, _cfge.getEnvironmentVarDefaults())
126        _cfge.clearEnvironmentVars()
127        self.assertEqual(0, _cfge.getNumEnvironmentVars())
128        self.assertEqual("luts", _cfge.getSearchPath())
129        _cfge.setSearchPath("otherdir")
130        self.assertEqual("otherdir", _cfge.getSearchPath())
131        _cfge.sanityCheck()
132        _cfge.setDescription("testdesc")
133        self.assertEqual("testdesc", _cfge.getDescription())
134        self.assertEqual(self.SIMPLE_PROFILE, _cfg.serialize())
135        #self.assertEqual("$07d1fb1509eeae1837825fd4242f8a69:$885ad1683add38a11f7bbe34e8bf9ac0",
136        #                _cfg.getCacheID())
137        con = _cfg.getCurrentContext()
138        self.assertNotEqual(0, con.getNumStringVars())
139        #self.assertEqual("", _cfg.getCacheID(con))
140        #self.assertEqual("", _cfge.getWorkingDir())
141        _cfge.setWorkingDir("/foobar")
142        self.assertEqual("/foobar", _cfge.getWorkingDir())
143        self.assertEqual(3, _cfge.getNumColorSpaces())
144        self.assertEqual("lnh", _cfge.getColorSpaceNameByIndex(1))
145        lnh = _cfge.getColorSpace("lnh")
146        self.assertEqual("ln", lnh.getFamily())
147        self.assertEqual(0, _cfge.getIndexForColorSpace("foobar"))
148        cs = OCIO.ColorSpace()
149        cs.setName("blah")
150        _cfge.addColorSpace(cs)
151        self.assertEqual(3, _cfge.getIndexForColorSpace("blah"))
152        #_cfge.clearColorSpaces()
153        #_cfge.parseColorSpaceFromString("foo")
154        self.assertEqual(False, _cfg.isStrictParsingEnabled())
155        _cfge.setStrictParsingEnabled(True)
156        self.assertEqual(True, _cfge.isStrictParsingEnabled())
157        self.assertEqual(2, _cfge.getNumRoles())
158        self.assertEqual(False, _cfg.hasRole("foo"))
159        _cfge.setRole("foo", "vd8")
160        self.assertEqual(3, _cfge.getNumRoles())
161        self.assertEqual(True, _cfge.hasRole("foo"))
162        self.assertEqual("foo", _cfge.getRoleName(1))
163        self.assertEqual("sRGB", _cfge.getDefaultDisplay())
164        self.assertEqual(1, _cfge.getNumDisplays())
165        self.assertEqual("sRGB", _cfge.getDisplay(0))
166        self.assertEqual("Film1D", _cfge.getDefaultView("sRGB"))
167        self.assertEqual(2, _cfge.getNumViews("sRGB"))
168        self.assertEqual("Raw", _cfge.getView("sRGB", 1))
169        self.assertEqual("vd8", _cfge.getDisplayColorSpaceName("sRGB", "Film1D"))
170        self.assertEqual("", _cfg.getDisplayLooks("sRGB", "Film1D"))
171        _cfge.addDisplay("foo", "bar", "foo", "wee")
172        _cfge.clearDisplays()
173        _cfge.setActiveDisplays("sRGB")
174        self.assertEqual("sRGB", _cfge.getActiveDisplays())
175        _cfge.setActiveViews("Film1D")
176        self.assertEqual("Film1D", _cfge.getActiveViews())
177        luma = _cfge.getDefaultLumaCoefs()
178        self.assertAlmostEqual(0.2126, luma[0], delta=1e-8)
179        _cfge.setDefaultLumaCoefs([0.1, 0.2, 0.3])
180        tnewluma = _cfge.getDefaultLumaCoefs()
181        self.assertAlmostEqual(0.1, tnewluma[0], delta=1e-8)
182        self.assertEqual(0, _cfge.getNumLooks())
183        lk = OCIO.Look()
184        lk.setName("coollook")
185        lk.setProcessSpace("somespace")
186        et = OCIO.ExponentTransform()
187        et.setValue([0.1, 0.2, 0.3, 0.4])
188        lk.setTransform(et)
189        iet = OCIO.ExponentTransform()
190        iet.setValue([-0.1, -0.2, -0.3, -0.4])
191        lk.setInverseTransform(iet)
192        _cfge.addLook(lk)
193        self.assertEqual(1, _cfge.getNumLooks())
194        self.assertEqual("coollook", _cfge.getLookNameByIndex(0))
195        glk = _cfge.getLook("coollook")
196        self.assertEqual("somespace", glk.getProcessSpace())
197        _cfge.clearLooks()
198        self.assertEqual(0, _cfge.getNumLooks())
199
200        #getProcessor(context, srcColorSpace, dstColorSpace)
201        #getProcessor(context, srcName,dstName);
202        #getProcessor(transform);
203        #getProcessor(transform, direction);
204        #getProcessor(context, transform, direction);
205
206        _proc = _cfg.getProcessor("lnh", "vd8")
207        self.assertEqual(False, _proc.isNoOp())
208        self.assertEqual(True, _proc.hasChannelCrosstalk())
209
210        #float packedpix[] = new float[]{0.48f, 0.18f, 0.9f, 1.0f,
211        #                                0.48f, 0.18f, 0.18f, 1.0f,
212        #                                0.48f, 0.18f, 0.18f, 1.0f,
213        #                                0.48f, 0.18f, 0.18f, 1.0f };
214        #FloatBuffer buf = ByteBuffer.allocateDirect(2 * 2 * 4 * Float.SIZE / 8).asFloatBuffer();
215        #buf.put(packedpix);
216        #PackedImageDesc foo = new PackedImageDesc(buf, 2, 2, 4);
217        #_proc.apply(foo);
218        #FloatBuffer wee = foo.getData();
219        #self.assertEqual(-2.4307251581696764E-35f, wee.get(2), 1e-8);
220
221        # TODO: these should work in-place
222        rgbfoo = _proc.applyRGB([0.48, 0.18, 0.18])
223        self.assertAlmostEqual(1.9351075, rgbfoo[0], delta=1e-7);
224        # TODO: these should work in-place
225        rgbafoo = _proc.applyRGBA([0.48, 0.18, 0.18, 1.0])
226        self.assertAlmostEqual(1.0, rgbafoo[3], delta=1e-8)
227        #self.assertEqual("$a92ef63abd9edf61ad5a7855da064648", _proc.getCpuCacheID())
228        desc = OCIO.GpuShaderDesc()
229        desc.setLanguage(OCIO.Constants.GPU_LANGUAGE_GLSL_1_3)
230        desc.setFunctionName("pytestocio")
231        desc.setLut3DEdgeLen(32)
232        glsl = _proc.getGpuShaderText(desc)
233        self.assertEqual(self.GLSLResult, glsl)
234        # old DEPRECIATED GpuShaderDesc dict support
235        desc2 = {"language": OCIO.Constants.GPU_LANGUAGE_GLSL_1_3, "functionName": "pytestocio", "lut3DEdgeLen": 32}
236        glsl = _proc.getGpuShaderText(desc2)
237        self.assertEqual(self.GLSLResult, glsl)
238        #self.assertEqual("$1dead2bf42974cd1769164e45a0c9e40", _proc.getGpuShaderTextCacheID(desc))
239        #self.assertEqual("$1dead2bf42974cd1769164e45a0c9e40", _proc.getGpuShaderTextCacheID(desc2))
240        len = desc.getLut3DEdgeLen()
241        size = 3 * len * len * len
242        self.assertEqual(0.0, _proc.getGpuLut3D(desc2)[size-1]);
243        self.assertEqual("<NULL>", _proc.getGpuLut3DCacheID(desc))
244        self.assertEqual("<NULL>", _proc.getGpuLut3DCacheID(desc2))
245
246        del _cfge
247        del _cfg
248