PageRenderTime 49ms CodeModel.GetById 14ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/src/pyglue/PyMatrixTransform.cpp

http://github.com/imageworks/OpenColorIO
C++ | 459 lines | 375 code | 49 blank | 35 comment | 33 complexity | 43d5510b9fbef78ab9c3835101e3c597 MD5 | raw file
  1/*
  2Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al.
  3All Rights Reserved.
  4
  5Redistribution and use in source and binary forms, with or without
  6modification, are permitted provided that the following conditions are
  7met:
  8* Redistributions of source code must retain the above copyright
  9  notice, this list of conditions and the following disclaimer.
 10* Redistributions in binary form must reproduce the above copyright
 11  notice, this list of conditions and the following disclaimer in the
 12  documentation and/or other materials provided with the distribution.
 13* Neither the name of Sony Pictures Imageworks nor the names of its
 14  contributors may be used to endorse or promote products derived from
 15  this software without specific prior written permission.
 16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 17"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 18LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 19A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 20OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 21SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 22LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 23DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 24THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 25(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 26OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27*/
 28
 29#include <Python.h>
 30#include <OpenColorIO/OpenColorIO.h>
 31
 32#include "PyUtil.h"
 33#include "PyDoc.h"
 34
 35#define GetConstMatrixTransform(pyobject) GetConstPyOCIO<PyOCIO_Transform, \
 36    ConstMatrixTransformRcPtr, MatrixTransform>(pyobject, \
 37    PyOCIO_MatrixTransformType)
 38
 39#define GetEditableMatrixTransform(pyobject) GetEditablePyOCIO<PyOCIO_Transform, \
 40    MatrixTransformRcPtr, MatrixTransform>(pyobject, \
 41    PyOCIO_MatrixTransformType)
 42
 43OCIO_NAMESPACE_ENTER
 44{
 45    
 46    namespace
 47    {
 48        
 49        ///////////////////////////////////////////////////////////////////////
 50        ///
 51        
 52        int PyOCIO_MatrixTransform_init(PyOCIO_Transform * self, PyObject * args, PyObject * kwds);
 53        PyObject * PyOCIO_MatrixTransform_equals(PyObject * self,  PyObject * args);
 54        PyObject * PyOCIO_MatrixTransform_getValue(PyObject * self);
 55        PyObject * PyOCIO_MatrixTransform_setValue(PyObject * self,  PyObject * args);
 56        PyObject * PyOCIO_MatrixTransform_getMatrix(PyObject * self);
 57        PyObject * PyOCIO_MatrixTransform_setMatrix(PyObject * self,  PyObject * args);
 58        PyObject * PyOCIO_MatrixTransform_getOffset(PyObject * self);
 59        PyObject * PyOCIO_MatrixTransform_setOffset(PyObject * self,  PyObject * args);
 60        PyObject * PyOCIO_MatrixTransform_Identity(PyObject * cls);
 61        PyObject * PyOCIO_MatrixTransform_Fit(PyObject * cls, PyObject * args);
 62        PyObject * PyOCIO_MatrixTransform_Sat(PyObject * cls, PyObject * args);
 63        PyObject * PyOCIO_MatrixTransform_Scale(PyObject * cls, PyObject * args);
 64        PyObject * PyOCIO_MatrixTransform_View(PyObject * cls, PyObject * args);
 65        
 66        ///////////////////////////////////////////////////////////////////////
 67        ///
 68        
 69        PyMethodDef PyOCIO_MatrixTransform_methods[] = {
 70            { "equals",
 71            PyOCIO_MatrixTransform_equals, METH_VARARGS, MATRIXTRANSFORM_EQUALS__DOC__ },
 72            { "getValue",
 73            (PyCFunction) PyOCIO_MatrixTransform_getValue, METH_NOARGS, MATRIXTRANSFORM_GETVALUE__DOC__ },
 74            { "setValue",
 75            PyOCIO_MatrixTransform_setValue, METH_VARARGS, MATRIXTRANSFORM_SETVALUE__DOC__ },
 76            { "getMatrix",
 77            (PyCFunction) PyOCIO_MatrixTransform_getMatrix, METH_NOARGS, MATRIXTRANSFORM_GETMATRIX__DOC__ },
 78            { "setMatrix",
 79            PyOCIO_MatrixTransform_setMatrix, METH_VARARGS, MATRIXTRANSFORM_SETMATRIX__DOC__ },
 80            { "getOffset",
 81            (PyCFunction) PyOCIO_MatrixTransform_getOffset, METH_NOARGS, MATRIXTRANSFORM_GETOFFSET__DOC__ },
 82            { "setOffset",
 83            PyOCIO_MatrixTransform_setOffset, METH_VARARGS, MATRIXTRANSFORM_SETOFFSET__DOC__ },
 84            { "Identity",
 85            (PyCFunction) PyOCIO_MatrixTransform_Identity, METH_NOARGS | METH_CLASS, MATRIXTRANSFORM_IDENTITY__DOC__ },
 86            { "Fit",
 87            PyOCIO_MatrixTransform_Fit, METH_VARARGS | METH_CLASS, MATRIXTRANSFORM_FIT__DOC__ },
 88            { "Sat",
 89            PyOCIO_MatrixTransform_Sat, METH_VARARGS | METH_CLASS, MATRIXTRANSFORM_SAT__DOC__ },
 90            { "Scale",
 91            PyOCIO_MatrixTransform_Scale, METH_VARARGS | METH_CLASS, MATRIXTRANSFORM_SCALE__DOC__ },
 92            { "View",
 93            PyOCIO_MatrixTransform_View, METH_VARARGS | METH_CLASS, MATRIXTRANSFORM_VIEW__DOC__ },
 94            { NULL, NULL, 0, NULL }
 95        };
 96    }
 97    
 98    ///////////////////////////////////////////////////////////////////////////
 99    ///
100    
101    PyTypeObject PyOCIO_MatrixTransformType = {
102        PyVarObject_HEAD_INIT(NULL, 0)
103        "OCIO.MatrixTransform",                     //tp_name
104        sizeof(PyOCIO_Transform),                   //tp_basicsize
105        0,                                          //tp_itemsize
106        0,                                          //tp_dealloc
107        0,                                          //tp_print
108        0,                                          //tp_getattr
109        0,                                          //tp_setattr
110        0,                                          //tp_compare
111        0,                                          //tp_repr
112        0,                                          //tp_as_number
113        0,                                          //tp_as_sequence
114        0,                                          //tp_as_mapping
115        0,                                          //tp_hash 
116        0,                                          //tp_call
117        0,                                          //tp_str
118        0,                                          //tp_getattro
119        0,                                          //tp_setattro
120        0,                                          //tp_as_buffer
121        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   //tp_flags
122        MATRIXTRANSFORM__DOC__,                     //tp_doc 
123        0,                                          //tp_traverse 
124        0,                                          //tp_clear 
125        0,                                          //tp_richcompare 
126        0,                                          //tp_weaklistoffset 
127        0,                                          //tp_iter 
128        0,                                          //tp_iternext 
129        PyOCIO_MatrixTransform_methods,             //tp_methods 
130        0,                                          //tp_members 
131        0,                                          //tp_getset 
132        &PyOCIO_TransformType,                      //tp_base 
133        0,                                          //tp_dict 
134        0,                                          //tp_descr_get 
135        0,                                          //tp_descr_set 
136        0,                                          //tp_dictoffset 
137        (initproc) PyOCIO_MatrixTransform_init,     //tp_init 
138        0,                                          //tp_alloc 
139        0,                                          //tp_new 
140        0,                                          //tp_free
141        0,                                          //tp_is_gc
142    };
143    
144    namespace
145    {
146        
147        ///////////////////////////////////////////////////////////////////////
148        ///
149        
150        int PyOCIO_MatrixTransform_init(PyOCIO_Transform * self, PyObject * /*args*/, PyObject * /*kwds*/)
151        {
152            OCIO_PYTRY_ENTER()
153            return BuildPyTransformObject<MatrixTransformRcPtr>(self, MatrixTransform::Create());
154            OCIO_PYTRY_EXIT(-1)
155        }
156        
157        PyObject * PyOCIO_MatrixTransform_equals(PyObject * self,  PyObject * args)
158        {
159            OCIO_PYTRY_ENTER()
160            PyObject* pyobject = 0;
161            if (!PyArg_ParseTuple(args,"O:equals",
162                &pyobject)) return NULL;
163            if(!IsPyOCIOType(pyobject, PyOCIO_MatrixTransformType))
164                throw Exception("MatrixTransform.equals requires a MatrixTransform argument");
165            ConstMatrixTransformRcPtr transform = GetConstMatrixTransform(self);
166            ConstMatrixTransformRcPtr in = GetConstMatrixTransform(pyobject);
167            return PyBool_FromLong(transform->equals(*in.get()));
168            OCIO_PYTRY_EXIT(NULL)
169        }
170        
171        PyObject * PyOCIO_MatrixTransform_getValue(PyObject * self)
172        {
173            OCIO_PYTRY_ENTER()
174            ConstMatrixTransformRcPtr transform = GetConstMatrixTransform(self);
175            std::vector<float> matrix(16);
176            std::vector<float> offset(4);
177            transform->getValue(&matrix[0], &offset[0]);
178            PyObject* pymatrix = CreatePyListFromFloatVector(matrix);
179            PyObject* pyoffset = CreatePyListFromFloatVector(offset);
180            PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset);
181            Py_DECREF(pymatrix);
182            Py_DECREF(pyoffset);
183            return pyreturnval;
184            OCIO_PYTRY_EXIT(NULL)
185        }
186        
187        PyObject * PyOCIO_MatrixTransform_setValue(PyObject * self, PyObject * args)
188        {
189            OCIO_PYTRY_ENTER()
190            PyObject* pymatrix = 0;
191            PyObject* pyoffset = 0;
192            if (!PyArg_ParseTuple(args, "OO:setValue",
193                &pymatrix, &pyoffset)) return NULL;
194            std::vector<float> matrix;
195            std::vector<float> offset;
196            if(!FillFloatVectorFromPySequence(pymatrix, matrix) ||
197                (matrix.size() != 16))
198            {
199                PyErr_SetString(PyExc_TypeError,
200                    "First argument must be a float array, size 16");
201                return 0;
202            }
203            if(!FillFloatVectorFromPySequence(pyoffset, offset) ||
204                (offset.size() != 4))
205            {
206                PyErr_SetString(PyExc_TypeError,
207                    "Second argument must be a float array, size 4");
208                return 0;
209            }
210            MatrixTransformRcPtr transform = GetEditableMatrixTransform(self);
211            transform->setValue(&matrix[0], &offset[0]);
212            Py_RETURN_NONE;
213            OCIO_PYTRY_EXIT(NULL)
214        }
215        
216        PyObject * PyOCIO_MatrixTransform_getMatrix(PyObject * self)
217        {
218            OCIO_PYTRY_ENTER()
219            ConstMatrixTransformRcPtr transform = GetConstMatrixTransform(self);
220            std::vector<float> matrix(16);
221            transform->getMatrix(&matrix[0]);
222            return CreatePyListFromFloatVector(matrix);
223            OCIO_PYTRY_EXIT(NULL)
224        }
225        
226        PyObject * PyOCIO_MatrixTransform_setMatrix(PyObject * self, PyObject * args)
227        {
228            OCIO_PYTRY_ENTER()
229            PyObject* pymatrix = 0;
230            if (!PyArg_ParseTuple(args,"O:setValue",
231                &pymatrix)) return NULL;
232            std::vector<float> matrix;
233            if(!FillFloatVectorFromPySequence(pymatrix, matrix) ||
234                (matrix.size() != 16))
235            {
236                PyErr_SetString(PyExc_TypeError,
237                    "First argument must be a float array, size 16");
238                return 0;
239            }
240            MatrixTransformRcPtr transform = GetEditableMatrixTransform(self);
241            transform->setMatrix(&matrix[0]);
242            Py_RETURN_NONE;
243            OCIO_PYTRY_EXIT(NULL)
244        }
245        
246        PyObject * PyOCIO_MatrixTransform_getOffset(PyObject * self)
247        {
248            OCIO_PYTRY_ENTER()
249            ConstMatrixTransformRcPtr transform = GetConstMatrixTransform(self);
250            std::vector<float> offset(4);
251            transform->getOffset(&offset[0]);
252            return CreatePyListFromFloatVector(offset);
253            OCIO_PYTRY_EXIT(NULL)
254        }
255        
256        PyObject * PyOCIO_MatrixTransform_setOffset(PyObject * self, PyObject * args)
257        {
258            OCIO_PYTRY_ENTER()
259            PyObject* pyoffset = 0;
260            if (!PyArg_ParseTuple(args, "O:setValue",
261                &pyoffset)) return NULL;
262            std::vector<float> offset;
263            if(!FillFloatVectorFromPySequence(pyoffset, offset) ||
264                (offset.size() != 4))
265            {
266                PyErr_SetString(PyExc_TypeError,
267                    "First argument must be a float array, size 4");
268                return 0;
269            }
270            MatrixTransformRcPtr transform = GetEditableMatrixTransform(self);
271            transform->setOffset(&offset[0]);
272            Py_RETURN_NONE;
273            OCIO_PYTRY_EXIT(NULL)
274        }
275        
276        PyObject * PyOCIO_MatrixTransform_Identity(PyObject * /*self*/)
277        {
278            OCIO_PYTRY_ENTER()
279            std::vector<float> matrix(16);
280            std::vector<float> offset(4);
281            MatrixTransform::Identity(&matrix[0], &offset[0]);
282            PyObject* pymatrix = CreatePyListFromFloatVector(matrix);
283            PyObject* pyoffset = CreatePyListFromFloatVector(offset);
284            PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset);
285            Py_DECREF(pymatrix);
286            Py_DECREF(pyoffset);
287            return pyreturnval;
288            OCIO_PYTRY_EXIT(NULL)
289        }
290        
291        PyObject * PyOCIO_MatrixTransform_Fit(PyObject * /*self*/, PyObject * args)
292        {
293            OCIO_PYTRY_ENTER()
294            
295            PyObject* pyoldmin = 0;
296            PyObject* pyoldmax = 0;
297            PyObject* pynewmin = 0;
298            PyObject* pynewmax = 0;
299            if (!PyArg_ParseTuple(args,"OOOO:Fit",
300                &pyoldmin, &pyoldmax, &pynewmin, &pynewmax)) return NULL;
301            
302            std::vector<float> oldmin;
303            if(!FillFloatVectorFromPySequence(pyoldmin, oldmin) ||
304                (oldmin.size() != 4))
305            {
306                PyErr_SetString(PyExc_TypeError,
307                    "First argument must be a float array, size 4");
308                return 0;
309            }
310            
311            std::vector<float> oldmax;
312            if(!FillFloatVectorFromPySequence(pyoldmax, oldmax) ||
313                (oldmax.size() != 4))
314            {
315                PyErr_SetString(PyExc_TypeError,
316                    "Second argument must be a float array, size 4");
317                return 0;
318            }
319            
320            std::vector<float> newmin;
321            if(!FillFloatVectorFromPySequence(pynewmin, newmin) ||
322                (newmin.size() != 4))
323            {
324                PyErr_SetString(PyExc_TypeError,
325                    "Third argument must be a float array, size 4");
326                return 0;
327            }
328            
329            std::vector<float> newmax;
330            if(!FillFloatVectorFromPySequence(pynewmax, newmax) ||
331                (newmax.size() != 4))
332            {
333                PyErr_SetString(PyExc_TypeError,
334                    "Fourth argument must be a float array, size 4");
335                return 0;
336            }
337            
338            std::vector<float> matrix(16);
339            std::vector<float> offset(4);
340            MatrixTransform::Fit(&matrix[0], &offset[0],
341                                 &oldmin[0], &oldmax[0],
342                                 &newmin[0], &newmax[0]);
343            PyObject* pymatrix = CreatePyListFromFloatVector(matrix);
344            PyObject* pyoffset = CreatePyListFromFloatVector(offset);
345            PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset);
346            Py_DECREF(pymatrix);
347            Py_DECREF(pyoffset);
348            return pyreturnval;
349            
350            OCIO_PYTRY_EXIT(NULL)
351        }
352        
353        PyObject * PyOCIO_MatrixTransform_Sat(PyObject * /*self*/, PyObject * args)
354        {
355            OCIO_PYTRY_ENTER()
356            
357            float sat = 0.0;
358            PyObject* pyluma = 0;
359            if (!PyArg_ParseTuple(args,"fO:Sat",
360                &sat, &pyluma)) return NULL;
361                
362            std::vector<float> luma;
363            if(!FillFloatVectorFromPySequence(pyluma, luma) ||
364                (luma.size() != 3))
365            {
366                PyErr_SetString(PyExc_TypeError,
367                    "Second argument must be a float array, size 3");
368                return 0;
369            }
370            
371            std::vector<float> matrix(16);
372            std::vector<float> offset(4);
373            MatrixTransform::Sat(&matrix[0], &offset[0],
374                                 sat, &luma[0]);
375            PyObject* pymatrix = CreatePyListFromFloatVector(matrix);
376            PyObject* pyoffset = CreatePyListFromFloatVector(offset);
377            PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset);
378            Py_DECREF(pymatrix);
379            Py_DECREF(pyoffset);
380            return pyreturnval;
381            
382            OCIO_PYTRY_EXIT(NULL)
383        }
384        
385        PyObject * PyOCIO_MatrixTransform_Scale(PyObject * /*self*/, PyObject * args)
386        {
387            OCIO_PYTRY_ENTER()
388            
389            PyObject* pyscale = 0;
390            if (!PyArg_ParseTuple(args,"O:Scale",
391                &pyscale)) return NULL;
392            
393            std::vector<float> scale;
394            if(!FillFloatVectorFromPySequence(pyscale, scale) ||
395                (scale.size() != 4))
396            {
397                PyErr_SetString(PyExc_TypeError,
398                    "Second argument must be a float array, size 4");
399                return 0;
400            }
401            
402            std::vector<float> matrix(16);
403            std::vector<float> offset(4);
404            MatrixTransform::Scale(&matrix[0], &offset[0], &scale[0]);
405            PyObject* pymatrix = CreatePyListFromFloatVector(matrix);
406            PyObject* pyoffset = CreatePyListFromFloatVector(offset);
407            PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset);
408            Py_DECREF(pymatrix);
409            Py_DECREF(pyoffset);
410            return pyreturnval;
411            
412            OCIO_PYTRY_EXIT(NULL)
413        }
414        
415        PyObject * PyOCIO_MatrixTransform_View(PyObject * /*self*/, PyObject * args)
416        {
417            OCIO_PYTRY_ENTER()
418            
419            PyObject* pychannelhot = 0;
420            PyObject* pyluma = 0;
421            if (!PyArg_ParseTuple(args,"OO:View",
422                &pychannelhot, &pyluma)) return NULL;
423            
424            std::vector<int> channelhot;
425            if(!FillIntVectorFromPySequence(pychannelhot, channelhot) ||
426                (channelhot.size() != 4))
427            {
428                PyErr_SetString(PyExc_TypeError,
429                    "First argument must be a bool/int array, size 4");
430                return 0;
431            }
432            
433            std::vector<float> luma;
434            if(!FillFloatVectorFromPySequence(pyluma, luma) ||
435                (luma.size() != 3))
436            {
437                PyErr_SetString(PyExc_TypeError,
438                    "Second argument must be a float array, size 3");
439                return 0;
440            }
441            
442            std::vector<float> matrix(16);
443            std::vector<float> offset(4);
444            MatrixTransform::View(&matrix[0], &offset[0],
445                                  &channelhot[0], &luma[0]);
446            PyObject* pymatrix = CreatePyListFromFloatVector(matrix);
447            PyObject* pyoffset = CreatePyListFromFloatVector(offset);
448            PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset);
449            Py_DECREF(pymatrix);
450            Py_DECREF(pyoffset);
451            return pyreturnval;
452            
453            OCIO_PYTRY_EXIT(NULL)
454        }
455        
456    }
457
458}
459OCIO_NAMESPACE_EXIT