diff options
author | Matteo F. Vescovi <mfv.debian@gmail.com> | 2013-08-20 09:53:19 +0100 |
---|---|---|
committer | Matteo F. Vescovi <mfv.debian@gmail.com> | 2013-08-20 09:53:19 +0100 |
commit | 66e5d9e2915733247bca47d077414ec2594aedad (patch) | |
tree | f4070a31bf015e159dadd34378cda703d8f6edea /src/pyglue |
opencolorio (1.0.8~dfsg0-2) unstable; urgency=low
* debian/rules: get-orig-source stuff added
* debian/rules: useless dh addon removed
* debian/rules: License.txt duplicate removed
* debian/rules: SSE optimization disabled (Closes: #719174)
* debian/libopencolorio1.symbols: file removed (Closes: #719175)
# imported from the archive
Diffstat (limited to 'src/pyglue')
53 files changed, 11641 insertions, 0 deletions
diff --git a/src/pyglue/CMakeLists.txt b/src/pyglue/CMakeLists.txt new file mode 100644 index 0000000..07188ea --- /dev/null +++ b/src/pyglue/CMakeLists.txt @@ -0,0 +1,106 @@ +if(CMAKE_FIRST_RUN) + message(STATUS "Python library to include 'lib' prefix: ${OCIO_PYGLUE_LIB_PREFIX}") +endif() + +if(CMAKE_FIRST_RUN) + message(STATUS "Python ${PYTHON_VERSION} okay (UCS: ${PYTHON_UCS}), will build the Python bindings against ${PYTHON_INCLUDE}") + message(STATUS "Python variant path is ${PYTHON_VARIANT_PATH}") +endif() + +if(CMAKE_COMPILER_IS_GNUCXX) + # Python breaks strict-aliasing rules. Disable the warning here. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-strict-aliasing") +endif() + +if(NOT WIN32) + find_package(PythonLibs) + if(NOT PYTHONLIBS_FOUND) + message(FATAL "Python libraries were not found, exiting.") + endif() + SET(PYTHON_INCLUDES ${PYTHON_INCLUDE_DIRS}) +endif() + +add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/src/pyglue/PyDoc.h + COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/src/pyglue/createPyDocH.py ${CMAKE_BINARY_DIR}/src/pyglue/PyDoc.h + COMMENT "Creating PyDoc.h") + +file( GLOB pyglue_src_files "${CMAKE_SOURCE_DIR}/src/pyglue/*.cpp" ) + +add_library(PyOpenColorIO MODULE ${pyglue_src_files} ${CMAKE_BINARY_DIR}/src/pyglue/PyDoc.h) + +if(OCIO_USE_BOOST_PTR) + include_directories( + ${PYTHON_INCLUDE} + ${Boost_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/export/ + ${CMAKE_BINARY_DIR}/export/ + ${CMAKE_CURRENT_BINARY_DIR} + ) +else() + include_directories( + ${PYTHON_INCLUDE} + ${CMAKE_SOURCE_DIR}/export/ + ${CMAKE_BINARY_DIR}/export/ + ${CMAKE_CURRENT_BINARY_DIR} + ) +endif() + +# Exclude the 'lib' prefix from the name. +if(NOT OCIO_PYGLUE_LIB_PREFIX) + set_property(TARGET PyOpenColorIO + PROPERTY PREFIX "" + ) +endif() + +if(WIN32) + if(OCIO_PYGLUE_LINK) + target_link_libraries(PyOpenColorIO OpenColorIO + debug ${PYTHON_LIB}/python26_d.lib + optimized ${PYTHON_LIB}/python26.lib) + else() + target_link_libraries(PyOpenColorIO OpenColorIO) + endif(OCIO_PYGLUE_LINK) +else() + if(OCIO_PYGLUE_LINK) + message(STATUS "Linking python bindings against: ${PYTHON_LIBRARY}") + message(STATUS "Python library dirs: ${PYTHON_LIBRARY_DIRS}") + link_directories(${PYTHON_LIBRARY}) + target_link_libraries(PyOpenColorIO OpenColorIO + ${PYTHON_LIBRARIES}) + else() + target_link_libraries(PyOpenColorIO OpenColorIO) + endif(OCIO_PYGLUE_LINK) +endif() + +# PyOpenColorIO so serves dual roles: +# - First, to provide the C API function necessary to act as a cpython module, +# (extern "C" PyMODINIT_FUNC initPyOpenColorIO(void) +# - Second, to act as a normal shared library, providing the C++ API functions +# to convert between C++ and python representation of the OCIO object. +# +# To fulfill this second role, as a shared libary, we must continue to define +# so version. +# +# TODO: This wont let the normal shared library symbols work on OSX. +# We should explore whether this should be built as a normal dylib, instead +# of as a bundle. See https://github.com/imageworks/OpenColorIO/pull/175 + +if(OCIO_PYGLUE_SONAME) + message(STATUS "Setting PyOCIO SOVERSION to: ${SOVERSION}") + set_target_properties(PyOpenColorIO PROPERTIES + VERSION ${OCIO_VERSION} + SOVERSION ${SOVERSION} + ) +endif() + +if(APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -undefined dynamic_lookup") +endif() + + +message("PYTHON_VARIANT_PATH: ${PYTHON_VARIANT_PATH}") + +install(TARGETS PyOpenColorIO DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/${PYTHON_VARIANT_PATH}) + +install(FILES ${CMAKE_SOURCE_DIR}/export/PyOpenColorIO/PyOpenColorIO.h + DESTINATION ${CMAKE_INSTALL_PREFIX}/include/PyOpenColorIO/) diff --git a/src/pyglue/DocStrings/AllocationTransform.py b/src/pyglue/DocStrings/AllocationTransform.py new file mode 100644 index 0000000..26bdaa2 --- /dev/null +++ b/src/pyglue/DocStrings/AllocationTransform.py @@ -0,0 +1,54 @@ + +class AllocationTransform: + """ + Respans the 'expanded' range into the specified (often compressed) range. + + Performs both squeeze (offset) and log transforms. + """ + def __init__(self): + pass + + def getAllocation(self): + """ + getAllocation() + + Returns the allocation specified in the transform. Allocation is an + enum, defined in Constants. + + :return: Allocation + :rtype: string + """ + pass + + def setAllocation(self, hwalloc): + """ + setAllocation(hwalloc) + + Sets the allocation of the transform. + + :param hwalloc: Allocation + :type hwalloc: object + """ + pass + + def getVars(self): + """ + getVars() + + Returns the allocation values specified in the transform. + + :return: allocation values + :rtype: list of floats + """ + pass + + def setVars(self, vars): + """ + setVars(pyvars) + + Sets the allocation in the transform. + + :param pyvars: list of floats + :type pyvars: object + """ + pass diff --git a/src/pyglue/DocStrings/CDLTransform.py b/src/pyglue/DocStrings/CDLTransform.py new file mode 100644 index 0000000..63acbd2 --- /dev/null +++ b/src/pyglue/DocStrings/CDLTransform.py @@ -0,0 +1,141 @@ + +class CDLTransform: + """ + CDLTransform + """ + def __init__(self): + pass + + def equals(self): + pass + + def getXML(self): + pass + + def setXML(self, xmltext): + pass + + def getSlope(self): + pass + + def getOffset(self): + pass + + def getPower(self): + pass + + def getSOP(self): + pass + + def getSat(self): + pass + + def setSlope(self, slope): + """ + setSlope(pyData) + + Sets the slope ('S' part of SOP) in :py:class:`PyOpenColorIO.CDLTransform`. + + :param pyData: + :type pyData: object + """ + pass + + def setOffset(self, offset): + """ + setOffset(pyData) + + Sets the offset ('O' part of SOP) in :py:class:`PyOpenColorIO.CDLTransform`. + + :param pyData: list of three floats + :type pyData: object + """ + pass + + def setPower(self, power): + """ + setPower(pyData) + + Sets the power ('P' part of SOP) in :py:class:`PyOpenColorIO.CDLTransform`. + + :param pyData: list of three floats + :type pyData: object + """ + pass + + def setSOP(self, sop): + """ + setSOP(pyData) + + Sets SOP in :py:class:`PyOpenColorIO.CDLTransform`. + + :param pyData: list of nine floats + :type pyData: object + """ + pass + + def setSat(self, sat): + """ + setSAT(pyData) + + Sets SAT (saturation) in :py:class:`PyOpenColorIO.CDLTransform`. + + :param pyData: saturation + :type pyData: float + """ + pass + + def getSatLumaCoefs(self): + """ + getSatLumaCoefs(pyData) + + Returns the SAT (saturation) and luma coefficients in :py:class:`CDLTransform`. + + :return: saturation and luma coefficients + :rtype: list of floats + """ + pass + + def getID(self): + """ + getID() + + Returns the ID from :py:class:`PyOpenColorIO.CDLTransform`. + + :return: ID + :rtype: string + """ + pass + + def setID(self, id): + """ + setID(str) + + Sets the ID in :py:class:`PyOpenColorIO.CDLTransform`. + + :param str: ID + :type str: string + """ + pass + + def getDescription(self): + """ + getDescription() + + Returns the description of :py:class:`PyOpenColorIO.CDLTransform`. + + :return: description + :rtype: string + """ + pass + + def setDescription(self, desc): + """ + setDescription(str) + + Sets the description of :py:class:`PyOpenColorIO.CDLTransform`. + + :param str: description + :type str: string + """ + pass diff --git a/src/pyglue/DocStrings/ColorSpace.py b/src/pyglue/DocStrings/ColorSpace.py new file mode 100644 index 0000000..caf351b --- /dev/null +++ b/src/pyglue/DocStrings/ColorSpace.py @@ -0,0 +1,103 @@ + +class ColorSpace: + """ + A color space is the state of an image in terms of colorimetry and color + encoding. I.e., it defines how an image's color information needs to be + interpreted. + + Transforming images between different color spaces is the primary + motivation for the OCIO library. + + While a complete discussion of color spaces is beyond the scope of this + documentation, traditional uses would be to have color spaces describing + image capture devices, such as cameras and scanners, and internal + 'convenience' spaces, such as scene-linear and logarithmic. + + Color spaces are specific to a particular image precision + (float32, uint8, etc.). The set of color spaces that provide equivalent + mappings (at different precisions) are referred to as a 'family'. + + .. code-block:: python + + import PyOpenColorIO as OCIO + config = OCIO.Config() + + """ + def __init__(self): + pass + + def isEditable(self): + pass + + def createEditableCopy(self): + pass + + def getName(self): + pass + + def setName(self, name): + pass + + def getFamily(self): + pass + + def setFamily(self, family): + pass + + def getEqualityGroup(self): + pass + + def setEqualityGroup(self, equalityGroup): + pass + + def getDescription(self): + pass + + def setDescription(self, desc): + pass + + def getBitDepth(self): + pass + + def setBitDepth(self, bitDepth): + pass + + def isData(self): + """ + 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 + :py:class:`PyOpenColorIO.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. + """ + pass + + def setIsData(self, isData): + pass + + def getAllocation(self): + """ + 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. + """ + pass + + def setAllocation(self, allocation): + pass + + def getAllocationVars(self): + pass + + def setAllocationVars(self, vars): + pass + + def getTransform(self): + pass + + def setTransform(self, transform, direction): + pass + diff --git a/src/pyglue/DocStrings/ColorSpaceTransform.py b/src/pyglue/DocStrings/ColorSpaceTransform.py new file mode 100644 index 0000000..a4de30b --- /dev/null +++ b/src/pyglue/DocStrings/ColorSpaceTransform.py @@ -0,0 +1,51 @@ + +class ColorSpaceTransform: + """ + ColorSpaceTransform + """ + def __init__(self): + pass + + def getSrc(self): + """ + getSrc() + + Returns the name of the source ColorSpace in this transform. + + :return: ColorSpace + :rtype: string + """ + pass + + def setSrc(self, srcname): + """ + setSrc(srcname) + + Sets the source ColorSpace in this transform. + + :param str: source ColorSpace + :type str: string + """ + pass + + def getDst(self): + """ + getDst() + + Returns the name of the destination ColorSpace in this transform. + + :return: ColorSpace + :rtype: string + """ + pass + + def setDst(self, dstname): + """ + setDst(dstname) + + Sets the destination ColorSpace in this transform. + + :param str: destination ColorSpace + :type str: string + """ + pass diff --git a/src/pyglue/DocStrings/Config.py b/src/pyglue/DocStrings/Config.py new file mode 100644 index 0000000..688e822 --- /dev/null +++ b/src/pyglue/DocStrings/Config.py @@ -0,0 +1,527 @@ + +class Config: + """ + Config + """ + + def __init__(self): + pass + + def CreateFromEnv(self): + """ + CreateFromEnv() + + Create a :py:class:`PyOpenColorIO.Config` object using the environment variable. + + :returns: Config object + """ + pass + + def CreateFromFile(self): + """ + CreateFromFile(filename) + + Create a :py:class:`PyOpenColorIO.Config` object using the information in a file. + + :param filename: name of file + :type filename: string + :return: Config object + """ + pass + + def isEditable(self): + """ + isEditable() + + Returns whether Config is editable. + + The configurations returned from + :py:function:`PyOpenColorIO.GetCurrentConfig` are not editable, and if + you want to edit them you can use + :py:method:`PyOpenColorIO.Config.createEditableCopy`. + + If you attempt to call any of the set functions on a noneditable + Config, an exception will be thrown. + + :return: state of :py:class:`PyOpenColorIO.Config`'s editability + :rtype: bool + """ + pass + + def createEditableCopy(self): + """ + createEditableCopy() + + Returns an editable copy of :py:class:`PyOpenColorIO.Config`. + + :return: editable copy of :py:class:`PyOpenColorIO.Config` + :rtype: Config object + """ + pass + + def sanityCheck(self): + """ + sanityCheck() + + This will throw an exception if :py:class:`PyOpenColorIO.Config` is + malformed. The most common error occurs when references are made to + colorspaces that do not exist. + """ + pass + + def getDescription(self): + """ + getDescription() + + Returns the stored description of :py:class:`PyOpenColorIO.Config`. + + :return: stored description of :py:class:`PyOpenColorIO.Config` + :rtype: string + """ + pass + + def setDescription(self, desc): + """ + setDescription(desc) + + Sets the description of :py:class:`PyOpenColorIO.Config`. + + :param desc: description of :py:class:`PyOpenColorIO.Config` + :type desc: string + """ + pass + + def serialize(self): + """ + serialize() + + Returns the string representation of :py:class:`PyOpenColorIO.Config` + in YAML text form. This is typically stored on disk in a file with the + .ocio extension. + + :return: :py:class:`PyOpenColorIO.Config` in YAML text form + :rtype: string + """ + pass + + def getCacheID(self, pycontext=None): + """ + getCacheID([, pycontext]) + + 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 :py:class:`PyOpenColorIO.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 :py:method:`PyOpenColorIO.Config.serialize`). + + :param pycontext: optional + :type pycontext: object + :return: hash of :py:class:`PyOpenColorIO.Config` + :rtype: string + """ + pass + + def getCurrentContext(self): + """ + getCurrentContext() + + Return the current context, which is essentially a record of all + the environment variables that are available for use in file path + lookups. + + :return: context + :rtype: pycontext + """ + pass + + def getSearchPath(self): + """ + getSearchPath() + + Returns the search path. + + :return: search path + :rtype: string + """ + pass + + def setSearchPath(self, searchpath): + """ + setSearchPath(path) + + Sets the search path. + + :param path: the search path + :type path: string + """ + pass + + def getWorkingDir(self): + """ + getWorkingDir() + + Returns the working directory. + + :return: the working directory + :rtype path: string + """ + pass + + def setWorkingDir(self, dirname): + """ + setWorkingDir(path) + + Sets the working directory. + + :param path: the working directory + :type path: string + """ + pass + + def getColorSpaces(self): + """ + getColorSpaces() + + Returns all the ColorSpaces defined in :py:class:`Config`. + + :return: ColorSpaces in :py:class:`PyOpenColorIO.Config` + :rtype: tuple + """ + pass + + def getColorSpace(self, name): + """ + getColorSpace(name) + + Returns the data for the specified color space in :py:class:`Config`. + + This will return null if the specified name is not found. + + :param name: name of color space + :type name: string + :return: data for specified color space + :rtype: pyColorSpace object + """ + pass + + def addColorSpace(self, colorSpace): + """ + addColorSpace(pyColorSpace) + + Add a specified color space to :py:class:`PyOpenColorIO.Config`. + + :param pyColorSpace: color space + :type pyColorSpace: object + + .. note:: + If another color space is already registered with the same name, + this will overwrite it. + """ + pass + + def clearColorSpaces(self): + """ + clearColorSpaces() + + Clear the color spaces in :py:class:`PyOpenColorIO.Config`. + """ + pass + + def parseColorSpaceFromString(self, str): + """ + parseColorSpaceFromString(str) + + Parses out the color space from a string. + + Given the specified string, gets the longest, right-most color space substring. + * If strict parsing is enabled, and no color space is found, return an empty string. + * If strict parsing is disabled, return the default role, if defined. + * If the default role is not defined, return an empty string. + + :param str: ColorSpace data + :type str: string + :return: parsed data + :rtype: string + """ + pass + + def setRole(self, role, csname): + """ + setRole(role, csname) + + Set a role's ColorSpace. + + Setting the colorSpaceName name to a null string unsets it. + + :param role: role whose ColorSpace will be set + :type role: string + :param csname: name of ColorSpace + :type csname: string + """ + pass + + def getDefaultDisplay(self): + """ + getDefaultDisplay() + + Returns the default display set in :py:class:`PyOpenColorIO.Config`. + + :return: default display + :rtype: string + """ + pass + + def getDisplays(self): + """ + getDisplays() + + Returns all the displays defined in :py:class:`PyOpenColorIO.Config`. + + :return: displays in :py:class:`Config` + :rtype: list of strings + """ + pass + + def getDefaultView(self, display): + """ + getDefaultView(display) + + Returns the default view of :py:class:`PyOpenColorIO.Config`. + + :param display: default view + :type display: string + :return: view + :rtype: string + """ + pass + + def getViews(self, display): + """ + getViews(display) + + Returns all the views defined in :py:class:`PyOpenColorIO.Config`. + + :param display: views in :py:class:`Config` + :type display: string + :return: views in :py:class:`Config`. + :rtype: list of strings + """ + pass + + def getDisplayColorSpaceName(self, display, view): + """ + getDisplayColorSpaceName(display, view) + + Returns the ColorSpace name corresponding to the display and view + combination in :py:class:`PyOpenColorIO.Config`. + + :param display: display + :type display: string + :param view: view + :type view: string + :return: display color space name + :rtype: string + """ + pass + + def getDisplayLooks(self, display, view): + """ + getDisplayLooks(display, view) + + Returns the looks corresponding to the display and view combination in + :py:class:`PyOpenColorIO.Config`. + + :param display: display + :type display: string + :param view: view + :type view: string + :return: looks + :rtype: string + """ + pass + + def addDisplay(self, display, view, csname, looks=None): + """ + addDisplay(display, view, colorSpaceName[, looks]) + + NEEDS WORK + + :param display: + :type display: string + :param view: + :type view: string + :param colorSpaceName: + :type colorSpaceName: string + :param looks: optional + :type looks: string + """ + pass + + def clearDisplays(self): + """ + clearDisplays() + """ + pass + + def setActiveDisplays(self, dislpays): + """ + setActiveDisplays(displays) + + Sets the active displays in :py:class:`PyOpenColorIO.Config`. + + :param displays: active displays + :type displays: string + """ + pass + + def getActiveDisplays(self): + """ + getActiveDisplays() + + Returns the active displays in :py:class:`PyOpenColorIO.Config`. + + :return: active displays + :rtype: string + """ + pass + + def setActiveViews(self, views): + """ + setActiveViews(views) + + Sets the active views in :py:class:`PyOpenColorIO.Config`. + + :param views: active views + :type views: string + """ + pass + + def getActiveViews(self): + """ + getActiveViews() + + Returns the active views in :py:class:`PyOpenColorIO.Config`. + + :return: active views + :rtype: string + """ + pass + + def getDefaultLumaCoefs(self): + """ + getDefaultLumaCoefs() + + Returns the default luma coefficients in :py:class:`PyOpenColorIO.Config`. + + :return: luma coefficients + :rtype: list of floats + """ + pass + + def setDefaultLumaCoefs(self, coefficients): + """ + setDefaultLumaCoefs(pyCoef) + + Sets the default luma coefficients in :py:class:`PyOpenColorIO.Config`. + + :param pyCoef: luma coefficients + :type pyCoef: object + """ + pass + + def getLook(self, lookname): + """ + getLook(str) + + Returns the information of a specified look in + :py:class:`PyOpenColorIO.Config`. + + :param str: look + :type str: string + :return: specified look + :rtype: look object + """ + pass + + def getLooks(self): + """ + getLooks() + + Returns a list of all the looks defined in + :py:class:`PyOpenColorIO.Config`. + + :return: looks + :rtype: tuple of look objects + """ + pass + + def addLook(self, look): + """ + addLook(pylook) + + Adds a look to :py:class:`PyOpenColorIO.Config`. + + :param pylook: look + :type pylook: look object + """ + pass + + def clearLooks(self): + """ + clearLooks() + + Clear looks in :py:class:`PyOpenColorIO.Config`. + """ + pass + + def getProcessor(self, arg1, arg2=None, direction=None, context=None): + """ + getProcessor(arg1[, arg2[, direction[, context]]) + + Returns a processor for a specified transform. + + Although this is not often needed, it allows for the reuse of atomic + OCIO functionality, such as applying an individual LUT file. + + There are two canonical ways of creating a + :py:class:`PyOpenColorIO.Processor`: + + #. Pass a transform into arg1, in which case arg2 will be ignored. + #. Set arg1 as the source and arg2 as the destination. These can be + ColorSpace names, objects, or roles. + + Both arguments, ``direction`` (of transform) and ``context``, are + optional and respected for both methods of + :py:class:`PyOpenColorIO.Processor` creation. + + This will fail if either the source or destination color space is null. + + See Python: Processor for more details. + + .. note:: + This may provide higher fidelity than anticipated due to internal + optimizations. For example, if inputColorSpace and 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 optionally + supported using the pixelStrideBytes arg). ??? + + :param arg1: + :type arg1: object + :param arg2: ignored if arg1 is a transform + :type arg2: object + :param direction: optional + :type direction: string + :param context: optional + :type context: object + """ + pass diff --git a/src/pyglue/DocStrings/Constants.py b/src/pyglue/DocStrings/Constants.py new file mode 100644 index 0000000..a58a38c --- /dev/null +++ b/src/pyglue/DocStrings/Constants.py @@ -0,0 +1,43 @@ + +class Constants: + + def __init__(self): + pass + + def GetInverseTransformDirection(self, direction): + """ + GetInverseTransformDirection(direction) + + :param s: + :param type: string + """ + pass + + def CombineTransformDirections(self, dir1, dir2): + """ + CombineTransformDirections(dir1, dir2) + + :param s1: + :param type: string + :param s2: + :param type: string + """ + pass + + def BitDepthIsFloat(self, bitDepth): + """ + BitDepthIsFloat(bitDepth) + + :param s: + :param type: string + """ + pass + + def BitDepthToInt(self, bitDepth): + """ + BitDepthToInt(bitDepth) + + :param s: + :param type: string + """ + pass diff --git a/src/pyglue/DocStrings/Context.py b/src/pyglue/DocStrings/Context.py new file mode 100644 index 0000000..ff73dbf --- /dev/null +++ b/src/pyglue/DocStrings/Context.py @@ -0,0 +1,32 @@ + +class Context: + """ + Context + """ + def __init__(self): + pass + def isEditable(self): + pass + def createEditableCopy(self): + pass + def getCacheID(self): + pass + def getSearchPath(self): + pass + def setSearchPath(self, searchPath): + pass + def getWorkingDir(self): + pass + def setWorkingDir(self, workingDir): + pass + def getStringVar(self): + pass + def setStringVar(self, stringVar): + pass + def loadEnvironment(self): + pass + def resolveStringVar(self, stringVar): + pass + def resolveFileLocation(self, fileLocation): + pass + diff --git a/src/pyglue/DocStrings/DisplayTransform.py b/src/pyglue/DocStrings/DisplayTransform.py new file mode 100644 index 0000000..2d68ac3 --- /dev/null +++ b/src/pyglue/DocStrings/DisplayTransform.py @@ -0,0 +1,222 @@ + +class DisplayTransform: + """ + Used to create transforms for displays. + """ + def __init__(self): + pass + + def getInputColorSpaceName(self): + """ + getInputColorSpaceName() + + Returns the name of the input ColorSpace of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :return: name of input ColorSpace + :rtype: string + """ + pass + + def setInputColorSpaceName(self, name): + """ + setInputColorSpaceName(name) + + Sets the name of the input ColorSpace of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :param name: name of input ColorSpace + :type name: string + """ + pass + + def getLinearCC(self): + """ + getLinearCC() + + Returns the linear CC transform of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :return: linear CC transform + :rtype: object + """ + pass + + def setLinearCC(self, transform): + """ + setLinearCC(pyCC) + + Sets the linear CC transform of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :param pyCC: linear CC + :type pyCC: object + """ + pass + + def getColorTimingCC(self): + """ + getColorTimingCC() + + Returns the color timing CC transform of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :return: color timing CC transform + :rtype: object + """ + pass + + def setColorTimingCC(self, transform): + """ + setColorTimingCC(pyCC) + + Sets the color timing CC transform of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :param pyCC: color timing CC + :type pyCC: object + """ + pass + + def getChannelView(self): + """ + getChannelView() + + Returns the channel view of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :return: channel view + :rtype: object + """ + pass + + def setChannelView(self, transform): + """ + setChannelView(pyCC) + + Sets the channel view transform of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :param pyCC: channel view transform + :type pyCC: object + """ + pass + + def getDisplay(self): + """ + getDisplay() + + Returns the display of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :return: display + :rtype: string + """ + pass + + def setDisplay(self, displayName): + """ + setDisplay(str) + + Sets the display of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :param str: display + :type str: string + """ + pass + + def getView(self): + """ + getView() + + Returns the view of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :return: view + :rtype: string + """ + pass + + def setView(self, viewName): + """ + setView(str) + + Sets the view of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :param str: view + :type str: string + """ + pass + + def getDisplayCC(self): + """ + getDisplayCC() + + Returns the display CC transform of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :return: display CC + :rtype: object + """ + pass + + def setDisplayCC(self, transform): + """ + setDisplayCC(pyCC) + + Sets the display CC transform of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :param pyCC: display CC + :type pyCC: object + """ + pass + + def getLooksOverride(self): + """ + getLooksOverride() + + Returns the looks in :py:class:`PyOpenColorIO.DisplayTransform` that's + overriding :py:class:`PyOpenColorIO.Config`'s. + + :return: looks override + :rtype: string + """ + pass + + def setLooksOverride(self, looksStr): + """ + setLooksOverride(str) + + Sets the looks override of :py:class:`PyOpenColorIO.DisplayTransform`. + + :param str: looks override + :type str: string + """ + pass + + def getLooksOverrideEnabled(self): + """ + getLooksOverrideEnabled() + + Returns whether the looks override of + :py:class:`PyOpenColorIO.DisplayTransform` is enabled. + + :return: looks override enabling + :rtype: bool + """ + pass + + def setLooksOverrideEnabled(self, enabled): + """ + setLooksOverrideEnabled(enabled) + + Sets the looks override enabling of + :py:class:`PyOpenColorIO.DisplayTransform`. + + :param enabled: looks override enabling + :type enabled: object + """ + pass diff --git a/src/pyglue/DocStrings/Exception.py b/src/pyglue/DocStrings/Exception.py new file mode 100644 index 0000000..75bba8e --- /dev/null +++ b/src/pyglue/DocStrings/Exception.py @@ -0,0 +1,11 @@ + +class Exception: + """ + An exception class to throw for errors detected at runtime. + + .. warning:: + All functions in the Config class can potentially throw this exception. + """ + def __init__(self): + pass + diff --git a/src/pyglue/DocStrings/ExceptionMissingFile.py b/src/pyglue/DocStrings/ExceptionMissingFile.py new file mode 100644 index 0000000..6aa102a --- /dev/null +++ b/src/pyglue/DocStrings/ExceptionMissingFile.py @@ -0,0 +1,11 @@ + +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. + """ + def __init__(self): + pass + diff --git a/src/pyglue/DocStrings/ExponentTransform.py b/src/pyglue/DocStrings/ExponentTransform.py new file mode 100644 index 0000000..930bb39 --- /dev/null +++ b/src/pyglue/DocStrings/ExponentTransform.py @@ -0,0 +1,31 @@ + +class ExponentTransform: + """ + ExponentTransform + """ + def __init__(self): + pass + + def getValue(self): + """ + getValue() + + Returns the values in the exponent transform of + :py:class:`PyOpenColorIO.ExponentTransform`. + + :return: exponent transform values + :rtype: list of floats + """ + pass + + def setValue(self, value): + """ + setValue() + + Sets the values in the exponent transform of + :py:class:`PyOpenColorIO.ExponentTransform`. + + :param pyData: exponent transform values + :type pyData: list of 4 floats + """ + pass diff --git a/src/pyglue/DocStrings/FileTransform.py b/src/pyglue/DocStrings/FileTransform.py new file mode 100644 index 0000000..05a7026 --- /dev/null +++ b/src/pyglue/DocStrings/FileTransform.py @@ -0,0 +1,19 @@ + +class FileTransform: + """ + FileTransform + """ + def __init__(self): + pass + def getSrc(self): + pass + def setSrc(self, src): + pass + def getCCCId(self): + pass + def setCCCId(self, cccid): + pass + def getInterpolation(self): + pass + def setInterpolation(self, interp): + pass diff --git a/src/pyglue/DocStrings/GroupTransform.py b/src/pyglue/DocStrings/GroupTransform.py new file mode 100644 index 0000000..80a5bf8 --- /dev/null +++ b/src/pyglue/DocStrings/GroupTransform.py @@ -0,0 +1,21 @@ + +class GroupTransform: + """ + GroupTransform + """ + def __init__(self): + pass + def getTransform(self): + pass + def getTransforms(self): + pass + def setTransforms(self, transforms): + pass + def size(self): + pass + def push_back(self, transform): + pass + def clear(self): + pass + def empty(self): + pass diff --git a/src/pyglue/DocStrings/LogTransform.py b/src/pyglue/DocStrings/LogTransform.py new file mode 100644 index 0000000..ee823bb --- /dev/null +++ b/src/pyglue/DocStrings/LogTransform.py @@ -0,0 +1,26 @@ + +class LogTransform: + """ + LogTransform + """ + def __init__(self): + pass + + def getBase(self): + """ + getBase() + + Returns the base of :py:class:`PyOpenColorIO.LogTransform`. + """ + pass + + def setBase(self, base): + """ + setBase(base) + + Sets the base in :py:class:`PyOpenColorIO.LogTransform`. + + :param base: base of log transform + :type base: float + """ + pass diff --git a/src/pyglue/DocStrings/Look.py b/src/pyglue/DocStrings/Look.py new file mode 100644 index 0000000..787fb5c --- /dev/null +++ b/src/pyglue/DocStrings/Look.py @@ -0,0 +1,35 @@ + +class 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. + """ + def __init__(self): + pass + + def isEditable(self): + pass + + def createEditableCopy(self): + pass + + def getName(self): + pass + + def setName(self, name): + pass + + def getProcessSpace(self): + pass + + def setProcessSpace(self, csname): + pass + + def getTransform(self): + pass + + def setTransform(self, transform): + pass + diff --git a/src/pyglue/DocStrings/LookTransform.py b/src/pyglue/DocStrings/LookTransform.py new file mode 100644 index 0000000..9b0c62a --- /dev/null +++ b/src/pyglue/DocStrings/LookTransform.py @@ -0,0 +1,19 @@ + +class LookTransform: + """ + LookTransform + """ + def __init__(self): + pass + def getSrc(self): + pass + def setSrc(self, srcname): + pass + def getDst(self): + pass + def setDst(self, dstname): + pass + def getLooks(self): + pass + def setLooks(self, looks): + pass diff --git a/src/pyglue/DocStrings/MatrixTransform.py b/src/pyglue/DocStrings/MatrixTransform.py new file mode 100644 index 0000000..8b89ca5 --- /dev/null +++ b/src/pyglue/DocStrings/MatrixTransform.py @@ -0,0 +1,29 @@ + +class MatrixTransform: + """ + MatrixTransfom + """ + def __init__(self): + pass + def getValue(self): + pass + def setValue(self, value): + pass + def getMatrix(self): + pass + def setMatrix(self, matrix): + pass + def getOffset(self): + pass + def setOffset(self, offset): + pass + def Identity(self): + pass + def Fit(self): + pass + def Sat(self): + pass + def Scale(self): + pass + def View(self): + pass diff --git a/src/pyglue/DocStrings/OpenColorIO.py b/src/pyglue/DocStrings/OpenColorIO.py new file mode 100644 index 0000000..0b7e376 --- /dev/null +++ b/src/pyglue/DocStrings/OpenColorIO.py @@ -0,0 +1,17 @@ + +class OpenColorIO: + """ + OpenColorIO API + """ + def __init__(self): + pass + def ClearAllCaches(self): + pass + def GetLoggingLevel(self): + pass + def SetLoggingLevel(self, level): + pass + def GetCurrentConfig(self): + pass + def SetCurrentConfig(self, config): + pass diff --git a/src/pyglue/DocStrings/Processor.py b/src/pyglue/DocStrings/Processor.py new file mode 100644 index 0000000..7ce02bf --- /dev/null +++ b/src/pyglue/DocStrings/Processor.py @@ -0,0 +1,141 @@ + +class Processor: + """ + Processor is the baked representation of a particular color transform. + Once you have a process for a particular transform created, you can hang + onto it to efficiently transform pixels. + + Processors can only be created from the `PyOpenColorIO.Config` + getProcessor(...) call. + """ + + def __init__(self): + pass + + def isNoOp(self): + """ + isNoOp() + + Returns whether the actual transformation represented by + :py:class:`PyOpenColorIO.Processor` is a no-op. + + :return: whether transform is a no-op + :rtype: bool + """ + pass + + def hasChannelCrosstalk(self): + """ + hasChannelCrosstalk() + + Returns whether the transformation of + :py:class:`PyOpenColorIO.Processor` introduces crosstalk between the + image channels. + + :return: whether there's crosstalk between channels + :rtype: bool + """ + pass + + def getMetadata(self): + """ + getMetadata() + + Returns information about the process that generated this processor. + + :return: processor metadata + :rtype: `PyOpenColorIO.ProcessorMetadata` + """ + pass + + def applyRGB(self, pixeldata): + """ + applyRGB(pixeldata) + + Apply the RGB part of the transform represented by + :py:class:`PyOpenColorIO.Processor` to an image. + + :param pixeldata: rgbrgb... array (length % 3 == 0) + :type pixeldata: object + :return: color converted pixeldata + :rtype: list + """ + pass + + def applyRGBA(self, pixeldata): + """ + applyRGBA(pixeldata) + + Apply the RGB and alpha part of the transform represented by + :py:class:`PyOpenColorIO.Processor` to an image. + + :param pixeldata: rgbargba... array (length % 4 == 0) + :type pixeldata: object + :return: color converted pixeldata + :rtype: list + """ + pass + + def getCpuCacheID(self): + """ + getCpuCacheID() + + Returns the cache ID of the CPU that :py:class:`PyOpenColorIO.Processor` + will run on. + + :return: CPU cache ID + :rtype: string + """ + pass + + def getGpuShaderText(self, shaderDesc): + """ + getGpuShaderText(shaderDesc) + + Returns the GPU shader text. + + :param shaderDesc: define 'language','functionName','lut3DEdgeLen' + :type shaderDesc: dict + :return: GPU shader text + :rtype: string + """ + pass + + def getGpuShaderTextCacheID(self, shaderDesc): + """ + getGpuShaderTextCacheID(shaderDesc) + + Returns the GPU shader text cache ID. + + :param shaderDesc: define 'language','functionName','lut3DEdgeLen' + :type shaderDesc: dict + :return: GPU shader text cache ID + :rtype: string + """ + pass + + def getGpuLut3D(self, shaderDesc): + """ + getGpuLut3D(shaderDesc) + + Returns the GPU LUT 3D. + + :param shaderDesc: define 'language','functionName','lut3DEdgeLen' + :type shaderDesc: dict + :return: GPU LUT 3D + :rtype: list + """ + pass + + def getGpuLut3DCacheID(self, shaderDesc): + """ + getGpuLut3DCacheID(shaderDesc) + + Returns the GPU 3D LUT cache ID. + + :param shaderDesc: two params + :type shaderDesc: dict + :return: GPU 3D LUT cache ID + :rtype: string + """ + pass diff --git a/src/pyglue/DocStrings/ProcessorMetadata.py b/src/pyglue/DocStrings/ProcessorMetadata.py new file mode 100644 index 0000000..2e1d21a --- /dev/null +++ b/src/pyglue/DocStrings/ProcessorMetadata.py @@ -0,0 +1,34 @@ + +class ProcessorMetadata: + """ + ProcessorMetadata + + This contains meta information about the process that generated + this processor. The results of these functions do not + impact the pixel processing. + + """ + def __init__(self): + pass + + def getFiles(self): + """ + getFiles() + + Returns a list of file references used internally by this processor + + :return: list of filenames + :rtype: list + """ + pass + + def getLooks(self): + """ + getLooks() + + Returns a list of looks used internally by this processor + + :return: list of look names + :rtype: list + """ + pass diff --git a/src/pyglue/DocStrings/Transform.py b/src/pyglue/DocStrings/Transform.py new file mode 100644 index 0000000..b0819be --- /dev/null +++ b/src/pyglue/DocStrings/Transform.py @@ -0,0 +1,19 @@ + +class Transform: + """ + These are typically only needed when creating or manipulating configurations. + """ + def __init__(self): + pass + + def isEditable(self): + pass + + def createEditableCopy(self): + pass + + def getDirection(self): + pass + + def setDirection(self): + pass diff --git a/src/pyglue/DocStrings/__init__.py b/src/pyglue/DocStrings/__init__.py new file mode 100644 index 0000000..6afe720 --- /dev/null +++ b/src/pyglue/DocStrings/__init__.py @@ -0,0 +1,23 @@ + +from Exception import * +from ExceptionMissingFile import * +from OpenColorIO import * +from Constants import * +from Config import * +from ColorSpace import * +from Processor import * +from ProcessorMetadata import * +from Context import * +from Look import * +from Transform import * + +from AllocationTransform import * +from CDLTransform import * +from ColorSpaceTransform import * +from DisplayTransform import * +from ExponentTransform import * +from FileTransform import * +from GroupTransform import * +from LogTransform import * +from LookTransform import * +from MatrixTransform import * diff --git a/src/pyglue/PyAllocationTransform.cpp b/src/pyglue/PyAllocationTransform.cpp new file mode 100644 index 0000000..a977274 --- /dev/null +++ b/src/pyglue/PyAllocationTransform.cpp @@ -0,0 +1,300 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +//Rarely used. could use a log transform instead. This can sample by log when doing the offset to make best use of the data. + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddAllocationTransformObjectToModule( PyObject* m ) + { + PyOCIO_AllocationTransformType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_AllocationTransformType) < 0 ) return false; + + Py_INCREF( &PyOCIO_AllocationTransformType ); + PyModule_AddObject(m, "AllocationTransform", + (PyObject *)&PyOCIO_AllocationTransformType); + + return true; + } + + /* + bool IsPyAllocationTransform(PyObject * pyobject) + { + if(!pyobject) return false; + return PyObject_TypeCheck(pyobject, &PyOCIO_AllocationTransformType); + } + */ + + ConstAllocationTransformRcPtr GetConstAllocationTransform(PyObject * pyobject, bool allowCast) + { + ConstAllocationTransformRcPtr transform = \ + DynamicPtrCast<const AllocationTransform>(GetConstTransform(pyobject, allowCast)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.AllocationTransform."); + } + return transform; + } + + AllocationTransformRcPtr GetEditableAllocationTransform(PyObject * pyobject) + { + AllocationTransformRcPtr transform = \ + DynamicPtrCast<AllocationTransform>(GetEditableTransform(pyobject)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.AllocationTransform."); + } + return transform; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_AllocationTransform_init( PyOCIO_Transform * self, PyObject * args, PyObject * kwds ); + + PyObject * PyOCIO_AllocationTransform_equals( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_AllocationTransform_getAllocation( PyObject * self ); + PyObject * PyOCIO_AllocationTransform_setAllocation( PyObject * self, PyObject *args ); + PyObject * PyOCIO_AllocationTransform_getVars( PyObject * self ); + PyObject * PyOCIO_AllocationTransform_setVars( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_AllocationTransform_methods[] = { + {"getAllocation", + (PyCFunction) PyOCIO_AllocationTransform_getAllocation, METH_NOARGS, ALLOCATIONTRANSFORM_GETALLOCATION__DOC__ }, + {"setAllocation", + PyOCIO_AllocationTransform_setAllocation, METH_VARARGS, ALLOCATIONTRANSFORM_SETALLOCATION__DOC__ }, + {"getVars", + (PyCFunction) PyOCIO_AllocationTransform_getVars, METH_NOARGS, ALLOCATIONTRANSFORM_GETVARS__DOC__ }, + {"setVars", + PyOCIO_AllocationTransform_setVars, METH_VARARGS, ALLOCATIONTRANSFORM_SETVARS__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_AllocationTransformType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.AllocationTransform", //tp_name + sizeof(PyOCIO_Transform), //tp_basicsize + 0, //tp_itemsize + 0, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + ALLOCATIONTRANSFORM__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_AllocationTransform_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + &PyOCIO_TransformType, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_AllocationTransform_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + + /////////////////////////////////////////////////////////////////////// + /// + + int PyOCIO_AllocationTransform_init( PyOCIO_Transform *self, PyObject * /*args*/, PyObject * /*kwds*/ ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstTransformRcPtr(); + self->cppobj = new TransformRcPtr(); + self->isconst = true; + + try + { + *self->cppobj = AllocationTransform::Create(); + self->isconst = false; + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create AllocationTransform: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_AllocationTransform_getAllocation( PyObject * self ) + { + try + { + ConstAllocationTransformRcPtr transform = GetConstAllocationTransform(self, true); + return PyString_FromString( AllocationToString( transform->getAllocation()) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_AllocationTransform_setAllocation( PyObject * self, PyObject * args ) + { + try + { + Allocation hwalloc; + if (!PyArg_ParseTuple(args,"O&:setAllocation", + ConvertPyObjectToAllocation, &hwalloc)) return NULL; + + AllocationTransformRcPtr transform = GetEditableAllocationTransform(self); + transform->setAllocation( hwalloc ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_AllocationTransform_getVars( PyObject * self ) + { + try + { + ConstAllocationTransformRcPtr transform = GetConstAllocationTransform(self, true); + + std::vector<float> vars(transform->getNumVars()); + if(!vars.empty()) + { + transform->getVars(&vars[0]); + } + + return CreatePyListFromFloatVector(vars); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_AllocationTransform_setVars( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyvars = 0; + if (!PyArg_ParseTuple(args,"O:setVars", &pyvars)) return NULL; + + std::vector<float> vars; + if(!FillFloatVectorFromPySequence(pyvars, vars)) + { + PyErr_SetString(PyExc_TypeError, "First argument must be a float array."); + return 0; + } + + AllocationTransformRcPtr transform = GetEditableAllocationTransform(self); + if(!vars.empty()) + { + transform->setVars(static_cast<int>(vars.size()), &vars[0]); + } + + Py_RETURN_NONE; + + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyCDLTransform.cpp b/src/pyglue/PyCDLTransform.cpp new file mode 100644 index 0000000..5702940 --- /dev/null +++ b/src/pyglue/PyCDLTransform.cpp @@ -0,0 +1,611 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddCDLTransformObjectToModule( PyObject* m ) + { + PyOCIO_CDLTransformType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_CDLTransformType) < 0 ) return false; + + Py_INCREF( &PyOCIO_CDLTransformType ); + PyModule_AddObject(m, "CDLTransform", + (PyObject *)&PyOCIO_CDLTransformType); + + return true; + } + + bool IsPyCDLTransform(PyObject * pyobject) + { + if(!pyobject) return false; + return PyObject_TypeCheck(pyobject, &PyOCIO_CDLTransformType); + } + + ConstCDLTransformRcPtr GetConstCDLTransform(PyObject * pyobject, bool allowCast) + { + ConstCDLTransformRcPtr transform = \ + DynamicPtrCast<const CDLTransform>(GetConstTransform(pyobject, allowCast)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.CDLTransform."); + } + return transform; + } + + CDLTransformRcPtr GetEditableCDLTransform(PyObject * pyobject) + { + CDLTransformRcPtr transform = \ + DynamicPtrCast<CDLTransform>(GetEditableTransform(pyobject)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.CDLTransform."); + } + return transform; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_CDLTransform_init( PyOCIO_Transform * self, PyObject * args, PyObject * kwds ); + + PyObject * PyOCIO_CDLTransform_equals( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_CDLTransform_getXML( PyObject * self ); + PyObject * PyOCIO_CDLTransform_setXML( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_CDLTransform_getSlope( PyObject * self ); + PyObject * PyOCIO_CDLTransform_getOffset( PyObject * self ); + PyObject * PyOCIO_CDLTransform_getPower( PyObject * self ); + PyObject * PyOCIO_CDLTransform_getSOP( PyObject * self ); + PyObject * PyOCIO_CDLTransform_getSat( PyObject * self ); + + PyObject * PyOCIO_CDLTransform_setSlope( PyObject * self, PyObject *args ); + PyObject * PyOCIO_CDLTransform_setOffset( PyObject * self, PyObject *args ); + PyObject * PyOCIO_CDLTransform_setPower( PyObject * self, PyObject *args ); + PyObject * PyOCIO_CDLTransform_setSOP( PyObject * self, PyObject *args ); + PyObject * PyOCIO_CDLTransform_setSat( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_CDLTransform_getSatLumaCoefs( PyObject * self ); + + PyObject * PyOCIO_CDLTransform_getID( PyObject * self ); + PyObject * PyOCIO_CDLTransform_setID( PyObject * self, PyObject *args ); + PyObject * PyOCIO_CDLTransform_getDescription( PyObject * self ); + PyObject * PyOCIO_CDLTransform_setDescription( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_CDLTransform_methods[] = { + {"equals", + PyOCIO_CDLTransform_equals, METH_VARARGS, CDLTRANSFORM_EQUALS__DOC__ }, + {"getXML", + (PyCFunction) PyOCIO_CDLTransform_getXML, METH_NOARGS, CDLTRANSFORM_GETXML__DOC__ }, + {"setXML", + PyOCIO_CDLTransform_setXML, METH_VARARGS, CDLTRANSFORM_SETXML__DOC__ }, + {"getSlope", + (PyCFunction) PyOCIO_CDLTransform_getSlope, METH_NOARGS, CDLTRANSFORM_GETSLOPE__DOC__ }, + {"getOffset", + (PyCFunction) PyOCIO_CDLTransform_getOffset, METH_NOARGS, CDLTRANSFORM_GETOFFSET__DOC__ }, + {"getPower", + (PyCFunction) PyOCIO_CDLTransform_getPower, METH_NOARGS, CDLTRANSFORM_GETPOWER__DOC__ }, + {"getSOP", + (PyCFunction) PyOCIO_CDLTransform_getSOP, METH_NOARGS, CDLTRANSFORM_GETSOP__DOC__ }, + {"getSat", + (PyCFunction) PyOCIO_CDLTransform_getSat, METH_NOARGS, CDLTRANSFORM_GETSAT__DOC__ }, + {"setSlope", + PyOCIO_CDLTransform_setSlope, METH_VARARGS, CDLTRANSFORM_SETSLOPE__DOC__ }, + {"setOffset", + PyOCIO_CDLTransform_setOffset, METH_VARARGS, CDLTRANSFORM_SETOFFSET__DOC__ }, + {"setPower", + PyOCIO_CDLTransform_setPower, METH_VARARGS, CDLTRANSFORM_SETPOWER__DOC__ }, + {"setSOP", + PyOCIO_CDLTransform_setSOP, METH_VARARGS, CDLTRANSFORM_SETSOP__DOC__ }, + {"setSat", + PyOCIO_CDLTransform_setSat, METH_VARARGS, CDLTRANSFORM_SETSAT__DOC__ }, + {"getSatLumaCoefs", + (PyCFunction) PyOCIO_CDLTransform_getSatLumaCoefs, METH_NOARGS, CDLTRANSFORM_GETSATLUMACOEFS__DOC__ }, + {"getID", + (PyCFunction) PyOCIO_CDLTransform_getID, METH_NOARGS, CDLTRANSFORM_GETID__DOC__ }, + {"setID", + PyOCIO_CDLTransform_setID, METH_VARARGS, CDLTRANSFORM_SETID__DOC__ }, + {"getDescription", + (PyCFunction) PyOCIO_CDLTransform_getDescription, METH_NOARGS, CDLTRANSFORM_GETDESCRIPTION__DOC__ }, + {"setDescription", + PyOCIO_CDLTransform_setDescription, METH_VARARGS, CDLTRANSFORM_SETDESCRIPTION__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_CDLTransformType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.CDLTransform", //tp_name + sizeof(PyOCIO_Transform), //tp_basicsize + 0, //tp_itemsize + 0, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + CDLTRANSFORM__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_CDLTransform_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + &PyOCIO_TransformType, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_CDLTransform_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_CDLTransform_init( PyOCIO_Transform *self, PyObject * /*args*/, PyObject * /*kwds*/ ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstTransformRcPtr(); + self->cppobj = new TransformRcPtr(); + self->isconst = true; + + try + { + *self->cppobj = CDLTransform::Create(); + self->isconst = false; + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create CDLTransform: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_CDLTransform_equals( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyother = 0; + + if (!PyArg_ParseTuple(args,"O:equals", + &pyother)) return NULL; + + ConstCDLTransformRcPtr transform = GetConstCDLTransform(self, true); + if(!IsPyCDLTransform(pyother)) + { + return PyBool_FromLong(false); + } + + ConstCDLTransformRcPtr other = GetConstCDLTransform(pyother, true); + + return PyBool_FromLong(transform->equals(other)); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_CDLTransform_getXML( PyObject * self ) + { + try + { + ConstCDLTransformRcPtr transform = GetConstCDLTransform(self, true); + return PyString_FromString( transform->getXML() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_setXML( PyObject * self, PyObject * args ) + { + try + { + const char * str = 0; + if (!PyArg_ParseTuple(args,"s:setXML", + &str)) return NULL; + + CDLTransformRcPtr transform = GetEditableCDLTransform(self); + transform->setXML( str ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_CDLTransform_getSlope( PyObject * self ) + { + try + { + ConstCDLTransformRcPtr transform = GetConstCDLTransform(self, true); + std::vector<float> data(3); + transform->getSlope(&data[0]); + return CreatePyListFromFloatVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_getOffset( PyObject * self ) + { + try + { + ConstCDLTransformRcPtr transform = GetConstCDLTransform(self, true); + std::vector<float> data(3); + transform->getOffset(&data[0]); + return CreatePyListFromFloatVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_getPower( PyObject * self ) + { + try + { + ConstCDLTransformRcPtr transform = GetConstCDLTransform(self, true); + std::vector<float> data(3); + transform->getPower(&data[0]); + return CreatePyListFromFloatVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_getSOP( PyObject * self ) + { + try + { + ConstCDLTransformRcPtr transform = GetConstCDLTransform(self, true); + std::vector<float> data(9); + transform->getSOP(&data[0]); + return CreatePyListFromFloatVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_getSat( PyObject * self ) + { + try + { + ConstCDLTransformRcPtr transform = GetConstCDLTransform(self, true); + return PyFloat_FromDouble(transform->getSat()); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_CDLTransform_setSlope( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyData = 0; + if (!PyArg_ParseTuple(args,"O:setSlope", &pyData)) return NULL; + CDLTransformRcPtr transform = GetEditableCDLTransform(self); + + std::vector<float> data; + if(!FillFloatVectorFromPySequence(pyData, data) || (data.size() != 3)) + { + PyErr_SetString(PyExc_TypeError, "First argument must be a float array, size 3"); + return 0; + } + + transform->setSlope( &data[0] ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_setOffset( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyData = 0; + if (!PyArg_ParseTuple(args,"O:setOffset", &pyData)) return NULL; + CDLTransformRcPtr transform = GetEditableCDLTransform(self); + + std::vector<float> data; + if(!FillFloatVectorFromPySequence(pyData, data) || (data.size() != 3)) + { + PyErr_SetString(PyExc_TypeError, "First argument must be a float array, size 3"); + return 0; + } + + transform->setOffset( &data[0] ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_setPower( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyData = 0; + if (!PyArg_ParseTuple(args,"O:setPower", &pyData)) return NULL; + CDLTransformRcPtr transform = GetEditableCDLTransform(self); + + std::vector<float> data; + if(!FillFloatVectorFromPySequence(pyData, data) || (data.size() != 3)) + { + PyErr_SetString(PyExc_TypeError, "First argument must be a float array, size 3"); + return 0; + } + + transform->setPower( &data[0] ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_setSOP( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyData = 0; + if (!PyArg_ParseTuple(args,"O:setSOP", &pyData)) return NULL; + CDLTransformRcPtr transform = GetEditableCDLTransform(self); + + std::vector<float> data; + if(!FillFloatVectorFromPySequence(pyData, data) || (data.size() != 9)) + { + PyErr_SetString(PyExc_TypeError, "First argument must be a float array, size 9"); + return 0; + } + + transform->setSOP( &data[0] ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_setSat( PyObject * self, PyObject * args ) + { + try + { + float sat; + if (!PyArg_ParseTuple(args,"f:setSat", &sat)) return NULL; + CDLTransformRcPtr transform = GetEditableCDLTransform(self); + + transform->setSat( sat ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_CDLTransform_getSatLumaCoefs( PyObject * self ) + { + try + { + ConstCDLTransformRcPtr transform = GetConstCDLTransform(self, true); + std::vector<float> data(3); + transform->getSatLumaCoefs(&data[0]); + return CreatePyListFromFloatVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + // + + PyObject * PyOCIO_CDLTransform_getID( PyObject * self ) + { + try + { + ConstCDLTransformRcPtr transform = GetConstCDLTransform(self, true); + return PyString_FromString( transform->getID() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_setID( PyObject * self, PyObject * args ) + { + try + { + const char * str = 0; + if (!PyArg_ParseTuple(args,"s:setID", + &str)) return NULL; + + CDLTransformRcPtr transform = GetEditableCDLTransform(self); + transform->setID( str ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_getDescription( PyObject * self ) + { + try + { + ConstCDLTransformRcPtr transform = GetConstCDLTransform(self, true); + return PyString_FromString( transform->getDescription() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_CDLTransform_setDescription( PyObject * self, PyObject * args ) + { + try + { + const char * str = 0; + if (!PyArg_ParseTuple(args,"s:setDescription", + &str)) return NULL; + + CDLTransformRcPtr transform = GetEditableCDLTransform(self); + transform->setDescription( str ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyColorSpace.cpp b/src/pyglue/PyColorSpace.cpp new file mode 100644 index 0000000..f169ad6 --- /dev/null +++ b/src/pyglue/PyColorSpace.cpp @@ -0,0 +1,756 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyColorSpace.h" +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddColorSpaceObjectToModule( PyObject* m ) + { + PyOCIO_ColorSpaceType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_ColorSpaceType) < 0 ) return false; + + Py_INCREF( &PyOCIO_ColorSpaceType ); + PyModule_AddObject(m, "ColorSpace", + (PyObject *)&PyOCIO_ColorSpaceType); + + return true; + } + + PyObject * BuildConstPyColorSpace(ConstColorSpaceRcPtr colorSpace) + { + if (!colorSpace) + { + Py_RETURN_NONE; + } + + PyOCIO_ColorSpace * pycolorSpace = PyObject_New( + PyOCIO_ColorSpace, (PyTypeObject * ) &PyOCIO_ColorSpaceType); + + pycolorSpace->constcppobj = new ConstColorSpaceRcPtr(); + *pycolorSpace->constcppobj = colorSpace; + + pycolorSpace->cppobj = new ColorSpaceRcPtr(); + pycolorSpace->isconst = true; + + return ( PyObject * ) pycolorSpace; + } + + PyObject * BuildEditablePyColorSpace(ColorSpaceRcPtr colorSpace) + { + if (!colorSpace) + { + Py_RETURN_NONE; + } + + PyOCIO_ColorSpace * pycolorSpace = PyObject_New( + PyOCIO_ColorSpace, (PyTypeObject * ) &PyOCIO_ColorSpaceType); + + pycolorSpace->constcppobj = new ConstColorSpaceRcPtr(); + pycolorSpace->cppobj = new ColorSpaceRcPtr(); + *pycolorSpace->cppobj = colorSpace; + + pycolorSpace->isconst = false; + + return ( PyObject * ) pycolorSpace; + } + + bool IsPyColorSpace(PyObject * pyobject) + { + if(!pyobject) return false; + return (PyObject_Type(pyobject) == (PyObject *) (&PyOCIO_ColorSpaceType)); + } + + bool IsPyColorSpaceEditable(PyObject * pyobject) + { + if(!IsPyColorSpace(pyobject)) + { + throw Exception("PyObject must be an OCIO.ColorSpace."); + } + + PyOCIO_ColorSpace * pycolorSpace = reinterpret_cast<PyOCIO_ColorSpace *> (pyobject); + return (!pycolorSpace->isconst); + } + + ConstColorSpaceRcPtr GetConstColorSpace(PyObject * pyobject, bool allowCast) + { + if(!IsPyColorSpace(pyobject)) + { + throw Exception("PyObject must be an OCIO.ColorSpace."); + } + + PyOCIO_ColorSpace * pycolorspace = reinterpret_cast<PyOCIO_ColorSpace *> (pyobject); + if(pycolorspace->isconst && pycolorspace->constcppobj) + { + return *pycolorspace->constcppobj; + } + + if(allowCast && !pycolorspace->isconst && pycolorspace->cppobj) + { + return *pycolorspace->cppobj; + } + + throw Exception("PyObject must be a valid OCIO.ColorSpace."); + } + + ColorSpaceRcPtr GetEditableColorSpace(PyObject * pyobject) + { + if(!IsPyColorSpace(pyobject)) + { + throw Exception("PyObject must be an OCIO.ColorSpace."); + } + + PyOCIO_ColorSpace * pycolorspace = reinterpret_cast<PyOCIO_ColorSpace *> (pyobject); + if(!pycolorspace->isconst && pycolorspace->cppobj) + { + return *pycolorspace->cppobj; + } + + throw Exception("PyObject must be an editable OCIO.ColorSpace."); + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_ColorSpace_init( PyOCIO_ColorSpace * self, PyObject * args, PyObject * kwds ); + void PyOCIO_ColorSpace_delete( PyOCIO_ColorSpace * self, PyObject * args ); + PyObject * PyOCIO_ColorSpace_isEditable( PyObject * self ); + PyObject * PyOCIO_ColorSpace_createEditableCopy( PyObject * self ); + + PyObject * PyOCIO_ColorSpace_getName( PyObject * self ); + PyObject * PyOCIO_ColorSpace_setName( PyObject * self, PyObject *args ); + PyObject * PyOCIO_ColorSpace_getFamily( PyObject * self ); + PyObject * PyOCIO_ColorSpace_setFamily( PyObject * self, PyObject *args ); + PyObject * PyOCIO_ColorSpace_getEqualityGroup( PyObject * self ); + PyObject * PyOCIO_ColorSpace_setEqualityGroup( PyObject * self, PyObject *args ); + PyObject * PyOCIO_ColorSpace_getDescription( PyObject * self ); + PyObject * PyOCIO_ColorSpace_setDescription( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_ColorSpace_getBitDepth( PyObject * self ); + PyObject * PyOCIO_ColorSpace_setBitDepth( PyObject * self, PyObject *args ); + PyObject * PyOCIO_ColorSpace_isData( PyObject * self ); + PyObject * PyOCIO_ColorSpace_setIsData( PyObject * self, PyObject *args ); + PyObject * PyOCIO_ColorSpace_getAllocation( PyObject * self ); + PyObject * PyOCIO_ColorSpace_setAllocation( PyObject * self, PyObject *args ); + PyObject * PyOCIO_ColorSpace_getAllocationVars( PyObject * self ); + PyObject * PyOCIO_ColorSpace_setAllocationVars( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_ColorSpace_getTransform( PyObject * self, PyObject *args ); + PyObject * PyOCIO_ColorSpace_setTransform( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_ColorSpace_methods[] = { + {"isEditable", + (PyCFunction) PyOCIO_ColorSpace_isEditable, METH_NOARGS, COLORSPACE_ISEDITABLE__DOC__ }, + {"createEditableCopy", + (PyCFunction) PyOCIO_ColorSpace_createEditableCopy, METH_NOARGS, COLORSPACE_CREATEEDITABLECOPY__DOC__ }, + {"getName", + (PyCFunction) PyOCIO_ColorSpace_getName, METH_NOARGS, COLORSPACE_GETNAME__DOC__ }, + {"setName", + PyOCIO_ColorSpace_setName, METH_VARARGS, COLORSPACE_SETNAME__DOC__ }, + {"getFamily", + (PyCFunction) PyOCIO_ColorSpace_getFamily, METH_NOARGS, COLORSPACE_GETFAMILY__DOC__ }, + {"setFamily", + PyOCIO_ColorSpace_setFamily, METH_VARARGS, COLORSPACE_SETFAMILY__DOC__ }, + {"getEqualityGroup", + (PyCFunction) PyOCIO_ColorSpace_getEqualityGroup, METH_NOARGS, COLORSPACE_GETEQUALITYGROUP__DOC__ }, + {"setEqualityGroup", + PyOCIO_ColorSpace_setEqualityGroup, METH_VARARGS, COLORSPACE_SETEQUALITYGROUP__DOC__ }, + {"getDescription", + (PyCFunction) PyOCIO_ColorSpace_getDescription, METH_NOARGS, COLORSPACE_GETDESCRIPTION__DOC__ }, + {"setDescription", + PyOCIO_ColorSpace_setDescription, METH_VARARGS, COLORSPACE_SETDESCRIPTION__DOC__ }, + {"getBitDepth", + (PyCFunction) PyOCIO_ColorSpace_getBitDepth, METH_NOARGS, COLORSPACE_GETBITDEPTH__DOC__ }, + {"setBitDepth", + PyOCIO_ColorSpace_setBitDepth, METH_VARARGS, COLORSPACE_SETBITDEPTH__DOC__ }, + {"isData", + (PyCFunction) PyOCIO_ColorSpace_isData, METH_NOARGS, COLORSPACE_ISDATA__DOC__ }, + {"setIsData", + PyOCIO_ColorSpace_setIsData, METH_VARARGS, COLORSPACE_SETISDATA__DOC__ }, + {"getAllocation", + (PyCFunction) PyOCIO_ColorSpace_getAllocation, METH_NOARGS, COLORSPACE_GETALLOCATION__DOC__ }, + {"setAllocation", + PyOCIO_ColorSpace_setAllocation, METH_VARARGS, COLORSPACE_SETALLOCATION__DOC__ }, + {"getAllocationVars", + (PyCFunction) PyOCIO_ColorSpace_getAllocationVars, METH_NOARGS, COLORSPACE_GETALLOCATIONVARS__DOC__ }, + {"setAllocationVars", + PyOCIO_ColorSpace_setAllocationVars, METH_VARARGS, COLORSPACE_SETALLOCATIONVARS__DOC__ }, + {"getTransform", + PyOCIO_ColorSpace_getTransform, METH_VARARGS, COLORSPACE_GETTRANSFORM__DOC__ }, + {"setTransform", + PyOCIO_ColorSpace_setTransform, METH_VARARGS, COLORSPACE_SETTRANSFORM__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_ColorSpaceType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.ColorSpace", //tp_name + sizeof(PyOCIO_ColorSpace), //tp_basicsize + 0, //tp_itemsize + (destructor)PyOCIO_ColorSpace_delete, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + COLORSPACE__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_ColorSpace_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + 0, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_ColorSpace_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_ColorSpace_init( PyOCIO_ColorSpace *self, PyObject * args, PyObject * kwds ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstColorSpaceRcPtr(); + self->cppobj = new ColorSpaceRcPtr(); + self->isconst = true; + + // Parse optional kwargs + char * name = NULL; + char * family = NULL; + char * equalityGroup = NULL; + char * description = NULL; + char * bitDepth = NULL; + bool isData = false; // TODO: Do not rely on the default value + char * allocation = NULL; + PyObject * allocationVars = NULL; + PyObject * toRefTransform = NULL; + PyObject * fromRefTransform = NULL; + + + const char * toRefStr = + ColorSpaceDirectionToString(COLORSPACE_DIR_TO_REFERENCE); + const char * fromRefStr = + ColorSpaceDirectionToString(COLORSPACE_DIR_FROM_REFERENCE); + const char *kwlist[] = { + "name", "family", "equalityGroup", + "description", "bitDepth", + "isData", + "allocation", "allocationVars", + toRefStr, fromRefStr, + NULL + }; + + if(!PyArg_ParseTupleAndKeywords(args, kwds, "|sssssO&sOOO", + const_cast<char **>(kwlist), + &name, &family, &equalityGroup, &description, &bitDepth, + ConvertPyObjectToBool, &isData, + &allocation, &allocationVars, + &toRefTransform, &fromRefTransform)) return -1; + + try + { + ColorSpaceRcPtr colorSpace = ColorSpace::Create(); + *self->cppobj = colorSpace; + self->isconst = false; + + if(name) colorSpace->setName(name); + if(family) colorSpace->setFamily(family); + if(equalityGroup) colorSpace->setEqualityGroup(equalityGroup); + if(description) colorSpace->setDescription(description); + if(bitDepth) colorSpace->setBitDepth(BitDepthFromString(bitDepth)); + colorSpace->setIsData(isData); // TODO: Do not rely on the default value + if(allocation) colorSpace->setAllocation(AllocationFromString(allocation)); + if(allocationVars) + { + std::vector<float> vars; + if(!FillFloatVectorFromPySequence(allocationVars, vars)) + { + PyErr_SetString(PyExc_TypeError, "allocationVars kwarg must be a float array."); + return -1; + } + colorSpace->setAllocationVars(static_cast<int>(vars.size()), &vars[0]); + } + if(toRefTransform) + { + ConstTransformRcPtr transform = GetConstTransform(toRefTransform, true); + colorSpace->setTransform(transform, COLORSPACE_DIR_TO_REFERENCE); + } + if(fromRefTransform) + { + ConstTransformRcPtr transform = GetConstTransform(fromRefTransform, true); + colorSpace->setTransform(transform, COLORSPACE_DIR_FROM_REFERENCE); + } + + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create colorSpace: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + + void PyOCIO_ColorSpace_delete( PyOCIO_ColorSpace *self, PyObject * /*args*/ ) + { + delete self->constcppobj; + delete self->cppobj; + + self->ob_type->tp_free((PyObject*)self); + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_ColorSpace_isEditable( PyObject * self ) + { + return PyBool_FromLong(IsPyColorSpaceEditable(self)); + } + + PyObject * PyOCIO_ColorSpace_createEditableCopy( PyObject * self ) + { + try + { + ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); + ColorSpaceRcPtr copy = colorSpace->createEditableCopy(); + return BuildEditablePyColorSpace( copy ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_ColorSpace_getName( PyObject * self ) + { + try + { + ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); + return PyString_FromString( colorSpace->getName() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ColorSpace_setName( PyObject * self, PyObject * args ) + { + try + { + char * name = 0; + if (!PyArg_ParseTuple(args,"s:setName", &name)) return NULL; + + ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); + colorSpace->setName( name ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_ColorSpace_getFamily( PyObject * self ) + { + try + { + ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); + return PyString_FromString( colorSpace->getFamily() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ColorSpace_setFamily( PyObject * self, PyObject * args ) + { + try + { + char * name = 0; + if (!PyArg_ParseTuple(args,"s:setFamily", &name)) return NULL; + + ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); + colorSpace->setFamily( name ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_ColorSpace_getEqualityGroup( PyObject * self ) + { + try + { + ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); + return PyString_FromString( colorSpace->getEqualityGroup() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ColorSpace_setEqualityGroup( PyObject * self, PyObject * args ) + { + try + { + char * name = 0; + if (!PyArg_ParseTuple(args,"s:setEqualityGroup", &name)) return NULL; + + ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); + colorSpace->setEqualityGroup( name ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_ColorSpace_getDescription( PyObject * self ) + { + try + { + ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); + return PyString_FromString( colorSpace->getDescription() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ColorSpace_setDescription( PyObject * self, PyObject * args ) + { + try + { + char * name = 0; + if (!PyArg_ParseTuple(args,"s:setDescription", &name)) return NULL; + + ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); + colorSpace->setDescription( name ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_ColorSpace_getBitDepth( PyObject * self ) + { + try + { + ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); + return PyString_FromString( BitDepthToString( colorSpace->getBitDepth()) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ColorSpace_setBitDepth( PyObject * self, PyObject * args ) + { + try + { + char * name = 0; + if (!PyArg_ParseTuple(args,"s:setBitDepth", &name)) return NULL; + + ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); + colorSpace->setBitDepth( BitDepthFromString( name ) ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_ColorSpace_isData( PyObject * self ) + { + try + { + ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); + return PyBool_FromLong( colorSpace->isData() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ColorSpace_setIsData( PyObject * self, PyObject * args ) + { + try + { + bool isData = false; + if (!PyArg_ParseTuple(args,"O&:setIsData", + ConvertPyObjectToBool, &isData)) return NULL; + + ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); + colorSpace->setIsData( isData ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_ColorSpace_getAllocation( PyObject * self ) + { + try + { + ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); + return PyString_FromString( AllocationToString( colorSpace->getAllocation()) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ColorSpace_setAllocation( PyObject * self, PyObject * args ) + { + try + { + Allocation hwalloc; + if (!PyArg_ParseTuple(args,"O&:setAllocation", + ConvertPyObjectToAllocation, &hwalloc)) return NULL; + + ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); + colorSpace->setAllocation( hwalloc ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_ColorSpace_getAllocationVars( PyObject * self ) + { + try + { + ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); + + std::vector<float> allocationvars(colorSpace->getAllocationNumVars()); + if(!allocationvars.empty()) + { + colorSpace->getAllocationVars(&allocationvars[0]); + } + + return CreatePyListFromFloatVector(allocationvars); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ColorSpace_setAllocationVars( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyvars = 0; + if (!PyArg_ParseTuple(args,"O:setAllocationVars", &pyvars)) return NULL; + + std::vector<float> vars; + if(!FillFloatVectorFromPySequence(pyvars, vars)) + { + PyErr_SetString(PyExc_TypeError, "First argument must be a float array."); + return 0; + } + + ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); + if(!vars.empty()) + { + colorSpace->setAllocationVars(static_cast<int>(vars.size()), &vars[0]); + } + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_ColorSpace_getTransform( PyObject * self, PyObject *args ) + { + try + { + ColorSpaceDirection dir; + if (!PyArg_ParseTuple(args,"O&:getTransform", + ConvertPyObjectToColorSpaceDirection, &dir)) return NULL; + + ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); + ConstTransformRcPtr transform = colorSpace->getTransform(dir); + return BuildConstPyTransform(transform); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_ColorSpace_setTransform( PyObject * self, PyObject *args ) + { + + try + { + PyObject * pytransform = 0; + ColorSpaceDirection dir; + if (!PyArg_ParseTuple(args,"OO&:setTransform", &pytransform, + ConvertPyObjectToColorSpaceDirection, &dir)) return NULL; + + ConstTransformRcPtr transform = GetConstTransform(pytransform, true); + ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); + colorSpace->setTransform(transform, dir); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyColorSpace.h b/src/pyglue/PyColorSpace.h new file mode 100644 index 0000000..ae7d7d0 --- /dev/null +++ b/src/pyglue/PyColorSpace.h @@ -0,0 +1,52 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef INCLUDED_PYOCIO_PYCOLORSPACE_H +#define INCLUDED_PYOCIO_PYCOLORSPACE_H + +#include <PyOpenColorIO/PyOpenColorIO.h> + +OCIO_NAMESPACE_ENTER +{ + // TODO: Maybe put this in a pyinternal namespace? + + typedef struct { + PyObject_HEAD + ConstColorSpaceRcPtr * constcppobj; + ColorSpaceRcPtr * cppobj; + bool isconst; + } PyOCIO_ColorSpace; + + extern PyTypeObject PyOCIO_ColorSpaceType; + + bool AddColorSpaceObjectToModule( PyObject* m ); +} +OCIO_NAMESPACE_EXIT + +#endif diff --git a/src/pyglue/PyColorSpaceTransform.cpp b/src/pyglue/PyColorSpaceTransform.cpp new file mode 100644 index 0000000..a4dc0fa --- /dev/null +++ b/src/pyglue/PyColorSpaceTransform.cpp @@ -0,0 +1,294 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddColorSpaceTransformObjectToModule( PyObject* m ) + { + PyOCIO_ColorSpaceTransformType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_ColorSpaceTransformType) < 0 ) return false; + + Py_INCREF( &PyOCIO_ColorSpaceTransformType ); + PyModule_AddObject(m, "ColorSpaceTransform", + (PyObject *)&PyOCIO_ColorSpaceTransformType); + + return true; + } + + bool IsPyColorSpaceTransform(PyObject * pyobject) + { + if(!pyobject) return false; + return PyObject_TypeCheck(pyobject, &PyOCIO_ColorSpaceTransformType); + } + + ConstColorSpaceTransformRcPtr GetConstColorSpaceTransform(PyObject * pyobject, bool allowCast) + { + ConstColorSpaceTransformRcPtr transform = \ + DynamicPtrCast<const ColorSpaceTransform>(GetConstTransform(pyobject, allowCast)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.ColorSpaceTransform."); + } + return transform; + } + + ColorSpaceTransformRcPtr GetEditableColorSpaceTransform(PyObject * pyobject) + { + ColorSpaceTransformRcPtr transform = \ + DynamicPtrCast<ColorSpaceTransform>(GetEditableTransform(pyobject)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.ColorSpaceTransform."); + } + return transform; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_ColorSpaceTransform_init( PyOCIO_Transform * self, PyObject * args, PyObject * kwds ); + + PyObject * PyOCIO_ColorSpaceTransform_getSrc( PyObject * self ); + PyObject * PyOCIO_ColorSpaceTransform_setSrc( PyObject * self, PyObject *args ); + PyObject * PyOCIO_ColorSpaceTransform_getDst( PyObject * self ); + PyObject * PyOCIO_ColorSpaceTransform_setDst( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_ColorSpaceTransform_methods[] = { + {"getSrc", + (PyCFunction) PyOCIO_ColorSpaceTransform_getSrc, METH_NOARGS, COLORSPACETRANSFORM_GETSRC__DOC__ }, + {"setSrc", + PyOCIO_ColorSpaceTransform_setSrc, METH_VARARGS, COLORSPACETRANSFORM_SETSRC__DOC__ }, + {"getDst", + (PyCFunction) PyOCIO_ColorSpaceTransform_getDst, METH_NOARGS, COLORSPACETRANSFORM_GETDST__DOC__ }, + {"setDst", + PyOCIO_ColorSpaceTransform_setDst, METH_VARARGS, COLORSPACETRANSFORM_SETDST__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_ColorSpaceTransformType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.ColorSpaceTransform", //tp_name + sizeof(PyOCIO_Transform), //tp_basicsize + 0, //tp_itemsize + 0, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + COLORSPACETRANSFORM__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_ColorSpaceTransform_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + &PyOCIO_TransformType, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_ColorSpaceTransform_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_ColorSpaceTransform_init( PyOCIO_Transform *self, + PyObject * args, PyObject * kwds ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstTransformRcPtr(); + self->cppobj = new TransformRcPtr(); + self->isconst = true; + + // Parse optional kwargs + char * src = NULL; + char * dst = NULL; + char * direction = NULL; + + static const char *kwlist[] = { + "src", + "dst", + "direction", + NULL + }; + + if(!PyArg_ParseTupleAndKeywords(args, kwds, "|sss", + const_cast<char **>(kwlist), + &src, &dst, &direction )) return -1; + + try + { + ColorSpaceTransformRcPtr transform = ColorSpaceTransform::Create(); + *self->cppobj = transform; + self->isconst = false; + + if(src) transform->setSrc(src); + if(dst) transform->setDst(dst); + if(direction) transform->setDirection(TransformDirectionFromString(direction)); + + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create ColorSpaceTransform: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_ColorSpaceTransform_getSrc( PyObject * self ) + { + try + { + ConstColorSpaceTransformRcPtr transform = GetConstColorSpaceTransform(self, true); + return PyString_FromString( transform->getSrc() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ColorSpaceTransform_setSrc( PyObject * self, PyObject * args ) + { + try + { + const char * str = 0; + if (!PyArg_ParseTuple(args,"s:setSrc", + &str)) return NULL; + + ColorSpaceTransformRcPtr transform = GetEditableColorSpaceTransform(self); + transform->setSrc( str ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ColorSpaceTransform_getDst( PyObject * self ) + { + try + { + ConstColorSpaceTransformRcPtr transform = GetConstColorSpaceTransform(self, true); + return PyString_FromString( transform->getDst() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ColorSpaceTransform_setDst( PyObject * self, PyObject * args ) + { + try + { + const char * str = 0; + if (!PyArg_ParseTuple(args,"s:setDst", + &str)) return NULL; + + ColorSpaceTransformRcPtr transform = GetEditableColorSpaceTransform(self); + transform->setDst( str ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyConfig.cpp b/src/pyglue/PyConfig.cpp new file mode 100644 index 0000000..2c6339d --- /dev/null +++ b/src/pyglue/PyConfig.cpp @@ -0,0 +1,1220 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyColorSpace.h" +#include "PyConfig.h" +#include "PyUtil.h" +#include "PyDoc.h" + +#include <sstream> + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + bool AddConfigObjectToModule( PyObject* m ) + { + PyOCIO_ConfigType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_ConfigType) < 0 ) return false; + + Py_INCREF( &PyOCIO_ConfigType ); + PyModule_AddObject(m, "Config", + (PyObject *)&PyOCIO_ConfigType); + + return true; + } + + PyObject * BuildConstPyConfig(ConstConfigRcPtr config) + { + if (!config.get()) + { + Py_RETURN_NONE; + } + + PyOCIO_Config * pyconfig = PyObject_New( + PyOCIO_Config, (PyTypeObject * ) &PyOCIO_ConfigType); + + pyconfig->constcppobj = new ConstConfigRcPtr(); + *pyconfig->constcppobj = config; + + pyconfig->cppobj = new ConfigRcPtr(); + pyconfig->isconst = true; + + return ( PyObject * ) pyconfig; + } + + PyObject * BuildEditablePyConfig(ConfigRcPtr config) + { + if (!config) + { + Py_RETURN_NONE; + } + + PyOCIO_Config * pyconfig = PyObject_New( + PyOCIO_Config, (PyTypeObject * ) &PyOCIO_ConfigType); + + pyconfig->constcppobj = new ConstConfigRcPtr(); + pyconfig->cppobj = new ConfigRcPtr(); + *pyconfig->cppobj = config; + + pyconfig->isconst = false; + + return ( PyObject * ) pyconfig; + } + + bool IsPyConfig(PyObject * pyobject) + { + if(!pyobject) return false; + return (PyObject_Type(pyobject) == (PyObject *) (&PyOCIO_ConfigType)); + } + + bool IsPyConfigEditable(PyObject * pyobject) + { + if(!IsPyConfig(pyobject)) + { + throw Exception("PyObject must be an OCIO.Config."); + } + + PyOCIO_Config * pyconfig = reinterpret_cast<PyOCIO_Config *> (pyobject); + return (!pyconfig->isconst); + } + + ConstConfigRcPtr GetConstConfig(PyObject * pyobject, bool allowCast) + { + if(!IsPyConfig(pyobject)) + { + throw Exception("PyObject must be an OCIO.Config."); + } + + PyOCIO_Config * pyconfig = reinterpret_cast<PyOCIO_Config *> (pyobject); + if(pyconfig->isconst && pyconfig->constcppobj) + { + return *pyconfig->constcppobj; + } + + if(allowCast && !pyconfig->isconst && pyconfig->cppobj) + { + return *pyconfig->cppobj; + } + + throw Exception("PyObject must be a valid OCIO.Config."); + } + + ConfigRcPtr GetEditableConfig(PyObject * pyobject) + { + if(!IsPyConfig(pyobject)) + { + throw Exception("PyObject must be an OCIO.Config."); + } + + PyOCIO_Config * pyconfig = reinterpret_cast<PyOCIO_Config *> (pyobject); + if(!pyconfig->isconst && pyconfig->cppobj) + { + return *pyconfig->cppobj; + } + + throw Exception("PyObject must be an editable OCIO.Config."); + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + PyObject * PyOCIO_Config_CreateFromEnv( PyObject * cls ); + PyObject * PyOCIO_Config_CreateFromFile( PyObject * cls, PyObject * args ); + + int PyOCIO_Config_init( PyOCIO_Config * self, PyObject * args, PyObject * kwds ); + void PyOCIO_Config_delete( PyOCIO_Config * self, PyObject * args ); + + PyObject * PyOCIO_Config_isEditable( PyObject * self ); + PyObject * PyOCIO_Config_createEditableCopy( PyObject * self ); + + PyObject * PyOCIO_Config_sanityCheck( PyObject * self ); + + PyObject * PyOCIO_Config_getDescription( PyObject * self ); + PyObject * PyOCIO_Config_setDescription( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_Config_serialize( PyObject * self ); + PyObject * PyOCIO_Config_getCacheID( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_Config_getCurrentContext( PyObject * self ); + + PyObject * PyOCIO_Config_getSearchPath( PyObject * self ); + PyObject * PyOCIO_Config_setSearchPath( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_Config_getWorkingDir( PyObject * self ); + PyObject * PyOCIO_Config_setWorkingDir( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_Config_getColorSpaces( PyObject * self ); + PyObject * PyOCIO_Config_getColorSpace( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Config_addColorSpace( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Config_clearColorSpaces( PyObject * self ); + PyObject * PyOCIO_Config_parseColorSpaceFromString( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Config_setRole( PyObject * self, PyObject * args ); + + PyObject * PyOCIO_Config_getDefaultDisplay( PyObject * self ); + PyObject * PyOCIO_Config_getDisplays( PyObject * self ); + PyObject * PyOCIO_Config_getDefaultView( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Config_getViews( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Config_getDisplayColorSpaceName( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Config_getDisplayLooks( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Config_addDisplay( PyObject * self, PyObject * args, PyObject * kwargs ); + PyObject * PyOCIO_Config_clearDisplays( PyObject * self ); + PyObject * PyOCIO_Config_setActiveDisplays( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Config_getActiveDisplays( PyObject * self ); + PyObject * PyOCIO_Config_setActiveViews( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Config_getActiveViews( PyObject * self ); + + PyObject * PyOCIO_Config_getDefaultLumaCoefs( PyObject * self ); + PyObject * PyOCIO_Config_setDefaultLumaCoefs( PyObject * self, PyObject * args ); + + PyObject * PyOCIO_Config_getLook( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Config_getLooks( PyObject * self ); + PyObject * PyOCIO_Config_addLook( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Config_clearLooks( PyObject * self ); + + PyObject * PyOCIO_Config_getProcessor( PyObject * self, PyObject * args, PyObject * kwargs ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_Config_methods[] = { + {"CreateFromEnv", + (PyCFunction) PyOCIO_Config_CreateFromEnv, METH_NOARGS | METH_CLASS, CONFIG_CREATEFROMENV__DOC__ }, + {"CreateFromFile", + PyOCIO_Config_CreateFromFile, METH_VARARGS | METH_CLASS, CONFIG_CREATEFROMFILE__DOC__ }, + {"isEditable", + (PyCFunction) PyOCIO_Config_isEditable, METH_NOARGS, CONFIG_ISEDITABLE__DOC__ }, + {"createEditableCopy", + (PyCFunction) PyOCIO_Config_createEditableCopy, METH_NOARGS, CONFIG_CREATEEDITABLECOPY__DOC__ }, + {"sanityCheck", + (PyCFunction) PyOCIO_Config_sanityCheck, METH_NOARGS, CONFIG_SANITYCHECK__DOC__ }, + {"getDescription", + (PyCFunction) PyOCIO_Config_getDescription, METH_NOARGS, CONFIG_GETDESCRIPTION__DOC__ }, + {"setDescription", + PyOCIO_Config_setDescription, METH_VARARGS, CONFIG_SETDESCRIPTION__DOC__ }, + {"serialize", + (PyCFunction) PyOCIO_Config_serialize, METH_NOARGS, CONFIG_SERIALIZE__DOC__ }, + {"getCacheID", + PyOCIO_Config_getCacheID, METH_VARARGS, CONFIG_GETCACHEID__DOC__ }, + {"getCurrentContext", + (PyCFunction) PyOCIO_Config_getCurrentContext, METH_NOARGS, CONFIG_GETCURRENTCONTEXT__DOC__ }, + {"getSearchPath", + (PyCFunction) PyOCIO_Config_getSearchPath, METH_NOARGS, CONFIG_GETSEARCHPATH__DOC__ }, + {"setSearchPath", + PyOCIO_Config_setSearchPath, METH_VARARGS, CONFIG_SETSEARCHPATH__DOC__ }, + {"getWorkingDir", + (PyCFunction) PyOCIO_Config_getWorkingDir, METH_NOARGS, CONFIG_GETWORKINGDIR__DOC__ }, + {"setWorkingDir", + PyOCIO_Config_setWorkingDir, METH_VARARGS, CONFIG_SETWORKINGDIR__DOC__ }, + {"getColorSpaces", + (PyCFunction) PyOCIO_Config_getColorSpaces, METH_NOARGS, CONFIG_GETCOLORSPACES__DOC__ }, + {"getColorSpace", + PyOCIO_Config_getColorSpace, METH_VARARGS, CONFIG_GETCOLORSPACE__DOC__ }, + {"addColorSpace", + PyOCIO_Config_addColorSpace, METH_VARARGS, CONFIG_ADDCOLORSPACE__DOC__ }, + {"clearColorSpaces", + (PyCFunction) PyOCIO_Config_clearColorSpaces, METH_NOARGS, CONFIG_CLEARCOLORSPACES__DOC__ }, + {"parseColorSpaceFromString", + PyOCIO_Config_parseColorSpaceFromString, METH_VARARGS, CONFIG_PARSECOLORSPACEFROMSTRING__DOC__ }, + {"setRole", + PyOCIO_Config_setRole, METH_VARARGS, CONFIG_SETROLE__DOC__ }, + {"getDefaultDisplay", + (PyCFunction) PyOCIO_Config_getDefaultDisplay, METH_NOARGS, CONFIG_GETDEFAULTDISPLAY__DOC__ }, + {"getDisplays", + (PyCFunction) PyOCIO_Config_getDisplays, METH_NOARGS, CONFIG_GETDISPLAYS__DOC__ }, + {"getDefaultView", + PyOCIO_Config_getDefaultView, METH_VARARGS, CONFIG_GETDEFAULTVIEW__DOC__ }, + {"getViews", + PyOCIO_Config_getViews, METH_VARARGS, CONFIG_GETVIEWS__DOC__ }, + {"getDisplayColorSpaceName", + PyOCIO_Config_getDisplayColorSpaceName, METH_VARARGS, CONFIG_GETDISPLAYCOLORSPACENAME__DOC__ }, + {"getDisplayLooks", + PyOCIO_Config_getDisplayLooks, METH_VARARGS, CONFIG_GETDISPLAYLOOKS__DOC__ }, + {"addDisplay", + (PyCFunction) PyOCIO_Config_addDisplay, METH_KEYWORDS, CONFIG_ADDDISPLAY__DOC__ }, + {"clearDisplays", + (PyCFunction) PyOCIO_Config_clearDisplays, METH_NOARGS, CONFIG_CLEARDISPLAYS__DOC__ }, + {"setActiveDisplays", + PyOCIO_Config_setActiveDisplays, METH_VARARGS, CONFIG_SETACTIVEDISPLAYS__DOC__ }, + {"getActiveDisplays", + (PyCFunction) PyOCIO_Config_getActiveDisplays, METH_NOARGS, CONFIG_GETACTIVEDISPLAYS__DOC__ }, + {"setActiveViews", + PyOCIO_Config_setActiveViews, METH_VARARGS, CONFIG_SETACTIVEVIEWS__DOC__ }, + {"getActiveViews", + (PyCFunction) PyOCIO_Config_getActiveViews, METH_NOARGS, CONFIG_GETACTIVEVIEWS__DOC__ }, + {"getDefaultLumaCoefs", + (PyCFunction) PyOCIO_Config_getDefaultLumaCoefs, METH_NOARGS, CONFIG_GETDEFAULTLUMACOEFS__DOC__ }, + {"setDefaultLumaCoefs", + PyOCIO_Config_setDefaultLumaCoefs, METH_VARARGS, CONFIG_SETDEFAULTLUMACOEFS__DOC__ }, + {"getLook", + PyOCIO_Config_getLook, METH_VARARGS, CONFIG_GETLOOK__DOC__ }, + {"getLooks", + (PyCFunction) PyOCIO_Config_getLooks, METH_NOARGS, CONFIG_GETLOOKS__DOC__ }, + {"addLook", + PyOCIO_Config_addLook, METH_VARARGS, CONFIG_ADDLOOK__DOC__ }, + {"clearLook", // THIS SHOULD BE REMOVED IN THE NEXT BINARY INCOMPATIBLE VERSION + (PyCFunction) PyOCIO_Config_clearLooks, METH_NOARGS, CONFIG_CLEARLOOKS__DOC__ }, + {"clearLooks", + (PyCFunction) PyOCIO_Config_clearLooks, METH_NOARGS, CONFIG_CLEARLOOKS__DOC__ }, + {"getProcessor", + (PyCFunction) PyOCIO_Config_getProcessor, METH_KEYWORDS, CONFIG_GETPROCESSOR__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_ConfigType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.Config", //tp_name + sizeof(PyOCIO_Config), //tp_basicsize + 0, //tp_itemsize + (destructor)PyOCIO_Config_delete, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + CONFIG__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_Config_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + 0, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_Config_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// static methods + + namespace + { + PyObject * PyOCIO_Config_CreateFromEnv( PyObject * /*cls*/ ) + { + try + { + return BuildConstPyConfig( Config::CreateFromEnv() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_CreateFromFile( PyObject * /*cls*/, PyObject * args ) + { + try + { + char * filename = 0; + if (!PyArg_ParseTuple(args,"s:CreateFromFile", &filename)) return NULL; + + return BuildConstPyConfig( Config::CreateFromFile(filename) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + + /////////////////////////////////////////////////////////////////////// + // Insert class markup here + int PyOCIO_Config_init( PyOCIO_Config *self, PyObject * /*args*/, PyObject * /*kwds*/ ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + self->constcppobj = new ConstConfigRcPtr(); + self->cppobj = new ConfigRcPtr(); + self->isconst = true; + + try + { + *self->cppobj = Config::Create(); + self->isconst = false; + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create config: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + void PyOCIO_Config_delete( PyOCIO_Config *self, PyObject * /*args*/ ) + { + delete self->constcppobj; + delete self->cppobj; + + self->ob_type->tp_free((PyObject*)self); + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Config_isEditable( PyObject * self ) + { + return PyBool_FromLong(IsPyConfigEditable(self)); + } + + PyObject * PyOCIO_Config_createEditableCopy( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + ConfigRcPtr copy = config->createEditableCopy(); + return BuildEditablePyConfig( copy ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_sanityCheck( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + config->sanityCheck(); + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Config_getDescription( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + return PyString_FromString( config->getDescription() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_setDescription( PyObject * self, PyObject * args ) + { + try + { + char * desc = 0; + if (!PyArg_ParseTuple(args,"s:setDescription", &desc)) return NULL; + + ConfigRcPtr config = GetEditableConfig(self); + config->setDescription( desc ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_serialize( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + + std::ostringstream os; + + config->serialize(os); + + return PyString_FromString( os.str().c_str() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + + } + + PyObject * PyOCIO_Config_getCacheID( PyObject * self, PyObject * args ) + { + try + { PyObject * pycontext = NULL; + if (!PyArg_ParseTuple(args,"|O:getCacheID", &pycontext)) return NULL; + + ConstConfigRcPtr config = GetConstConfig(self, true); + + // Parse the context + ConstContextRcPtr context; + if(pycontext != NULL) + { + context = GetConstContext(pycontext, true); + } + else + { + context = config->getCurrentContext(); + } + + return PyString_FromString( config->getCacheID(context) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getCurrentContext( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + + return BuildConstPyContext(config->getCurrentContext()); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getSearchPath( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + return PyString_FromString( config->getSearchPath() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_setSearchPath( PyObject * self, PyObject * args ) + { + try + { + char * path = 0; + if (!PyArg_ParseTuple(args,"s:setSearchPath", &path)) return NULL; + + ConfigRcPtr config = GetEditableConfig(self); + config->setSearchPath( path ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getWorkingDir( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + return PyString_FromString( config->getWorkingDir() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_setWorkingDir( PyObject * self, PyObject * args ) + { + try + { + char * path = 0; + if (!PyArg_ParseTuple(args,"s:setWorkingDir", &path)) return NULL; + + ConfigRcPtr config = GetEditableConfig(self); + config->setWorkingDir( path ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getColorSpaces( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + int numColorSpaces = config->getNumColorSpaces(); + + PyObject* tuple = PyTuple_New( numColorSpaces ); + for(int i = 0; i<numColorSpaces; ++i) + { + const char * name = config->getColorSpaceNameByIndex(i); + ConstColorSpaceRcPtr cs = config->getColorSpace(name); + PyObject * pycs = BuildConstPyColorSpace(cs); + PyTuple_SetItem(tuple, i, pycs); + } + + return tuple; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getColorSpace( PyObject * self, PyObject * args ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + + char * name = 0; + if (!PyArg_ParseTuple(args,"s:getColorSpace", &name)) return NULL; + + return BuildConstPyColorSpace(config->getColorSpace(name)); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Config_addColorSpace( PyObject * self, PyObject * args ) + { + try + { + ConfigRcPtr config = GetEditableConfig(self); + + PyObject * pyColorSpace = 0; + if (!PyArg_ParseTuple(args,"O:addColorSpace", &pyColorSpace)) return NULL; + + config->addColorSpace( GetConstColorSpace(pyColorSpace, true) ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_clearColorSpaces( PyObject * self ) + { + try + { + ConfigRcPtr config = GetEditableConfig(self); + config->clearColorSpaces(); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_parseColorSpaceFromString( PyObject * self, PyObject * args ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + + char * str = 0; + + if (!PyArg_ParseTuple(args,"s:parseColorSpaceFromString", + &str)) return NULL; + + const char * cs = config->parseColorSpaceFromString(str); + if(cs) + { + return PyString_FromString( cs ); + } + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_setRole( PyObject * self, PyObject * args ) + { + try + { + ConfigRcPtr config = GetEditableConfig(self); + + char * role = 0; + char * csname = 0; + + if (!PyArg_ParseTuple(args,"ss:setRole", + &role, &csname)) return NULL; + + config->setRole(role, csname); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Config_getDefaultDisplay( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + return PyString_FromString( config->getDefaultDisplay() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getDisplays( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + + std::vector<std::string> data; + int numDevices = config->getNumDisplays(); + + for(int i=0; i<numDevices; ++i) + { + data.push_back( config->getDisplay(i) ); + } + + return CreatePyListFromStringVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getDefaultView( PyObject * self, PyObject * args ) + { + try + { + char * display = 0; + if (!PyArg_ParseTuple(args,"s:getDefaultView", + &display)) return NULL; + + ConstConfigRcPtr config = GetConstConfig(self, true); + return PyString_FromString( config->getDefaultView(display) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getViews( PyObject * self, PyObject * args ) + { + try + { + char * display = 0; + if (!PyArg_ParseTuple(args,"s:getViews", + &display)) return NULL; + + ConstConfigRcPtr config = GetConstConfig(self, true); + std::vector<std::string> data; + int num = config->getNumViews(display); + for(int i=0; i<num; ++i) + { + data.push_back( config->getView(display, i) ); + } + + return CreatePyListFromStringVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getDisplayColorSpaceName( PyObject * self, PyObject * args ) + { + try + { + char * display = 0; + char * view = 0; + if (!PyArg_ParseTuple(args,"ss:getDisplayColorSpaceName", + &display, &view)) return NULL; + + ConstConfigRcPtr config = GetConstConfig(self, true); + return PyString_FromString( config->getDisplayColorSpaceName(display, view) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getDisplayLooks( PyObject * self, PyObject * args ) + { + try + { + char * display = 0; + char * view = 0; + if (!PyArg_ParseTuple(args,"ss:getDisplayLooks", + &display, &view)) return NULL; + + ConstConfigRcPtr config = GetConstConfig(self, true); + return PyString_FromString( config->getDisplayLooks(display, view) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_addDisplay( PyObject * self, PyObject * args, PyObject * kwargs) + { + try + { + ConfigRcPtr config = GetEditableConfig(self); + + char * display = 0; + char * view = 0; + char * colorSpaceName = 0; + char * looks = 0; + + const char * kwlist[] = {"display", "view", "colorSpaceName", "looks", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sss|s", + const_cast<char**>(kwlist), + &display, &view, &colorSpaceName, &looks)) + return 0; + + std::string lookStr; + if(looks) lookStr = looks; + + config->addDisplay(display, view, colorSpaceName, lookStr.c_str()); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_clearDisplays( PyObject * self ) + { + try + { + ConfigRcPtr config = GetEditableConfig(self); + config->clearDisplays(); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_setActiveDisplays( PyObject * self, PyObject * args ) + { + try + { + ConfigRcPtr config = GetEditableConfig(self); + + char * displays = 0; + + if (!PyArg_ParseTuple(args,"s:setActiveDisplays", + &displays)) return NULL; + + config->setActiveDisplays(displays); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getActiveDisplays( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + return PyString_FromString( config->getActiveDisplays() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_setActiveViews( PyObject * self, PyObject * args ) + { + try + { + ConfigRcPtr config = GetEditableConfig(self); + + char * views = 0; + + if (!PyArg_ParseTuple(args,"s:setActiveViews", + &views)) return NULL; + + config->setActiveViews(views); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getActiveViews( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + return PyString_FromString( config->getActiveViews() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Config_setDefaultLumaCoefs( PyObject * self, PyObject * args ) + { + try + { + ConfigRcPtr config = GetEditableConfig(self); + + PyObject* pyCoef = 0; + if (!PyArg_ParseTuple(args, "O:setDefaultLumaCoefs", &pyCoef)) + { + return 0; + } + + std::vector<float> coef; + if(!FillFloatVectorFromPySequence(pyCoef, coef) || (coef.size() != 3)) + { + PyErr_SetString(PyExc_TypeError, "First argument must be a float array, size 3"); + return 0; + } + + config->setDefaultLumaCoefs(&coef[0]); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getDefaultLumaCoefs( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + + std::vector<float> coef(3); + config->getDefaultLumaCoefs(&coef[0]); + + return CreatePyListFromFloatVector(coef); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Config_getLook( PyObject * self, PyObject * args ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + + char * str = 0; + if (!PyArg_ParseTuple(args,"s:getLook", + &str)) return NULL; + + return BuildConstPyLook(config->getLook(str)); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_getLooks( PyObject * self ) + { + try + { + ConstConfigRcPtr config = GetConstConfig(self, true); + int num = config->getNumLooks(); + + PyObject* tuple = PyTuple_New( num ); + for(int i = 0; i<num; ++i) + { + const char * name = config->getLookNameByIndex(i); + ConstLookRcPtr look = config->getLook(name); + PyObject * pylook = BuildConstPyLook(look); + PyTuple_SetItem(tuple, i, pylook); + } + + return tuple; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_addLook( PyObject * self, PyObject * args ) + { + try + { + ConfigRcPtr config = GetEditableConfig(self); + + PyObject * pyLook = 0; + if (!PyArg_ParseTuple(args,"O:addLook", &pyLook)) return NULL; + + config->addLook( GetConstLook(pyLook, true) ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Config_clearLooks( PyObject * self ) + { + try + { + ConfigRcPtr config = GetEditableConfig(self); + config->clearLooks(); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Config_getProcessor( PyObject * self, PyObject * args, PyObject * kwargs) + { + try + { + // We want this call to be as flexible as possible. + // arg1 will either be a PyTransform + // or arg1, arg2 will be {str, ColorSpace} + + PyObject * arg1 = Py_None; + PyObject * arg2 = Py_None; + + const char * direction = 0; + PyObject * pycontext = Py_None; + + const char * kwlist[] = {"arg1", "arg2", "direction", "context", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OsO", + const_cast<char**>(kwlist), + &arg1, &arg2, &direction, &pycontext)) + return 0; + + ConstConfigRcPtr config = GetConstConfig(self, true); + + // Parse the direction string + TransformDirection dir = TRANSFORM_DIR_FORWARD; + if(direction) dir = TransformDirectionFromString( direction ); + + // Parse the context + ConstContextRcPtr context; + if(pycontext != Py_None) context = GetConstContext(pycontext, true); + if(!context) context = config->getCurrentContext(); + + if(IsPyTransform(arg1)) + { + ConstTransformRcPtr transform = GetConstTransform(arg1, true); + return BuildConstPyProcessor(config->getProcessor(context, transform, dir)); + } + + // Any two (Colorspaces, colorspace name, roles) + ConstColorSpaceRcPtr cs1, cs2; + + if(IsPyColorSpace(arg1)) + { + cs1 = GetConstColorSpace(arg1, true); + } + else if(PyString_Check(arg1)) + { + cs1 = config->getColorSpace(PyString_AsString(arg1)); + } + if(!cs1) + { + PyErr_SetString(PyExc_ValueError, + "Could not parse first arg. Allowed types include ColorSpace, ColorSpace name, Role."); + return NULL; + } + + if(IsPyColorSpace(arg2)) + { + cs2 = GetConstColorSpace(arg2, true); + } + else if(PyString_Check(arg2)) + { + cs2 = config->getColorSpace(PyString_AsString(arg2)); + } + if(!cs2) + { + PyErr_SetString(PyExc_ValueError, + "Could not parse second arg. Allowed types include ColorSpace, ColorSpace name, Role."); + return NULL; + } + + return BuildConstPyProcessor(config->getProcessor(context, cs1, cs2)); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyConfig.h b/src/pyglue/PyConfig.h new file mode 100644 index 0000000..05ba954 --- /dev/null +++ b/src/pyglue/PyConfig.h @@ -0,0 +1,52 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef INCLUDED_PYOCIO_PYCONFIG_H +#define INCLUDED_PYOCIO_PYCONFIG_H + +#include <PyOpenColorIO/PyOpenColorIO.h> + +OCIO_NAMESPACE_ENTER +{ + // TODO: Maybe put this in a pyinternal namespace? + + typedef struct { + PyObject_HEAD + ConstConfigRcPtr * constcppobj; + ConfigRcPtr * cppobj; + bool isconst; + } PyOCIO_Config; + + extern PyTypeObject PyOCIO_ConfigType; + + bool AddConfigObjectToModule( PyObject* m ); +} +OCIO_NAMESPACE_EXIT + +#endif diff --git a/src/pyglue/PyConstants.cpp b/src/pyglue/PyConstants.cpp new file mode 100644 index 0000000..ff004bf --- /dev/null +++ b/src/pyglue/PyConstants.cpp @@ -0,0 +1,239 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyColorSpace.h" +#include "PyConstants.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + + namespace + { + PyObject * PyOCIO_Constants_GetInverseTransformDirection( PyObject * self, PyObject *args ); + PyObject * PyOCIO_Constants_CombineTransformDirections( PyObject * self, PyObject *args ); + PyObject * PyOCIO_Constants_BitDepthIsFloat( PyObject * self, PyObject *args ); + PyObject * PyOCIO_Constants_BitDepthToInt( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef LocalModuleMethods[] = { + {"GetInverseTransformDirection", + PyOCIO_Constants_GetInverseTransformDirection, METH_VARARGS, CONSTANTS_GETINVERSETRANSFORMDIRECTION__DOC__ }, + {"CombineTransformDirections", + PyOCIO_Constants_CombineTransformDirections, METH_VARARGS, CONSTANTS_COMBINETRANSFORMDIRECTIONS__DOC__ }, + {"BitDepthIsFloat", + PyOCIO_Constants_BitDepthIsFloat, METH_VARARGS, CONSTANTS_BITDEPTHISFLOAT__DOC__ }, + {"BitDepthToInt", + PyOCIO_Constants_BitDepthToInt, METH_VARARGS, CONSTANTS_BITDEPTHTOINT__DOC__ }, + {NULL, NULL, 0, NULL} /* Sentinel */ + }; + + } + + void AddConstantsModule(PyObject *enclosingModule) + { + // Add sub-module + std::string moduleName = PyModule_GetName(enclosingModule); + moduleName += ".Constants"; + + PyObject * m = Py_InitModule3(const_cast<char*>(moduleName.c_str()), + LocalModuleMethods, CONSTANTS__DOC__); + Py_INCREF(m); + + // Add Module Constants + PyModule_AddStringConstant(m, "LOGGING_LEVEL_NONE", + const_cast<char*>(LoggingLevelToString(LOGGING_LEVEL_NONE))); + PyModule_AddStringConstant(m, "LOGGING_LEVEL_WARNING", + const_cast<char*>(LoggingLevelToString(LOGGING_LEVEL_WARNING))); + PyModule_AddStringConstant(m, "LOGGING_LEVEL_INFO", + const_cast<char*>(LoggingLevelToString(LOGGING_LEVEL_INFO))); + PyModule_AddStringConstant(m, "LOGGING_LEVEL_UNKNOWN", + const_cast<char*>(LoggingLevelToString(LOGGING_LEVEL_UNKNOWN))); + + PyModule_AddStringConstant(m, "TRANSFORM_DIR_UNKNOWN", + const_cast<char*>(TransformDirectionToString(TRANSFORM_DIR_UNKNOWN))); + PyModule_AddStringConstant(m, "TRANSFORM_DIR_FORWARD", + const_cast<char*>(TransformDirectionToString(TRANSFORM_DIR_FORWARD))); + PyModule_AddStringConstant(m, "TRANSFORM_DIR_INVERSE", + const_cast<char*>(TransformDirectionToString(TRANSFORM_DIR_INVERSE))); + + PyModule_AddStringConstant(m, "COLORSPACE_DIR_UNKNOWN", + const_cast<char*>(ColorSpaceDirectionToString(COLORSPACE_DIR_UNKNOWN))); + PyModule_AddStringConstant(m, "COLORSPACE_DIR_TO_REFERENCE", + const_cast<char*>(ColorSpaceDirectionToString(COLORSPACE_DIR_TO_REFERENCE))); + PyModule_AddStringConstant(m, "COLORSPACE_DIR_FROM_REFERENCE", + const_cast<char*>(ColorSpaceDirectionToString(COLORSPACE_DIR_FROM_REFERENCE))); + + PyModule_AddStringConstant(m, "BIT_DEPTH_UNKNOWN", + const_cast<char*>(BitDepthToString(BIT_DEPTH_UNKNOWN))); + PyModule_AddStringConstant(m, "BIT_DEPTH_UINT8", + const_cast<char*>(BitDepthToString(BIT_DEPTH_UINT8))); + PyModule_AddStringConstant(m, "BIT_DEPTH_UINT10", + const_cast<char*>(BitDepthToString(BIT_DEPTH_UINT10))); + PyModule_AddStringConstant(m, "BIT_DEPTH_UINT12", + const_cast<char*>(BitDepthToString(BIT_DEPTH_UINT12))); + PyModule_AddStringConstant(m, "BIT_DEPTH_UINT14", + const_cast<char*>(BitDepthToString(BIT_DEPTH_UINT14))); + PyModule_AddStringConstant(m, "BIT_DEPTH_UINT16", + const_cast<char*>(BitDepthToString(BIT_DEPTH_UINT16))); + PyModule_AddStringConstant(m, "BIT_DEPTH_UINT32", + const_cast<char*>(BitDepthToString(BIT_DEPTH_UINT32))); + PyModule_AddStringConstant(m, "BIT_DEPTH_F16", + const_cast<char*>(BitDepthToString(BIT_DEPTH_F16))); + PyModule_AddStringConstant(m, "BIT_DEPTH_F32", + const_cast<char*>(BitDepthToString(BIT_DEPTH_F32))); + + PyModule_AddStringConstant(m, "ALLOCATION_UNKNOWN", + const_cast<char*>(AllocationToString(ALLOCATION_UNKNOWN))); + PyModule_AddStringConstant(m, "ALLOCATION_UNIFORM", + const_cast<char*>(AllocationToString(ALLOCATION_UNIFORM))); + PyModule_AddStringConstant(m, "ALLOCATION_LG2", + const_cast<char*>(AllocationToString(ALLOCATION_LG2))); + + PyModule_AddStringConstant(m, "INTERP_UNKNOWN", + const_cast<char*>(InterpolationToString(INTERP_UNKNOWN))); + PyModule_AddStringConstant(m, "INTERP_NEAREST", + const_cast<char*>(InterpolationToString(INTERP_NEAREST))); + PyModule_AddStringConstant(m, "INTERP_LINEAR", + const_cast<char*>(InterpolationToString(INTERP_LINEAR))); + PyModule_AddStringConstant(m, "INTERP_TETRAHEDRAL", + const_cast<char*>(InterpolationToString(INTERP_TETRAHEDRAL))); + PyModule_AddStringConstant(m, "INTERP_BEST", + const_cast<char*>(InterpolationToString(INTERP_BEST))); + + PyModule_AddStringConstant(m, "GPU_LANGUAGE_UNKNOWN", + const_cast<char*>(GpuLanguageToString(GPU_LANGUAGE_UNKNOWN))); + PyModule_AddStringConstant(m, "GPU_LANGUAGE_CG", + const_cast<char*>(GpuLanguageToString(GPU_LANGUAGE_CG))); + PyModule_AddStringConstant(m, "GPU_LANGUAGE_GLSL_1_0", + const_cast<char*>(GpuLanguageToString(GPU_LANGUAGE_GLSL_1_0))); + PyModule_AddStringConstant(m, "GPU_LANGUAGE_GLSL_1_3", + const_cast<char*>(GpuLanguageToString(GPU_LANGUAGE_GLSL_1_3))); + + PyModule_AddStringConstant(m, "ROLE_DEFAULT", const_cast<char*>(ROLE_DEFAULT)); + PyModule_AddStringConstant(m, "ROLE_REFERENCE", const_cast<char*>(ROLE_REFERENCE)); + PyModule_AddStringConstant(m, "ROLE_DATA", const_cast<char*>(ROLE_DATA)); + PyModule_AddStringConstant(m, "ROLE_COLOR_PICKING", const_cast<char*>(ROLE_COLOR_PICKING)); + PyModule_AddStringConstant(m, "ROLE_SCENE_LINEAR", const_cast<char*>(ROLE_SCENE_LINEAR)); + PyModule_AddStringConstant(m, "ROLE_COMPOSITING_LOG", const_cast<char*>(ROLE_COMPOSITING_LOG)); + PyModule_AddStringConstant(m, "ROLE_COLOR_TIMING", const_cast<char*>(ROLE_COLOR_TIMING)); + PyModule_AddStringConstant(m, "ROLE_TEXTURE_PAINT", const_cast<char*>(ROLE_TEXTURE_PAINT)); + PyModule_AddStringConstant(m, "ROLE_MATTE_PAINT", const_cast<char*>(ROLE_MATTE_PAINT)); + + // Add the module + PyModule_AddObject(enclosingModule, "Constants", m); + } + + + namespace + { + + PyObject * PyOCIO_Constants_GetInverseTransformDirection( PyObject * /*module*/, PyObject * args ) + { + try + { + char * s = 0; + if (!PyArg_ParseTuple(args,"s:GetInverseTransformDirection", s)) return NULL; + + TransformDirection dir = TransformDirectionFromString(s); + dir = GetInverseTransformDirection(dir); + return PyString_FromString( TransformDirectionToString(dir) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Constants_CombineTransformDirections( PyObject * /*module*/, PyObject * args ) + { + try + { + char * s1 = 0; + char * s2 = 0; + if (!PyArg_ParseTuple(args,"ss:CombineTransformDirections", &s1, &s2)) return NULL; + + TransformDirection dir1 = TransformDirectionFromString(s1); + TransformDirection dir2 = TransformDirectionFromString(s2); + + TransformDirection dir = CombineTransformDirections(dir1, dir2); + return PyString_FromString( TransformDirectionToString(dir) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Constants_BitDepthIsFloat( PyObject * /*module*/, PyObject * args ) + { + try + { + char * s = 0; + if (!PyArg_ParseTuple(args,"s:BitDepthIsFloat", &s)) return NULL; + + BitDepth bitdepth = BitDepthFromString(s); + return PyBool_FromLong( BitDepthIsFloat(bitdepth) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Constants_BitDepthToInt( PyObject * /*module*/, PyObject * args ) + { + try + { + char * s = 0; + if (!PyArg_ParseTuple(args,"s:BitDepthToInt", &s)) return NULL; + + BitDepth bitdepth = BitDepthFromString(s); + return PyInt_FromLong( BitDepthToInt(bitdepth) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyConstants.h b/src/pyglue/PyConstants.h new file mode 100644 index 0000000..28b1797 --- /dev/null +++ b/src/pyglue/PyConstants.h @@ -0,0 +1,41 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef INCLUDED_PYOCIO_PYCONSTANTS_H +#define INCLUDED_PYOCIO_PYCONSTANTS_H + +#include <PyOpenColorIO/PyOpenColorIO.h> + +OCIO_NAMESPACE_ENTER +{ + void AddConstantsModule(PyObject *enclosingModule); +} +OCIO_NAMESPACE_EXIT + +#endif diff --git a/src/pyglue/PyContext.cpp b/src/pyglue/PyContext.cpp new file mode 100644 index 0000000..6a97aad --- /dev/null +++ b/src/pyglue/PyContext.cpp @@ -0,0 +1,494 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyContext.h" +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddContextObjectToModule( PyObject* m ) + { + PyOCIO_ContextType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_ContextType) < 0 ) return false; + + Py_INCREF( &PyOCIO_ContextType ); + PyModule_AddObject(m, "Context", + (PyObject *)&PyOCIO_ContextType); + + return true; + } + + PyObject * BuildConstPyContext(ConstContextRcPtr context) + { + if (!context) + { + Py_RETURN_NONE; + } + + PyOCIO_Context * pycontext = PyObject_New( + PyOCIO_Context, (PyTypeObject * ) &PyOCIO_ContextType); + + pycontext->constcppobj = new ConstContextRcPtr(); + *pycontext->constcppobj = context; + + pycontext->cppobj = new ContextRcPtr(); + pycontext->isconst = true; + + return ( PyObject * ) pycontext; + } + + PyObject * BuildEditablePyContext(ContextRcPtr context) + { + if (!context) + { + Py_RETURN_NONE; + } + + PyOCIO_Context * pycontext = PyObject_New( + PyOCIO_Context, (PyTypeObject * ) &PyOCIO_ContextType); + + pycontext->constcppobj = new ConstContextRcPtr(); + pycontext->cppobj = new ContextRcPtr(); + *pycontext->cppobj = context; + + pycontext->isconst = false; + + return ( PyObject * ) pycontext; + } + + bool IsPyContext(PyObject * pyobject) + { + if(!pyobject) return false; + return (PyObject_Type(pyobject) == (PyObject *) (&PyOCIO_ContextType)); + } + + bool IsPyContextEditable(PyObject * pyobject) + { + if(!IsPyContext(pyobject)) + { + throw Exception("PyObject must be an OCIO.Context."); + } + + PyOCIO_Context * pycontext = reinterpret_cast<PyOCIO_Context *> (pyobject); + return (!pycontext->isconst); + } + + ConstContextRcPtr GetConstContext(PyObject * pyobject, bool allowCast) + { + if(!IsPyContext(pyobject)) + { + throw Exception("PyObject must be an OCIO.Context."); + } + + PyOCIO_Context * pycontext = reinterpret_cast<PyOCIO_Context *> (pyobject); + if(pycontext->isconst && pycontext->constcppobj) + { + return *pycontext->constcppobj; + } + + if(allowCast && !pycontext->isconst && pycontext->cppobj) + { + return *pycontext->cppobj; + } + + throw Exception("PyObject must be a valid OCIO.Context."); + } + + ContextRcPtr GetEditableContext(PyObject * pyobject) + { + if(!IsPyContext(pyobject)) + { + throw Exception("PyObject must be an OCIO.Context."); + } + + PyOCIO_Context * pycontext = reinterpret_cast<PyOCIO_Context *> (pyobject); + if(!pycontext->isconst && pycontext->cppobj) + { + return *pycontext->cppobj; + } + + throw Exception("PyObject must be an editable OCIO.Context."); + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_Context_init( PyOCIO_Context * self, PyObject * args, PyObject * kwds ); + void PyOCIO_Context_delete( PyOCIO_Context * self, PyObject * args ); + PyObject * PyOCIO_Context_isEditable( PyObject * self ); + PyObject * PyOCIO_Context_createEditableCopy( PyObject * self ); + PyObject * PyOCIO_Context_getCacheID( PyObject * self ); + + PyObject * PyOCIO_Context_getSearchPath( PyObject * self ); + PyObject * PyOCIO_Context_setSearchPath( PyObject * self, PyObject *args ); + PyObject * PyOCIO_Context_getWorkingDir( PyObject * self ); + PyObject * PyOCIO_Context_setWorkingDir( PyObject * self, PyObject *args ); + PyObject * PyOCIO_Context_getStringVar( PyObject * self, PyObject *args ); + PyObject * PyOCIO_Context_setStringVar( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_Context_loadEnvironment( PyObject * self ); + + PyObject * PyOCIO_Context_resolveStringVar( PyObject * self, PyObject *args ); + PyObject * PyOCIO_Context_resolveFileLocation( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_Context_methods[] = { + {"isEditable", + (PyCFunction) PyOCIO_Context_isEditable, METH_NOARGS, CONTEXT_ISEDITABLE__DOC__ }, + {"createEditableCopy", + (PyCFunction) PyOCIO_Context_createEditableCopy, METH_NOARGS, CONTEXT_CREATEEDITABLECOPY__DOC__ }, + {"getCacheID", + (PyCFunction) PyOCIO_Context_getCacheID, METH_NOARGS, CONTEXT_GETCACHEID__DOC__ }, + {"getSearchPath", + (PyCFunction) PyOCIO_Context_getSearchPath, METH_NOARGS, CONTEXT_GETSEARCHPATH__DOC__ }, + {"setSearchPath", + PyOCIO_Context_setSearchPath, METH_VARARGS, CONTEXT_SETSEARCHPATH__DOC__ }, + {"getWorkingDir", + (PyCFunction) PyOCIO_Context_getWorkingDir, METH_NOARGS, CONTEXT_GETWORKINGDIR__DOC__ }, + {"setWorkingDir", + PyOCIO_Context_setWorkingDir, METH_VARARGS, CONTEXT_SETWORKINGDIR__DOC__ }, + {"getStringVar", + PyOCIO_Context_getStringVar, METH_VARARGS, CONTEXT_GETSTRINGVAR__DOC__ }, + {"setStringVar", + PyOCIO_Context_setStringVar, METH_VARARGS, CONTEXT_SETSTRINGVAR__DOC__ }, + {"loadEnvironment", + (PyCFunction) PyOCIO_Context_loadEnvironment, METH_NOARGS, CONTEXT_LOADENVIRONMENT__DOC__ }, + {"resolveStringVar", + PyOCIO_Context_resolveStringVar, METH_VARARGS, CONTEXT_RESOLVESTRINGVAR__DOC__ }, + {"resolveFileLocation", + PyOCIO_Context_resolveFileLocation, METH_VARARGS, CONTEXT_RESOLVEFILELOCATION__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_ContextType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.Context", //tp_name + sizeof(PyOCIO_Context), //tp_basicsize + 0, //tp_itemsize + (destructor)PyOCIO_Context_delete, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + CONTEXT__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_Context_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + 0, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_Context_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_Context_init( PyOCIO_Context *self, PyObject * /*args*/, PyObject * /*kwds*/ ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstContextRcPtr(); + self->cppobj = new ContextRcPtr(); + self->isconst = true; + + try + { + *self->cppobj = Context::Create(); + self->isconst = false; + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create context: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + + void PyOCIO_Context_delete( PyOCIO_Context *self, PyObject * /*args*/ ) + { + delete self->constcppobj; + delete self->cppobj; + + self->ob_type->tp_free((PyObject*)self); + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_Context_isEditable( PyObject * self ) + { + return PyBool_FromLong(IsPyContextEditable(self)); + } + + PyObject * PyOCIO_Context_createEditableCopy( PyObject * self ) + { + try + { + ConstContextRcPtr context = GetConstContext(self, true); + ContextRcPtr copy = context->createEditableCopy(); + return BuildEditablePyContext( copy ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Context_getCacheID( PyObject * self ) + { + try + { + ConstContextRcPtr context = GetConstContext(self, true); + return PyString_FromString( context->getCacheID() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + + PyObject * PyOCIO_Context_getSearchPath( PyObject * self ) + { + try + { + ConstContextRcPtr context = GetConstContext(self, true); + return PyString_FromString( context->getSearchPath() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Context_setSearchPath( PyObject * self, PyObject * args ) + { + try + { + char * path = 0; + if (!PyArg_ParseTuple(args,"s:setSearchPath", &path)) return NULL; + + ContextRcPtr context = GetEditableContext(self); + context->setSearchPath( path ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Context_getWorkingDir( PyObject * self ) + { + try + { + ConstContextRcPtr context = GetConstContext(self, true); + return PyString_FromString( context->getWorkingDir() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Context_setWorkingDir( PyObject * self, PyObject * args ) + { + try + { + char * dirname = 0; + if (!PyArg_ParseTuple(args,"s:setWorkingDir", &dirname)) return NULL; + + ContextRcPtr context = GetEditableContext(self); + context->setWorkingDir( dirname ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Context_getStringVar( PyObject * self, PyObject * args ) + { + try + { + char * name = 0; + if (!PyArg_ParseTuple(args,"s:getStringVar", &name)) return NULL; + + ConstContextRcPtr context = GetConstContext(self, true); + return PyString_FromString( context->getStringVar(name) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Context_setStringVar( PyObject * self, PyObject * args ) + { + try + { + char * name = 0; + char * value = 0; + if (!PyArg_ParseTuple(args,"ss:setStringVar", &name, &value)) return NULL; + + ContextRcPtr context = GetEditableContext(self); + context->setStringVar( name, value ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Context_loadEnvironment( PyObject * self ) + { + try + { + ContextRcPtr context = GetEditableContext(self); + context->loadEnvironment(); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Context_resolveStringVar( PyObject * self, PyObject * args ) + { + try + { + char * str = 0; + if (!PyArg_ParseTuple(args,"s:resolveStringVar", &str)) return NULL; + + ConstContextRcPtr context = GetConstContext(self, true); + return PyString_FromString( context->resolveStringVar(str) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Context_resolveFileLocation( PyObject * self, PyObject * args ) + { + try + { + char * filename = 0; + if (!PyArg_ParseTuple(args,"s:resolveFileLocation", &filename)) return NULL; + + ConstContextRcPtr context = GetConstContext(self, true); + return PyString_FromString( context->resolveFileLocation(filename) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyContext.h b/src/pyglue/PyContext.h new file mode 100644 index 0000000..02e5623 --- /dev/null +++ b/src/pyglue/PyContext.h @@ -0,0 +1,52 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef INCLUDED_PYOCIO_PYCONTEXT_H +#define INCLUDED_PYOCIO_PYCONTEXT_H + +#include <PyOpenColorIO/PyOpenColorIO.h> + +OCIO_NAMESPACE_ENTER +{ + // TODO: Maybe put this in a pyinternal namespace? + + typedef struct { + PyObject_HEAD + ConstContextRcPtr * constcppobj; + ContextRcPtr * cppobj; + bool isconst; + } PyOCIO_Context; + + extern PyTypeObject PyOCIO_ContextType; + + bool AddContextObjectToModule( PyObject* m ); +} +OCIO_NAMESPACE_EXIT + +#endif diff --git a/src/pyglue/PyDisplayTransform.cpp b/src/pyglue/PyDisplayTransform.cpp new file mode 100644 index 0000000..6a29153 --- /dev/null +++ b/src/pyglue/PyDisplayTransform.cpp @@ -0,0 +1,577 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddDisplayTransformObjectToModule( PyObject* m ) + { + PyOCIO_DisplayTransformType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_DisplayTransformType) < 0 ) return false; + + Py_INCREF( &PyOCIO_DisplayTransformType ); + PyModule_AddObject(m, "DisplayTransform", + (PyObject *)&PyOCIO_DisplayTransformType); + + return true; + } + + bool IsPyDisplayTransform(PyObject * pyobject) + { + if(!pyobject) return false; + return PyObject_TypeCheck(pyobject, &PyOCIO_DisplayTransformType); + } + + ConstDisplayTransformRcPtr GetConstDisplayTransform(PyObject * pyobject, bool allowCast) + { + ConstDisplayTransformRcPtr transform = \ + DynamicPtrCast<const DisplayTransform>(GetConstTransform(pyobject, allowCast)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.DisplayTransform."); + } + return transform; + } + + DisplayTransformRcPtr GetEditableDisplayTransform(PyObject * pyobject) + { + DisplayTransformRcPtr transform = \ + DynamicPtrCast<DisplayTransform>(GetEditableTransform(pyobject)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.DisplayTransform."); + } + return transform; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_DisplayTransform_init( PyOCIO_Transform * self, PyObject * args, PyObject * kwds ); + + PyObject * PyOCIO_DisplayTransform_getInputColorSpaceName( PyObject * self ); + PyObject * PyOCIO_DisplayTransform_setInputColorSpaceName( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_DisplayTransform_getLinearCC( PyObject * self ); + PyObject * PyOCIO_DisplayTransform_setLinearCC( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_DisplayTransform_getColorTimingCC( PyObject * self ); + PyObject * PyOCIO_DisplayTransform_setColorTimingCC( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_DisplayTransform_getChannelView( PyObject * self ); + PyObject * PyOCIO_DisplayTransform_setChannelView( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_DisplayTransform_getDisplay( PyObject * self ); + PyObject * PyOCIO_DisplayTransform_setDisplay( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_DisplayTransform_getView( PyObject * self ); + PyObject * PyOCIO_DisplayTransform_setView( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_DisplayTransform_getDisplayCC( PyObject * self ); + PyObject * PyOCIO_DisplayTransform_setDisplayCC( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_DisplayTransform_getLooksOverride( PyObject * self ); + PyObject * PyOCIO_DisplayTransform_setLooksOverride( PyObject * self, PyObject *args ); + PyObject * PyOCIO_DisplayTransform_getLooksOverrideEnabled( PyObject * self ); + PyObject * PyOCIO_DisplayTransform_setLooksOverrideEnabled( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_DisplayTransform_methods[] = { + {"getInputColorSpaceName", + (PyCFunction) PyOCIO_DisplayTransform_getInputColorSpaceName, METH_NOARGS, DISPLAYTRANSFORM_GETINPUTCOLORSPACENAME__DOC__ }, + {"setInputColorSpaceName", + PyOCIO_DisplayTransform_setInputColorSpaceName, METH_VARARGS, DISPLAYTRANSFORM_SETINPUTCOLORSPACENAME__DOC__ }, + {"getLinearCC", + (PyCFunction) PyOCIO_DisplayTransform_getLinearCC, METH_NOARGS, DISPLAYTRANSFORM_GETLINEARCC__DOC__ }, + {"setLinearCC", + PyOCIO_DisplayTransform_setLinearCC, METH_VARARGS, DISPLAYTRANSFORM_SETLINEARCC__DOC__ }, + {"getColorTimingCC", + (PyCFunction) PyOCIO_DisplayTransform_getColorTimingCC, METH_NOARGS, DISPLAYTRANSFORM_GETCOLORTIMINGCC__DOC__ }, + {"setColorTimingCC", + PyOCIO_DisplayTransform_setColorTimingCC, METH_VARARGS, DISPLAYTRANSFORM_SETCOLORTIMINGCC__DOC__ }, + {"getChannelView", + (PyCFunction) PyOCIO_DisplayTransform_getChannelView, METH_NOARGS, DISPLAYTRANSFORM_GETCHANNELVIEW__DOC__ }, + {"setChannelView", + PyOCIO_DisplayTransform_setChannelView, METH_VARARGS, DISPLAYTRANSFORM_SETCHANNELVIEW__DOC__ }, + {"getDisplay", + (PyCFunction) PyOCIO_DisplayTransform_getDisplay, METH_NOARGS, DISPLAYTRANSFORM_GETDISPLAY__DOC__ }, + {"setDisplay", + PyOCIO_DisplayTransform_setDisplay, METH_VARARGS, DISPLAYTRANSFORM_SETDISPLAY__DOC__ }, + {"getView", + (PyCFunction) PyOCIO_DisplayTransform_getView, METH_NOARGS, DISPLAYTRANSFORM_GETVIEW__DOC__ }, + {"setView", + PyOCIO_DisplayTransform_setView, METH_VARARGS, DISPLAYTRANSFORM_SETVIEW__DOC__ }, + {"getDisplayCC", + (PyCFunction) PyOCIO_DisplayTransform_getDisplayCC, METH_NOARGS, DISPLAYTRANSFORM_GETDISPLAYCC__DOC__ }, + {"setDisplayCC", + PyOCIO_DisplayTransform_setDisplayCC, METH_VARARGS, DISPLAYTRANSFORM_SETDISPLAYCC__DOC__ }, + {"getLooksOverride", + (PyCFunction) PyOCIO_DisplayTransform_getLooksOverride, METH_NOARGS, DISPLAYTRANSFORM_GETLOOKSOVERRIDE__DOC__ }, + {"setLooksOverride", + PyOCIO_DisplayTransform_setLooksOverride, METH_VARARGS, DISPLAYTRANSFORM_SETLOOKSOVERRIDE__DOC__ }, + {"getLooksOverrideEnabled", + (PyCFunction) PyOCIO_DisplayTransform_getLooksOverrideEnabled, METH_NOARGS, DISPLAYTRANSFORM_GETLOOKSOVERRIDEENABLED__DOC__ }, + {"setLooksOverrideEnabled", + PyOCIO_DisplayTransform_setLooksOverrideEnabled, METH_VARARGS, DISPLAYTRANSFORM_SETLOOKSOVERRIDEENABLED__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_DisplayTransformType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.DisplayTransform", //tp_name + sizeof(PyOCIO_Transform), //tp_basicsize + 0, //tp_itemsize + 0, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + DISPLAYTRANSFORM__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_DisplayTransform_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + &PyOCIO_TransformType, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_DisplayTransform_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + + int PyOCIO_DisplayTransform_init( PyOCIO_Transform *self, PyObject * /*args*/, PyObject * /*kwds*/ ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstTransformRcPtr(); + self->cppobj = new TransformRcPtr(); + self->isconst = true; + + try + { + *self->cppobj = DisplayTransform::Create(); + self->isconst = false; + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create DisplayTransform: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_DisplayTransform_getInputColorSpaceName( PyObject * self ) + { + try + { + ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self, true); + return PyString_FromString( transform->getInputColorSpaceName() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_DisplayTransform_setInputColorSpaceName( PyObject * self, PyObject * args ) + { + try + { + char * name = 0; + if (!PyArg_ParseTuple(args,"s:setInputColorSpaceName", &name)) return NULL; + + DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); + transform->setInputColorSpaceName( name ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_DisplayTransform_getLinearCC( PyObject * self ) + { + try + { + ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self, true); + return BuildConstPyTransform(transform->getLinearCC()); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_DisplayTransform_setLinearCC( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyCC = 0; + if (!PyArg_ParseTuple(args,"O:setLinearCC", &pyCC)) return NULL; + + DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); + + ConstTransformRcPtr cc = GetConstTransform(pyCC, true); + transform->setLinearCC(cc); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_DisplayTransform_getColorTimingCC( PyObject * self ) + { + try + { + ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self, true); + return BuildConstPyTransform(transform->getColorTimingCC()); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_DisplayTransform_setColorTimingCC( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyCC = 0; + if (!PyArg_ParseTuple(args,"O:setColorTimingCC", &pyCC)) return NULL; + + DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); + + ConstTransformRcPtr cc = GetConstTransform(pyCC, true); + transform->setColorTimingCC(cc); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_DisplayTransform_getChannelView( PyObject * self ) + { + try + { + ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self, true); + return BuildConstPyTransform(transform->getChannelView()); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_DisplayTransform_setChannelView( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyCC = 0; + if (!PyArg_ParseTuple(args,"O:setChannelView", &pyCC)) return NULL; + + DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); + + ConstTransformRcPtr t = GetConstTransform(pyCC, true); + transform->setChannelView(t); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_DisplayTransform_getDisplay( PyObject * self ) + { + try + { + ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self, true); + return PyString_FromString( transform->getDisplay() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_DisplayTransform_setDisplay( PyObject * self, PyObject * args ) + { + try + { + char * str = 0; + if (!PyArg_ParseTuple(args,"s:setDisplay", &str)) return NULL; + + DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); + transform->setDisplay( str ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_DisplayTransform_getView( PyObject * self ) + { + try + { + ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self, true); + return PyString_FromString( transform->getView() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_DisplayTransform_setView( PyObject * self, PyObject * args ) + { + try + { + char * str = 0; + if (!PyArg_ParseTuple(args,"s:setView", &str)) return NULL; + + DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); + transform->setView( str ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_DisplayTransform_getDisplayCC( PyObject * self ) + { + try + { + ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self, true); + return BuildConstPyTransform(transform->getDisplayCC()); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_DisplayTransform_setDisplayCC( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyCC = 0; + if (!PyArg_ParseTuple(args,"O:setDisplayCC", &pyCC)) return NULL; + + DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); + + ConstTransformRcPtr cc = GetConstTransform(pyCC, true); + transform->setDisplayCC(cc); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_DisplayTransform_getLooksOverride( PyObject * self ) + { + try + { + ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self, true); + return PyString_FromString( transform->getLooksOverride() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_DisplayTransform_setLooksOverride( PyObject * self, PyObject * args ) + { + try + { + char * str = 0; + if (!PyArg_ParseTuple(args,"s:setLooksOverride", &str)) return NULL; + + DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); + transform->setLooksOverride( str ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_DisplayTransform_getLooksOverrideEnabled( PyObject * self ) + { + try + { + ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self, true); + return PyBool_FromLong( transform->getLooksOverrideEnabled() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_DisplayTransform_setLooksOverrideEnabled( PyObject * self, PyObject * args ) + { + try + { + bool enabled = false; + if (!PyArg_ParseTuple(args,"O&:setLooksOverrideEnabled", + ConvertPyObjectToBool, &enabled)) return NULL; + + DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); + transform->setLooksOverrideEnabled( enabled ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyExponentTransform.cpp b/src/pyglue/PyExponentTransform.cpp new file mode 100644 index 0000000..2fa7ba3 --- /dev/null +++ b/src/pyglue/PyExponentTransform.cpp @@ -0,0 +1,269 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddExponentTransformObjectToModule( PyObject* m ) + { + PyOCIO_ExponentTransformType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_ExponentTransformType) < 0 ) return false; + + Py_INCREF( &PyOCIO_ExponentTransformType ); + PyModule_AddObject(m, "ExponentTransform", + (PyObject *)&PyOCIO_ExponentTransformType); + + return true; + } + + bool IsPyExponentTransform(PyObject * pyobject) + { + if(!pyobject) return false; + return PyObject_TypeCheck(pyobject, &PyOCIO_ExponentTransformType); + } + + ConstExponentTransformRcPtr GetConstExponentTransform(PyObject * pyobject, bool allowCast) + { + ConstExponentTransformRcPtr transform = \ + DynamicPtrCast<const ExponentTransform>(GetConstTransform(pyobject, allowCast)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.ExponentTransform."); + } + return transform; + } + + ExponentTransformRcPtr GetEditableExponentTransform(PyObject * pyobject) + { + ExponentTransformRcPtr transform = \ + DynamicPtrCast<ExponentTransform>(GetEditableTransform(pyobject)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.ExponentTransform."); + } + return transform; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_ExponentTransform_init( PyOCIO_Transform * self, PyObject * args, PyObject * kwds ); + + PyObject * PyOCIO_ExponentTransform_getValue( PyObject * self ); + PyObject * PyOCIO_ExponentTransform_setValue( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_ExponentTransform_methods[] = { + {"getValue", + (PyCFunction) PyOCIO_ExponentTransform_getValue, METH_NOARGS, EXPONENTTRANSFORM_GETVALUE__DOC__ }, + {"setValue", + PyOCIO_ExponentTransform_setValue, METH_VARARGS, EXPONENTTRANSFORM_SETVALUE__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_ExponentTransformType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.ExponentTransform", //tp_name + sizeof(PyOCIO_Transform), //tp_basicsize + 0, //tp_itemsize + 0, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + EXPONENTTRANSFORM__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_ExponentTransform_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + &PyOCIO_TransformType, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_ExponentTransform_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_ExponentTransform_init( PyOCIO_Transform *self, + PyObject * args, PyObject * kwds ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstTransformRcPtr(); + self->cppobj = new TransformRcPtr(); + self->isconst = true; + + // Parse optional kwargs + PyObject * pyvalue = Py_None; + char * direction = NULL; + + static const char *kwlist[] = { + "value", + "direction", + NULL + }; + + if(!PyArg_ParseTupleAndKeywords(args, kwds, "|Os", + const_cast<char **>(kwlist), + &pyvalue, &direction )) return -1; + + try + { + ExponentTransformRcPtr transform = ExponentTransform::Create(); + *self->cppobj = transform; + self->isconst = false; + + if(pyvalue != Py_None) + { + std::vector<float> data; + if(!FillFloatVectorFromPySequence(pyvalue, data) || (data.size() != 4)) + { + PyErr_SetString(PyExc_TypeError, "Value argument must be a float array, size 4"); + return -1; + } + + transform->setValue( &data[0] ); + } + if(direction) transform->setDirection(TransformDirectionFromString(direction)); + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create ExponentTransform: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_ExponentTransform_getValue( PyObject * self ) + { + try + { + ConstExponentTransformRcPtr transform = GetConstExponentTransform(self, true); + std::vector<float> data(4); + transform->getValue(&data[0]); + return CreatePyListFromFloatVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ExponentTransform_setValue( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyData = 0; + if (!PyArg_ParseTuple(args,"O:setValue", &pyData)) return NULL; + ExponentTransformRcPtr transform = GetEditableExponentTransform(self); + + std::vector<float> data; + if(!FillFloatVectorFromPySequence(pyData, data) || (data.size() != 4)) + { + PyErr_SetString(PyExc_TypeError, "First argument must be a float array, size 4"); + return 0; + } + + transform->setValue( &data[0] ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyFileTransform.cpp b/src/pyglue/PyFileTransform.cpp new file mode 100644 index 0000000..2e85232 --- /dev/null +++ b/src/pyglue/PyFileTransform.cpp @@ -0,0 +1,344 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddFileTransformObjectToModule( PyObject* m ) + { + PyOCIO_FileTransformType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_FileTransformType) < 0 ) return false; + + Py_INCREF( &PyOCIO_FileTransformType ); + PyModule_AddObject(m, "FileTransform", + (PyObject *)&PyOCIO_FileTransformType); + + return true; + } + + bool IsPyFileTransform(PyObject * pyobject) + { + if(!pyobject) return false; + return PyObject_TypeCheck(pyobject, &PyOCIO_FileTransformType); + } + + ConstFileTransformRcPtr GetConstFileTransform(PyObject * pyobject, bool allowCast) + { + ConstFileTransformRcPtr transform = \ + DynamicPtrCast<const FileTransform>(GetConstTransform(pyobject, allowCast)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.FileTransform."); + } + return transform; + } + + FileTransformRcPtr GetEditableFileTransform(PyObject * pyobject) + { + FileTransformRcPtr transform = \ + DynamicPtrCast<FileTransform>(GetEditableTransform(pyobject)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.FileTransform."); + } + return transform; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_FileTransform_init( PyOCIO_Transform * self, PyObject * args, PyObject * kwds ); + + PyObject * PyOCIO_FileTransform_getSrc( PyObject * self ); + PyObject * PyOCIO_FileTransform_setSrc( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_FileTransform_getCCCId( PyObject * self ); + PyObject * PyOCIO_FileTransform_setCCCId( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_FileTransform_getInterpolation( PyObject * self ); + PyObject * PyOCIO_FileTransform_setInterpolation( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_FileTransform_methods[] = { + {"getSrc", + (PyCFunction) PyOCIO_FileTransform_getSrc, METH_NOARGS, FILETRANSFORM_GETSRC__DOC__ }, + {"setSrc", + PyOCIO_FileTransform_setSrc, METH_VARARGS, FILETRANSFORM_SETSRC__DOC__ }, + {"getCCCId", + (PyCFunction) PyOCIO_FileTransform_getCCCId, METH_NOARGS, FILETRANSFORM_GETCCCID__DOC__ }, + {"setCCCId", + PyOCIO_FileTransform_setCCCId, METH_VARARGS, FILETRANSFORM_SETCCCID__DOC__ }, + {"getInterpolation", + (PyCFunction) PyOCIO_FileTransform_getInterpolation, METH_NOARGS, FILETRANSFORM_GETINTERPOLATION__DOC__ }, + {"setInterpolation", + PyOCIO_FileTransform_setInterpolation, METH_VARARGS, FILETRANSFORM_SETINTERPOLATION__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_FileTransformType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.FileTransform", //tp_name + sizeof(PyOCIO_Transform), //tp_basicsize + 0, //tp_itemsize + 0, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + FILETRANSFORM__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_FileTransform_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + &PyOCIO_TransformType, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_FileTransform_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_FileTransform_init( PyOCIO_Transform *self, + PyObject * args, PyObject * kwds ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstTransformRcPtr(); + self->cppobj = new TransformRcPtr(); + self->isconst = true; + + // Parse optional kwargs + char * src = NULL; + char * cccid = NULL; + char * interpolation = NULL; + char * direction = NULL; + + static const char *kwlist[] = { + "src", + "cccid", + "interpolation", + "direction", + NULL + }; + + if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ssss", + const_cast<char **>(kwlist), + &src, &cccid, &interpolation, &direction )) return -1; + + try + { + FileTransformRcPtr transform = FileTransform::Create(); + *self->cppobj = transform; + self->isconst = false; + + if(src) transform->setSrc(src); + if(cccid) transform->setCCCId(cccid); + if(interpolation) transform->setInterpolation(InterpolationFromString(interpolation)); + if(direction) transform->setDirection(TransformDirectionFromString(direction)); + + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create FileTransform: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_FileTransform_getSrc( PyObject * self ) + { + try + { + ConstFileTransformRcPtr transform = GetConstFileTransform(self, true); + return PyString_FromString( transform->getSrc() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_FileTransform_setSrc( PyObject * self, PyObject * args ) + { + try + { + char * src = 0; + if (!PyArg_ParseTuple(args,"s:setSrc", &src)) return NULL; + + FileTransformRcPtr transform = GetEditableFileTransform(self); + transform->setSrc( src ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_FileTransform_getCCCId( PyObject * self ) + { + try + { + ConstFileTransformRcPtr transform = GetConstFileTransform(self, true); + return PyString_FromString( transform->getCCCId() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_FileTransform_setCCCId( PyObject * self, PyObject * args ) + { + try + { + char * id = 0; + if (!PyArg_ParseTuple(args,"s:setCCCId", &id)) return NULL; + + FileTransformRcPtr transform = GetEditableFileTransform(self); + transform->setCCCId( id ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_FileTransform_getInterpolation( PyObject * self ) + { + try + { + ConstFileTransformRcPtr transform = GetConstFileTransform(self, true); + Interpolation interp = transform->getInterpolation(); + return PyString_FromString( InterpolationToString( interp ) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_FileTransform_setInterpolation( PyObject * self, PyObject * args ) + { + try + { + Interpolation interp; + if (!PyArg_ParseTuple(args,"O&:setInterpolation", + ConvertPyObjectToInterpolation, &interp)) return NULL; + + FileTransformRcPtr transform = GetEditableFileTransform(self); + transform->setInterpolation(interp); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyGroupTransform.cpp b/src/pyglue/PyGroupTransform.cpp new file mode 100644 index 0000000..32f5b8d --- /dev/null +++ b/src/pyglue/PyGroupTransform.cpp @@ -0,0 +1,397 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddGroupTransformObjectToModule( PyObject* m ) + { + PyOCIO_GroupTransformType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_GroupTransformType) < 0 ) return false; + + Py_INCREF( &PyOCIO_GroupTransformType ); + PyModule_AddObject(m, "GroupTransform", + (PyObject *)&PyOCIO_GroupTransformType); + + return true; + } + + bool IsPyGroupTransform(PyObject * pyobject) + { + if(!pyobject) return false; + return PyObject_TypeCheck(pyobject, &PyOCIO_GroupTransformType); + } + + ConstGroupTransformRcPtr GetConstGroupTransform(PyObject * pyobject, bool allowCast) + { + ConstGroupTransformRcPtr transform = \ + DynamicPtrCast<const GroupTransform>(GetConstTransform(pyobject, allowCast)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.GroupTransform."); + } + return transform; + } + + GroupTransformRcPtr GetEditableGroupTransform(PyObject * pyobject) + { + GroupTransformRcPtr transform = \ + DynamicPtrCast<GroupTransform>(GetEditableTransform(pyobject)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.GroupTransform."); + } + return transform; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_GroupTransform_init( PyOCIO_Transform * self, PyObject * args, PyObject * kwds ); + + PyObject * PyOCIO_GroupTransform_getTransform( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_GroupTransform_getTransforms( PyObject * self ); + PyObject * PyOCIO_GroupTransform_setTransforms( PyObject * self, PyObject *args ); + + // TODO: make these appear more like a pysequence. .append, len(), etc + + PyObject * PyOCIO_GroupTransform_size( PyObject * self ); + PyObject * PyOCIO_GroupTransform_push_back( PyObject * self, PyObject *args ); + PyObject * PyOCIO_GroupTransform_clear( PyObject * self ); + PyObject * PyOCIO_GroupTransform_empty( PyObject * self ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_GroupTransform_methods[] = { + {"getTransform", + PyOCIO_GroupTransform_getTransform, METH_VARARGS, GROUPTRANSFORM_GETTRANSFORM__DOC__ }, + {"getTransforms", + (PyCFunction) PyOCIO_GroupTransform_getTransforms, METH_NOARGS, GROUPTRANSFORM_GETTRANSFORMS__DOC__ }, + {"setTransforms", + PyOCIO_GroupTransform_setTransforms, METH_VARARGS, GROUPTRANSFORM_SETTRANSFORMS__DOC__ }, + {"size", + (PyCFunction) PyOCIO_GroupTransform_size, METH_NOARGS, GROUPTRANSFORM_SIZE__DOC__ }, + {"push_back", + PyOCIO_GroupTransform_push_back, METH_VARARGS, GROUPTRANSFORM_PUSH_BACK__DOC__ }, + {"clear", + (PyCFunction) PyOCIO_GroupTransform_clear, METH_NOARGS, GROUPTRANSFORM_CLEAR__DOC__ }, + {"empty", + (PyCFunction) PyOCIO_GroupTransform_empty, METH_NOARGS, GROUPTRANSFORM_EMPTY__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_GroupTransformType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.GroupTransform", //tp_name + sizeof(PyOCIO_Transform), //tp_basicsize + 0, //tp_itemsize + 0, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + GROUPTRANSFORM__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_GroupTransform_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + &PyOCIO_TransformType, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_GroupTransform_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_GroupTransform_init( PyOCIO_Transform *self, + PyObject * args, PyObject * kwds ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstTransformRcPtr(); + self->cppobj = new TransformRcPtr(); + self->isconst = true; + + // Parse optional kwargs + PyObject * pytransforms = Py_None; + char * direction = NULL; + + static const char *kwlist[] = { + "transforms", + "direction", + NULL + }; + + if(!PyArg_ParseTupleAndKeywords(args, kwds, "|Os", + const_cast<char **>(kwlist), + &pytransforms, &direction )) return -1; + + try + { + GroupTransformRcPtr transform = GroupTransform::Create(); + *self->cppobj = transform; + self->isconst = false; + + if(pytransforms != Py_None) + { + std::vector<ConstTransformRcPtr> data; + if(!FillTransformVectorFromPySequence(pytransforms, data)) + { + PyErr_SetString(PyExc_TypeError, "Kwarg 'transforms' must be a transform array."); + return -1; + } + + for(unsigned int i=0; i<data.size(); ++i) + { + transform->push_back( data[i] ); + } + } + + if(direction) transform->setDirection(TransformDirectionFromString(direction)); + + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create GroupTransform: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_GroupTransform_getTransform( PyObject * self, PyObject * args ) + { + try + { + int index = 0; + + if (!PyArg_ParseTuple(args,"i:getTransform", &index)) return NULL; + + ConstGroupTransformRcPtr transform = GetConstGroupTransform(self, true); + ConstTransformRcPtr childTransform = transform->getTransform(index); + + return BuildConstPyTransform(childTransform); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_GroupTransform_getTransforms( PyObject * self) + { + try + { + ConstGroupTransformRcPtr transform = GetConstGroupTransform(self, true); + + std::vector<ConstTransformRcPtr> transforms; + for(int i=0; i<transform->size(); ++i) + { + transforms.push_back(transform->getTransform(i)); + } + + return CreatePyListFromTransformVector(transforms); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_GroupTransform_setTransforms( PyObject * self, PyObject *args ) + { + try + { + PyObject * pytransforms = 0; + + if (!PyArg_ParseTuple(args,"O:setTransforms", &pytransforms)) return NULL; + + GroupTransformRcPtr transform = GetEditableGroupTransform(self); + + std::vector<ConstTransformRcPtr> data; + if(!FillTransformVectorFromPySequence(pytransforms, data)) + { + PyErr_SetString(PyExc_TypeError, "First argument must be a transform array."); + return 0; + } + + transform->clear(); + + for(unsigned int i=0; i<data.size(); ++i) + { + transform->push_back( data[i] ); + } + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_GroupTransform_size( PyObject * self ) + { + try + { + ConstGroupTransformRcPtr transform = GetConstGroupTransform(self, true); + return PyInt_FromLong( transform->size() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_GroupTransform_push_back( PyObject * self, PyObject *args ) + { + try + { + PyObject * pytransform = 0; + + if (!PyArg_ParseTuple(args,"O:push_back", &pytransform)) return NULL; + + GroupTransformRcPtr transform = GetEditableGroupTransform(self); + + if(!IsPyTransform(pytransform)) + { + throw Exception("GroupTransform.push_back requires a transform as the first arg."); + } + + transform->push_back( GetConstTransform(pytransform, true) ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_GroupTransform_clear( PyObject * self ) + { + try + { + GroupTransformRcPtr transform = GetEditableGroupTransform(self); + transform->clear(); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_GroupTransform_empty( PyObject * self ) + { + try + { + ConstGroupTransformRcPtr transform = GetConstGroupTransform(self, true); + return PyBool_FromLong( transform->empty() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyLogTransform.cpp b/src/pyglue/PyLogTransform.cpp new file mode 100644 index 0000000..e2c1462 --- /dev/null +++ b/src/pyglue/PyLogTransform.cpp @@ -0,0 +1,251 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddLogTransformObjectToModule( PyObject* m ) + { + PyOCIO_LogTransformType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_LogTransformType) < 0 ) return false; + + Py_INCREF( &PyOCIO_LogTransformType ); + PyModule_AddObject(m, "LogTransform", + (PyObject *)&PyOCIO_LogTransformType); + + return true; + } + + bool IsPyLogTransform(PyObject * pyobject) + { + if(!pyobject) return false; + return PyObject_TypeCheck(pyobject, &PyOCIO_LogTransformType); + } + + ConstLogTransformRcPtr GetConstLogTransform(PyObject * pyobject, bool allowCast) + { + ConstLogTransformRcPtr transform = \ + DynamicPtrCast<const LogTransform>(GetConstTransform(pyobject, allowCast)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.LogTransform."); + } + return transform; + } + + LogTransformRcPtr GetEditableLogTransform(PyObject * pyobject) + { + LogTransformRcPtr transform = \ + DynamicPtrCast<LogTransform>(GetEditableTransform(pyobject)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.LogTransform."); + } + return transform; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_LogTransform_init( PyOCIO_Transform * self, PyObject * args, PyObject * kwds ); + + PyObject * PyOCIO_LogTransform_getBase( PyObject * self ); + PyObject * PyOCIO_LogTransform_setBase( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_LogTransform_methods[] = { + {"getBase", + (PyCFunction) PyOCIO_LogTransform_getBase, METH_NOARGS, LOGTRANSFORM_GETBASE__DOC__ }, + {"setBase", + PyOCIO_LogTransform_setBase, METH_VARARGS, LOGTRANSFORM_SETBASE__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_LogTransformType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.LogTransform", //tp_name + sizeof(PyOCIO_Transform), //tp_basicsize + 0, //tp_itemsize + 0, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + LOGTRANSFORM__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_LogTransform_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + &PyOCIO_TransformType, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_LogTransform_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_LogTransform_init( PyOCIO_Transform *self, + PyObject * args, PyObject * kwds ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstTransformRcPtr(); + self->cppobj = new TransformRcPtr(); + self->isconst = true; + + // Parse optional kwargs + float base = -1.0f; // -1.0 is an illegal value for log transform base + char * direction = NULL; + + static const char *kwlist[] = { + "base", + "direction", + NULL + }; + + if(!PyArg_ParseTupleAndKeywords(args, kwds, "|fs", + const_cast<char **>(kwlist), + &base, &direction )) return -1; + + try + { + LogTransformRcPtr transform = LogTransform::Create(); + *self->cppobj = transform; + self->isconst = false; + + if(base != -1.0f) transform->setBase(base); + if(direction) transform->setDirection(TransformDirectionFromString(direction)); + + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create LogTransform: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_LogTransform_getBase( PyObject * self ) + { + try + { + ConstLogTransformRcPtr transform = GetConstLogTransform(self, true); + return PyFloat_FromDouble(transform->getBase()); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_LogTransform_setBase( PyObject * self, PyObject * args ) + { + try + { + float base; + if (!PyArg_ParseTuple(args,"f:setBase", &base)) return NULL; + LogTransformRcPtr transform = GetEditableLogTransform(self); + + transform->setBase( base ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyLook.cpp b/src/pyglue/PyLook.cpp new file mode 100644 index 0000000..3f1128f --- /dev/null +++ b/src/pyglue/PyLook.cpp @@ -0,0 +1,450 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyLook.h" +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddLookObjectToModule( PyObject* m ) + { + PyOCIO_LookType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_LookType) < 0 ) return false; + + Py_INCREF( &PyOCIO_LookType ); + PyModule_AddObject(m, "Look", + (PyObject *)&PyOCIO_LookType); + + return true; + } + + PyObject * BuildConstPyLook(ConstLookRcPtr look) + { + if (!look) + { + Py_RETURN_NONE; + } + + PyOCIO_Look * pyLook = PyObject_New( + PyOCIO_Look, (PyTypeObject * ) &PyOCIO_LookType); + + pyLook->constcppobj = new ConstLookRcPtr(); + *pyLook->constcppobj = look; + + pyLook->cppobj = new LookRcPtr(); + pyLook->isconst = true; + + return ( PyObject * ) pyLook; + } + + PyObject * BuildEditablePyLook(LookRcPtr look) + { + if (!look) + { + Py_RETURN_NONE; + } + + PyOCIO_Look * pyLook = PyObject_New( + PyOCIO_Look, (PyTypeObject * ) &PyOCIO_LookType); + + pyLook->constcppobj = new ConstLookRcPtr(); + pyLook->cppobj = new LookRcPtr(); + *pyLook->cppobj = look; + + pyLook->isconst = false; + + return ( PyObject * ) pyLook; + } + + bool IsPyLook(PyObject * pyobject) + { + if(!pyobject) return false; + return (PyObject_Type(pyobject) == (PyObject *) (&PyOCIO_LookType)); + } + + bool IsPyLookEditable(PyObject * pyobject) + { + if(!IsPyLook(pyobject)) + { + throw Exception("PyObject must be an OCIO.Look."); + } + + PyOCIO_Look * pyLook = reinterpret_cast<PyOCIO_Look *> (pyobject); + return (!pyLook->isconst); + } + + ConstLookRcPtr GetConstLook(PyObject * pyobject, bool allowCast) + { + if(!IsPyLook(pyobject)) + { + throw Exception("PyObject must be an OCIO.Look."); + } + + PyOCIO_Look * pylook = reinterpret_cast<PyOCIO_Look *> (pyobject); + if(pylook->isconst && pylook->constcppobj) + { + return *pylook->constcppobj; + } + + if(allowCast && !pylook->isconst && pylook->cppobj) + { + return *pylook->cppobj; + } + + throw Exception("PyObject must be a valid OCIO.Look."); + } + + LookRcPtr GetEditableLook(PyObject * pyobject) + { + if(!IsPyLook(pyobject)) + { + throw Exception("PyObject must be an OCIO.Look."); + } + + PyOCIO_Look * pylook = reinterpret_cast<PyOCIO_Look *> (pyobject); + if(!pylook->isconst && pylook->cppobj) + { + return *pylook->cppobj; + } + + throw Exception("PyObject must be an editable OCIO.Look."); + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_Look_init( PyOCIO_Look * self, PyObject * args, PyObject * kwds ); + void PyOCIO_Look_delete( PyOCIO_Look * self, PyObject * args ); + PyObject * PyOCIO_Look_isEditable( PyObject * self ); + PyObject * PyOCIO_Look_createEditableCopy( PyObject * self ); + + PyObject * PyOCIO_Look_getName( PyObject * self ); + PyObject * PyOCIO_Look_setName( PyObject * self, PyObject *args ); + PyObject * PyOCIO_Look_getProcessSpace( PyObject * self ); + PyObject * PyOCIO_Look_setProcessSpace( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_Look_getTransform( PyObject * self ); + PyObject * PyOCIO_Look_setTransform( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_Look_methods[] = { + {"isEditable", + (PyCFunction) PyOCIO_Look_isEditable, METH_NOARGS, LOOK_ISEDITABLE__DOC__ }, + {"createEditableCopy", + (PyCFunction) PyOCIO_Look_createEditableCopy, METH_NOARGS, LOOK_CREATEEDITABLECOPY__DOC__ }, + {"getName", + (PyCFunction) PyOCIO_Look_getName, METH_NOARGS, LOOK_GETNAME__DOC__ }, + {"setName", + PyOCIO_Look_setName, METH_VARARGS, LOOK_SETNAME__DOC__ }, + {"getProcessSpace", + (PyCFunction) PyOCIO_Look_getProcessSpace, METH_NOARGS, LOOK_GETPROCESSSPACE__DOC__ }, + {"setProcessSpace", + PyOCIO_Look_setProcessSpace, METH_VARARGS, LOOK_SETPROCESSSPACE__DOC__ }, + {"getTransform", + (PyCFunction) PyOCIO_Look_getTransform, METH_NOARGS, LOOK_GETTRANSFORM__DOC__ }, + {"setTransform", + PyOCIO_Look_setTransform, METH_VARARGS, LOOK_SETTRANSFORM__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_LookType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.Look", //tp_name + sizeof(PyOCIO_Look), //tp_basicsize + 0, //tp_itemsize + (destructor)PyOCIO_Look_delete, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + LOOK__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_Look_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + 0, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_Look_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_Look_init( PyOCIO_Look *self, PyObject * args, PyObject * kwds ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstLookRcPtr(); + self->cppobj = new LookRcPtr(); + self->isconst = true; + + // Parse optional kwargs + char * name = NULL; + char * processSpace = NULL; + PyObject * pytransform = NULL; + + const char *kwlist[] = { + "name", "processSpace", "transform", + NULL + }; + + if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ssO", + const_cast<char **>(kwlist), + &name, &processSpace, &pytransform)) return -1; + + try + { + LookRcPtr look = Look::Create(); + *self->cppobj = look; + self->isconst = false; + + if(name) look->setName(name); + if(processSpace) look->setProcessSpace(processSpace); + + if(pytransform) + { + ConstTransformRcPtr transform = GetConstTransform(pytransform, true); + look->setTransform(transform); + } + + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create look: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + void PyOCIO_Look_delete( PyOCIO_Look *self, PyObject * /*args*/ ) + { + delete self->constcppobj; + delete self->cppobj; + + self->ob_type->tp_free((PyObject*)self); + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Look_isEditable( PyObject * self ) + { + return PyBool_FromLong(IsPyLookEditable(self)); + } + + PyObject * PyOCIO_Look_createEditableCopy( PyObject * self ) + { + try + { + ConstLookRcPtr look = GetConstLook(self, true); + LookRcPtr copy = look->createEditableCopy(); + return BuildEditablePyLook( copy ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Look_getName( PyObject * self ) + { + try + { + ConstLookRcPtr look = GetConstLook(self, true); + return PyString_FromString( look->getName() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Look_setName( PyObject * self, PyObject * args ) + { + try + { + char * name = 0; + if (!PyArg_ParseTuple(args,"s:setName", &name)) return NULL; + + LookRcPtr look = GetEditableLook(self); + look->setName( name ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Look_getProcessSpace( PyObject * self ) + { + try + { + ConstLookRcPtr look = GetConstLook(self, true); + return PyString_FromString( look->getProcessSpace() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Look_setProcessSpace( PyObject * self, PyObject * args ) + { + try + { + char * processSpace = 0; + if (!PyArg_ParseTuple(args,"s:setProcessSpace", &processSpace)) return NULL; + + LookRcPtr look = GetEditableLook(self); + look->setProcessSpace( processSpace ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Look_getTransform( PyObject * self ) + { + try + { + ConstLookRcPtr look = GetConstLook(self, true); + ConstTransformRcPtr transform = look->getTransform(); + return BuildConstPyTransform(transform); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Look_setTransform( PyObject * self, PyObject *args ) + { + try + { + PyObject * pytransform = 0; + if (!PyArg_ParseTuple(args,"O:setTransform", &pytransform)) + return NULL; + + ConstTransformRcPtr transform = GetConstTransform(pytransform, true); + LookRcPtr look = GetEditableLook(self); + look->setTransform(transform); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyLook.h b/src/pyglue/PyLook.h new file mode 100644 index 0000000..371eafa --- /dev/null +++ b/src/pyglue/PyLook.h @@ -0,0 +1,50 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef INCLUDED_PYOCIO_PYLOOK_H +#define INCLUDED_PYOCIO_PYLOOK_H + +#include <PyOpenColorIO/PyOpenColorIO.h> + +OCIO_NAMESPACE_ENTER +{ + typedef struct { + PyObject_HEAD + ConstLookRcPtr * constcppobj; + LookRcPtr * cppobj; + bool isconst; + } PyOCIO_Look; + + extern PyTypeObject PyOCIO_LookType; + + bool AddLookObjectToModule( PyObject* m ); +} +OCIO_NAMESPACE_EXIT + +#endif diff --git a/src/pyglue/PyLookTransform.cpp b/src/pyglue/PyLookTransform.cpp new file mode 100644 index 0000000..6b57afb --- /dev/null +++ b/src/pyglue/PyLookTransform.cpp @@ -0,0 +1,343 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddLookTransformObjectToModule( PyObject* m ) + { + PyOCIO_LookTransformType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_LookTransformType) < 0 ) return false; + + Py_INCREF( &PyOCIO_LookTransformType ); + PyModule_AddObject(m, "LookTransform", + (PyObject *)&PyOCIO_LookTransformType); + + return true; + } + + bool IsPyLookTransform(PyObject * pyobject) + { + if(!pyobject) return false; + return PyObject_TypeCheck(pyobject, &PyOCIO_LookTransformType); + } + + ConstLookTransformRcPtr GetConstLookTransform(PyObject * pyobject, bool allowCast) + { + ConstLookTransformRcPtr transform = \ + DynamicPtrCast<const LookTransform>(GetConstTransform(pyobject, allowCast)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.LookTransform."); + } + return transform; + } + + LookTransformRcPtr GetEditableLookTransform(PyObject * pyobject) + { + LookTransformRcPtr transform = \ + DynamicPtrCast<LookTransform>(GetEditableTransform(pyobject)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.LookTransform."); + } + return transform; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_LookTransform_init( PyOCIO_Transform * self, PyObject * args, PyObject * kwds ); + + PyObject * PyOCIO_LookTransform_getSrc( PyObject * self ); + PyObject * PyOCIO_LookTransform_setSrc( PyObject * self, PyObject *args ); + PyObject * PyOCIO_LookTransform_getDst( PyObject * self ); + PyObject * PyOCIO_LookTransform_setDst( PyObject * self, PyObject *args ); + PyObject * PyOCIO_LookTransform_getLooks( PyObject * self ); + PyObject * PyOCIO_LookTransform_setLooks( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_LookTransform_methods[] = { + {"getSrc", + (PyCFunction) PyOCIO_LookTransform_getSrc, METH_NOARGS, LOOKTRANSFORM_GETSRC__DOC__ }, + {"setSrc", + PyOCIO_LookTransform_setSrc, METH_VARARGS, LOOKTRANSFORM_SETSRC__DOC__ }, + {"getDst", + (PyCFunction) PyOCIO_LookTransform_getDst, METH_NOARGS, LOOKTRANSFORM_GETDST__DOC__ }, + {"setDst", + PyOCIO_LookTransform_setDst, METH_VARARGS, LOOKTRANSFORM_SETDST__DOC__ }, + {"getLooks", + (PyCFunction) PyOCIO_LookTransform_getLooks, METH_NOARGS, LOOKTRANSFORM_GETLOOKS__DOC__ }, + {"setLooks", + PyOCIO_LookTransform_setLooks, METH_VARARGS, LOOKTRANSFORM_SETLOOKS__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_LookTransformType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.LookTransform", //tp_name + sizeof(PyOCIO_Transform), //tp_basicsize + 0, //tp_itemsize + 0, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + LOOKTRANSFORM__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_LookTransform_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + &PyOCIO_TransformType, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_LookTransform_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_LookTransform_init( PyOCIO_Transform *self, + PyObject * args, PyObject * kwds ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstTransformRcPtr(); + self->cppobj = new TransformRcPtr(); + self->isconst = true; + + // Parse optional kwargs + char * src = NULL; + char * dst = NULL; + char * looks = NULL; + char * direction = NULL; + + static const char *kwlist[] = { + "src", + "dst", + "looks", + "direction", + NULL + }; + + if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ssss", + const_cast<char **>(kwlist), + &src, &dst, &looks, &direction )) return -1; + + try + { + LookTransformRcPtr transform = LookTransform::Create(); + *self->cppobj = transform; + self->isconst = false; + + if(src) transform->setSrc(src); + if(dst) transform->setDst(dst); + if(looks) transform->setLooks(looks); + if(direction) transform->setDirection(TransformDirectionFromString(direction)); + + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create LookTransform: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_LookTransform_getSrc( PyObject * self ) + { + try + { + ConstLookTransformRcPtr transform = GetConstLookTransform(self, true); + return PyString_FromString( transform->getSrc() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_LookTransform_setSrc( PyObject * self, PyObject * args ) + { + try + { + const char * str = 0; + if (!PyArg_ParseTuple(args,"s:setSrc", + &str)) return NULL; + + LookTransformRcPtr transform = GetEditableLookTransform(self); + transform->setSrc( str ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_LookTransform_getDst( PyObject * self ) + { + try + { + ConstLookTransformRcPtr transform = GetConstLookTransform(self, true); + return PyString_FromString( transform->getDst() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_LookTransform_setDst( PyObject * self, PyObject * args ) + { + try + { + const char * str = 0; + if (!PyArg_ParseTuple(args,"s:setDst", + &str)) return NULL; + + LookTransformRcPtr transform = GetEditableLookTransform(self); + transform->setDst( str ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_LookTransform_getLooks( PyObject * self ) + { + try + { + ConstLookTransformRcPtr transform = GetConstLookTransform(self, true); + return PyString_FromString( transform->getLooks() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_LookTransform_setLooks( PyObject * self, PyObject * args ) + { + try + { + const char * str = 0; + if (!PyArg_ParseTuple(args,"s:setLooks", + &str)) return NULL; + + LookTransformRcPtr transform = GetEditableLookTransform(self); + transform->setLooks( str ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyMain.cpp b/src/pyglue/PyMain.cpp new file mode 100644 index 0000000..4feea32 --- /dev/null +++ b/src/pyglue/PyMain.cpp @@ -0,0 +1,236 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> +namespace OCIO = OCIO_NAMESPACE; + +#include "PyColorSpace.h" +#include "PyConfig.h" +#include "PyContext.h" +#include "PyConstants.h" +#include "PyLook.h" +#include "PyProcessor.h" +#include "PyProcessorMetadata.h" +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +namespace +{ + PyObject * PyOCIO_ClearAllCaches(PyObject * /* self */) + { + try + { + OCIO::ClearAllCaches(); + Py_RETURN_NONE; + } + catch(...) + { + OCIO::Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_GetLoggingLevel(PyObject * /* self */) + { + try + { + return PyString_FromString( + OCIO::LoggingLevelToString(OCIO::GetLoggingLevel()) ); + } + catch(...) + { + OCIO::Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_SetLoggingLevel(PyObject * /*self*/, PyObject * args) + { + try + { + PyObject * pylevel; + if (!PyArg_ParseTuple(args, "O:SetLoggingLevel", &pylevel)) + { + return NULL; + } + + // We explicitly cast to a str to handle both the str and int cases. + PyObject * pystr = PyObject_Str(pylevel); + if(!pystr) + { + throw OCIO::Exception("Fist argument must be a LOGGING_LEVEL"); + } + + OCIO::LoggingLevel level = OCIO::LoggingLevelFromString(PyString_AsString(pystr)); + OCIO::SetLoggingLevel(level); + + Py_DECREF(pystr); + + Py_RETURN_NONE; + } + catch(...) + { + OCIO::Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_GetCurrentConfig(PyObject * /* self */) + { + try + { + return OCIO::BuildConstPyConfig( OCIO::GetCurrentConfig() ); + } + catch(...) + { + OCIO::Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_SetCurrentConfig(PyObject * /*self*/, PyObject * args) + { + try + { + PyObject * pyconfig; + if (!PyArg_ParseTuple(args, "O!:SetCurrentConfig", + &OCIO::PyOCIO_ConfigType, &pyconfig)) + { + return NULL; + } + + OCIO::ConstConfigRcPtr c = OCIO::GetConstConfig(pyconfig, true); + OCIO::SetCurrentConfig(c); + + Py_RETURN_NONE; + } + catch(...) + { + OCIO::Python_Handle_Exception(); + return NULL; + } + } + + PyMethodDef PyOCIO_methods[] = { + {"ClearAllCaches", + (PyCFunction) PyOCIO_ClearAllCaches, METH_NOARGS, OCIO::OPENCOLORIO_CLEARALLCACHES__DOC__ }, + {"GetLoggingLevel", + (PyCFunction) PyOCIO_GetLoggingLevel, METH_NOARGS, OCIO::OPENCOLORIO_GETLOGGINGLEVEL__DOC__ }, + {"SetLoggingLevel", + (PyCFunction) PyOCIO_SetLoggingLevel, METH_VARARGS, OCIO::OPENCOLORIO_SETLOGGINGLEVEL__DOC__ }, + {"GetCurrentConfig", + (PyCFunction) PyOCIO_GetCurrentConfig, METH_NOARGS, OCIO::OPENCOLORIO_GETCURRENTCONFIG__DOC__ }, + {"SetCurrentConfig", + (PyCFunction) PyOCIO_SetCurrentConfig, METH_VARARGS, OCIO::OPENCOLORIO_SETCURRENTCONFIG__DOC__ }, + {NULL, NULL, 0, NULL} /* Sentinel */ + }; +} + +OCIO_NAMESPACE_ENTER +{ + namespace + { + PyObject * g_exceptionType = NULL; + PyObject * g_exceptionMissingFileType = NULL; + } + + // These are explicitly initialized in the init function + // to make sure they're not initialized until after the module is + + PyObject * GetExceptionPyType() + { + return g_exceptionType; + } + + void SetExceptionPyType(PyObject * pytypeobj) + { + g_exceptionType = pytypeobj; + } + + PyObject * GetExceptionMissingFilePyType() + { + return g_exceptionMissingFileType; + } + + void SetExceptionMissingFilePyType(PyObject * pytypeobj) + { + g_exceptionMissingFileType = pytypeobj; + } +} +OCIO_NAMESPACE_EXIT + +extern "C" +PyMODINIT_FUNC +initPyOpenColorIO(void) +{ + PyObject * m; + m = Py_InitModule3("PyOpenColorIO", PyOCIO_methods, OCIO::OPENCOLORIO__DOC__); + + PyModule_AddStringConstant(m, "version", OCIO::GetVersion()); + PyModule_AddIntConstant(m, "hexversion", OCIO::GetVersionHex()); + + // Create Exceptions, and add to the module + // TODO: add support for PyErr_NewExceptionWithDoc for python2.7+ + OCIO::SetExceptionPyType( + PyErr_NewException(const_cast<char*>("PyOpenColorIO.Exception"), + PyExc_RuntimeError, NULL)); + PyModule_AddObject(m, "Exception", OCIO::GetExceptionPyType()); + + // TODO: add support for PyErr_NewExceptionWithDoc for python2.7+ + OCIO::SetExceptionMissingFilePyType( + PyErr_NewException(const_cast<char*>("PyOpenColorIO.ExceptionMissingFile"), + OCIO::GetExceptionPyType(), NULL)); + PyModule_AddObject(m, "ExceptionMissingFile", OCIO::GetExceptionMissingFilePyType()); + + // Register Classes + + OCIO::AddColorSpaceObjectToModule( m ); + OCIO::AddConfigObjectToModule( m ); + OCIO::AddConstantsModule( m ); + OCIO::AddContextObjectToModule( m ); + OCIO::AddLookObjectToModule( m ); + OCIO::AddProcessorObjectToModule( m ); + OCIO::AddProcessorMetadataObjectToModule( m ); + + OCIO::AddTransformObjectToModule( m ); + { + OCIO::AddAllocationTransformObjectToModule( m ); + OCIO::AddCDLTransformObjectToModule( m ); + OCIO::AddColorSpaceTransformObjectToModule( m ); + OCIO::AddDisplayTransformObjectToModule( m ); + OCIO::AddExponentTransformObjectToModule( m ); + OCIO::AddFileTransformObjectToModule( m ); + OCIO::AddGroupTransformObjectToModule( m ); + OCIO::AddLogTransformObjectToModule( m ); + OCIO::AddLookTransformObjectToModule( m ); + OCIO::AddMatrixTransformObjectToModule( m ); + } +} diff --git a/src/pyglue/PyMatrixTransform.cpp b/src/pyglue/PyMatrixTransform.cpp new file mode 100644 index 0000000..f0a0012 --- /dev/null +++ b/src/pyglue/PyMatrixTransform.cpp @@ -0,0 +1,630 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddMatrixTransformObjectToModule( PyObject* m ) + { + PyOCIO_MatrixTransformType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_MatrixTransformType) < 0 ) return false; + + Py_INCREF( &PyOCIO_MatrixTransformType ); + PyModule_AddObject(m, "MatrixTransform", + (PyObject *)&PyOCIO_MatrixTransformType); + + return true; + } + + bool IsPyMatrixTransform(PyObject * pyobject) + { + if(!pyobject) return false; + return PyObject_TypeCheck(pyobject, &PyOCIO_MatrixTransformType); + } + + ConstMatrixTransformRcPtr GetConstMatrixTransform(PyObject * pyobject, bool allowCast) + { + ConstMatrixTransformRcPtr transform = \ + DynamicPtrCast<const MatrixTransform>(GetConstTransform(pyobject, allowCast)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.MatrixTransform."); + } + return transform; + } + + MatrixTransformRcPtr GetEditableMatrixTransform(PyObject * pyobject) + { + MatrixTransformRcPtr transform = \ + DynamicPtrCast<MatrixTransform>(GetEditableTransform(pyobject)); + if(!transform) + { + throw Exception("PyObject must be a valid OCIO.MatrixTransform."); + } + return transform; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_MatrixTransform_init( PyOCIO_Transform * self, + PyObject * args, PyObject * kwds ); + + PyObject * PyOCIO_MatrixTransform_getValue( PyObject * self ); + PyObject * PyOCIO_MatrixTransform_setValue( PyObject * self, PyObject *args ); + PyObject * PyOCIO_MatrixTransform_getMatrix( PyObject * self ); + PyObject * PyOCIO_MatrixTransform_setMatrix( PyObject * self, PyObject *args ); + PyObject * PyOCIO_MatrixTransform_getOffset( PyObject * self ); + PyObject * PyOCIO_MatrixTransform_setOffset( PyObject * self, PyObject *args ); + + PyObject * PyOCIO_MatrixTransform_Identity( PyObject * cls ); + PyObject * PyOCIO_MatrixTransform_Fit( PyObject * cls, PyObject * args ); + PyObject * PyOCIO_MatrixTransform_Sat( PyObject * cls, PyObject * args ); + PyObject * PyOCIO_MatrixTransform_Scale( PyObject * cls, PyObject * args ); + PyObject * PyOCIO_MatrixTransform_View( PyObject * cls, PyObject * args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_MatrixTransform_methods[] = { + {"getValue", + (PyCFunction) PyOCIO_MatrixTransform_getValue, METH_NOARGS, MATRIXTRANSFORM_GETVALUE__DOC__ }, + {"setValue", + PyOCIO_MatrixTransform_setValue, METH_VARARGS, MATRIXTRANSFORM_SETVALUE__DOC__ }, + {"getMatrix", + (PyCFunction) PyOCIO_MatrixTransform_getMatrix, METH_NOARGS, MATRIXTRANSFORM_GETMATRIX__DOC__ }, + {"setMatrix", + PyOCIO_MatrixTransform_setMatrix, METH_VARARGS, MATRIXTRANSFORM_SETMATRIX__DOC__ }, + {"getOffset", + (PyCFunction) PyOCIO_MatrixTransform_getOffset, METH_NOARGS, MATRIXTRANSFORM_GETOFFSET__DOC__ }, + {"setOffset", + PyOCIO_MatrixTransform_setOffset, METH_VARARGS, MATRIXTRANSFORM_SETOFFSET__DOC__ }, + {"Identity", + (PyCFunction) PyOCIO_MatrixTransform_Identity, METH_NOARGS | METH_CLASS, MATRIXTRANSFORM_IDENTITY__DOC__ }, + {"Fit", + PyOCIO_MatrixTransform_Fit, METH_VARARGS | METH_CLASS, MATRIXTRANSFORM_FIT__DOC__ }, + {"Sat", + PyOCIO_MatrixTransform_Sat, METH_VARARGS | METH_CLASS, MATRIXTRANSFORM_SAT__DOC__ }, + {"Scale", + PyOCIO_MatrixTransform_Scale, METH_VARARGS | METH_CLASS, MATRIXTRANSFORM_SCALE__DOC__ }, + {"View", + PyOCIO_MatrixTransform_View, METH_VARARGS | METH_CLASS, MATRIXTRANSFORM_VIEW__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_MatrixTransformType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.MatrixTransform", //tp_name + sizeof(PyOCIO_Transform), //tp_basicsize + 0, //tp_itemsize + 0, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + MATRIXTRANSFORM__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_MatrixTransform_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + &PyOCIO_TransformType, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_MatrixTransform_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_MatrixTransform_init( PyOCIO_Transform *self, + PyObject * /*args*/, PyObject * /*kwds*/ ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstTransformRcPtr(); + self->cppobj = new TransformRcPtr(); + self->isconst = true; + + try + { + *self->cppobj = MatrixTransform::Create(); + self->isconst = false; + return 0; + } + catch ( const std::exception & e ) + { + std::string message = "Cannot create MatrixTransform: "; + message += e.what(); + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_MatrixTransform_getValue( PyObject * self ) + { + try + { + ConstMatrixTransformRcPtr transform = GetConstMatrixTransform(self, true); + + std::vector<float> matrix(16); + std::vector<float> offset(4); + + transform->getValue(&matrix[0], &offset[0]); + + PyObject* pymatrix = CreatePyListFromFloatVector(matrix); + PyObject* pyoffset = CreatePyListFromFloatVector(offset); + + PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset); + Py_DECREF(pymatrix); + Py_DECREF(pyoffset); + + return pyreturnval; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_MatrixTransform_setValue( PyObject * self, PyObject * args ) + { + try + { + PyObject * pymatrix = 0; + PyObject * pyoffset = 0; + if (!PyArg_ParseTuple(args,"OO:setValue", + &pymatrix, &pyoffset)) return NULL; + + std::vector<float> matrix; + std::vector<float> offset; + + if(!FillFloatVectorFromPySequence(pymatrix, matrix) || + (matrix.size() != 16)) + { + PyErr_SetString(PyExc_TypeError, + "First argument must be a float array, size 16"); + return 0; + } + + if(!FillFloatVectorFromPySequence(pyoffset, offset) || + (offset.size() != 4)) + { + PyErr_SetString(PyExc_TypeError, + "Second argument must be a float array, size 4"); + return 0; + } + + MatrixTransformRcPtr transform = GetEditableMatrixTransform(self); + transform->setValue(&matrix[0], &offset[0]); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_MatrixTransform_getMatrix( PyObject * self ) + { + try + { + ConstMatrixTransformRcPtr transform = GetConstMatrixTransform(self, true); + + std::vector<float> matrix(16); + transform->getMatrix(&matrix[0]); + + return CreatePyListFromFloatVector(matrix); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_MatrixTransform_setMatrix( PyObject * self, PyObject * args ) + { + try + { + PyObject * pymatrix = 0; + if (!PyArg_ParseTuple(args,"O:setValue", &pymatrix)) return NULL; + + std::vector<float> matrix; + + if(!FillFloatVectorFromPySequence(pymatrix, matrix) || + (matrix.size() != 16)) + { + PyErr_SetString(PyExc_TypeError, + "First argument must be a float array, size 16"); + return 0; + } + + MatrixTransformRcPtr transform = GetEditableMatrixTransform(self); + transform->setMatrix(&matrix[0]); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_MatrixTransform_getOffset( PyObject * self ) + { + try + { + ConstMatrixTransformRcPtr transform = GetConstMatrixTransform(self, true); + + std::vector<float> offset(4); + transform->getOffset(&offset[0]); + + return CreatePyListFromFloatVector(offset); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_MatrixTransform_setOffset( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyoffset = 0; + if (!PyArg_ParseTuple(args,"O:setValue", &pyoffset)) return NULL; + + std::vector<float> offset; + + if(!FillFloatVectorFromPySequence(pyoffset, offset) || + (offset.size() != 4)) + { + PyErr_SetString(PyExc_TypeError, + "First argument must be a float array, size 4"); + return 0; + } + + MatrixTransformRcPtr transform = GetEditableMatrixTransform(self); + transform->setOffset(&offset[0]); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_MatrixTransform_Identity( PyObject * /*cls*/ ) + { + try + { + std::vector<float> matrix(16); + std::vector<float> offset(4); + + MatrixTransform::Identity(&matrix[0], &offset[0]); + + PyObject* pymatrix = CreatePyListFromFloatVector(matrix); + PyObject* pyoffset = CreatePyListFromFloatVector(offset); + + PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset); + Py_DECREF(pymatrix); + Py_DECREF(pyoffset); + + return pyreturnval; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_MatrixTransform_Fit( PyObject * /*cls*/, PyObject * args ) + { + try + { + PyObject * pyoldmin = 0; + PyObject * pyoldmax = 0; + PyObject * pynewmin = 0; + PyObject * pynewmax = 0; + + if (!PyArg_ParseTuple(args,"OOOO:Fit", + &pyoldmin, &pyoldmax, &pynewmin, &pynewmax)) return NULL; + + std::vector<float> oldmin; + std::vector<float> oldmax; + std::vector<float> newmin; + std::vector<float> newmax; + + if(!FillFloatVectorFromPySequence(pyoldmin, oldmin) || + (oldmin.size() != 4)) + { + PyErr_SetString(PyExc_TypeError, + "First argument must be a float array, size 4"); + return 0; + } + + if(!FillFloatVectorFromPySequence(pyoldmax, oldmax) || + (oldmax.size() != 4)) + { + PyErr_SetString(PyExc_TypeError, + "Second argument must be a float array, size 4"); + return 0; + } + + if(!FillFloatVectorFromPySequence(pynewmin, newmin) || + (newmin.size() != 4)) + { + PyErr_SetString(PyExc_TypeError, + "Third argument must be a float array, size 4"); + return 0; + } + + if(!FillFloatVectorFromPySequence(pynewmax, newmax) || + (newmax.size() != 4)) + { + PyErr_SetString(PyExc_TypeError, + "Fourth argument must be a float array, size 4"); + return 0; + } + + + std::vector<float> matrix(16); + std::vector<float> offset(4); + + MatrixTransform::Fit(&matrix[0], &offset[0], + &oldmin[0], &oldmax[0], + &newmin[0], &newmax[0]); + + PyObject* pymatrix = CreatePyListFromFloatVector(matrix); + PyObject* pyoffset = CreatePyListFromFloatVector(offset); + + PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset); + Py_DECREF(pymatrix); + Py_DECREF(pyoffset); + + return pyreturnval; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_MatrixTransform_Sat( PyObject * /*cls*/, PyObject * args ) + { + try + { + float sat = 0.0; + PyObject * pyluma = 0; + + if (!PyArg_ParseTuple(args,"fO:Sat", + &sat, &pyluma)) return NULL; + + std::vector<float> luma; + + if(!FillFloatVectorFromPySequence(pyluma, luma) || + (luma.size() != 3)) + { + PyErr_SetString(PyExc_TypeError, + "Second argument must be a float array, size 3"); + return 0; + } + + std::vector<float> matrix(16); + std::vector<float> offset(4); + + MatrixTransform::Sat(&matrix[0], &offset[0], + sat, &luma[0]); + + PyObject* pymatrix = CreatePyListFromFloatVector(matrix); + PyObject* pyoffset = CreatePyListFromFloatVector(offset); + + PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset); + Py_DECREF(pymatrix); + Py_DECREF(pyoffset); + + return pyreturnval; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_MatrixTransform_Scale( PyObject * /*cls*/, PyObject * args ) + { + try + { + PyObject * pyscale = 0; + + if (!PyArg_ParseTuple(args,"O:Scale", + &pyscale)) return NULL; + + std::vector<float> scale; + + if(!FillFloatVectorFromPySequence(pyscale, scale) || + (scale.size() != 4)) + { + PyErr_SetString(PyExc_TypeError, + "Second argument must be a float array, size 4"); + return 0; + } + + std::vector<float> matrix(16); + std::vector<float> offset(4); + + MatrixTransform::Scale(&matrix[0], &offset[0], + &scale[0]); + + PyObject* pymatrix = CreatePyListFromFloatVector(matrix); + PyObject* pyoffset = CreatePyListFromFloatVector(offset); + + PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset); + Py_DECREF(pymatrix); + Py_DECREF(pyoffset); + + return pyreturnval; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_MatrixTransform_View( PyObject * /*cls*/, PyObject * args ) + { + try + { + PyObject * pychannelhot = 0; + PyObject * pyluma = 0; + + if (!PyArg_ParseTuple(args,"OO:View", + &pychannelhot, &pyluma)) return NULL; + + std::vector<int> channelhot; + std::vector<float> luma; + + if(!FillIntVectorFromPySequence(pychannelhot, channelhot) || + (channelhot.size() != 4)) + { + PyErr_SetString(PyExc_TypeError, + "First argument must be a bool/int array, size 4"); + return 0; + } + + if(!FillFloatVectorFromPySequence(pyluma, luma) || + (luma.size() != 3)) + { + PyErr_SetString(PyExc_TypeError, + "Second argument must be a float array, size 3"); + return 0; + } + + std::vector<float> matrix(16); + std::vector<float> offset(4); + + MatrixTransform::View(&matrix[0], &offset[0], + &channelhot[0], &luma[0]); + + PyObject* pymatrix = CreatePyListFromFloatVector(matrix); + PyObject* pyoffset = CreatePyListFromFloatVector(offset); + + PyObject* pyreturnval = Py_BuildValue("(OO)", pymatrix, pyoffset); + Py_DECREF(pymatrix); + Py_DECREF(pyoffset); + + return pyreturnval; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyProcessor.cpp b/src/pyglue/PyProcessor.cpp new file mode 100644 index 0000000..e393041 --- /dev/null +++ b/src/pyglue/PyProcessor.cpp @@ -0,0 +1,500 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyProcessor.h" +#include "PyUtil.h" +#include "PyDoc.h" + +#include <sstream> + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddProcessorObjectToModule( PyObject* m ) + { + PyOCIO_ProcessorType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_ProcessorType) < 0 ) return false; + + Py_INCREF( &PyOCIO_ProcessorType ); + PyModule_AddObject(m, "Processor", + (PyObject *)&PyOCIO_ProcessorType); + + return true; + } + + PyObject * BuildConstPyProcessor(ConstProcessorRcPtr processor) + { + if (!processor) + { + Py_RETURN_NONE; + } + + PyOCIO_Processor * pyProcessor = PyObject_New( + PyOCIO_Processor, (PyTypeObject * ) &PyOCIO_ProcessorType); + + pyProcessor->constcppobj = new ConstProcessorRcPtr(); + *pyProcessor->constcppobj = processor; + + return ( PyObject * ) pyProcessor; + } + + bool IsPyProcessor(PyObject * pyobject) + { + if(!pyobject) return false; + return (PyObject_Type(pyobject) == (PyObject *) (&PyOCIO_ProcessorType)); + } + + ConstProcessorRcPtr GetConstProcessor(PyObject * pyobject) + { + if(!IsPyProcessor(pyobject)) + { + throw Exception("PyObject must be an OCIO.Processor."); + } + + PyOCIO_Processor * pyProcessor = reinterpret_cast<PyOCIO_Processor *> (pyobject); + if(pyProcessor->constcppobj) + { + return *pyProcessor->constcppobj; + } + + throw Exception("PyObject must be a valid OCIO.Processor."); + } + + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_Processor_init( PyOCIO_Processor * self, PyObject * args, PyObject * kwds ); + void PyOCIO_Processor_delete( PyOCIO_Processor * self, PyObject * args ); + + PyObject * PyOCIO_Processor_isNoOp( PyObject * self ); + PyObject * PyOCIO_Processor_hasChannelCrosstalk( PyObject * self ); + PyObject * PyOCIO_Processor_getMetadata( PyObject * self ); + PyObject * PyOCIO_Processor_applyRGB( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Processor_applyRGBA( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Processor_getCpuCacheID( PyObject * self ); + + PyObject * PyOCIO_Processor_getGpuShaderText( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Processor_getGpuShaderTextCacheID( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Processor_getGpuLut3D( PyObject * self, PyObject * args ); + PyObject * PyOCIO_Processor_getGpuLut3DCacheID( PyObject * self, PyObject * args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_Processor_methods[] = { + {"isNoOp", + (PyCFunction) PyOCIO_Processor_isNoOp, METH_NOARGS, PROCESSOR_ISNOOP__DOC__ }, + {"hasChannelCrosstalk", + (PyCFunction) PyOCIO_Processor_hasChannelCrosstalk, METH_NOARGS, PROCESSOR_HASCHANNELCROSSTALK__DOC__ }, + {"getMetadata", + (PyCFunction) PyOCIO_Processor_getMetadata, METH_NOARGS, PROCESSOR_GETMETADATA__DOC__ }, + {"applyRGB", + PyOCIO_Processor_applyRGB, METH_VARARGS, PROCESSOR_APPLYRGB__DOC__ }, + {"applyRGBA", + PyOCIO_Processor_applyRGBA, METH_VARARGS, PROCESSOR_APPLYRGBA__DOC__ }, + {"getCpuCacheID", + (PyCFunction) PyOCIO_Processor_getCpuCacheID, METH_NOARGS, PROCESSOR_GETCPUCACHEID__DOC__ }, + {"getGpuShaderText", + PyOCIO_Processor_getGpuShaderText, METH_VARARGS, PROCESSOR_GETGPUSHADERTEXT__DOC__ }, + {"getGpuShaderTextCacheID", + PyOCIO_Processor_getGpuShaderTextCacheID, METH_VARARGS, PROCESSOR_GETGPUSHADERTEXTCACHEID__DOC__ }, + {"getGpuLut3D", + PyOCIO_Processor_getGpuLut3D, METH_VARARGS, PROCESSOR_GETGPULUT3D__DOC__ }, + {"getGpuLut3DCacheID", + PyOCIO_Processor_getGpuLut3DCacheID, METH_VARARGS, PROCESSOR_GETGPULUT3DCACHEID__DOC__ }, + {NULL, NULL, 0, NULL} + }; + + const char initMessage[] = + "Processor objects cannot be instantiated directly. " + "Please use config.getProcessor() instead."; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_ProcessorType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.Processor", //tp_name + sizeof(PyOCIO_Processor), //tp_basicsize + 0, //tp_itemsize + (destructor)PyOCIO_Processor_delete, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + PROCESSOR__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_Processor_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + 0, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_Processor_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + // TODO: The use of a dict, rather than a native class is not ideal + // in the next API revision, use a native type. + + void FillShaderDescFromPyDict(GpuShaderDesc & shaderDesc, + PyObject * dict) + { + if(!PyDict_Check(dict)) + { + throw Exception("GpuShaderDesc must be a dict type."); + } + + PyObject *key, *value; + Py_ssize_t pos = 0; + + while (PyDict_Next(dict, &pos, &key, &value)) + { + std::string keystr; + if(!GetStringFromPyObject(key, &keystr)) + throw Exception("GpuShaderDesc keys must be strings."); + + if(keystr == "language") + { + GpuLanguage language = GPU_LANGUAGE_UNKNOWN; + if(ConvertPyObjectToGpuLanguage(value, &language) == 0) + throw Exception("GpuShaderDesc language must be a GpuLanguage."); + shaderDesc.setLanguage(language); + } + else if(keystr == "functionName") + { + std::string functionName; + if(!GetStringFromPyObject(value, &functionName)) + throw Exception("GpuShaderDesc functionName must be a string."); + shaderDesc.setFunctionName(functionName.c_str()); + } + else if(keystr == "lut3DEdgeLen") + { + int lut3DEdgeLen = 0; + if(!GetIntFromPyObject(value, &lut3DEdgeLen)) + throw Exception("GpuShaderDesc lut3DEdgeLen must be an integer."); + shaderDesc.setLut3DEdgeLen(lut3DEdgeLen); + } + else + { + std::ostringstream os; + os << "Unknown GpuShaderDesc key, '"; + os << keystr << "'. "; + os << "Allowed keys: ("; + os << "'language', 'functionName', 'lut3DEdgeLen')."; + throw Exception(os.str().c_str()); + } + } + } + } + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_Processor_init( PyOCIO_Processor */*self*/, + PyObject * /*args*/, PyObject * /*kwds*/ ) + { + PyErr_SetString( PyExc_RuntimeError, initMessage); + return -1; + } + + void PyOCIO_Processor_delete( PyOCIO_Processor *self, PyObject * /*args*/ ) + { + delete self->constcppobj; + self->ob_type->tp_free((PyObject*)self); + } + + PyObject * PyOCIO_Processor_isNoOp( PyObject * self ) + { + try + { + ConstProcessorRcPtr processor = GetConstProcessor(self); + return PyBool_FromLong( processor->isNoOp() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Processor_hasChannelCrosstalk( PyObject * self ) + { + try + { + ConstProcessorRcPtr processor = GetConstProcessor(self); + return PyBool_FromLong( processor->hasChannelCrosstalk() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Processor_getMetadata( PyObject * self ) + { + try + { + ConstProcessorRcPtr processor = GetConstProcessor(self); + return BuildConstPyProcessorMetadata( processor->getMetadata() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Processor_applyRGB( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyData = 0; + if (!PyArg_ParseTuple(args,"O:applyRGB", &pyData)) return NULL; + + ConstProcessorRcPtr processor = GetConstProcessor(self); + if(processor->isNoOp()) + { + Py_INCREF(pyData); + return pyData; + } + + std::vector<float> data; + if(!FillFloatVectorFromPySequence(pyData, data) || ((data.size()%3) != 0)) + { + std::ostringstream os; + os << "First argument must be a float array, size multiple of 3. "; + os << "Size: " << data.size() << "."; + PyErr_SetString(PyExc_TypeError, os.str().c_str()); + return 0; + } + + PackedImageDesc img(&data[0], data.size()/3, 1, 3); + processor->apply(img); + + return CreatePyListFromFloatVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Processor_applyRGBA( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyData = 0; + if (!PyArg_ParseTuple(args,"O:applyRGBA", &pyData)) return NULL; + + ConstProcessorRcPtr processor = GetConstProcessor(self); + if(processor->isNoOp()) + { + Py_INCREF(pyData); + return pyData; + } + + std::vector<float> data; + if(!FillFloatVectorFromPySequence(pyData, data) || ((data.size()%4) != 0)) + { + std::ostringstream os; + os << "First argument must be a float array, size multiple of 4. "; + os << "Size: " << data.size() << "."; + PyErr_SetString(PyExc_TypeError, os.str().c_str()); + return 0; + } + + PackedImageDesc img(&data[0], data.size()/4, 1, 4); + processor->apply(img); + + return CreatePyListFromFloatVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Processor_getCpuCacheID( PyObject * self ) + { + try + { + ConstProcessorRcPtr processor = GetConstProcessor(self); + return PyString_FromString( processor->getCpuCacheID() ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Processor_getGpuShaderText( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyData = 0; + if (!PyArg_ParseTuple(args,"O!:getGpuShaderText", + &PyDict_Type, &pyData)) return NULL; + ConstProcessorRcPtr processor = GetConstProcessor(self); + + GpuShaderDesc shaderDesc; + FillShaderDescFromPyDict(shaderDesc, pyData); + + return PyString_FromString( processor->getGpuShaderText(shaderDesc) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Processor_getGpuShaderTextCacheID( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyData = 0; + if (!PyArg_ParseTuple(args,"O!:getGpuShaderTextCacheID", + &PyDict_Type, &pyData)) return NULL; + ConstProcessorRcPtr processor = GetConstProcessor(self); + + GpuShaderDesc shaderDesc; + FillShaderDescFromPyDict(shaderDesc, pyData); + + return PyString_FromString( processor->getGpuShaderTextCacheID(shaderDesc) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Processor_getGpuLut3D( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyData = 0; + if (!PyArg_ParseTuple(args,"O!:getGpuLut3D", + &PyDict_Type, &pyData)) return NULL; + ConstProcessorRcPtr processor = GetConstProcessor(self); + + GpuShaderDesc shaderDesc; + FillShaderDescFromPyDict(shaderDesc, pyData); + + int len = shaderDesc.getLut3DEdgeLen(); + std::vector<float> lut3d(3*len*len*len); + + // TODO: return more compact binary data? (ex array, ...) + processor->getGpuLut3D(&lut3d[0], shaderDesc); + return CreatePyListFromFloatVector(lut3d); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Processor_getGpuLut3DCacheID( PyObject * self, PyObject * args ) + { + try + { + PyObject * pyData = 0; + if (!PyArg_ParseTuple(args,"O!:getGpuLut3DCacheID", + &PyDict_Type, &pyData)) return NULL; + ConstProcessorRcPtr processor = GetConstProcessor(self); + + GpuShaderDesc shaderDesc; + FillShaderDescFromPyDict(shaderDesc, pyData); + + return PyString_FromString( processor->getGpuLut3DCacheID(shaderDesc) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyProcessor.h b/src/pyglue/PyProcessor.h new file mode 100644 index 0000000..571847d --- /dev/null +++ b/src/pyglue/PyProcessor.h @@ -0,0 +1,50 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef INCLUDED_PYOCIO_PYPROCESSOR_H +#define INCLUDED_PYOCIO_PYPROCESSOR_H + +#include <PyOpenColorIO/PyOpenColorIO.h> + +OCIO_NAMESPACE_ENTER +{ + // TODO: Maybe put this in a pyinternal namespace? + + typedef struct { + PyObject_HEAD + ConstProcessorRcPtr * constcppobj; + } PyOCIO_Processor; + + extern PyTypeObject PyOCIO_ProcessorType; + + bool AddProcessorObjectToModule( PyObject* m ); +} +OCIO_NAMESPACE_EXIT + +#endif diff --git a/src/pyglue/PyProcessorMetadata.cpp b/src/pyglue/PyProcessorMetadata.cpp new file mode 100644 index 0000000..f8a4a92 --- /dev/null +++ b/src/pyglue/PyProcessorMetadata.cpp @@ -0,0 +1,245 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyProcessorMetadata.h" +#include "PyUtil.h" +#include "PyDoc.h" + +#include <sstream> + +OCIO_NAMESPACE_ENTER +{ + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddProcessorMetadataObjectToModule( PyObject* m ) + { + PyOCIO_ProcessorMetadataType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_ProcessorMetadataType) < 0 ) return false; + + Py_INCREF( &PyOCIO_ProcessorMetadataType ); + PyModule_AddObject(m, "ProcessorMetadata", + (PyObject *)&PyOCIO_ProcessorMetadataType); + + return true; + } + + PyObject * BuildConstPyProcessorMetadata(ConstProcessorMetadataRcPtr metadata) + { + if (!metadata) + { + Py_RETURN_NONE; + } + + PyOCIO_ProcessorMetadata * pyMetadata = PyObject_New( + PyOCIO_ProcessorMetadata, (PyTypeObject * ) &PyOCIO_ProcessorMetadataType); + + pyMetadata->constcppobj = new ConstProcessorMetadataRcPtr(); + *pyMetadata->constcppobj = metadata; + + return ( PyObject * ) pyMetadata; + } + + bool IsPyProcessorMetadata(PyObject * pyobject) + { + if(!pyobject) return false; + return (PyObject_Type(pyobject) == (PyObject *) (&PyOCIO_ProcessorMetadataType)); + } + + ConstProcessorMetadataRcPtr GetConstProcessorMetadata(PyObject * pyobject) + { + if(!IsPyProcessorMetadata(pyobject)) + { + throw Exception("PyObject must be an OCIO.ProcessorMetadata."); + } + + PyOCIO_ProcessorMetadata * pyMetadata = reinterpret_cast<PyOCIO_ProcessorMetadata *> (pyobject); + if(pyMetadata->constcppobj) + { + return *pyMetadata->constcppobj; + } + + throw Exception("PyObject must be a valid OCIO.ProcessorMetadata."); + } + + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + int PyOCIO_ProcessorMetadata_init( PyOCIO_ProcessorMetadata * self, PyObject * args, PyObject * kwds ); + void PyOCIO_ProcessorMetadata_delete( PyOCIO_ProcessorMetadata * self, PyObject * args ); + + PyObject * PyOCIO_ProcessorMetadata_getFiles( PyObject * self ); + PyObject * PyOCIO_ProcessorMetadata_getLooks( PyObject * self ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_ProcessorMetadata_methods[] = { + {"getFiles", + (PyCFunction) PyOCIO_ProcessorMetadata_getFiles, METH_NOARGS, + PROCESSORMETADATA_GETFILES__DOC__ }, + {"getLooks", + (PyCFunction) PyOCIO_ProcessorMetadata_getLooks, METH_NOARGS, + PROCESSORMETADATA_GETLOOKS__DOC__ }, + {NULL, NULL, 0, NULL} + }; + + const char initMessage[] = + "ProcessorMetadata objects cannot be instantiated directly. " + "Please use processor.getMetadata() instead."; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_ProcessorMetadataType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.ProcessorMetadata", //tp_name + sizeof(PyOCIO_ProcessorMetadata), //tp_basicsize + 0, //tp_itemsize + (destructor)PyOCIO_ProcessorMetadata_delete,//tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + PROCESSORMETADATA__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_ProcessorMetadata_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + 0, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_ProcessorMetadata_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_ProcessorMetadata_init( PyOCIO_ProcessorMetadata */*self*/, + PyObject * /*args*/, PyObject * /*kwds*/ ) + { + PyErr_SetString( PyExc_RuntimeError, initMessage); + return -1; + } + + void PyOCIO_ProcessorMetadata_delete( PyOCIO_ProcessorMetadata *self, PyObject * /*args*/ ) + { + delete self->constcppobj; + self->ob_type->tp_free((PyObject*)self); + } + + PyObject * PyOCIO_ProcessorMetadata_getFiles( PyObject * self ) + { + try + { + ConstProcessorMetadataRcPtr metadata = GetConstProcessorMetadata(self); + + std::vector<std::string> data; + for(int i=0; i<metadata->getNumFiles(); ++i) + { + data.push_back(metadata->getFile(i)); + } + + return CreatePyListFromStringVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_ProcessorMetadata_getLooks( PyObject * self ) + { + try + { + ConstProcessorMetadataRcPtr metadata = GetConstProcessorMetadata(self); + + std::vector<std::string> data; + for(int i=0; i<metadata->getNumLooks(); ++i) + { + data.push_back(metadata->getLook(i)); + } + + return CreatePyListFromStringVector(data); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + } // anon namespace + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyProcessorMetadata.h b/src/pyglue/PyProcessorMetadata.h new file mode 100644 index 0000000..4aada84 --- /dev/null +++ b/src/pyglue/PyProcessorMetadata.h @@ -0,0 +1,50 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef INCLUDED_PYOCIO_PYPROCESSORMETADATA_H +#define INCLUDED_PYOCIO_PYPROCESSORMETADATA_H + +#include <PyOpenColorIO/PyOpenColorIO.h> + +OCIO_NAMESPACE_ENTER +{ + // TODO: Maybe put this in a pyinternal namespace? + + typedef struct { + PyObject_HEAD + ConstProcessorMetadataRcPtr * constcppobj; + } PyOCIO_ProcessorMetadata; + + extern PyTypeObject PyOCIO_ProcessorMetadataType; + + bool AddProcessorMetadataObjectToModule( PyObject* m ); +} +OCIO_NAMESPACE_EXIT + +#endif diff --git a/src/pyglue/PyTransform.cpp b/src/pyglue/PyTransform.cpp new file mode 100644 index 0000000..848e966 --- /dev/null +++ b/src/pyglue/PyTransform.cpp @@ -0,0 +1,411 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyTransform.h" +#include "PyUtil.h" +#include "PyDoc.h" + +#include <sstream> + +OCIO_NAMESPACE_ENTER +{ + namespace + { + PyOCIO_Transform * PyTransform_New(ConstTransformRcPtr transform) + { + if (!transform) + { + return 0x0; + } + + PyOCIO_Transform * pyobj = 0x0; + + if(ConstAllocationTransformRcPtr allocationTransform = \ + DynamicPtrCast<const AllocationTransform>(transform)) + { + pyobj = PyObject_New(PyOCIO_Transform, + (PyTypeObject * ) &PyOCIO_AllocationTransformType); + } + else if(ConstCDLTransformRcPtr cdlTransform = \ + DynamicPtrCast<const CDLTransform>(transform)) + { + pyobj = PyObject_New(PyOCIO_Transform, + (PyTypeObject * ) &PyOCIO_CDLTransformType); + } + else if(ConstColorSpaceTransformRcPtr colorSpaceTransform = \ + DynamicPtrCast<const ColorSpaceTransform>(transform)) + { + pyobj = PyObject_New(PyOCIO_Transform, + (PyTypeObject * ) &PyOCIO_ColorSpaceTransformType); + } + else if(ConstDisplayTransformRcPtr displayTransform = \ + DynamicPtrCast<const DisplayTransform>(transform)) + { + pyobj = PyObject_New(PyOCIO_Transform, + (PyTypeObject * ) &PyOCIO_DisplayTransformType); + } + else if(ConstExponentTransformRcPtr exponentTransform = \ + DynamicPtrCast<const ExponentTransform>(transform)) + { + pyobj = PyObject_New(PyOCIO_Transform, + (PyTypeObject * ) &PyOCIO_ExponentTransformType); + } + else if(ConstFileTransformRcPtr fileTransform = \ + DynamicPtrCast<const FileTransform>(transform)) + { + pyobj = PyObject_New(PyOCIO_Transform, + (PyTypeObject * ) &PyOCIO_FileTransformType); + } + else if(ConstGroupTransformRcPtr groupTransform = \ + DynamicPtrCast<const GroupTransform>(transform)) + { + pyobj = PyObject_New(PyOCIO_Transform, + (PyTypeObject * ) &PyOCIO_GroupTransformType); + } + else if(ConstLogTransformRcPtr logTransform = \ + DynamicPtrCast<const LogTransform>(transform)) + { + pyobj = PyObject_New(PyOCIO_Transform, + (PyTypeObject * ) &PyOCIO_LogTransformType); + } + else if(ConstLookTransformRcPtr lookTransform = \ + DynamicPtrCast<const LookTransform>(transform)) + { + pyobj = PyObject_New(PyOCIO_Transform, + (PyTypeObject * ) &PyOCIO_LookTransformType); + } + else if(ConstMatrixTransformRcPtr matrixTransform = \ + DynamicPtrCast<const MatrixTransform>(transform)) + { + pyobj = PyObject_New(PyOCIO_Transform, + (PyTypeObject * ) &PyOCIO_MatrixTransformType); + } + + return pyobj; + } + } + + PyObject * BuildConstPyTransform(ConstTransformRcPtr transform) + { + if (!transform) + { + Py_RETURN_NONE; + } + + PyOCIO_Transform * pyobj = PyTransform_New(transform); + + if(!pyobj) + { + std::ostringstream os; + os << "Unknown transform type for BuildConstPyTransform."; + throw Exception(os.str().c_str()); + } + + pyobj->constcppobj = new ConstTransformRcPtr(); + pyobj->cppobj = new TransformRcPtr(); + + *pyobj->constcppobj = transform; + pyobj->isconst = true; + + return (PyObject *) pyobj; + } + + PyObject * BuildEditablePyTransform(TransformRcPtr transform) + { + if (!transform) + { + Py_RETURN_NONE; + } + + PyOCIO_Transform * pyobj = PyTransform_New(transform); + + pyobj->constcppobj = new ConstTransformRcPtr(); + pyobj->cppobj = new TransformRcPtr(); + + *pyobj->cppobj = transform; + pyobj->isconst = false; + + return (PyObject *) pyobj; + } + + bool IsPyTransform(PyObject * pyobject) + { + if(!pyobject) return false; + return PyObject_TypeCheck(pyobject, &PyOCIO_TransformType); + } + + bool IsPyTransformEditable(PyObject * pyobject) + { + if(!IsPyTransform(pyobject)) return false; + + PyOCIO_Transform * pyobj = reinterpret_cast<PyOCIO_Transform *> (pyobject); + return (!pyobj->isconst); + } + + TransformRcPtr GetEditableTransform(PyObject * pyobject) + { + if(!IsPyTransform(pyobject)) + { + throw Exception("PyObject must be an OCIO.Transform."); + } + + PyOCIO_Transform * pytransform = reinterpret_cast<PyOCIO_Transform *> (pyobject); + if(!pytransform->isconst && pytransform->cppobj) + { + return *pytransform->cppobj; + } + + throw Exception("PyObject must be an editable OCIO.Transform."); + } + + ConstTransformRcPtr GetConstTransform(PyObject * pyobject, bool allowCast) + { + if(!IsPyTransform(pyobject)) + { + throw Exception("PyObject must be an OCIO.Transform."); + } + + PyOCIO_Transform * pytransform = reinterpret_cast<PyOCIO_Transform *> (pyobject); + if(pytransform->isconst && pytransform->constcppobj) + { + return *pytransform->constcppobj; + } + + if(allowCast && !pytransform->isconst && pytransform->cppobj) + { + return *pytransform->cppobj; + } + + throw Exception("PyObject must be a valid OCIO.Transform."); + } + + /////////////////////////////////////////////////////////////////////////// + /// + + bool AddTransformObjectToModule( PyObject* m ) + { + PyOCIO_TransformType.tp_new = PyType_GenericNew; + if ( PyType_Ready(&PyOCIO_TransformType) < 0 ) return false; + + Py_INCREF( &PyOCIO_TransformType ); + PyModule_AddObject(m, "Transform", + (PyObject *)&PyOCIO_TransformType); + + return true; + } + + namespace + { + int PyOCIO_Transform_init( PyOCIO_Transform * self, PyObject * args, PyObject * kwds ); + void PyOCIO_Transform_delete( PyOCIO_Transform * self, PyObject * args ); + + PyObject * PyOCIO_Transform_isEditable( PyObject * self ); + PyObject * PyOCIO_Transform_createEditableCopy( PyObject * self ); + PyObject * PyOCIO_Transform_getDirection( PyObject * self ); + PyObject * PyOCIO_Transform_setDirection( PyObject * self, PyObject *args ); + + /////////////////////////////////////////////////////////////////////// + /// + + PyMethodDef PyOCIO_Transform_methods[] = { + {"isEditable", + (PyCFunction) PyOCIO_Transform_isEditable, METH_NOARGS, TRANSFORM_ISEDITABLE__DOC__ }, + {"createEditableCopy", + (PyCFunction) PyOCIO_Transform_createEditableCopy, METH_NOARGS, TRANSFORM_CREATEEDITABLECOPY__DOC__ }, + {"getDirection", + (PyCFunction) PyOCIO_Transform_getDirection, METH_NOARGS, TRANSFORM_GETDIRECTION__DOC__ }, + {"setDirection", + PyOCIO_Transform_setDirection, METH_VARARGS, TRANSFORM_SETDIRECTION__DOC__ }, + {NULL, NULL, 0, NULL} + }; + } + + /////////////////////////////////////////////////////////////////////////// + /// + + PyTypeObject PyOCIO_TransformType = { + PyObject_HEAD_INIT(NULL) + 0, //ob_size + "OCIO.Transform", //tp_name + sizeof(PyOCIO_Transform), //tp_basicsize + 0, //tp_itemsize + (destructor) PyOCIO_Transform_delete, //tp_dealloc + 0, //tp_print + 0, //tp_getattr + 0, //tp_setattr + 0, //tp_compare + 0, //tp_repr + 0, //tp_as_number + 0, //tp_as_sequence + 0, //tp_as_mapping + 0, //tp_hash + 0, //tp_call + 0, //tp_str + 0, //tp_getattro + 0, //tp_setattro + 0, //tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags + TRANSFORM__DOC__, //tp_doc + 0, //tp_traverse + 0, //tp_clear + 0, //tp_richcompare + 0, //tp_weaklistoffset + 0, //tp_iter + 0, //tp_iternext + PyOCIO_Transform_methods, //tp_methods + 0, //tp_members + 0, //tp_getset + 0, //tp_base + 0, //tp_dict + 0, //tp_descr_get + 0, //tp_descr_set + 0, //tp_dictoffset + (initproc) PyOCIO_Transform_init, //tp_init + 0, //tp_alloc + 0, //tp_new + 0, //tp_free + 0, //tp_is_gc + 0, //tp_bases + 0, //tp_mro + 0, //tp_cache + 0, //tp_subclasses + 0, //tp_weaklist + 0, //tp_del + #if PY_VERSION_HEX > 0x02060000 + 0, //tp_version_tag + #endif + }; + + /////////////////////////////////////////////////////////////////////////// + /// + + namespace + { + /////////////////////////////////////////////////////////////////////// + /// + int PyOCIO_Transform_init( PyOCIO_Transform *self, PyObject * /*args*/, PyObject * /*kwds*/ ) + { + /////////////////////////////////////////////////////////////////// + /// init pyobject fields + + self->constcppobj = new ConstTransformRcPtr(); + self->cppobj = new TransformRcPtr(); + self->isconst = true; + + std::string message = "Base Transforms class can not be instantiated."; + PyErr_SetString( PyExc_RuntimeError, message.c_str() ); + return -1; + } + + //////////////////////////////////////////////////////////////////////// + /// + + void PyOCIO_Transform_delete( PyOCIO_Transform *self, PyObject * /*args*/ ) + { + delete self->constcppobj; + delete self->cppobj; + + self->ob_type->tp_free((PyObject*)self); + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Transform_isEditable( PyObject * self ) + { + return PyBool_FromLong(IsPyTransformEditable(self)); + } + + PyObject * PyOCIO_Transform_createEditableCopy( PyObject * self ) + { + try + { + ConstTransformRcPtr transform = GetConstTransform(self, true); + TransformRcPtr copy = transform->createEditableCopy(); + + PyOCIO_Transform * pycopy = PyTransform_New(copy); + pycopy->constcppobj = new ConstTransformRcPtr(); + pycopy->cppobj = new TransformRcPtr(); + *pycopy->cppobj = copy; + pycopy->isconst = false; + + return (PyObject *) pycopy; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + //////////////////////////////////////////////////////////////////////// + /// + + PyObject * PyOCIO_Transform_getDirection( PyObject * self ) + { + try + { + ConstTransformRcPtr transform = GetConstTransform(self, true); + TransformDirection dir = transform->getDirection(); + return PyString_FromString( TransformDirectionToString( dir ) ); + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + + PyObject * PyOCIO_Transform_setDirection( PyObject * self, PyObject * args ) + { + try + { + TransformDirection dir; + if (!PyArg_ParseTuple(args,"O&:setDirection", + ConvertPyObjectToTransformDirection, &dir)) return NULL; + + TransformRcPtr transform = GetEditableTransform(self); + transform->setDirection( dir ); + + Py_RETURN_NONE; + } + catch(...) + { + Python_Handle_Exception(); + return NULL; + } + } + } + +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyTransform.h b/src/pyglue/PyTransform.h new file mode 100644 index 0000000..0ff3e6b --- /dev/null +++ b/src/pyglue/PyTransform.h @@ -0,0 +1,81 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef INCLUDED_PYOCIO_PYTRANSFORM_H +#define INCLUDED_PYOCIO_PYTRANSFORM_H + +#include <PyOpenColorIO/PyOpenColorIO.h> + +OCIO_NAMESPACE_ENTER +{ + // TODO: Maybe put this in a pyinternal namespace? + + typedef struct { + PyObject_HEAD + ConstTransformRcPtr * constcppobj; + TransformRcPtr * cppobj; + bool isconst; + } PyOCIO_Transform; + + extern PyTypeObject PyOCIO_TransformType; + bool AddTransformObjectToModule( PyObject* m ); + + extern PyTypeObject PyOCIO_AllocationTransformType; + bool AddAllocationTransformObjectToModule( PyObject* m ); + + extern PyTypeObject PyOCIO_CDLTransformType; + bool AddCDLTransformObjectToModule( PyObject* m ); + + extern PyTypeObject PyOCIO_ColorSpaceTransformType; + bool AddColorSpaceTransformObjectToModule( PyObject* m ); + + extern PyTypeObject PyOCIO_DisplayTransformType; + bool AddDisplayTransformObjectToModule( PyObject* m ); + + extern PyTypeObject PyOCIO_ExponentTransformType; + bool AddExponentTransformObjectToModule( PyObject* m ); + + extern PyTypeObject PyOCIO_FileTransformType; + bool AddFileTransformObjectToModule( PyObject* m ); + + extern PyTypeObject PyOCIO_GroupTransformType; + bool AddGroupTransformObjectToModule( PyObject* m ); + + extern PyTypeObject PyOCIO_LogTransformType; + bool AddLogTransformObjectToModule( PyObject* m ); + + extern PyTypeObject PyOCIO_LookTransformType; + bool AddLookTransformObjectToModule( PyObject* m ); + + extern PyTypeObject PyOCIO_MatrixTransformType; + bool AddMatrixTransformObjectToModule( PyObject* m ); +} +OCIO_NAMESPACE_EXIT + +#endif diff --git a/src/pyglue/PyUtil.cpp b/src/pyglue/PyUtil.cpp new file mode 100644 index 0000000..3058c9d --- /dev/null +++ b/src/pyglue/PyUtil.cpp @@ -0,0 +1,742 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include <Python.h> + +#include <OpenColorIO/OpenColorIO.h> + +#include "PyUtil.h" + +#include <sstream> + +OCIO_NAMESPACE_ENTER +{ + + + /////////////////////////////////////////////////////////////////////////// + + + // http://docs.python.org/c-api/object.html#PyObject_IsTrue + int ConvertPyObjectToBool(PyObject *object, void *valuePtr) + { + bool *boolPtr = static_cast<bool*>(valuePtr); + int status = PyObject_IsTrue(object); + + if (status == -1 || PyErr_Occurred()) + { + if (!PyErr_Occurred()) + { + PyErr_SetString(PyExc_ValueError, "could not convert object to bool."); + } + + return 0; + } + + *boolPtr = (status == 1) ? true : false; + + return 1; + } + + int ConvertPyObjectToAllocation(PyObject *object, void *valuePtr) + { + Allocation* allocPtr = static_cast<Allocation*>(valuePtr); + + if(!PyString_Check(object)) + { + PyErr_SetString(PyExc_ValueError, "Object is not a string."); + return 0; + } + + *allocPtr = AllocationFromString(PyString_AsString( object )); + + return 1; + } + + + + int ConvertPyObjectToInterpolation(PyObject *object, void *valuePtr) + { + Interpolation* interpPtr = static_cast<Interpolation*>(valuePtr); + + if(!PyString_Check(object)) + { + PyErr_SetString(PyExc_ValueError, "Object is not a string."); + return 0; + } + + *interpPtr = InterpolationFromString(PyString_AsString( object )); + + return 1; + } + + int ConvertPyObjectToTransformDirection(PyObject *object, void *valuePtr) + { + TransformDirection* dirPtr = static_cast<TransformDirection*>(valuePtr); + + if(!PyString_Check(object)) + { + PyErr_SetString(PyExc_ValueError, "Object is not a string."); + return 0; + } + + *dirPtr = TransformDirectionFromString(PyString_AsString( object )); + + return 1; + } + + + int ConvertPyObjectToColorSpaceDirection(PyObject *object, void *valuePtr) + { + ColorSpaceDirection* dirPtr = static_cast<ColorSpaceDirection*>(valuePtr); + + if(!PyString_Check(object)) + { + PyErr_SetString(PyExc_ValueError, "Object is not a string."); + return 0; + } + + *dirPtr = ColorSpaceDirectionFromString(PyString_AsString( object )); + + return 1; + } + + + int ConvertPyObjectToGpuLanguage(PyObject *object, void *valuePtr) + { + GpuLanguage* gpuLanguagePtr = static_cast<GpuLanguage*>(valuePtr); + + if(!PyString_Check(object)) + { + PyErr_SetString(PyExc_ValueError, "Object is not a string."); + return 0; + } + + *gpuLanguagePtr = GpuLanguageFromString(PyString_AsString( object )); + + return 1; + } + + + + /////////////////////////////////////////////////////////////////////////// + + bool GetIntFromPyObject(PyObject* object, int* val) + { + if(!val || !object) return false; + + if( PyInt_Check( object ) ) + { + *val = static_cast<int>( PyInt_AS_LONG( object ) ); + return true; + } + + if( PyFloat_Check( object ) ) + { + *val = static_cast<int>( PyFloat_AS_DOUBLE( object ) ); + return true; + } + + PyObject* intObject = PyNumber_Int(object); + if(intObject) + { + *val = static_cast<int>( PyInt_AS_LONG( intObject ) ); + Py_DECREF(intObject); + return true; + } + + PyErr_Clear(); + return false; + } + + bool GetFloatFromPyObject(PyObject* object, float* val) + { + if(!val || !object) return false; + + if( PyFloat_Check( object ) ) + { + *val = static_cast<float>( PyFloat_AS_DOUBLE( object ) ); + return true; + } + + if( PyInt_Check( object ) ) + { + *val = static_cast<float>( PyInt_AS_LONG( object ) ); + return true; + } + + PyObject* floatObject = PyNumber_Float(object); + if(floatObject) + { + *val = static_cast<float>( PyFloat_AS_DOUBLE( floatObject ) ); + Py_DECREF(floatObject); + return true; + } + + PyErr_Clear(); + return false; + } + + bool GetDoubleFromPyObject(PyObject* object, double* val) + { + if(!val || !object) return false; + + if( PyFloat_Check( object ) ) + { + *val = PyFloat_AS_DOUBLE( object ); + return true; + } + + if( PyInt_Check( object ) ) + { + *val = static_cast<double>( PyInt_AS_LONG( object ) ); + return true; + } + + PyObject* floatObject = PyNumber_Float(object); + if(floatObject) + { + *val = PyFloat_AS_DOUBLE( floatObject ); + Py_DECREF(floatObject); + return true; + } + + PyErr_Clear(); + return false; + } + + bool GetStringFromPyObject(PyObject* object, std::string* val) + { + if(!val || !object) return false; + + if( PyString_Check( object ) ) + { + *val = std::string(PyString_AS_STRING(object)); + return true; + } + + PyObject* strObject = PyObject_Str(object); + if(strObject) + { + *val = std::string(PyString_AS_STRING(strObject)); + Py_DECREF(strObject); + return true; + } + + PyErr_Clear(); + return false; + } + + + + /////////////////////////////////////////////////////////////////////////// + + PyObject* CreatePyListFromIntVector(const std::vector<int> &data) + { + PyObject* returnlist = PyList_New( data.size() ); + if(!returnlist) return 0; + + for(unsigned int i =0; i<data.size(); ++i) + { + PyList_SET_ITEM(returnlist, i, PyInt_FromLong(data[i])); + } + + return returnlist; + } + + PyObject* CreatePyListFromFloatVector(const std::vector<float> &data) + { + PyObject* returnlist = PyList_New( data.size() ); + if(!returnlist) return 0; + + for(unsigned int i =0; i<data.size(); ++i) + { + PyList_SET_ITEM(returnlist, i, PyFloat_FromDouble(data[i])); + } + + return returnlist; + } + + PyObject* CreatePyListFromDoubleVector(const std::vector<double> &data) + { + PyObject* returnlist = PyList_New( data.size() ); + if(!returnlist) return 0; + + for(unsigned int i =0; i<data.size(); ++i) + { + PyList_SET_ITEM(returnlist, i, PyFloat_FromDouble(data[i])); + } + + return returnlist; + } + + PyObject* CreatePyListFromStringVector(const std::vector<std::string> &data) + { + PyObject* returnlist = PyList_New( data.size() ); + if(!returnlist) return 0; + + for(unsigned int i =0; i<data.size(); ++i) + { + PyObject *str = PyString_FromString(data[i].c_str()); + if (str == NULL) + { + Py_DECREF(returnlist); + return NULL; + } + PyList_SET_ITEM(returnlist, i, str); + } + + return returnlist; + } + + PyObject* CreatePyListFromTransformVector(const std::vector<ConstTransformRcPtr> &data) + { + PyObject* returnlist = PyList_New( data.size() ); + if(!returnlist) return 0; + + for(unsigned int i =0; i<data.size(); ++i) + { + PyList_SET_ITEM(returnlist, i, BuildConstPyTransform(data[i])); + } + + return returnlist; + } + + + namespace + { + // These are safer than PySequence_Fast, as we can + // Confirm that no exceptions will be set in the python runtime. + + inline bool PyListOrTuple_Check(PyObject* pyobj) + { + return (PyTuple_Check(pyobj) || PyList_Check(pyobj)); + } + + inline int PyListOrTuple_GET_SIZE(PyObject* pyobj) + { + if(PyList_Check(pyobj)) + { + return static_cast<int>(PyList_GET_SIZE(pyobj)); + } + else if(PyTuple_Check(pyobj)) + { + return static_cast<int>(PyTuple_GET_SIZE(pyobj)); + } + return -1; + } + + // Return a boworrowed reference + inline PyObject* PyListOrTuple_GET_ITEM(PyObject* pyobj, int index) + { + if(PyList_Check(pyobj)) + { + return PyList_GET_ITEM(pyobj, index); + } + else if(PyTuple_Check(pyobj)) + { + return PyTuple_GET_ITEM(pyobj, index); + } + return 0; + } + } + + /////////////////////////////////////////////////////////////////////////// + + /* + A note on why PyErr_Clear is needed in multiple locations... + + Even though it's not immediately apparent, almost every function + in the Abstract Objects Layer, + http://www.python.org/doc/2.5/api/abstract.html + can set a global excpetion under certain circumstances. + + For example, calling the equivalent of int( obj ) will set + an exception if the object cannot be casted (such as None), + or if it's a custom type that implements the number protocol + but throws an exception during the cast. + + During iteration, even an object that implements the sequence + protocol can raise an exception if the iteration fails. + + As we want to guarantee that an exception *never* remains on + the stack after an internal failure, the simplest way to + guarantee this is to always call PyErr_Clear() before + returing the failure condition. + */ + + bool FillIntVectorFromPySequence(PyObject* datalist, std::vector<int> &data) + { + data.clear(); + + // First, try list or tuple iteration (for speed). + if(PyListOrTuple_Check(datalist)) + { + int sequenceSize = PyListOrTuple_GET_SIZE(datalist); + data.reserve(sequenceSize); + + for(int i=0; i < sequenceSize; i++) + { + PyObject* item = PyListOrTuple_GET_ITEM(datalist, i); + + int val; + if (!GetIntFromPyObject(item, &val)) + { + data.clear(); + return false; + } + data.push_back(val); + } + + return true; + } + // As a fallback, try general iteration. + else + { + PyObject *item; + PyObject *iter = PyObject_GetIter(datalist); + if (iter == NULL) + { + PyErr_Clear(); + return false; + } + while((item = PyIter_Next(iter)) != NULL) + { + int val; + if (!GetIntFromPyObject(item, &val)) + { + Py_DECREF(item); + Py_DECREF(iter); + + data.clear(); + return false; + } + data.push_back(val); + Py_DECREF(item); + } + + Py_DECREF(iter); + if (PyErr_Occurred()) + { + PyErr_Clear(); + data.clear(); + return false; + } + return true; + } + } + + bool FillFloatVectorFromPySequence(PyObject* datalist, std::vector<float> &data) + { + data.clear(); + + if(PyListOrTuple_Check(datalist)) + { + int sequenceSize = PyListOrTuple_GET_SIZE(datalist); + data.reserve(sequenceSize); + + for(int i=0; i < sequenceSize; i++) + { + PyObject* item = PyListOrTuple_GET_ITEM(datalist, i); + + float val; + if (!GetFloatFromPyObject(item, &val)) + { + data.clear(); + return false; + } + data.push_back(val); + } + return true; + } + else + { + PyObject *item; + PyObject *iter = PyObject_GetIter(datalist); + if (iter == NULL) + { + PyErr_Clear(); + return false; + } + while((item = PyIter_Next(iter)) != NULL) + { + float val; + if (!GetFloatFromPyObject(item, &val)) + { + Py_DECREF(item); + Py_DECREF(iter); + + data.clear(); + return false; + } + data.push_back(val); + Py_DECREF(item); + } + Py_DECREF(iter); + if (PyErr_Occurred()) + { + PyErr_Clear(); + data.clear(); + return false; + } + return true; + } + } + + bool FillDoubleVectorFromPySequence(PyObject* datalist, std::vector<double> &data) + { + data.clear(); + + if(PyListOrTuple_Check(datalist)) + { + int sequenceSize = PyListOrTuple_GET_SIZE(datalist); + data.reserve(sequenceSize); + + for(int i=0; i < sequenceSize; i++) + { + PyObject* item = PyListOrTuple_GET_ITEM(datalist, i); + double val; + if (!GetDoubleFromPyObject(item, &val)) + { + data.clear(); + return false; + } + data.push_back( val ); + } + return true; + } + else + { + PyObject *item; + PyObject *iter = PyObject_GetIter(datalist); + if (iter == NULL) + { + PyErr_Clear(); + return false; + } + while((item = PyIter_Next(iter)) != NULL) + { + double val; + if (!GetDoubleFromPyObject(item, &val)) + { + Py_DECREF(item); + Py_DECREF(iter); + + data.clear(); + return false; + } + data.push_back(val); + Py_DECREF(item); + } + + Py_DECREF(iter); + if (PyErr_Occurred()) + { + PyErr_Clear(); + data.clear(); + return false; + } + return true; + } + } + + + bool FillStringVectorFromPySequence(PyObject* datalist, std::vector<std::string> &data) + { + data.clear(); + + if(PyListOrTuple_Check(datalist)) + { + int sequenceSize = PyListOrTuple_GET_SIZE(datalist); + data.reserve(sequenceSize); + + for(int i=0; i < sequenceSize; i++) + { + PyObject* item = PyListOrTuple_GET_ITEM(datalist, i); + std::string val; + if (!GetStringFromPyObject(item, &val)) + { + data.clear(); + return false; + } + data.push_back( val ); + } + return true; + } + else + { + PyObject *item; + PyObject *iter = PyObject_GetIter(datalist); + if (iter == NULL) + { + PyErr_Clear(); + return false; + } + while((item = PyIter_Next(iter)) != NULL) + { + std::string val; + if (!GetStringFromPyObject(item, &val)) + { + Py_DECREF(item); + Py_DECREF(iter); + + data.clear(); + return false; + } + data.push_back(val); + Py_DECREF(item); + } + + Py_DECREF(iter); + if (PyErr_Occurred()) + { + PyErr_Clear(); + data.clear(); + return false; + } + return true; + } + } + + + + bool FillTransformVectorFromPySequence(PyObject* datalist, std::vector<ConstTransformRcPtr> &data) + { + data.clear(); + + if(PyListOrTuple_Check(datalist)) + { + int sequenceSize = PyListOrTuple_GET_SIZE(datalist); + data.reserve(sequenceSize); + + for(int i=0; i < sequenceSize; i++) + { + PyObject* item = PyListOrTuple_GET_ITEM(datalist, i); + ConstTransformRcPtr val; + try + { + val = GetConstTransform(item, true); + } + catch(...) + { + data.clear(); + return false; + } + + data.push_back( val ); + } + return true; + } + else + { + PyObject *item; + PyObject *iter = PyObject_GetIter(datalist); + if (iter == NULL) + { + PyErr_Clear(); + return false; + } + while((item = PyIter_Next(iter)) != NULL) + { + ConstTransformRcPtr val; + try + { + val = GetConstTransform(item, true); + } + catch(...) + { + Py_DECREF(item); + Py_DECREF(iter); + + data.clear(); + return false; + } + + data.push_back(val); + Py_DECREF(item); + } + + Py_DECREF(iter); + if (PyErr_Occurred()) + { + PyErr_Clear(); + data.clear(); + return false; + } + + return true; + } + } + + /////////////////////////////////////////////////////////////////////////// + + + + + /////////////////////////////////////////////////////////////////////////// + + /* See the header for the justification for this function. + + The trick to making this technique work is that we know + we've been called from within a catch block, so there + is an exception on the stack. We can re-throw this + exception, using the throw statement. By doing this + inside a try...catch block, it's possible to use the + standard catch mechanism to categorize whatever exception + was actually caught by the caller. + */ + + void Python_Handle_Exception() + { + try + { + // Re-throw whatever exception is already on the stack. + // This will fail horribly if no exception is already + // on the stack, so this function must only be called + // from inside an exception handler catch block! + throw; + } + catch (ExceptionMissingFile & e) + { + PyErr_SetString(GetExceptionMissingFilePyType(), e.what()); + } + catch (Exception & e) + { + PyErr_SetString(GetExceptionPyType(), e.what()); + } + catch (std::exception& e) + { + PyErr_SetString(PyExc_RuntimeError, e.what()); + } + catch (...) + { + PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception caught."); + } + } +} +OCIO_NAMESPACE_EXIT diff --git a/src/pyglue/PyUtil.h b/src/pyglue/PyUtil.h new file mode 100644 index 0000000..589a7b8 --- /dev/null +++ b/src/pyglue/PyUtil.h @@ -0,0 +1,103 @@ +/* +Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of Sony Pictures Imageworks nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef INCLUDED_PYOCIO_PYUTIL_H +#define INCLUDED_PYOCIO_PYUTIL_H + +#include <PyOpenColorIO/PyOpenColorIO.h> + +#include <vector> + +OCIO_NAMESPACE_ENTER +{ + + int ConvertPyObjectToBool(PyObject *object, void *valuePtr); + + int ConvertPyObjectToAllocation(PyObject *object, void *valuePtr); + + int ConvertPyObjectToInterpolation(PyObject *object, void *valuePtr); + + int ConvertPyObjectToTransformDirection(PyObject *object, void *valuePtr); + + int ConvertPyObjectToColorSpaceDirection(PyObject *object, void *valuePtr); + + int ConvertPyObjectToGpuLanguage(PyObject *object, void *valuePtr); + + /////////////////////////////////////////////////////////////////////////// + + // Generics. + // None of these allow an interpreter error to leak + + //! Use a variety of methods to get the value, as the specified type + //! from the specified PyObject. (Return true on success, false on failure) + //! + //! 1. See if object is PyFloat, return value + //! 2. See if object is PyInt, return value + //! 3. Attempt to cast to PyFloat / PyInt (equivalent to calling float(obj)/int(obj) in python) + + bool GetIntFromPyObject(PyObject* object, int* val); + bool GetFloatFromPyObject(PyObject* object, float* val); + bool GetDoubleFromPyObject(PyObject* object, double* val); + + //! 1. See if object is a PyString, return value + //! 2. Attempt to cast to a PyString (equivalent to calling str(obj) in python + //! Note: This will basically always succeed, even if the object is not string-like + //! (such as passing Py_None as val), so you cannot use this to check str type. + + bool GetStringFromPyObject(PyObject* object, std::string* val); + + + // Can return a null pointer if PyList_New(size) fails. + PyObject* CreatePyListFromIntVector(const std::vector<int> &data); + PyObject* CreatePyListFromFloatVector(const std::vector<float> &data); + PyObject* CreatePyListFromDoubleVector(const std::vector<double> &data); + PyObject* CreatePyListFromStringVector(const std::vector<std::string> &data); + PyObject* CreatePyListFromTransformVector(const std::vector<ConstTransformRcPtr> &data); + + //! Fill the specified vector type from the given pyobject + //! Return true on success, false on failure. + //! The PyObject must be a tuple or list, filled with the appropriate data types + //! (either PyInt, PyFloat, or something convertible to one) + + bool FillIntVectorFromPySequence(PyObject* datalist, std::vector<int> &data); + bool FillFloatVectorFromPySequence(PyObject* datalist, std::vector<float> &data); + bool FillDoubleVectorFromPySequence(PyObject* datalist, std::vector<double> &data); + bool FillStringVectorFromPySequence(PyObject* datalist, std::vector<std::string> &data); + bool FillTransformVectorFromPySequence(PyObject* datalist, std::vector<ConstTransformRcPtr> &data); + + + + + /////////////////////////////////////////////////////////////////////////// + + void Python_Handle_Exception(); +} +OCIO_NAMESPACE_EXIT + +#endif diff --git a/src/pyglue/createPyDocH.py b/src/pyglue/createPyDocH.py new file mode 100644 index 0000000..fd2e795 --- /dev/null +++ b/src/pyglue/createPyDocH.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python + +""" +This script contains mock OpenColorIO classes which define the __doc__ +strings that will end up in the final binding. These __doc__ strings are +also used by sphinx's autodoc extension to also include this documentation +in the html and pdf formats. +""" + +import re, sys + +from DocStrings import * + +def DocStringToCString(name, doc_string): + _cstr = doc_string + _cstr = _cstr.rstrip(' ') + _cstr = _cstr.rstrip('\n') + _cstr = _cstr.lstrip('\n') + _cstr = _cstr.lstrip(' ') + _cstr = _cstr.replace("\"", "\\\"") + _cstr = _cstr.replace("\n", "\\n") + _cstr = _cstr.replace("\r", "\\n") + return "const char %s[%d] = \"%s\";" % (name, len(_cstr)+1, _cstr) + +def GetDocStrings(inst): + _out = "" + _cname = inst.__name__ + _cdoc = inst.__doc__ + if _cdoc == None: + _cdoc = "" + _out = "%s\n" % DocStringToCString("%s__DOC__" % _cname.upper(), _cdoc) + for mem in dir(inst): + if mem[0:2] == "__": + continue # skip + _doc = eval("inst.%s.__doc__" % mem) + if _doc == None: + _doc = "" + _name = "%s_%s__DOC__" % (_cname.upper(), eval("inst.%s.__name__" % mem).upper()) + _out += "%s\n" % DocStringToCString(_name, _doc) + #print mem + return _out + +if __name__ == "__main__": + + if len(sys.argv) <= 1: + sys.stderr.write("\nYou need to specify an output file\n\n") + sys.exit(1) + + fileh = file(sys.argv[1], 'w') + fileh.write('\n') + fileh.write("/* DO NOT EDIT THIS FILE - it is machine generated */\n") + fileh.write("\n") + fileh.write("#include <OpenColorIO/OpenColorIO.h>\n") + fileh.write("\n") + fileh.write("OCIO_NAMESPACE_ENTER\n") + fileh.write("{\n") + fileh.write("\n") + fileh.write("%s\n" % GetDocStrings(Exception)) + fileh.write("%s\n" % GetDocStrings(ExceptionMissingFile)) + fileh.write("%s\n" % GetDocStrings(OpenColorIO)) + fileh.write("%s\n" % GetDocStrings(Constants)) + fileh.write("%s\n" % GetDocStrings(Config)) + #fileh.write("%s\n" % GetDocStrings(Baker)) + fileh.write("%s\n" % GetDocStrings(ColorSpace)) + fileh.write("%s\n" % GetDocStrings(Processor)) + fileh.write("%s\n" % GetDocStrings(ProcessorMetadata)) + fileh.write("%s\n" % GetDocStrings(Context)) + fileh.write("%s\n" % GetDocStrings(Look)) + fileh.write("%s\n" % GetDocStrings(Transform)) + fileh.write("\n") + fileh.write("%s\n" % GetDocStrings(AllocationTransform)) + fileh.write("%s\n" % GetDocStrings(CDLTransform)) + fileh.write("%s\n" % GetDocStrings(ColorSpaceTransform)) + fileh.write("%s\n" % GetDocStrings(DisplayTransform)) + fileh.write("%s\n" % GetDocStrings(ExponentTransform)) + fileh.write("%s\n" % GetDocStrings(FileTransform)) + fileh.write("%s\n" % GetDocStrings(GroupTransform)) + fileh.write("%s\n" % GetDocStrings(LogTransform)) + fileh.write("%s\n" % GetDocStrings(LookTransform)) + fileh.write("%s\n" % GetDocStrings(MatrixTransform)) + fileh.write("\n") + fileh.write("}\n") + fileh.write("OCIO_NAMESPACE_EXIT\n") + fileh.write("\n") + fileh.flush() + fileh.close() |