opencolorio-1.1.0~dfsg0.orig/0000755000175000017500000000000013227423302014262 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/docs/0000755000175000017500000000000013223553423015216 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/docs/CMakeLists.txt0000644000175000017500000001522113223553423017757 0ustar mfvmfv ############################################################################### ### External Doc Apps ### if (WIN32) # Workaround to mimic *nix '> PYTHONPATH=XXX CMD' # on windows, it becomes '> set PYTHONPATH=XXX \n call CMD' # '\n' is here because '\\&' does not work. set(PYT_PRE_CMD set PYTHONPATH=${PYTHONPATH} "\n" call ) # Unfortunately some windows tools require to have # the paths with the '\' (not working with '//'). set(PYT_LIB_OUTPUT ${EXTDIST_ROOT}) string(REGEX REPLACE "/" "\\\\" PYT_LIB_OUTPUT ${PYT_LIB_OUTPUT}) set(PYT_EXTDIST_BINPATH ${EXTDIST_BINPATH}) string(REGEX REPLACE "/" "\\\\" PYT_EXTDIST_BINPATH ${PYT_EXTDIST_BINPATH}) else() set(PYT_PRE_CMD PYTHONPATH=${PYTHONPATH}) set(PYT_LIB_OUTPUT ${EXTDIST_ROOT}) set(PYT_EXTDIST_BINPATH ${EXTDIST_BINPATH}) endif() # setuptools # https://pypi.python.org/pypi/setuptools set(SETUPTOOLS_VERSION 1.1.6) ExternalProject_Add(setuptools URL ${CMAKE_SOURCE_DIR}/ext/setuptools-${SETUPTOOLS_VERSION}.tar.gz BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ${CMAKE_COMMAND} -E make_directory ${EXTDIST_PYTHONPATH} BUILD_COMMAND ${PYT_PRE_CMD} ${PYTHON} setup.py build INSTALL_COMMAND ${PYT_PRE_CMD} ${PYTHON} setup.py install --prefix=${PYT_LIB_OUTPUT} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/setuptools-prefix/src/setuptools ) # docutils # https://pypi.python.org/pypi/docutils set(DOCUTILS_VERSION 0.11) ExternalProject_Add(docutils DEPENDS setuptools URL ${CMAKE_SOURCE_DIR}/ext/docutils-${DOCUTILS_VERSION}.tar.gz BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ${CMAKE_COMMAND} -E make_directory ${EXTDIST_PYTHONPATH} BUILD_COMMAND ${PYT_PRE_CMD} ${PYTHON} setup.py build INSTALL_COMMAND ${PYT_PRE_CMD} ${PYTHON} setup.py install --prefix=${PYT_LIB_OUTPUT} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/docutils-prefix/src/docutils ) # jinja2 # https://pypi.python.org/pypi/Jinja2 set(JINJA2_VERSION 2.7.1) ExternalProject_Add(Jinja2 DEPENDS setuptools URL ${CMAKE_SOURCE_DIR}/ext/Jinja2-${JINJA2_VERSION}.tar.gz BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ${CMAKE_COMMAND} -E make_directory ${EXTDIST_PYTHONPATH} BUILD_COMMAND ${PYT_PRE_CMD} ${PYTHON} setup.py build INSTALL_COMMAND ${PYT_PRE_CMD} ${PYTHON} setup.py install --prefix=${PYT_LIB_OUTPUT} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Jinja2-prefix/src/Jinja2 ) # Pygments # https://pypi.python.org/pypi/Pygments set(PYGMENTS_VERSION 1.6) ExternalProject_Add(Pygments DEPENDS setuptools URL ${CMAKE_SOURCE_DIR}/ext/Pygments-${PYGMENTS_VERSION}.tar.gz BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ${CMAKE_COMMAND} -E make_directory ${EXTDIST_PYTHONPATH} BUILD_COMMAND ${PYT_PRE_CMD} ${PYTHON} setup.py build INSTALL_COMMAND ${PYT_PRE_CMD} ${PYTHON} setup.py install --prefix=${PYT_LIB_OUTPUT} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Pygments-prefix/src/Pygments ) # sphinx # https://pypi.python.org/pypi/Sphinx set(SPHINX_VERSION 1.2b3) ExternalProject_Add(Sphinx DEPENDS setuptools docutils Jinja2 Pygments URL ${CMAKE_SOURCE_DIR}/ext/Sphinx-${SPHINX_VERSION}.tar.gz PATCH_COMMAND patch -p1 < ${CMAKE_SOURCE_DIR}/ext/Sphinx-${SPHINX_VERSION}.patch BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ${CMAKE_COMMAND} -E make_directory ${EXTDIST_PYTHONPATH} BUILD_COMMAND ${PYT_PRE_CMD} ${PYTHON} setup.py build INSTALL_COMMAND ${PYT_PRE_CMD} ${PYTHON} setup.py install --prefix=${PYT_LIB_OUTPUT} --install-scripts=${PYT_EXTDIST_BINPATH} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Sphinx-prefix/src/Sphinx ) ############################################################################### ### Create Doc Targets ### message(STATUS "Create sphinx conf.py from conf.py.in") configure_file(${CMAKE_SOURCE_DIR}/docs/conf.py.in ${CMAKE_BINARY_DIR}/docs/conf.py @ONLY) message(STATUS "Copying doc to staging area") file( COPY ${CMAKE_SOURCE_DIR}/docs/ DESTINATION ${CMAKE_BINARY_DIR}/docs # Ignore dot files like emacs' temporary .#somefile.rst which # break Sphinx (and must be manually removed from the destination) PATTERN ".*" EXCLUDE ) message(STATUS "Copy extra doc files to staging area") list(APPEND DOCFILES ${CMAKE_SOURCE_DIR}/README.md) list(APPEND DOCFILES ${CMAKE_SOURCE_DIR}/INSTALL) list(APPEND DOCFILES ${CMAKE_SOURCE_DIR}/ChangeLog) list(APPEND DOCFILES ${CMAKE_SOURCE_DIR}/LICENSE) list(APPEND DOCFILES ${CMAKE_SOURCE_DIR}/share/nuke/ocionuke/viewer.py) CopyFiles(RSTDOC ${DOCFILES}) message(STATUS "Extracting .rst files from C++ headers") ExtractRstCPP(${CMAKE_SOURCE_DIR}/export/OpenColorIO/OpenColorIO.h ${CMAKE_BINARY_DIR}/docs/developers/api/OpenColorIO.rst) ExtractRstCPP(${CMAKE_SOURCE_DIR}/export/OpenColorIO/OpenColorTransforms.h ${CMAKE_BINARY_DIR}/docs/developers/api/OpenColorTransforms.rst) ExtractRstCPP(${CMAKE_SOURCE_DIR}/export/OpenColorIO/OpenColorTypes.h ${CMAKE_BINARY_DIR}/docs/developers/api/OpenColorTypes.rst) if(OCIO_BUILD_PYGLUE) set(DEPLIBS OpenColorIO PyOpenColorIO) else() set(DEPLIBS OpenColorIO) endif() add_custom_target(doc ALL COMMAND ${PYT_PRE_CMD} ${EXTDIST_BINPATH}/sphinx-build -b html . ${CMAKE_CURRENT_BINARY_DIR}/build-html DEPENDS ${DEPLIBS} ${CMAKE_BINARY_DIR}/docs/conf.py developers/api/OpenColorIO.rst developers/api/OpenColorTransforms.rst developers/api/OpenColorTypes.rst ${RSTDOC_OUTPUT} COMMENT "Building html docs" SOURCES ${DOCFILES}) # note: ExternalProject will not build when added to a add_custom_target this # works around this problem. This seems to be fixed in the cmake ^HEAD add_dependencies(doc Sphinx) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build-html/ DESTINATION ${CMAKE_INSTALL_PREFIX}/share/doc/OpenColorIO/html PATTERN .* EXCLUDE ) find_package(LATEX) if(PDFLATEX_COMPILER) add_custom_target(latex COMMAND ${PYT_PRE_CMD} ${EXTDIST_BINPATH}/sphinx-build -b latex . ${CMAKE_CURRENT_BINARY_DIR}/build-latex DEPENDS OpenColorIO ${CMAKE_BINARY_DIR}/docs/conf.py developers/api/OpenColorIO.rst developers/api/OpenColorTransforms.rst developers/api/OpenColorTypes.rst ${RSTDOC_OUTPUT} COMMENT "Building latex doc" SOURCES ${DOCFILES}) add_dependencies(latex Sphinx) add_custom_target(pdf ALL COMMAND ${PDFLATEX_COMPILER} OpenColorIO.tex WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build-latex COMMENT "Building pdf doc" SOURCES ${DOCFILES}) add_dependencies(pdf latex) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/build-latex/OpenColorIO.pdf DESTINATION ${CMAKE_INSTALL_PREFIX}/share/doc/OpenColorIO/) endif() opencolorio-1.1.0~dfsg0.orig/docs/FAQ.rst0000644000175000017500000001625013223553423016363 0ustar mfvmfv.. _faq: FAQ === License? ******** New BSD. You are welcome to include the OpenColorIO in commercial, or open source applications. See the :ref:`license` for further details. .. _faq-terminology: Terminology *********** - Transform - a function that alters RGB(A) data (e.g transform an image from scene linear to sRGB) - Reference space - a space that connects colorspaces - Colorspace - a meaningful space that can be transferred to and from the reference space - Display - a virtual or physical display device (e.g an sRGB display device) - View - a meaningful view of the reference space on a Display (e.g a film emulation view on an sRGB display device) - Role - abstract colorspace naming (e.g specify the "lnh" colorspace as the scene_linear role, or the color-picker UI uses color_picking role) - Look - a color transform which applies a creative look (for example a per-shot netural grade to remove color-casts from a sequence of film scans, or a DI look) .. _faq-supportedlut: What LUT Formats are supported? ******************************* ========= =================================== =============================== Ext Details Notes ========= =================================== =============================== 3dl Autodesk Apps: Lustre, Flame, etc. Read + Write Support. Supports shaper LUT + 3D ccc ASC CDL ColorCorrectionCollection Full read support. cc ASC CDL ColorCorrection Full read support. csp Cinespace (Rising Sun Research) Read + Write Support. Shaper is LUT. Spline-based shaper LUT, with resampled into simple 1D LUT either 1D or 3D LUT. with 2^16 samples. cub Truelight format. Shaper Lut + 3D Full read support. cube Iridas format. Either 1D or 3D Lut. Full read support hdl Houdini. 1D Lut, 3D lut, 1D shaper Only 'C' type is supported. Lut Need to add R G B A RGB RGBA ALL. No support for Sampling tag. Header fields must be in strict order. look IRIDAS .look Read baked 3D LUT embedded in file. No mask support. mga/m3d Pandora 3D lut Full read support. spi1d 1D format. Imageworks native 1D Full read support. lut format. HDR friendly, supports arbitrary input and output domains spi3d 3D format. Imageworks native 3D Full read support. lut format. spimtx 3x3 matrix + color offset. Full read support. Imageworks native color matrix format vf Inventor 3d lut. Read support for 3d lut data and global_transform element ========= =================================== =============================== .. note:: Shaper LUT application in OCIO currently only supports linear interpolation. For very small shaper LUT sizes this may not be sufficient. (CSP shaper luts excluded; they do use spline interpolation at load-time). Can you query a color space by name (like "Rec709") and get back XYZ coordinates of its primaries and whitepoint? ***************************************************************************************************************** Not currently. OCIO is a color configuration 'playback' tool that tries to be as flexible as possible; color information such as this is often only needed / relevant at configuration authoring time. Making primaries / whitepoint required would limit the pipeline OCIO could service. In the strictest sense, we would consider OCIO to be a 'baked' representation of color processes, similar to how Alembic files do not store animation rig data, but rather only the baked geometry. Also, remember that not all colorspaces using in visual effects even have strongly defined color space definitions. For example, scanned film negatives, when linearized with 1d transfer curves (the historical norm in vfx), do not have defined primaries/white point. Each rgb value could of course individually be tied to a specific color, but if you were to do a sweep of the pure 'red channel', for example, you'd find that it creates a curves in chromaticity space, not a single point. (This is due to the 1d linearization not attempting to undo the subtractive processes that created the pixels in the first place. But many color spaces in OCIO *do* have very strongly defined white points/chromaticities. On the display side, for example, we have very precise information on this. Perhaps OCIO should include optional metadata to tag outputs? We are looking at this as as a OCIO 1.2 feature. Can you convert XYZ <-> named color space RGB values? ***************************************************** OCIO includes a MatrixTransform, so the processing capability is there. But there is no convenience function to compute this matrix for you. (We do include other Matrix convenience functions though, so it already has a place to be added. See MatrixTransform in export/OpenColorTransforms.h) There's talk of extended OCIO 1.2 to have a plugin api where colorspaces could be dynamically added at runtime (such as after reading exr chromaticity header metadata). This would necessitate adding such a feature. What are the differences between Nuke's Vectorfield and OCIOFileTransform? ************************************************************************** (All tests done with Nuke 6.3) ========= ============================================= =============================== Ext Details Notes ========= ============================================= =============================== 3dl Matched Results ccc n/a cc n/a csp *Difference* Gain error. Believe OCIO is correct, but need to verify. cub Matched Results Note: Nuke's .cub exporter is broken (gain error) cube Matched Results hdl n/a mga/m3d n/a spi1d n/a spi3d n/a spimtx n/a vf *Difference* Gain error. Believe OCIO is correct, but need to verify. ========= ============================================= =============================== All gain differences are due to a common 'gotcha' when interpolating 3d luts, related to internal index computation. If you have a 32x32x32 3dlut, when sampling values from (0,1) do you internally scale by 31.0 or 32.0? This is typically well-defined for each format, (in this case the answer is usually 31.0) but when incorrectly handled in an application, you occationally see gain errors that differ by this amount. (In the case of a 32-sized 3dlut, 32/31 = ~3% error) What do ColorSpace::setAllocation() and ColorSpace::setAllocationVars() do? *************************************************************************** These hints only come into play during GPU processing, and are used to determine proper colorspace allocation handling for 3D LUTs. See this page :ref:`allocationvars` for further information. opencolorio-1.1.0~dfsg0.orig/docs/License.rst0000755000175000017500000000006313223553423017334 0ustar mfvmfv.. _license: License ======= .. include:: LICENSE opencolorio-1.1.0~dfsg0.orig/docs/configurations/0000755000175000017500000000000013223553423020250 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/docs/configurations/aces_1.0.3.rst0000644000175000017500000003164413223553423022444 0ustar mfvmfvaces_1.0.3 ========== ACES 1.0.3 OpenColorIO configuration Information about ACES *********************** The **ACES** project home page is here: - http://www.oscars.org/aces The latest documentation on the ACES transforms and specifications can be found here: - http://www.oscars.org/science-technology/aces/aces-documentation Colorspaces *********** Colorspaces in this configurations are grouped into the following families: ACES, ADX, Look, Output, Input, Utility, Aliases. Descriptions for the colorspaces in the different families are provided below. For ease of use across a broader number of applications, the family name of each colorspace is pre-pended to the colorspace name when the configuration is authored. Those prefixes will be omitted in this document, but will show up when the configuration is loaded and used. ACES Colorspaces ---------------- - ACES2065-1 - ACEScc - ACEScct - ACESproxy - ACEScg **Description** Colorspaces and transforms representing the core ACES working and interchange colorspaces. **Technical information** Transforms generated based on the `ACES CTL Transforms `_ Output Colorspaces ------------------ - sRGB - sRGB (D60 sim.) - Rec.709 - Rec.709 (D60 sim.) - Rec.2020 - Rec.2020 ST2048 (1000 nits) - DCDM (P3 gamut clip) - DCDM - P3-D60 ST2048 (1000 nits) - P3-D60 ST2048 (2000 nits) - P3-D60 ST2048 (4000 nits) - P3-D60 - P3-DCI **Description** Colorspaces and transforms implementing the ACES Output Transforms. These colorspaces produce code values ready for display on hardware devices calibrated to the standard used to name the colorspace. **Technical information** - Transforms generated based on the `ACES CTL Transforms `_ - All transforms produce full-range output. Host applications should be used to apply an full-to-legal scaling needed. Input Colorspaces ----------------- There are a variety of Input Transforms covering different cameras manufacturers, gamuts, transfer functions and camera settings. See below for specifics. **Description** Colorspaces and transforms that implement the ACES Input Transforms. These colorspaces are used to convert from camera-specific formats and encodings to ACES. **Technical information** References and descriptions are provided for each group of Input Transforms below. - The colorspaces whose names include a transfer function and a gamut name are full implementations of ACES Input Transforms. - Ex. The ARRI 'V3 LogC (EI160) - Wide Gamut' colorspace - Ex. The RED 'REDlogFilm - DRAGONcolor2' colorspace - Ex. The Canon 'Canon-Log - DCI-P3 Daylight' colorspace - The colorspaces that start with 'Linear - ' will convert to or from a specific gamut but not apply a transfer function. - The colorspaces that start with 'Curve - ' will apply a transfer function but not convert between gamuts. ADX Colorspaces ''''''''''''''' - ADX10 - ADX16 **Description** Colorspaces and transforms representing the ACES ADX spaces used for film scanning and printing. **Technical information** - Transforms generated based on the `ACES CTL Transforms `_ - `Alex Fry's ACES 0.7.1 OCIO config `_ was also a valuable resource. ARRI '''' - `ARRI 'Working with ACES' `_ - `ARRI Input Transforms `_ - Conversations with Joseph Goldstone of ARRI Canon ''''' - `Canon ACES landing page `_ - `Clog white paper `_ - `C700 Drivers and Software `_ - `C500 Drivers and Software `_ - `C300 Drivers and Software `_ - Choose *OSX Mountain Lion v10.8* to download the IDTs - `C300 Mark II Drivers and Software `_ - Choose *OSX Mountain Lion v10.8* to download the IDTs, labeled "EOS C300 Mark II Input Transform Version 2.0 (for Cinema Gamut / BT.2020)" - `C100 Drivers and Software `_ - Choose *OSX Mountain Lion v10.8* to download the IDTs Panasonic ''''''''' - `Vlog/V-Gamut white paper `_ - `Varicam Drivers and Software `_ RED ''' - `Understanding REDlogFilm and REDgamma `_ - Conversations with Graeme Nattress of RED Sony '''' - `Sony Input Transforms `_ GoPro (Experimental) '''''''''''''''''''' - The quality and consistency of these transforms has not been verified. - Conversations with David Newman of GoPro Utility ------- **Description** A collection of colorspaces that are used to facilitate the creation of LUTs and other basic functionality. **Technical information** - The 'Log2 xx nits Shaper' and 'Dolby PQ xx nits Shaper' spaces cover the linear range centered around 18% grey. The 48 nits spaces cover -6.5 stops (0.0028125) to +6.5 stops(16.291740). The 1000 nits spaces cover -12 stops to +10 stops. The 2000 nits spaces cover -12 stops to +11 stops. The 4000 nits spaces cover -12 stops to +12 stops. - The LMT shaper spaces cover the linear range going from 10 stops below 18% grey (0.00017578125) to 6.5 stops above 18% grey (16.291740) - The colorspaces starting with 'Linear - ' will convert to or from a specific gamut but not apply a transfer function. - The colorspaces starting with 'Curve - ' will apply a transfer function but not convert between gamuts. Look ---- **Colorspaces** - ACES 1.0 to 0.1 emulation - ACES 1.0 to 0.2 emulation - ACES 1.0 to 0.7 emulation **Description** Colorspaces and transforms emulating the look of the ACES 0.1, 0.2 and 0.7 release. - Should be applied to data in the ACES2065-1 colorspace. - Should be used before an ACES Output Transform. **Technical information** Transforms generated based on the `ACES CTL Transforms `_ Roles ***** **Description** The role colorspaces are aliases to the colorspaces used for the *OCIO* 'roles' functionality. **Aliases** **Description** The alias colorspaces are named with all lower-case letters and no spaces, dashes, parentheses or other characters that would not work well in a filename. They are only references, aliases for the base colorspaces with more user-friendly names. These spaces were added to enable OCIO's token-based colorspace / filename matching. - These colorspaces should not generally be used by most artists. Roles ----- The standard *OCIO* roles are defined. They role assignments are: - **color_picking**: Output - Rec.709 - **color_timing**: ACEScc - **compositing_log**: ADX10 - **data**: Raw - **default**: ACES2065-1 - **matte_paint**: ACEScc - **reference**: Raw - **scene_linear**: ACEScg - **texture_paint**: Raw Additionally, a number of colorspaces that are gaining wider adoption have been added to the config. Their names and assignment are: - **compositing_linear**:: ACEScg - **rendering**:: ACEScg Displays and Views ****************** The default config has one Display named **ACES**, which contains the following Views / colorspaces: - sRGB, colorspace: sRGB - sRGB D60 sim., colorspace: sRGB (D60 sim.) - DCDM, colorspace: DCDM - DCDM P3 gamut clip, colorspace: DCDM (P3 gamut clip) - P3-D60, colorspace: P3-D60 - P3-D60 PQ 1000 nits, colorspace: P3-D60 PQ (1000 nits) - P3-D60 PQ 2000 nits, colorspace: P3-D60 PQ (2000 nits) - P3-D60 PQ 4000 nits, colorspace: P3-D60 PQ (4000 nits) - P3-DCI, colorspace: P3-DCI - Rec.2020, colorspace: Rec.2020 - Rec.2020 ST2048 1000 nits, colorspace: Rec.2020 ST2048 (1000 nits) - Rec.709, colorspace: Rec.709 - Rec.709 D60 sim., colorspace: Rec.709 (D60 sim.) - Raw, colorspace: Raw - Log, colorspace: ACEScc Considerations for custom config generation: - The choice of a single Display and many Views may not align well with the implementation of OCIO in an application. - If you would like to generate a config that contains multiple Displays, with a small number of Views for each, review the config generation script's '--createMultipleDisplays' option. - If a Look is added to the config, a new set of Views will be added, one for each of the Views listed above except Raw and Log, that includes the Look. The Views with Looks will be interleaved in the View list with the original Views. - To add a custom Look to the config, review the config generation script's '--addACESLookLUT', '--addACESLookCDL', '--addCustomLookLUT' and '--addCustomLookCDL' options. LUTs **** The default resolution is 65x65x65 for the 3D LUTs and 4096 for the 1D LUTs. **OCIO LUTs** The LUTs used internally by OCIO can be can be retrieved `from the repository here. `_ **Baked LUTs** LUTs that can be used outside of OCIO are included in the `'baked' directory here. `_ - The LUTs encode the ACES Output Transform for a specific colorspace input and are generally named: - 'Ouput Transform name' for 'Input colorspace name'.extension - Ex. 'sRGB (D60 sim.) for ACEScc.icc' The LUTs included in the 'baked' directory cover the following formats and applications: - .3dl for Autodesk Flame - .3dl for Autodesk Lustre - .lut for SideFX Houdini - .csp for Autodesk Maya - .icc for Adobe Photoshop Generating Configurations ************************* **Python** Configurations can be generated by the following *Python* package: `aces_1.0.3/python `_ Usage is described on the command line and in the package root `\_\_init__.py `_ file. Features exposed for customization by the user include: - The resolution of 1D and 3D LUTs - Inclusion of custom Looks - Two modes of creating the list of OCIO Displays and Views - Selection of shaper function: Log2 or Dolby PQ **CTL Source** The configuration depends on the **ACES 1.0.3** release. The release contains a number of file renames and the new ACEScct color space and a number of minor bug fixes and small additions, but is otherwise very similar as the master **ACES 1.0.2** release. The CTL is available here: - https://github.com/ampas/aces-dev/tree/v1.0.3/transforms/ctl Clone this repo using the following command: - git clone --branch v1.0.3 https://github.com/ampas/aces-dev.git Dependencies ************ The *Python* configuration generation package depends on the following libraries: - **OpenImageIO**: http://openimageio.org - Detailed build instructions can be found here: `OpenImageIO Build Instructions `_ - **OpenColorIO**: http://opencolorio.org - Detailed build instructions can be found here: `OpenColorIO Build Instructions `_ - **CTL**: https://github.com/ampas/CTL Building on macOS - Use the following commands to build these packages on macOS - OpenColorIO - brew install -vd opencolorio --with-python - Update the homebrew repository of install scripts to make sure that OpenImageIO is included. - brew tap homebrew/science - Optional Dependencies for OpenImageIO - brew install -vd libRaw - brew install -vd OpenCV - OpenImageIO - brew install -vd openimageio --with-python - CTL - brew install -vd CTL - OpenColorIO, a second time. *ociolutimage* will build with *openimageio* installed. - brew uninstall -vd opencolorio - brew install -vd opencolorio --with-python Thanks ****** The script used to generate these transforms and the transforms themselves were the product of work and conversations with a number of people. Thanks go to: - Steve Agland - Joe Bogacz - Jack Binks - Scott Dyer - Alex Fry - Alex Forsythe - Joseph Goldstone - Stephen Hill - Jim Houston - Thomas Mansencal - Robert Molholm - Nikola Milosevic - Will McCown - Graeme Nattress - David Newman - Sam Richards - Erik Strauss - Doug Walker - Kevin Wheatley Author ****** The original author of this OCIO config is: - Haarm-Pieter Duiker opencolorio-1.1.0~dfsg0.orig/docs/configurations/allocation_vars.rst0000644000175000017500000000776413223553423024200 0ustar mfvmfv.. _allocationvars: How to Configure ColorSpace Allocation ====================================== The allocation / allocation vars are utilized using during GPU 3dlut / shader text generation. (Processor::getGpuShaderText, Processor::getGpuLut3D). If, in the course of GPU processing, a 3D lut is required, the "allocation / allocation vars" direct how OCIO should sample the colorspace, with the intent being to maintain maximum fidelity and minimize clamping. Currently support allocations / variables: ALLOCATION_UNIFORM:: 2 vars: [min, max] ALLOCATION_LG2:: 2 vars: [lg2min, lg2max] 3 vars: [lg2min, lg2max, linear_offset] So say you have an srgb image (such as an 8-bit tif), where you know the data ranges between 0.0 - 1.0 (after converting to float). If you wanted to apply a 3d lut to this data, there is no danger in samplingthat space uniformly and clamping data outside (0,1). So for this colorspace we would tag it: .. code-block:: yaml allocation: uniform allocationvars: [0.0, 1.0] These are the defaults, so the tagging could also be skipped. But what if you were actually first processing the data, where occasionally small undershoot and overshoot values were encountered? If you wanted OCIO to preserve this overshoot / undershoot pixel information, you would do so by modifying the allocation vars. .. code-block:: yaml allocation: uniform allocationvars: [-0.125, 1.125] This would mean that any image data originally within [-0.125, 1.125] will be preserved during GPU processing. (Protip: Data outside this range *may* actually be preserved in some circumstances - such as if a 3d lut is not needed - but it's not required to be preserved). So why not leave this at huge values (such as [-1000.0, 1000.0]) all the time? Well, there's a cost to supporting this larger dynamic range, and that cost is reduced precision within the 3D luts sample space. So in general you're best served by using sensible allocations (the smallest you can get away with, but no smaller). Now in the case of high-dynamic range color spaces (such as float linear), a uniform sampling is not sufficient because the max value we need to preserve is so high. Say you were using a 32x32x32 3d lookup table (a common size). Middle gray is at 0.18, and specular values are very much above that. Say the max value we wanted to preserve in our coding space is 256.0, each 3d lut lattice coordinates would represent 8.0 units of linear light! That means the vast majority of the perceptually significant portions of the space wouldnt be sampled at all! unform allocation from 0-256\: 0 8.0 16.0 ... 240.0 256.0 So another allocation is defined, lg2 .. code-block:: yaml - ! name: linear description: | Scene-linear, high dynamic range. Used for rendering and compositing. allocation: lg2 allocationvars: [-8, 8] In this case, we're saying that the appropriate ways to sample the 3d lut are logarithmically, from 2^-8 stops to 2^8 stops. Sample locations: 2^-8\: 0.0039 2^-7\: 0.0078 2^-6\: 0.0156 ... 2^0\: 1.0 ... 2^6\: 64.0 2^7\: 128.0 2^8\: 256.0 Which gives us a much better perceptual sampling of the space. The one downside of this approach is that it can't represent 0.0, which is why we optionally allow a 3d allocation var, a black point offset. If you need to preserve 0.0 values, and you have a high dynamic range space, you can specify a small offset. Example: .. code-block:: yaml allocation: lg2 allocationvars: [-8, 8, 0.00390625] The [-15.0, 6.0] values in spi-vfx come from the fact that all of the linearizations provided in that profile span the region from 2^-15 stops, to 2^6 stops. One could probably change that black point to a higher number (such as -8), but if you raised it too much you would start seeing black values be clipped. Conversely, on the high end one could raise it a bit but if you raised it too far the precision would suffer around gray, and if you lowered it further you'd start to see highlight clipping. opencolorio-1.1.0~dfsg0.orig/docs/configurations/spi_vfx.rst0000644000175000017500000004436413223553423022473 0ustar mfvmfv.. _config-spivfx: spi-vfx ======= This is a real OCIO color profile in use at Sony Pictures Imageworks, and is suitable for use on visual effects (VFX) work. The concepts utilized in this profile have been successfully validated on a variety of Imageworks visual effects films, including Spider-Man, Alice In Wonderland, G-Force, and Green Lantern. **Conversion from film to/from scene-linear is a simple, trivially invertible 1D transform. The display transforms are complex, 3D film-print emulations.** In production, this profile is typically used before final color details are worked out. Although it sounds temporary, most of a film can be made off this configuration. Final color decisions for a film are often made long after significant work has been done. In some cases shots from a film can be finaled before the color details, such as which Digital Intermediate (DI) house will be used, are decided. Entire projects have been completed using this profile without modification. This profile embodies two philosophies of color management familiar to those in production: *"Keep It Simple"*, and, *"Don't Be Evil"*. The following steps outline a simplified visual effects color workflow: * Load a plate (log film scan, digital motion picture camera, etc) * Convert device color space to scene-linear * Render and composite in scene-linear * Convert from scene-linear to device color space * Output final plate It is absolutely critical to guarantee that process - end to end - is colorimetrically a no-op. Under no circumstances are any unintended modifications to the original image allowed. Thus, this profile uses very simple (1D) conversions for all input and output color space conversions. All of the complexity (the 3D LUT film emulation lifting) is handled at display time, and is never baked (or unbaked) into the imagery. For visualization, this profile includes a generic Kodak Vision print emulation suitable for display on a reference sRGB monitor or a P3 Digital Cinema projector. Caveot 1: Of course, we realize that there are many other color workflows that may be equally good (or better) than the one presented here. Please, if you have a successful alternative workflows share the details! Caveot 2: We are not distributing the code that generates the luts from their underlying curve representations. While we hope to publish this eventually, at the current time this process relies on internal tools and we don't have the spare development cycles to port this code to something suitable for distribution. Invertibility ************* Elements often need to be transferred back and forth many times between different colorspaces. Since it’s impossible to know in advance how many times an image may be transferred between colorspaces it is essential for the majority of transformations to be lossless invertible transformations. By the end of the color pipeline even a 1 value difference in a 10bit transformation can become a significant issue. Invertible transformations can be taken from the source space, to linear and back with no change to the data. A higher value is placed on transformations being predictable and invertible than absolutely correct. All 1-d luts allow for forward and inverse transformations with no loss. Unless specified all channels are equally affected. The luts are 1 bit wider than stated, so lg8 actually defines 9 bits worth of entries. This allows the rounding in the inverse direction to be applied unambiguously (lossless). Non-invertible transforms contain 3d lookups. 3D transformations can not be inverted due to gamut mapping issues. Non-invertible transformations are only used for final output media (such as QuickTimes) and for display purposes. Film Emulation Inversion ************************ Inverse film emulation luts aren’t supported in a default configuration. Imageworks does not use a film emulation inversion lut for texture or matte paintings. In its place a film emulation preview lut, commonly as an ICC profile, is used. Although most film emulation luts are similar they do differ significantly. The DI facility creating final color is often chosen long after significant vfx work has been begun. The film luts the film will be finished on are not made until weeks, or days, before DI begins. So the ‘true’ lut that will be used for the finishing is not available until very late in the production, from a VFX perspective. There are many color gamut mapping issues that arise when inverting film to video lut. Using a film inversion lut at this stage would bake in a look that isn't quite right and is very difficult to fully un-bake. It is safer to work with images in a non-constrained way and apply a visualization that can be toggled on and off. Scene Linear ++++++++++++ **lnf, lnh, ln16** **Middle Gray: 0.18** The linear space is a photometrically linear space, representing high-dynamic range (HDR) pixel values in our virtual world. Middle gray is defined to be at 0.18. While the dynamic range of lnf is technically unbounded, pixel values for natural, well exposed imagery will often fall between +/- 8 stops from gray. The scene linear colorspace is used for compositing, rendering, and is also the profile connection space. All colorspace conversions are made in relation how they transform into or out of scene linear. The colors defined in linear are implicitly bounded by film negative sensitivities. The space is based off an OCN film scan where values refer to linear light at the focal plane. 0.18 in linear will correspond to a %18 percent grey card captured on filmplane under the same lighting conditions where diffuse white is 1.0. Values above 1.0 in any channel would indicate a 'specular', or light emitting objects. lnf is a full precision (32-bit) floating point colorspace. It is used for rendering and compositing. lnh is a half precision (16-bit) floating point colorspace. It is used for rendering and compositing. ln16 is a 16 bit integer representation of the [0,1] range of lnf. This is no longer used but is kept if a legacy image needs to be loaded, or if linear images need to be loaded into an application that does not support float. Note that storing a float lnf image using an integer ln16 representation is destructive, and throws away data. Film Log ++++++++ **lg8, lg10, lg16, lgf** **Middle Gray: 445 (of 1023)** The log to linear curve is based on an analysis of several commonly used Kodak acquisition stocks. It was found that Kodak 5218 is right about in the middle in terms of tone response given the input imagery we receive. The curve incorporates some toe compensation. The curve gamma closely matches 5218. The transformation does not represent any single stock. The Imageworks log conversions are not channel specific, all color channels are transformed uniformly. Compositing productivity gains have been found using the toe compensations when compared to using a straight line log to linear curve. Shoulder compensation - while technically correct - detracted from compositing quality, often creating situations where grain film noise would result in larger than desired changes in linear light. lg8, lg10, and lg16 are similar. They are all the same log to linear transformation but are explicitly defined to be lossless at the specified bit depths. The luts use nearest neighbor interpolation to search for an exact match. Significant performance gains were found when using the proper bitdepth lut. While using the lg16 conversion on an 8 bit image will yield the same result, it is measurably slower than using the 8-bit conversion (assuming 8-bits is all that is needed). This performance gap remains even on current graphics hardware. .. figure:: images/spi-vfx/lg10_to_linear_light.jpeg :align: center lg10 to linear light. The green curve represents the lg to ln conversion. The red curve show the green channel of a Kodak 5218 exposure test. The x-axis is in 10bit input lg the output is in lg base2 linear light units. 0.0 Represents diffuse white. lg spaces specify 21 of stops of dynamic range. 0 in lg10 space is 15 stops below diffuse white. 445 correspond to 18% grey and is ~2.47 below diffuse white. 1023 in lg10 space is 6 stops above diffuse white. lgf is identical on the range from 0-1 to the standard lg luts. It specifies an additional range below 0.0 and above 1.0. In 10 bit the spaces is defined from -512 to 2048. Lg color timing number from either on set color correction devices or from a DI house to be applied in a way that can be fully inverted out without loss. Lgf specifies 18 stops above the lg10 max and 36 stops below the log10 min with a total dynamic range of 85 stops. The space is designed to be bigger than needed. .. figure:: images/spi-vfx/lgf_to_linear_light.jpeg :align: center lgf to linear light. The green curve represents the lg to ln conversion. The red curve show the green channel of a Kodak 5218 exposure test. The x axis is in 10bit input lg the output is in log(base2) linear light units. 0 Represents diffuse white Panalog (Genesis) +++++++++++++++++ **gn8, gn10, gn16, gnf** GN is the Imageworks Panalog space. It follows the Panalog specification and additionally extrapolates so all of the values from 0 to 1023 are defined. This was necessary due to compression artifacts that could create values below the Panalog specifications. gn8,10,16 are defined with diffuse white at 681, Max white is approximately 2.6 stops above diffuse white and black is approximately 12.6 stops below diffuse white. The dynamic range is less than that of lg. .. figure:: images/spi-vfx/gn10_to_linear_light.jpeg :align: center gn10 to linear light. the x axis is in 10bit Panalog values. The Y axis is in linear light. The green curve is the gn curve. the red curve is the Panalog data. gnf is similar in purpose and function to lgf. It is identical on the range from 0-1 to the regular gn and specifies an additional range below 0.0 and above 1.0. In 10 bit numbers gnf is defined from -255 to 3125. This allows for color timing number from either on set color correction devices or from a DI house to be applied in a way that can be fully inverted. Additionally it allows for lg10 based image data to be fully represented without clipping. gnf specifies 14.5 stops above the gn10 max and 18 of stops below the gn10 min. The entire range of gnf is 47 stops. .. figure:: images/spi-vfx/gnf_to_linear_light.jpeg :align: center gnf to linear light. the x axis is in 10bit Panalog values. The Y axis is in linear light. The green curve is the gn curve. the red curve is the Panalog data. Only a subset of the function is used to define the gnf solorspace Reference Art +++++++++++++ **vd8, vd16, vdf, hd10** The vd spaces are mappings of linear image data into display space. The main part of the transformation is defined as a single curve that is conceptually two parts. The first is a ln to lg conversion. The second is lg to sRGB conversion. This is based off the neutral channel response of the sRGB film emulation lut used in the profile. The dynamic range of the vd colorspace is limited. It is undesirable to map the vd max to the linear max. Such a conversion results in linear values are almost never what an artist intended. The rule of thumb is that, at the high end, single value deltas in an 8 bit image should never create over a half stop of additional linear light. The vd conversion curve is limited to prevent this case. .. figure :: images/spi-vfx/lg8_to_vd8.jpeg :align: center The curve used to map from Lg8 to vd 8. The x-axis is in lg8 units, the y-axis is in vd8 units. The dynamic range of the vd is limited to around 2.5 stops above diffuse white. This has two positive attributes. It allows vd to be used to directly on matte paintings. It also allows all of vd to be represented in a gn10 image. The last part of the transformation is a matrix transformation that moves the whitepoint of film to look correct when displayed with a d65 whitepoint. The main use of this colorspace is to import RGB images with an unknown colorspace. This colorspace no longer gets much use alone; However it is an integral part of many conversions. It is also part of the matte painting and diffuse texture pipelines. vdf works differently than the other floating spaces. It still only defines the color transformation from 0-1. This colorspace is used when we receive video space encoded exr's. HD10 is a vd based space that is used for importing and exporting REC709 range broadcast material. This works very well for broadcast camera native material and poorly for material with a film emulation lut baked in. This transformation works well exporting film based material to tape, even though it lacks a film emulation lut. It does not give an accurate color rendering but created a pleasing image that makes clients happy. Structurally the conversion is a matrix operation that scales the data then adds an offset to limit the range from 64-940. From there the standard vd transformation is applied. Texture Painting ++++++++++++++++ **dt8, dt16** DT 8,16 - Diffuse texture colorspaces. These colorspaces are used for the conversion of textures painted in video space into a range limited linear space for use in rendering. The Color space is based on the vd transformation but limits the conversion into linear space so that no values above diffuse white can be created. This ensures that textures do not add light to a render. This is achieved by using a matrix transformation to limit the mapping of vd to the linear value of diffuse white. Data ++++ **nc8, nc10, nc16, ncf** Non-Color (NC) spaces are used to hold any data that needs to be processed though the color pipeline unaltered. These are data spaces and can hold anything such as point clouds, normals, untagged reference art, etc. These data spaces do not get transformations applied at any point. Display Transforms ++++++++++++++++++ **srgb8, p3dci8, xyz16** **srgb8** bakes in the film3d emulation lut. This table can be used for either QuickTime generation or output to the sRGB display. The transformation is a 3d film emulation table with gray balance compensation, so a value of 445,445,445 in lg10 space os modified to become equal RGB values in sRGB. Additionally the lut is scaled so that at least one of the color channels on maximum white uses the display max. The transformation takes place in three parts. First the linear data is converted to the show log space. Then a film emulation table is applied. Then the grey balance and white scaling compensation are applied. This table is designed to be evaluated in a dimly lit office environment on a sRGB display. **p3dci8** is an implementation of film emulation table that has an output of DCI P3. This is only ever used for driving DLPs for display. The transformation has two parts. First the linear image data is converted to lg10 based image data then the DCI P3 film emulation lut is applied. No additional compensations are made. **xyz16** is designed for the creation of a Digital Cinema Distribution Master (DCDM). The color matches that of the P3 output (dlpqt8), but has an additional output transformation to convert to X'Y'Z'. The transformation takes the linear image data and converts it to lg, then applies the filmlook. The data is then in DCI P3 colorspace. That data is converted to display linear P3, using an inverse gamma curve. A matrix conversion is then used to transform from DCI P3’ into XYZ’. The final step is to reapply the gamma 2.6 to result in XYZ16 values. In this profile each display has three identical looks defined. The names are kept consistent between devices to minimize confusion. OCIO uses a specific tag to associate colorspaces with displays. The tags are nothing more than links to already defined colorspaces. **Film** is the image displayed though a film emulation lut. This visualization is display compensated and should visually match between a sRGB display and a P3 projector. The goal is to match how the film will look in a DI. The luts in use for this profile roughly match the Sony ColorWorks environment. **Raw** visualization shows the image data on the screen with no display compensation. This is used for image debugging purposes, for instance to see if potential image discontinuities are in the source data or the visualization. **Log** visualization displays the image as if it were converted to the show specific log. This is transformation also has no display compensation. The common use for this us to see how well elements fit into the comp without the film emulation lut disguising any flaws. Old school compositors love it for grain matching. sRGB Film : srgb8 sRGB Raw : nc10 sRGB Log : lg10 DCIP3 Raw : nc10 DCIP3 Log : lg10 DCIP3 Film : dlpqt8 Display Calibration +++++++++++++++++++ **sRGB** is the supported desktop display specification, calibrated to the sRGB standard and viewed in a dim office environment. As Imageworks switched from crt based display devices to LCD based devices a number of possible colorspaces were explored. It was a long decision but sRGB was chosen for a few reasons. An important one was that almost every display manufacturer can implement sRGB, reasonable well. This becomes a boon when we work needs to be done outside of our main facilities. Even a consumer display with calibration can come close to matching the sRGB standard. Since so many monitor manufacturers can hit sRGB calibration we are not tied to purchasing from a specific vendor. It becomes unnecessary to specify a specific display to with productions or external vendors. It also reduces the amount of studio specific color requirements that need to be communicated when working with other facilities. 80 cd/m^2, D65 white point, srgb gamma function (approx 2.4) **P3** was deemed especially unusable on the desktop. The full specification requires a white point of 48 cd/m^2. To adapt P3 for desktop use (in dim ambient environments), the whitepoint luminance needed to be raised. The specified 2.6 gamma is very challenging to the current display technology on very dark colors. This meant that we would have a special Imageworks video P3. A custom colorspace wouldn't make compositing better and would require a conversation, or conversion, every time video was sent out of house. **DCIP3** is a projector calibrated to DCI P3 mastering specification in a theatrical mastering environment. We use a mix of display technologies, SXRD and DLP, depending on application. Gamma 2.6. Traditional DCI calibration. opencolorio-1.1.0~dfsg0.orig/docs/configurations/nuke_default.rst0000644000175000017500000000072313223553423023452 0ustar mfvmfvnuke-default ============ This profile corresponds to the default Nuke color configuration (currently generated from Nuke 6.1). If you have made modifications to a nuke color configuration, and wish to re-export your own custom OCIO profile, please refer to the nuke_to_ocio utility script distributed with OpenColorIO. The following color transforms are defined: - linear - sRGB - rec709 - Cineon - Gamma 1.8 - Gamma 2.2 - Panalog - REDLog - ViperLog - REDSpace opencolorio-1.1.0~dfsg0.orig/docs/configurations/index.rst0000644000175000017500000000134613223553423022115 0ustar mfvmfv.. _configurations: Configurations ============== This section gives an overview of what existing (public) OCIO configurations exist, and how to create new ones. OCIO Configurations can be downloaded here: `.zip `__ `.tar.gz `__ (OCIO v1.0+) If you are interested in crafting custom color configurations, and need assistance, please contact: `ocio-dev `__\. Public Configs ************** .. toctree:: :maxdepth: 1 spi_vfx spi_anim nuke_default aces_1.0.3 Config Creation *************** .. toctree:: :maxdepth: 1 allocation_vars opencolorio-1.1.0~dfsg0.orig/docs/configurations/spi_anim.rst0000644000175000017500000000051613223553423022603 0ustar mfvmfvspi-anim ======== This is a real OCIO color profile in use at Sony Pictures Imageworks, and is suitable for use on animated features. The concepts utilized in this profile have been successfully validated on a variety of Sony Pictures Animation features including Cloudy With A Chance Of Meatballs, Surf's Up, and Arthur Christmas. opencolorio-1.1.0~dfsg0.orig/docs/configurations/images/0000755000175000017500000000000013223553423021515 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/docs/configurations/images/spi-vfx/0000755000175000017500000000000013223553423023111 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/docs/configurations/images/spi-vfx/lg8_to_vd8.jpeg0000644000175000017500000010647113223553423025746 0ustar mfvmfvJFIF        >" [  RS!"#3BQbc$124ACTasr5dqu%Dt”EU<!"1Q2Ra34BA$#Sqbr ?WOL<8B.nUQ>O(<Ft"LX9W3C<3/0Щ)%+xG leThL*RթGhٙw{Sqy?m'wYiQCGQ\+![#n ⤅zxIh!3:mYu&ޜxձ0 a%Nn6ӌܙ 7[a9nTSY|PQPRی&-U;xd!YZ ot#)SK|kku>S=bΩ.űDm[#v5r.aGo;I-̩ZownN"> kޒDmQI ;z8nS-&k2!rߐm˿13WMzFR;DڸB=_G ;LWb4a\}'`;V%Lj Kbn:v~KsY*%r\U!y;ro &6J2MWmS'&* ]!Kj囖ladnmDDi2?j<(1zES)9Nҡ!ļq垑A<(z)pKyN47dڎѢؔwEjaefp`g.D*rbV)`2fafܼl0rdʰm8:Mܷ(Ne‰_%%[mٓo{dxl=Ptv_3(;/,!RcCRs<8݋lXv?&o!pɖISjDoZRz]ݱz)2ԋ$,:.酽 lap;5+Heomɨ5޺z^ݷd!k`r]J mn6nrxLLp&9JVHSb]i-y3uR>Kn{}6PMmSh0lڙoun'Y'0f&HB l^KI^^;,mn˹cawcHaUUAn-yXVC:H=~fxL ˷iF]YRTGxͻ m|+I͚14O_ o)c,/wssZ?P `E׀ݝO2׺ӛ+x,J.6ch ,DNfTѷgl:J4)v.SMR3KK96a*.vrs 6m٧ (aZNǘ`EY_+W毐ei'Hb#!m%{Hj$j\VQ;M[n=U[ ;$$*T&ܪHYzn&MBP$ˠ]Xmw6jY;W쵉wf7vPiCnbYnwȸ (6ZŠniZcZwñ{GqgH0nF̔/I8nN^y3 º#Rn>84xQva&8wn+x$ܲ[0[Jk -|wf,(J6KgfrJ_sܛiB6L,鋠r˸XisBX >+ڃݺ#d6j4R-^ in٧nzJI& ߙ 6;NY/6n{XO'fqVU.riK8s k·v:VoHRa. 9R4&e8窺ȵÛ_F)WhZvR]iwvZW3v Ԩ+2JʁL%nO꼛 (gIh^%uV5wړyɦ\YmK`FGsucsurč2zV8T5WVC IU3@!:ȑ'|n9v~9}Aj\xUqL 1l^^9.԰9{8g :ʫҍS.\7D%u˼6{t (`g\u!`@A ]ƶ)7_a{v؈[u⽙Ϳ2L_+s)$p`i'ہ8{R2ۑjavpdu8VC 3Naϡ9rEede+a\w(nBBs Bs BBs Bs BBs Bs BBs Bs B Bs Bs B} 0} 0A (gH} 0} 0A (gH} 0} 0A (gH} 0} 0A (gH} 0} 0A (gH} 0} 0A (gH} 0} 0A (gH} 0} 0A (gH} 0} 0A (gH} 0} 0A (gHY'0'0+x!'0'0+x!'0'0+x!'0'0+x!'0'0+x!'0gМММ!8Ӵf6+ =!wZ?'ʞ6I ]H+ը%MӯJH52Hì2o6rfٴhu,ya u 8H"ʢ.w]Niq9<ڛ6g(:VY+jfeu'A[79)]R벮;.-9, mK˘ @k~jkQfY$ciɹKRnijNQ-˳/5gng)96rc +{ --S\#(. @նfwTS؞{S]m|n {k~jDM( iBf0na)}g\)˶LI9?w-7-0ԑ޵F7G9ff\Z$5dIӓ3>L/{E~N5?5;LőDDPfMmצveo^^Kp?--Ul ٸ8f*VhO4-BQu-ub@;b6r6;״8EJT20TW ZfhҟrN^e=R/xwblDJJ˓I4Xywڒrg mAp3` G`S {OÎ|1qƜTtpE-ܺz'ee& ǧ`AfVunnU훛0c14/M<#;=4nͷ &ofmfڭ9<&TτLz"ǚm3*=vt[~Qz8C]ن87ƶ&WZfcmEȱi7 ǚy3iP_m4&(VM]IgQhkoexGWtVVqQnִYY~(5,@z;c]n$duԖvQ+yǚo6E [ײ~֥9<&W9_m4 ͦG:{(VL4u-vW6xDZi7@3^ȼ]~(oǚIB8,]4o.#M"t7P"v5ڊ9<&W8߆m4 ͦG:PC2b$tkkHDZi7NT]}yĴ/ itsR9<&LT%K Zۏ4_m4.7WjMo7R_jp~r yMǜ6EfHi~PvY[&Zߓmߜ{jqAjuYy3iQҔWYW qͦC M:+9.Kz c^nA5{IfH iE=Z? C,){jqBj]YQk=f܅M",9<&|!]muZx]fHuܭ@,k,AJFw[c1i7t}[Z.QF7M"ځ>Ql%n2D0ۆʺmoɭQ9']j6a,L)33[h{,)KA5{I)aUW WmfHU ĽM-$C?` e^Ǿn0W=O(ն,~(Rh_7P,Dj6Zmi(''&UĿ,RAr yM17r iM"t(VYp)gUFEo!8<&;NZ7śn߆m4)KTW(fZTukm;F?5߆m4Ӯ8a_kIoڊkR1i7 ǚy3iQ3iQ~PvJU[ [m#~r yMO(WJoM"G~r yMę3-]:îߔ4ߎm4SΊ`rĵ`/A5{I?9<&WÛEo7&C2,z펵iW|.]dRRqQ'x̾?8<&DťYg7o8ԛ▎PDRFRpY+%vb,v.6&=Z\{jpS]U[rl+T|6 k^G&;r& MӴݪBY9ֆjUuNX;ĶR~OI~IYszj;iBBT4/Y[l]kS ꉪFu?EDI6҂$ꛯ-,޸ߍ#zst%,Ĵܵ'\`FUD'Gmڢ9MZIj]* P+IO_07Y O!A:LQD[9w%0p?㊤L<ȍGHӒxW|rV`m!(*z!:pVnZoC^. 8aU5c9 #h/C#h/C!t -?ÈSz1Yj ^&^GR-Qk={\- 8@N] \@ oD \@H7ܠrq-4iv<Gѓ`ܿÌo 1ك|z­o6SN&boEF=нjZq0IWo{/'K_%+0AV2 OU abT[7ܢrq)BWms}Ljׁo\ '/C!t5ADPaZ_rA6 83\br{ ކG^G^B JbN nGT)4b^oau4zkDunUi-BaZdiaxVJ4#q5Z:KxkGp2>]I/xe.⦾ i֙.֕)Eع>zKO<^LG/EJ7[h+]`U/rq>SQo!84ʇDQjq[hYjTJY 9vݿrsSq F߾r+#gtC=OK3m K)mK`[aeB\,~'8-?ÆztkU{NW}ԅUyjUfij/ʻ"n2w/1zp[ 8Q_ )Rڹ}Pj UKo79U9XJ7Ru1ղng(ڸQmCkZ$KFiERUP]?Æ4х:|7ܣtj%uz :,%e,Y绫k7udšu1YNwk5ǫýCO6ޟ8WQ4ϒɎ'qF [#n[CwtZ8mzitթѺiJ-QɹfomNE3NOvVZfNVmyeu֛vw}Ʈ"ǩU(Y,^I5U2cz,ܼ-^nYq]RN'$V)v憐YJ8eޘ9ݘqj{ܒRN>22S ͡b]fEXSJUnY&gUt VTlRT7SR4auܣS G{z-vϼ B)6o1IefƝvʚql]ESi~-Is.Dՠ &uƜ2콆f{>J\%ޞuU%ؖrqªi BEK;`xWzVa}on]üڒ2=J^8D'Uqa׼6UrR/GzJսO-` 1EIu2zYf, كW^훷's?t ?hEq`mp'/o\2]1{(6邭m:sXA2Ӹv`vZs:e$'.5ߓM=7{?+[uanTnZªEf]7'%&%qr;u2ssvVPen<}ԄR Qm4J1.U6R ˪9ynu>v1*2ŊmK[w[-%Պ]!FK 2-HIc޾qvЎq&gۗ3؀<˭0nKKn7HjQu`k{H&prԌmiFi-ޢ!߁EwCAI","3/6'90`M0!L>E*`MYr#Nm*@yIaF&ag&={X1b$Jh =*RpJh`*R1q?  AZCV=!OHz820!UڻzYh2OHz8iGag*Bk竅=!㣲@b'=3 %U{$g=!ᔑn*e,BӒٕN^+ܻM)GQϒ1g )ҠR9i&Z,l_ ]$|j u59NKQLKQ4:Y6j]65U@3I;# uڷRZ]]Ս)HҔSsmJ5#0vBn~Eۘms7%\p~P7U  ">wE-gr|"c׽ňqaڞneׯZrr-J2%n۱wbNj"^FvqRS+/xی5׎ѱ`QWfSЖ@7Չrs~85iBHa 0ImjױSDl+9k)9VHJkv\)ڶ$ H`2C"V5³_fE*iJS5XkaV^rQZf[kFssV$vk΃7QQR#aϯ_Pҭ"Luʹk`[jm4Gtk]Z~$K_f$|3_fE&nrU\%H_vkꋔi^cܤ.3_f[$k]ĆT+jo9?Yٯ )V_^՚k# H.-t?%aYϯ_ +9kR5: QS[!ueCNʴʫw5!v5+BF HaT5U F+9kMʴl(R]IV[,Z~$J³_fVs㈥J%j]Ij5U+kSr$J/V=k>M._f$[ "݆Z~$N.VZ,o9FHՅg>~8@4R/ָ,lĉkVOZ*{݆Z~$LzUo^6]$ag>~89QMU7YiֻFQƕmpfQ}U쳋J`2C"]bUrF8Vs㉔Ms&64a|f?a VU}ksɮ_VssJ# a]ĉڠlniTQyH6M}qOjmvruE}jLػ=}fx29OjwSk7i;v/ 4"'N$(v}_ʥTTNXz]F[Qalq9a5#̑9SӖbu$jR5l*my6HYvkT,˪OԻ^fۅFscڶ#X HaO)YvvHфg>~8aN47[v/7j jҦ-t?>X Hg>̾80ٯJHsT%75B]ćTJdJ2vv5ja2C!>\frODqg>zHaOJ6oUڲv]ZT%]ďapٗ5)Raw'Yvհnga9VJޫfgVs㋑ik]ĆabRTPr}}pʙiBR* ;F(]Z~$Z?'PyYEog>~8~OlMJӗyj; _iۼ7B_f,:>|>8mlKL    (*[xP_AR;{ Rx )VߝiIAn:ڸ>1=\L6J*h wN]2ᷰp^"EZkHϬl.klO74KiV&W^fa\"$4`KiV*W^q?q4J &F8a1qs}sg6iWjK9 n8% S 8|^zWp>:;$+&C)66ҫM{%-G eL[d. N25 . hMbs}GСФF3-njq4JѬ"Kv|E?a8a8<} ,Fڹ%о3P‰a'6b^q-1tq%ągDТTh5,,Îpy4 (1Q׈~25"M3P\pypc>iƅ&vy3PS!*1]k^n' n8Z-w7c"ML[4]oK.7S,&b6X$#lva,WiS3qy8pdMt;" Th{;$DLGfQ&% WocYW-p>R- :>\&pyBT#hDѨ_p(aOm"F8]LG$[$p(eO*'iK7 8|><q( <     39PT™^"Dg&={XoUZ_4`KcR,' ju YPթt<¥u,'n380ɜXT9tpaS8غag6cW_ep ]4 8_ Yg=\-¦p9ˣKcL}I09)gT9tpN]0sil5ݔ׬Y#jۑ"2gtpa8kr¦p9ˣC 5v2NgtpŒDbu-L~3]traK1&p>G Fof+nw-g~3]2%of+nwrp/n38 ]eLsG3]s )9^7Krp ]2%ي+^q-*g8.$ ]2XDWb5ܵp .P2ȊWfYW8k ]eLsG3]sjuIيS]7wdឦ&mS]/7wT9tqS\I38e'%bhk%S8LˢNK-]5Ki.(YL} 2gtq3]T9tq jaIvb͹µMm>G u1.6=dsT9tqnL p1&p>G>$ܮW''r~Q&V:U |_U>+.+&ۧ $5K.{+ ĚJU7WG C.~ Jey\.¦p9ˣ%cL}"S{YW r=,R1Nӕ50-WL}2dtLsG3]sDUVbN8kT+R{0J^w3*g8"-cL}S,"SCk8' r5,20JCYy850ƊY38N Ru|><q( <     39PT™^"Dg&={XoaUj[0ѩ~y-J}¶TJ4jWKA2h`_㆔^8iA\;-TZ |.^8iC*>YRVq-|9[G&JIKv[ we70A>e%*)4]M (0p҃ 1A1v(aFKU/:]w߬5 p҆dZ v5 |`&JP rB *3{ Zi~@[㆔^8iA;;0%nq-Wп (aDJZ y\h_\|traK /4-Q?bn rL}ʂTW@49Fh (0p҃A0`(4"ƌ5;-T-ܦ߫ p҆a.57v(4.$0p҆r]m…5 1 MJ9.vߌ#LiqB/4J 4 *v=LKٛemtɹ 0p҆zTemtÛr`1jC (@7*Xrv&VkL1D1dQ ]ûxdܱ-ۨĆw6|12-69Եƚ2EMDL[D[8iiv觞3Vi5ye/#k;3wq6j<٢P[W~Ċ6lQS2ʳ3 }qc2b75R$S:.Z32dʇa:ϳ"`(4YZ[A;$zcm*,C BVنpҍԄ-\\iPie>lJ&ZEC&;cuE*74^e.AJ /4Pi>0iEjZӫls&-qJjVV&pA> (aNV{0i!Wj(4 )UW'|>nVE^8iA㆔5 1A1v(aOV|F~PŸU W|>h/LbK$0p҆Tk-9^rp 1Tk/9^n L pxP`(4 4" )Ijړن[^8iC RUU=kK.|f(4"_!㆔2e M%R>0i0UBSdҡj\/J-')5=-U5 1ţuf%Zwk5O6˷y=o9俄YXu!N|/3|yP6%PAyO`A@AAA-gr/ؠ)~qTLDǯ"]3,D7ŪTJIFWV>+*i=dT Z\ɭngDi] rL}\]1L~8g`3%g9 0c:>URVq5zY..qr\5 1)U%cY!qtRRMjx&yHFH1xC..qv(cFʪK뎻L|L@/iI (UIyi\x[..qnL)q' *3znwsB!qtT$gq<#Ktpcqt]!,PƈTnq+y\oL/PiWVPķ) p-Ʌ.$0|a|1eUqYl.L~8e@ʪ+Y7_B:c\]1L~8g`2쪤-cMw|L-L}SV57w :*`K>t u3*9,uˋ?2Ī亭[oi.4Y^|e\||L~80e9vMLJMt9=0#>iUIUjsnq^xCEL q'~U&V7ÜopK:DjZbrpҨ7kN̕l%½~HQ$ĵE m ZiP&RUON5m;K4TuLJyW&g _g0m5E5.sVYlB^M;Vl~η9*t[==?+ֹ>t4\L;/5J-K|9>6S23 qxG\|KeU&XZYwÜOLCL~8CJ*L0gY7ÜN<#Kt-c0kc<۫\]1\ɭi=ܡQʪM-c0s-iE(94yÜ^aOJZCB UW|I;vH50 p|a|}Pi>`ˋ?2gb:U;tE 1ᎨeU_֫p5Bqt㋑/Ȑ/i UR9^7abJL~8eOʪV|W|9 kc!?|L~80E" iYUVZX>y3 kcRuU,{R ?\~DxCL~8eMK*Jt8 ?2eUBRC|9xja[1štf$ fL~8NNRJkzc\y!Ǻ>|>+)ϟ%&bϏ>f )    #ϔֵ%7⮐>S?ҿاC%~{S>1bHfu>fViĴ7smmw7:zʋ s!nڿnXXmIjf7(X7ך^ss^)]NKT6m.6ۭjUۉڡ7kZJtss>-'i p&GXͯ8|M >LVq*M|.s4(WRZlUks;^t9.$.|3$JvK|?b/Xͯ:{ጕhnֵrVq}1C\ >'sk>:myBQ*$J]7 Bp&BN"Lծ>pצ:9.$.|2oY5qLFO|1(WE&mu\Ldlu.H}`4:myXͯ8(] $Qk&|[ EC4] +k5%0Nם=u)q$lp&&H։[n;^t tUV^Vh{7[4H}#Nל}u9кJ$*nS[wanH}S+*]Mx݅aw6š.$.|2ԙ$䲪&'skΞaԛ"mjGBtեM.|"M!Ğ;^qα;^qP &jfPmqG6$p'8GRmUF"D[Z513Du -#uK<Ls5f#F-@ $!C@7IԶ8vr~Uת}Ai MFpy +FdHFD;=x@ЮԱ+j *q=>ȠT[^+~' %"N(c^H}1 Kw}Nל}[r= "kY7@_퍴ԑ,ԛ/6jxllhGJeF֥}qbn#X"M!Ī"LaTMݝ?l|O|KGRaV֤yq=11֥)"WZus|9q\ >aHPnΪ6+x/~;^qݡF*Y;CA$K740sFvל}7T+72HԯI9J`4H}#Nל}.ם=΅ТNdfTD}~[.|;% LBڪ-ޱ;^tHVFs҄H $^'skΞaNЎ4G5J"M!.|H|bw6t.A&J&+4j4)zmjN^'skΞr$.|2V_Y<W|9my V*mueEuǾc[\ >0%:myXͯ8 DRL:5|>w5 EC4&K.Ϧ.F:܉#`9 2PMiPq؍'skΞeLЎJTJ.ƵnLp&:˨NRVJyj+~;^tŝ|H(DKLş}8̓iASAA@AAEK| (*[xP஼ғffY$r 0w~菪.$]ADޤ8s {S@gn8:g&={X\S\1l1.uސ.wrKL. 䲵|\,ha]~ 3=U|kWF ]O`>X@ip0ҏpWھ5B>u 1,цR,.m,w^/_x|'ΰL5UU6W0\JW|::M'ьK+3i],憔av-Ɋ|(Id2[3u.Q_x|'ΰʃp֥x8#mWpY+d4elO`|'αWx?X0Έp+R q- -Ʌ 1,цT 1Xx8^ 2\*߭Kfky+,\JW|9D(jiIWr~-,цp Z5/7v sZ!&70S *NK*z(x|'ΰSk9-ZW(FekWTn,rȈe61/S4#jrI\ÊBW$0JJܹnw]|y$m %[hg7ѓ!GI2JmOձq<#p VU_B=LbٮUuW6,': 1*^bW'j}+,xF9DOxZԪı\qѼRWJJ}w|% ^X~.ut0 +JTj%y\+e-S^h-G:I70T *B+}:*y®^/*E]. %y+>r:NUjN_?s0WFRԝJ^ u믝>u1,цT 'Pv 2+u)x(WY`ܜw1i|Q"KLşQϒ1gǟo3`ZeGAAA@AAR;{" 39~xS>1bHLDǯ 8/50X'Wnf0v F핳 ښ,lJ73~ ˜ĞYs-"KLşQϒ1gǟo3`ZeGAAA@AAR;{" 39~xS>1bHLDǯ ]QaSymx_%3  Rh`[K^*Ws1?,N yK hR{Niۃ3jYsi<5TpS%Znmm}5Cii&ٗbsgΉr-N8;QlqP/M `޼asfƒ'6DuY)w&}l9Czvmnf\(]Kktsu*e,7n{13p"5Hbf g%MU/CiXaYtRUKЎ=Xq<p<珸XX[ܡ' fB5Tɹ ǖ\SL-Y4,_<˞'~tnU֬K>P"\)bu:k7*KR1ĉnyh2ƾYsgK݌zyK-t髭"rtff](Ft֑Iw@)IB]/*<牴4̺)>>Q"'\)bU:K0)*2%z^ tTkU>:~YsĪBx wW?yKО=msQΚM"$>QbVKuC:I74JYs<猺yK\)b-:$uk/&-ǞYs=RM:Jۅp<1\ƞ$q|KPž$q|Kv·-<p<猺yK\)b-hT3kJxTj,?8H*m5 yK&d,?8Hi8[XeODr˃WPye1ǖ\u9#Rua~<˞ғK-3 yK$[0ye A+ Ga\)a56H2ʇrSE>ye`rC%$K4GRd+iyPY_RC6mUUMfޏ5hR|WԞeBMkܓs9ơv0#CmTfnoG8dy`\?R{4~hVڙ|G^@a{N 05xhIQ/TUC͒%x%<8 d"rVX&EI82)'+/M~S:yBQmv6$"DsXJ"np=[~?֦]mBT}}-7}IVZXFB^hɴFvnqŻ>DJDȻ!E%HAMo֩[Gq|;οkU̥S(-Ki@ t~4Y_R{4#A.90e)QW~$͹ 1 3ڬ(wO#rKѢ?tW`K>c+H@ΒʢvegX"u6K7* o8KV!:HE$a,=ћӥhܑ#iprߙ)WZE]x/Fftfa{L#\+&$Mmn Y_R{]:K0*v|IODEƗiY[wgz9DƷIy|$Y_RDJp[usx9~#KtGG*e$O$"$$/!VHq7TSjHkL?/n c+1$}D~194cyQ7pY_RC-SͪM:V#o :?oq}I#TdID ip>TqY-Po*Hy_P<#0#A.9ܢ}?8H OyPY_R{fŸJoGBaz4G-|WԞeOMKNWę]/FƟ$Y~G7 E q$ iz4^#ԡ)8HԝKݖ?/WԞaJN*5'ז=@Ɨ$K$,=Ƙ$J*$ϻ Sj)ו W hY_R{:L)RHK_q- k$VQj*퍹GqC@caKΧZt4{[]\tJ+5QpDƷI] ů@~ↀb䆈jPSJkx>n' k%Qۈj"Rۍq#a-xCLLK&u p!>EwO4ꀪ6`J((6w"XT ZtMh|G@}6-LLͲ>m$-ŪdRq@Uz##c81Vݘ>b׋?NҬܪl|!q|QtIiTmܩFKkh z8]#7'kU[!!>9o&]kx9~6S3J3)qy8YbFE\uAéDw_*3iYcz\tH,8٨0*Gu~f%4Po/D|Zt3Q̵|DjqC@}з2nmkN?MҤl|!)9 DFyPEq+7_UXi.-xA^.c$4GqPosFTu*o k&Rt鸂(cb%n!$4GV iٕG|I{v8]\tJoIRL"[mODSW I] ů@~\\tsCPM*?%wrp]"U%I޹mS`Ԣ%\E.Hh.GT iBގoBb䆈ęVeJ]D\Zt] .Hh>$4F9IFycLp]"L%lYKֱ|Pt\s$1k3*)ʆsp!>9I^#()vжůF5n[]":9I։{9#GM?G× mCu!N|/3|VFHS>KLş}8̓iASAA@AAEK| ( d^ B{`Ҕ#ײY~#@lƉtmNf\uj]2QG3RQm+z*^efYqu!iKB,$$H(Z,Z÷w,cF.ɟj#3./Nn%mnzu,y!763 +eyvێjC{ E6(cjV3OʛRlm`/~%jLV(bM |FѧN̿4Բ:QWV{V%N@bxbVM /Yw">*'"h&`#MSs&]y-wqꋨ4K4,^mvolk6SÙnm+-ͶYe`_pHL :hP敹FL'nl.׷uc2JUP)K@ġ.Ӭ6ˈ7~n^u/ER oRģ/4-Ʉ!G6&kmB^:>.o>=)/(6@ؘcan꽋(:Mo-';G6rkwlkqIE&c,rIaޗn;ɞ=h"OJNԎoRf=nF*Ex.`ȶ㍹~A3Ae 8b)9RsǣR(r P'Ae 8b)9RsǣR(r P'Ae 8b)9\jc@6F]Juw֟nn$  Ğa}]$LƯ+7qi`Hx߷ytbO0Ѯ9_AYjq[vCӎ7/kt* K/@zH?)|m")/@zH`-/|m * K/@zH?)|m" 䛜! [ GRXônBV(bQ%XEiػȝfuK`[~zHOͿ=$U@>_6~SoIlOͿ=$|E[i~SoI>_6VZ_|AOͿ=$U@>_6~SoIlOͿ=$WT)}&lhv+mQXGA[pQϾK`P-xG36FPW! Yu(ѱxdLשCopencolorio-1.1.0~dfsg0.orig/docs/configurations/images/spi-vfx/lgf_to_linear_light.jpeg0000644000175000017500000011110013223553423027745 0ustar mfvmfvJFIF         >"` 4!"#23RSstCQTUcr$1Ba%56ADbdEquµe>!"12QBR34rAab$#Sq ?]}m#%%6ֵ[fG}aG7 *IWLs%;'T $cL;&_*G>r Z2`= IXʰOiKQB*D"!du"#Iw*"صxՆ`fD@'[YRX RҒST72҅-7m|er9NRdτT;HKDwdd#,)ܹq`kwj.Y.k_]?Bs$SHjZVK Qs16-e?d%'!SIdm7մcsViF\;q)ܹ:,"I)ŵ&2hAf#Qn{x20cpcWm޹HM9+Qoo/#¤i7[sreLR.,Gǒp)%EIzMD^3%B/FлE<k5T"IN 6mw4ȶ-q2!n$ҕ%Qꔧ#.Jm%*?; M!)E) zbp+㰩h֛JBtKl{8#XV"D)FKHȰ:Lƙ̦EYD/T1C$f " xK]r' y"$iK)ݣ {c[UO$g-] 3Y)m)SRirIk@)KxK+4ڹmjO' +P9D̺dx1-rd.n&Ik<'L8HTָIb!AפvԢd}AvkQGj}dx5w9I^) 9$ N%cҒ(72YZUSVND+VOac]߅N0KJʆ*u C}}kFnXNHe9o%)lKg)$jp6e,./,'8v(ݏanC!,k%˭1IwKQ)ei7-&_-q;yP^t*?J,Kˉ\q7򋈗#ʂ;yQ5t@ʼnyq7.&^Qq;yP^t*} bļyE~/(z1b^\Mˉ\DNT#ʆH/.&^Qpeߋ."^t* CWO X~/(2o/SGwH򡫧,Kˉ\q7򋈗#ʂ;yP%ߋ. yEKAz1b^\Mˉ\DNT#ʆH/.&^Qpeߋ."^t* CWO X~/(2o/SGwH򡫧,Kˉ\q7򋈗#ʂ;yP%ߋ. yUKAz me\"zܓ)*XnR}AR4R&gzЦ$S=[L*ǵ8mҰ "*ʊh7˸ 17#;]heI9p&%㑠*3I*UB ݓjڣ ah&Jeg#\\:RUk_]uﺕmAj;NƍS~$gI!bT[?O r7c3ފk5r!l^|xRڢPRnuUHAMw#%?@dS.Um?{[ŵ 9[Z زR0@#y%hCcdAj^q59)l{Mk{gdӝ}6RO4k @֥Ƭ eG8giJ2JJEE̯/ cFV䱨63M'9hiJl{eK<$Ĥ$BhI.A[`V*`s,ʙ&,w(n&%" : 2+'ATy6{t= x9xGB4]mw%c@k))Dor@Є#)w ܨu*I:nD .=> q6Cf ɩ^=qwW XGnQ5fձ z@!!wK/qbHܣB'4(GH XmP a!~Wd&vnx6} 4q^X~B壶AF98(7%$^vR)M5~ SHK KvBM9ը;4nKNCzi 4p .c)VM-tK|A|̱x7aUG*m&RtLNa.Czi 4q;b)4;yCTET[Ѷ4_=Z6_S#%)f#$2.JcYG81 kO8XU 駜:¨oM<\V%e,%b)%6c%5yP= '(O.Mxv*jĻ:Mv%r𗐷ۢUwG={# |scythӆmB~S39I.Nd'12\|GzF㭽(_}$dWV LN+ZƟncN ㌡ q(_}$fVBICE;^ {焎0tmKh3OAq~/S2%%JJU\Ե!)yeh~<=m}_%!gU^4#ϷEV癩?I3cOAqID5U+[ܷ{R0tQnHӉƛFhvz ڥ\eZ*ܞֆ;n|~[9o__En5SDh}㳃ՂɦCEr0tQnH_8(W}oud-IBjƥYܷ}$HBUW*?nH >p_^Q򫷟/98vf.:ۢUwFcuaj.R"/-Ôq0ҷgϖ*͇;}=Z{tQnHȞDUJЅOB"O| P9niU{mGU#0zW%Y.wh㳚u_i*˚o-|0tQONHΑ⛘$+ٛvz ؟UH1)6?D^o,e 0:_`Q{3aiGU#2RR4uUZwd0d׆w6ͽOAq~[3 %C!%T] T-d'19u)ciylf4y%YsR;ՎHӪ$U\=}$rk|t^ԋ(5Dr%)[Ӵ쑘U٩'iN؟t8JگNv*rcZTV 8x.i{V$asSMc&ImIm8ڴދ,JYwwg+Hm~|+;?źQ2~raZĽǔviެVhoV*NCHft!V^ ?BS3ަJ ( zcD6$ ^ldn Uٲ Ҳ8p "EƖR%:&ժnitcV):iM7(DWɫq//:qcIEErPX\IE 3!"4 G @ 8:,Ό\Aw(ϲv=EnA ¶m D1|RmژFbe;ֆK #ɹn!7BvtL8%GRf,E>% cQRܣ0ANSG". ޴3BN'EФe%d|ɁWA-3tM􍛰ѷDh?PS[a;PP&+=-oMyV1 R+Y ^2 iS߻&h5ٖ5Z& %-FROQ(S+IS6ɉu#;lfl!7Mo|^K  .\eYrX. 0h $"m T" 5& u%St3d)ERַny;mqbFOi ӂ7=&)7uy,,oFڄSeVޞNNqyzWF+ 5IAo&sk/RU7d!S: lQI8D ԔkS+zMnDޘBw9]?2.01"I% ,{YgzC4EJDDx %&du.Rj;:#v]$]$%gipQGjЍP>T'r3s~a-.a}߅U91Ix:J ܔ6JJ?+E[Zӳ[=w PUP<|j|Pdl;[5vhkuTԎ(+XUi_h8pƹiܔ*FգUo([v ܇<_0Trӊbsea \f@.yGMO"\*sp;H7s̅rQS vD iu5RԵwCo xcĥn%ѳp׶-89¸֫ELZtڡSց6<:8ELxc+HE%[+wC$Wx۴r Ҳ}0-(pP,JfX֝&TopGO"hA h?ӹG~|vi}M$1!nSijw8u]/K."F~=ʔxd9RRnENP28xٺU2iU]lh{'/& `}WwE. NEyJK36cHwm㻼Eջ|)*I{*dϛsB\k\c6-4],&.Tz:^\3vB23Sk%ww&+\YP:p43*TA1sB7M؞H=~W0d!kAF% $bҀۧHҔ,ILyy]kΫtd.gJjVCRA2ۻݮsxE)ɪgeJZ4\IA?džX7eYeݺɯY9NWY *iec{ROp_M,oޞs uؕ u'+kp,́S,ef&׈t3lۅKO1fI]>U2LZ݌SW!QaH١x 7B[BJ (]@!V)-;Jn9x\H88g= Cn-G~Vl?dwUo qA@IL5le)lE [P MQcg9*Sa.q> ;#b2sͶd0m :6},m!hmfq29(h~L2LN&fTnUW{E$%ҥ<84"0Q#7V.Q͉(s5)JZss =7/K n.GV x@NB|FL-^yʱvO =߅U91ƼgC('ʥn%jny+A9q4! M7 뒞D,!'zo8HC,&'7qGjԛ$ޚy~3 iro+d2m nٙ=h·hߣ7zm&ִ|\TmKhS ޚy~%jꛀJ鬱?Po"tl8~*DYR1tm_|`хoM<ѿG*{yR}yx5Glj[*Rk66V`opF4V݋N(>p5Rq)·hߣTJzibji6/+P҃y >cPTS$ޭmy!HpҔHw<;g~-cSVwsnL~iW)s:T,BG>mdY)VufS"% 85ǣ:)PcMkXapq,KB9fIZ5&2Y:xiOT41Uy=GdZ<1,4AgnW՘<ޝCNP'44V{f!q[I-'-纚k~Ēښfß-D,hwVnTUު+Qj?nk$a#XDYO% IhRݯdj+ g7a6*R3yV>]l3RɩY:T&Ko"C,8C$J+ɬ(b b#UN b~OǢӦ՟xh琧tQE9 wEpcl'R[2I`q9;~!!Ne\inֻRP2@q`-at9qF9 wEˊB>8a/Y[Z~1r+'|3O,D~J_FS:$8e};<Bv;ÎBBΑ⛘$+l Ma8)KUH뒂s]~( sx ',MwF9 wEd̮ fMxgCh,N wE9 wE[UYM.,ȍJᏅq@ fNfi$a w;)1_CLA"qغG.xqS(=C\ ڤ/ю{Q˿Dtov?FcyNhG|n|+;?źe~ȅT+om|+;?r)RHiX@A|s{4Z*)e:P'9vk$aѦ;!4S wbӉ,+Z)mjcn'.(.l2۽}$ZSu^+H~@hL 77ZpF[wtJw!P/8BR+ ԗVi`N&TTj6ȁ-:yGQL#480e*P9x$|Xo#JS^9.Z.- k{|Mn68觍W*0sn=7F[wt*u2E,jsA(1>nΝhnΝ5)_xQscQq t\K'ƹw?/і<#OI/ U\R~žXn5`Teԣ(sytezNH(<fi9omVo6T@V֑g> nΝZa@A|)BP* M,jO tizNH5$7C<(Η⇘MѦ<"}z.%Rn]C"a>̚7F[wt句k f,L2zEZ)>1̝>4izO:H`ڰm\*TI2+kH] ( |4l_?$MѦ;!nG$R5jN]ζO BcGo'M:wFf-e'VU$-f1Zp[=9=uGQ߾5bT㨊S9d.~0(G~|vi}XCAVDQm9"{ufW(oi-&u)*/vθ|9/~`U<8jfgPi$!p9EdPx"II)Ǯ jnj}XQmJJ-KP&",n4qumX43RJu+ɫvű5'@ [\1+,zu'54TLO$ Ɖ!ޜN^t![ޡpҰ6v-̓bԭ&/ɧ_SWs+"Kd9&Y6gc]-o0n.TV(Y))9 +2f#ychzMK뻫xǰxyZNqs65eGRloo02̝>0 k U p[; gb ѾƏluhqQ̧>η;»L^W\EǤ67Q߾bR)IHnglR5Ǧhά`WRe eJN+amg{uX.  Z p 28!x=ҫjRS% k1!14EU(5 Y#[t F4Lm)Oa [l”:xZ5im`c=<e#Rfgq+N1k)Qn\A?#`ⲃi%cCycf;$iԷB;Τ[ƂDiŁĀ7=[IIS-!kw(H :9Qj83iIo.)h2kƍn*YBsX#S )Bʤh#Wb|$dOM}Q|:r l,E $\ k^PDMR4RT%-^DZ:O)T˷%J5^`iPݽ-G S^>r]& y@jv-#͈6TF)4l[yfsrt9F)Nʧm2J2ZM4 &0N"iNޝn d\mkG]KLN,-P/+{(ׅkp2 gA]lݩ?Pi3cOfv,\c\]|DC~g> ^*}#prWsujc4%&wckbJ>5s3 MW²29n &ŵy7'͎) kbaږ-*9O[u)uNbx> YSxմɐY[#uXmiu1JvlF+Qks֩$'6qGZgk,o1RL% L$Τ+29ԙޓev^$P1C@y[k,]nRzNЙ.d%i"_iƾp΍hm wck,nRHjbQٕ7%L_~?^Q#Xn{@g2j SW('ER-x)>>(5cXjj{U!Jt&Z5H/=*_Ri4bx#Xt z +ջdd 0R) ,¤H璉cO#!.i [\5FsNIC;!W!WbDݲ6-zzWTO]'%M!^f%^ʞ\&aSpM[,U8BFMoJ5{uʃmuʇd63D,X>2ӟr8_* %8r3n.@rmEF-t;2VT(=:~kX~ 0ۅ£23`vepE *ovX>s ;[.)0Vlcmuʃ #>+on|Waliͺ7>cmuʇ:Bļ` Gv`r ǣ~24ypE6ۇ\z([bL"S|s|? q:CG)9¨۶dUT4:œib(;σnr蠫ml--J1!՛ֵcpmîT}e;}!dc Y0rmYCvM(7x8[*=`t!\W 2pE MC~x5œ~ }pVlmîT=0v#|hs͝t}+dӆw6lmîT1hdq!+q> ae-I5fCDA[E,srD_\m}/#Wp].3 q>]ߝy}bR k{Jyr%ѳp%o>#o\,`/#+O2*{yR}yhsQ{c+};noz&|H}iɧG8X95*Cexs`l!>HdjhD*ۄbBVO ۴ mLe&JR9Pvk|qŝ­IN&L- 7܅?(N.*@tRqw Z8Xݶfwjt0l^qBsc ]+x/!}m XS݌B=#8/(*yby Z~Esx ;CWĂHi[3hno> kH5F,MDZ/ZyN`C &M1D u8ֽ=O`J_8(v~ueE@,W9xXSW"E;o ?(v~wN{b+w@ܿH*o!V98{WC|n=DK6Etޒk\Q-w:sÛLb6W8/#%dm+wLj'D5{@Vv\S`m:Ƭlm?ASuW!liͺ7m^lX W{۟!NW (  6C @2+ q iA o>mߛ#G(9¨"\zx{̓MU<< s "+W o>M̧Α ǃ\vM?Hm~lX.Al3Œ~ y!ߝ}ba \#a8C7N>]6ߝ}b;@2F^ߤAid+юdga̓ɢ:W8[cv_ 0W! gb#mכ! t+%s9{'oAhqQ.o>vB%rʵWB?od\ZĶ>ΰ;»L\*gRC <̬ BB|+;?|\ChޟhO=/YghTGAyRc-lɭXIp¬pxjUHSV\&FRl!,Z,/ab:[>A:WR,-2yr{6(Fۜ,kp5{{z;Qv[ ʩ`l֕Eж .ݼM/ UFz&XB2ATضnB88!>?˞je x(A~ȵ8WZTr{jSp1RpB KRZTDHDޖn#? |q\^GSRMIܕg9RVE8&([ 8k$8Þm..3 qTpAN9X5BZUyŷ&5J?s[R{bDTy{r<Բ?2uiĩ-&ifJ3oxMhsI-JoQf܄TԵ6BlBiRٛJȹbW["U)J_8(W ;Pdy7,%Qp%_o? ^rpQp%_o? _"JG>XW {MYni-BMƛsNTY h;M|T5^q5Q&הF4ݼ<(Gdg.8ssq2N!6\QdgNxss8eZqO9εhs-m'meFqO66\xD엛%RYGSrǹIr9iBװcǔDޘ#$]#UQ߼q92 Ч4}B=2g$-$ h41p>0 ld &"rwvMpM萻"vے>t!\ 2 lܐيn9d:Wk9@8ଶ6@? HYdHqNEnV[["D헛f,ĤV֧pMNh1w4L)!"vK iSKNz+od4l_?$"vے:$'Roi숳1sTtwv?]BF]8uQ6;2lc"eW~An"-L`鸴O|'RJImBˍ3dX$\H.jA25OPe& ,vWcˍTNg@ ӑjHе{ົ ЈyP= }߅U91ƼfaUrD-xv.nǧ;ŧ"br'DɤG+N<5*a6q> a9 wAY6P\zD_$EKT97ڛl7Oڴ!].3 q:ƾxӤS{c"[:GoG$*R'#y t]hBƾxפS{#" gK>h:ƾxӤGKTܮw!:n.!7N9_{# |scyzE>U+qתxyLdcB9 c4J>a.q> ,&'7qGTrd2m a qC:ˊ}@̜qۨY fNxNmxd4<G,*x370HS,# slpaNv_͎GIߐ3lx-,u}*N`h2w4f2w4¸k5Q6|zi@*z#    #C@?Wʇy$[*"؎@H&;,OD&n;.d#o|4bu{-Wf;㩡v", z=_H-\OY@.3!Hs]HЭ%MĬU0h:) HiKr(?AC49Xt㏹L)IDC[s]$-v;Ol&)|1 sMQٻa&OZ<"d-b,z2OfK#w_ k2Տ|[ky>:4uE݈=U!#=h ]&i a|toaKgY1lcQf,/\`#S'לFҘ2YkTCNMq jV=,.o_ǚŧ8X[)\ !J+Hػp@~>&7r,j!xZeF/ ǚ_8(Ym)ldQ.i3T|qTF9 Je_Dž .rPUg¯D2Lh j 9Ae-m~X'i4*nᲶc~|W!sqӘS`ta\V2]6cxaTB!ctob 0:_`pVK' m #diȮq7f3k;DYKg z#o_CIS2ūGb fNfiJtF޿x?87D4 s)j8|Z-dFF}xc5R",n:9twv?]B%8uQ6|k|+;Olޟ 4r 9N    9T8H,t s{T؛$3BT3mox[BȚN8w't=Q29(Y$h^-Յ8I3"׋XX a<@λiʃR+$_׉d?ۈpvAc$W!K OWcv!TnC`t(NpP%]BuDTe]8.rQ򯷟/לcb[!xZc[))b+.!o`Ӊ4,wo+8Cuk&?AxH! 'M0&!׽Zj(Iʌ_"CJ_8(WX;I9cXA$vљ, ZUx85o9qÛC/zRRx8xwkeϸ. 7_׮yOliͺ,.lŶ$ڻAeHeYĸ'>X[8KwrKɦԮ̜\ /q P IQk˞;EZW%QJRJXb^8] [[.)0%>sx&It+\!1 H"CFٓ0ӛu `Cfz¼{_Ă$2!BțIwrYi$M?qp( 0Sscq6,fՍO| [.+?Ku "[7dWB-F@іdi9q1 0lcK rBHsrTi)%i Bp(g9@8dK*$ٔ҄].!ɧ m "[6̬{ˮ A2̝> kwrH L {ޒ 0W; m!YՋZDe hqQ4~ָc|ri[u\}cgư7¹ϏM?SA`A@AAA\_zA#cCĞ?d bCz&ѩ1<٬d=l~(s'YrD#*EH![HEk~HEnΧzXY[L%Gbr1)0_BʵAns!JK\:cOOt{i^=DkydE(Y}*~nץOOyOKNY:OO{i^:7Zr}*~nץOOQѼӖ`6Sv,}*~nץju7J`6Sv,;Tto(p:ce79H [>+I!zG$KLdb;)Qki6zESP+fؗcࢳmaJ5a:Z[-9nosm??7kmҧzXvQi0GS{i^sm??7kõGFNY:OO{i^:7Zr}*~nץOOQѼӖqA:OO͚t{N'kZr}*~nץOO{Tto)m9fosm??7kmҧzXvQi0GS{i^<'N,UZ'vk QI8V{ٮÕI7)NUZ)ץڣyd Z7Frr)`H8sm??7kĪOgrJknPSfTD>HvQi(XLYt1Cַ<$0mdB"%&tHZ2P?dƋHX(HY7-Py",53pպfrp'$Q]_NMuݶ#8eHQl$l1ޑ{ώQH",4 4LRb?yA5hY6 C"r&T R似vMh[O F)DKƌۻ] wwa3K K^ems]( 2UJsƵYNQYBijD*EШNJ]`e Pd]|ވ8πh{D noAazy({D noAazy({D noAazy({D hSsL3+(vRG:"e9͢Kô!Twnu H)T>X7ɘLwz"R><,b*e̻R̻R9*F* <2J 2J <2o˵(,˵(.Xҩ*_JR=)J3UvRu"j”myunLNhh^Jl8B@ 2oʑ#ʍxd:ca S6g%[- 6up*^()FDfqI,`!uiSBMZ<_YR7yPeHGGٗjPYjP8eHA#|Gf]Af]@#|GTTt}vvsTTR7yQeڔeڔR7yPeHGGٗjPYjP8eHF7/iq) ږB]:N̻R)IoX˴ I܋t3$y9#tj32"<6cp('qiA-:H^bQƴMhW욽tz 囗mEdMc)ܛuRN_ I܋tL@Za k+霓ll B+q!{;BM%ザ2[e5:HW\y#4q;Ɨ"V6eޢWC1@d򢶅@ؐ]$7tGF=hMin_wH<}$|yH; in_wH<}$|yHt[5I_/j>0FtGA7L} QuA in_wH<}$|yHt?W3Xq-d",Y;6-,$FK30Vɗ`W}_|3|e*PF57vKXpT!;jYsYF< F#Bl$Z7{T>ų%Hڭ~KlANyBLIn }E=Vr7Ŵv661%j& DWAI"aIWF8 Lʒ r:}iˏ`뽟|r߹AMDg.?MD߹@}iˏ`뽟|r߹AMDg.?MD߹@}iˏ`뽟|r߹AMDg.?MD߹@}iˏ`뽟|r߹AMD`—I3 T*qB4C +))Bkfo܀ "EN6l)cu?Zض* RHIe5!AZ)cx8$IS)!(M;=@}L7(%Ȟ҄[E B5a60"Bp 5!BHY Q`T)uUfjR4Ҕ \{{܈-71kO[US xJ 9mZEi{gr m>F^܂:H=ot`6{m lA$j x}#=GIi{gr m>FIB"¬d AOHI;IR޷D o ؽBfЩ\$ L8(/)uNJAЫy*Kܡn%ywE~i{gr m>F^܂:H=ot`6{m lA$j x}#=GIi{gr m>F^܂:HT+H~y8 4I4Blu "F7 IQ1 ײBm 2)Zp $%s.%[ե xMsz!{J" m܀ ZGbR<n)bkY&NR+YT7Z rȃ@[w <U^fzÍm܀".@YFnXwS8aٳ<}{; hKIeZjLb}=VIx8tOhSJJ]`W_G1+u:6.u>~~@~ [tX"G0u>6Eni]`W_G0Ku)]~~@~_dV6.u>~~@~ [tX"G0u>6Eni]`W_G0Ku)]~~@~_dV6.u>~~@~ [tX"G0u>6Eni]`W_G0Ku)]~~@~_dV6.u>~~@~ [tX"G0u>6Eni]`W_G0Ku)]~~@~_dV6.u>~~@~ [tX"G0u>6Eni]`W_G0Ku)]~~@~_dV6.u>~~@~ [tX"G0u>6Eni]`W_G0Ku)]~~@~_dV6.u>~~@~ [tX"G0u>6Eni]`W_G0Ku)]~~@~_dV6.u>~~@~ [tX"G0u>6Eni]`W_G0Ku)]~~@~_dV6.u>~~@~ [tX"G0u>6Eni]`W_G0Ku)]~~@~_dV6.u>}}f"Qt.E\sRRJ"\L<)hjT^n[lMC DlVRF" ]  23r!"#14CRScqsBQ$TUADabt5E%d<Q!"23AR14Bar‘#bS ?v1HRRֵ+)C >q}J\JtO8fh#uJHe[BKJvmuw˲Kש(nz!MJѩLۯR7!Mq*q-qKT9FBZR6wv 4/6A#C;e7;\˳No,h䑶IRxMO c JtޚM'iD:0-zMB’mXme$ݩܛ _6SSȔ)$MZ^(2.NJI6mn9vHlg ̛Cj2-)tm"FR[zDtSqjFQ(*BθKl-Jq2m 8W`Zv[r#[ѯZ})-=Znڤ))2Z$dJImvlJ^&1M,ʣm[SY~]HT* 4W{R#ܲcs.(izr(3SsTeBR "ya9GU~_1wc aw,i6Vkr+"F5J4k3z;oyQ|s3`pE#7rvGz9Hhg}"Koy҆g}" /QG o'oJw{w,4Fp/QG(oގ{w,9HyFprvGz9Hhg}"Koy҆g}" /QG o'oJw{w,4Fp/QG(oގ{w,9HyFprvGz9Hhg}"Koy҆g}" /QG o'oJw{w,4Fp/QG(oގ{w,9HyFprvGz9Hhg}"Koy҆g}" /QG o'oJwwҬ4Fp/QG(9~R"ATz+^ LLA&+MjB rRv *TN vx rpxL)\"#rB*_JX)Q9#җMIG>MnSw!ǫݭҲZ+ )mmeN.- &aA+rYUs)(&CQrKho+FIS mé6ZZ9ݹ *uwZb2ܥKF[#H%۽7o\qjKx?=}%}%@7c ;f%gR\q6Sɿ G' $DvbJoZ5=wqzመԌj(1[KBz'M {-ö60Tw[IUn;Mm43F2eV|!>F㛕٥+B#>n\qBQ켞ppꆢ>d%|ͨגn>Knj`y:>M’ԴXոR[n6Y-P#ay^jF򏰼,9X[s17z:rcFΕ1Ү;z휥ߣԵ3wIS+6:ûrcdv4LPܹwIV,X]/)fRn:M6e*SܧClx5IAJI-+)x;xi)sl7EFvE((֜Cykc#b{8i4dmLRaQ 5myŊ Cs?oEI$$2)hb񼘦i(!r )1[ǎ"  ӧ3"&f$lmFۑNɡq[BO`v JIĜp:%M=aj[U֮{%|2\hf8p)m!rdJZCz$'z$y`=O9ށ 9ށWT|~woA)WT|~woER1ٚjRoQk#݃(i=` _lLԦΏf);lngP|=*g,8XaL|`}_/`edk|Ҝv?<$$BQRvulogoSQd%呩V\'<Dk%'6)tZ틄Q/RVVVb*>^x<ahXf{F^ yʳ eYV1c2I*>]gg.I*>]g;((t] G틂%%G˭Gg]pAQ3Ǽio9=2Dʣ==0GtߔL"Us]v]e:{.8XJc#AANY~\튂zdJg*AW(P1zIبI=:>^Usl\/a*ctlyv1fl%#䣪lZQs.I5Ei:=ظI]/TVo@ Ċ="ب)"3Ԣl{+*HttVg5Ik5]k؏J -˩-A]P}ϗRӎ0yNg=o9~QE³o;>(Vmw>]Uc7n^_ WB25:]DdJճ~틂i5w>]Ddyt GzIب&J2Ԃ ظJ%QIZ=[OX>#b=$l\U/Hcl\%WU/RV\`y31 G#$暘ܛq5ZEGRw̡o19ո-EY틄 Z;Y틄$.v=eG(ʊ#V1o6 T|R%Gˬ;yQra}pdggx5|w:_LsˬpfGgxظ)Qu`yfUy邐9#OvINY~>n;a044XzaVs=ZC95DJc*vBMDt|2%c| l棫 NNj:zEظI$Ehls. H;y^y݆ # 팄IJRU0]PDԭ[y~WL$\qWl\"_sf8+*/Qqy7/$4g/ж#?(5.;8{ @Ksf==mEsz=pEG˩6mjOl\##WsF9ʏh孯9h+;ba/RVg~H?I [튂dfT|IZ=[<'9Egܙ2TJ]HЋw&ZܭyI0ƻ%HȏkKs}#JurGlT%WU/Hv}ʑ꛰nr`e$VTXxP"?1rX[I\I IMz^1`(߇C~ܬJ4^;)\?Gp0#ܥsu% ]Ulm//!o{trLRJd-qj u(F0aqRv6nBjŁh4wKBD^s2CndܩAIݨDLdFtZ$mY4h4t#b2C"i8o~&pf4<R?<9hr'8'a?|4~v_rѨ"s4gl6Q9iЏIh"l9#($bQJ#?DZv|dg󈘫No11Ω~ʳW՘RQY!GFKI舟6+I舞 GѹD%z] J=>D-'"i)?7FJDLdl#~#`rzd2z3 P']Uu舛?Hl:QZkl7T}ҏ{A2Rn5>*^o1֣?l3uRg+xzzHQFDM6 Q"b;a u+_(I%TVQR_)Fb6lk}Sc*KGVVQJBegc_l(;8l0zM'wʚ!%"3Ce"i8o~ahIWqWX`zU84Ja)Zq;QFmDM#W $fO:zyBe;wvtDLk[a;wuhֶ{^WFT)&Z"&N!DDDR?8or=Ŭ:SDhd_76($,DM2O |lGsS6Ǩw=aT tQDJl7âVqM*-؍(etJ^ԗ dLUp rͿGX8ǘTQN$h(ҴIl}iZDD?##sOQ*%DM%'c6h'RFEB7,eMj(īDDJ7JW^XTg4+dEr^]fբ"c)[ahz"&{aWLc?(rf-YGT!E< hSbӤo! Icw[eTh nD~qItQ d# 棫 ONc}[btJBM&qI6v|#E(ɿDMot QW4~p+Q-H7--%$j3Q%6z3TZL6SӜD42կfSv]wi-_7lQGa%e_7lt'CPIRխQj"M wGAh*!:eA&,[Ԉn9Fx+.JMnB$첻 t)`ڟ6J۫NqoRrZ䵥Uf9",t8(Ć"P(-FRv"c~]Wu(V(i}>?o? e *=*I[*Dd&9Q6_*=-v'4{}z,6R$,g)Qe)6MюU讼vLek9(-qkORol$lW3Kl9Ld6{V%QZM4ڑ4\KNV*?P[{1a9x9m;)\?G_IimiSijw;W9/n;.;s ]I!(t~qrZpSTdq-:ӍVJ Gfuݛg_q7b߇`_T2MIrj^GI/2[]R)M?qXin8#J<ֲi)TIRv6m.ɭQ+ۏܱ*#\xnNq#֚^:RE)%!iN)tCeMl2[bnh 2%! \67xle]bRr3oZBM$XS1RrN8_^_G::rNg#ɹS>#6>#XXHr'@2Li G as(|tx5yunX9>m<<:(#eEe1QYDra (rzck9dLjo9=1s˦ *ulEʧ<@n^y\s9]3 3*tÒVu嚕m uX&L$H#իw[aThAӝ! ;r#Ǡc~DAi"+ē[\jέoONj:&`!4yEkatsPB^V3˹dD/<ޏlI:6a,E&dRUak]!l7A]W?7Rp=IХ!D42´|#k "muU"-%wBsxںx9)Ťopv.)yhoYw?eԡ)QG^?܏jćqn-V-ŭjVa6$WX+)Vn'9έ4g/U䓜@{$TdQ\zTdQ\zsbMz1sbMz|WsSֶfl]OX#⹚Qjݶf# ҏT,79lwAn$aJ1;'S%% mfQƜ7vZ; STg[UsAL\L28M=ԃM`J$u +m棺koP8ArbHO0#kmm8_CϑFFft^ԢV4:ΈY,ێݽ]!af-M(PW6qrDfӏsmY'%6{Z,xb 4Cm%-%6VG%D iG_7)oQuq5 ?6[vԋAȈRfKwvѵܒ_-ZJҕIXdd= $T ef4C2 ]!O~Ch*m|b-)UbMfJDc1V5+n1!@㚷?P/i&#J1r'.)6δi.ԋϙ^;J6։s[BXcJBThvc>%֭CѸGU -~蠩m+TMOEn/1GLLnɯΞ=}qαcU)+$iI&߷K%(ʦ' Ie %TW%2j*Qm (Y5oolbolumpRIFHqBUJ|6#枓Yp$HK#"hl ^{p(IFa*tԷ}c$uhYGiW7W(IF aK5D<\PќSB .Juogiڵoy#ּf / TʑݬH\Fzt zRLPI.'oo4B$ծ7Riu9OL$Pml^:Q[xx LP4fmx:Q(kq8nqFq1Ωn*BIJf֑ (A_~$NFyaA‰SQJ≺̷FW Ü Mwn,4ׂ.f&'(_#gsQՐ'f WJ] $ɲ&os.d޵do382zMfMEIujqxd+VxS9gy: g,8Xa9o$ JOAhb9ȞLפy0"z3^Nڧ/T$-3=`glÙѱ‹9,%f9,%fQDQx'xO0Q,<3˦Q,<3˦+8ht5N7+.|"2u TQ\m?spj2)\BO,ҹE򄟲YM|A? H( ? H( x#1?c?sHn33<ԅFRWXc fpg+Eu0jA܍8B(jI4Hڬ"_rȲ>_ y~Iz My:לSrZFcjSZ wKZDˋcԤS| ix%xr';B,dXm[SN1n%zI'W=릏\qM4^IJa*AW[yUM522sq 㸖Y}OѯZHuVUhb8JJz3a͝$HiZ^z i[o:M6/Smh6z)i\::G1jOX&LoH `͊^Y9/wUc)Y&TT7^4O_rbN3=`'3=aJbYIZ#`LK2pSI\#L 'L\ :՚Tij3#+LK3Ur^aL:cE$IO0%G%Jm1,֒9Oժ\S'xޗN釐fDUߌS~i\ߊ)'AS+EH\PTĻ-VWz 5R(ItĢ})/%Ez\pjdJW:Ɣ-qz_K1%" N%R_F tTY ='kcGV}6J*? M%)Oa\:C)01"Be1,IM)VU|`Y4A&D)u0#z>Qj0o5]cCXj*ACk÷X(9-$zOZ|; mV\i\^_6g2FȒێ˯izUw;,vPppn/RRmڽ݆lCݐwЃ9β5JsZQ9KCod>z%V|B/q>շ?28VoNJaū# sS2ݣ"ѯLtīS\rV(B/W6ЙJ"4ђ7MQ!!) 5 TOdYK8)!Sz)#usTijmgR7WnmSF0 Sz)Ѻ |d\旂]cajbY¹6ijKI)\Lh5Bn3c v*W=MK89 $kW6ldۻ=onRzm<<:6 `Dn/(QG(J,rK\G(S3!9d1Y ^NytyrOL7VaRQnCy^Uy0Qu^Uy1WLU732z^s=ZJK^O@;­*z z*sSNNj: <Ӛ45Ӹ 5]72ii7*s)6$WX[oIkm+;shdS@YkI_A,/o7%gp:FW<Ͳ֕6 MƬdGM{P*=F[^r=Nn$\W3}`jz-KհRjzyY}for=(5Bn3cG{D6~Oxv۔+"aJr,o+w1delܯ_Â2)rHU%|ru$;rsu:>ood"A!8ՙknvw+azZru+==GetJRYQ%f,hFoD-#;Vv^v-ri%UhC_UD zGO# ӑM >C*>V+u35IM) \.D5^4lod=sOHfFzr)PʤǗ7ƅNE2_*TXƖ@B<:f:S3B-J9{tNPli7#`Z4$+QxNWv3\S}Σr G'B̒gjhͷLsie|k;v;%I6F)JJN$9ɭv;%3MK踊2[k7%V|n6u~[r6K?̝v:cf8O ${K $dW0vqkNEJGEC==r%SHʺ*Rx-Ϛ?S'4ʧb FS)ؤzIpm-Ϛ?Q/j+ 䕍fR=$|JONƙR$D:k)/ނU9EC:ҕe%v|$sڶI(;:dlᄒJ|N,kzIA*JjugƁv)%ܨgY+K\s lv|w{SǰI0Ү`ku?88XnI$$`隿q|X7w.ط.uڼ bI*Fjҷ/EG9[wj5_7;wj5_7طvUUnVw"ܨu[{tWGjI4(`qXM ;:Fg5NE4(4[qnaGܨun_4O3sڶ1M+;:D_8F3M+;:DlkfiY*TEkfiY*TIjtG3#ն&;Z$Ov_$k0tƨSU JW vIW/މgG; T<*>'xa$*pnqc:&%;fuQPRW|h3hGh9[X&Ss%_͍]I?WC@NE7C#y+΍*S g/ވv|$sڝI $sIJNlc/ $W0thc&KQw*&r];:*)Zw|Kc&, 6w0tԯ_5*a'ܨuZV|hESl$R7Ƈ3#ս8_&s%_x' $he.U)vrqa)طfCt9Ƈ he/Jl[g$+ Gcwko w0t??OIGsHƶȦrF+znaGܨuJܾ34G;ka$gsI6p`c $,`$pcK4S%rIkfi_*T=q4G3sڷE*JJOv;Tߘ2RQ$2+{Gjly[ߗ5BvVlK+Vs#:,)z&MsXeH-(j7m~t&jf)6)C'VHeTGqkR)J4ԥc%nV^n۶r/?߃앇)2e)Jb3YCmX:l G>W@Fe< Fc񲔥bmC1o9=0Cʣ+|W3S6槭l\OX 5Bn3ciGy_kvٛd6z; ɷw{ðܥ9XIx; STg;Is@V(*_m:/ARnW/јQD4n:~ށ=pWαGܚ[;h)WHo9=2!QKm7*I]g͌ 7&IYbu>+.|-'.V=unܚpдcB>˿9,k2_[rkrgs%¶MʯccJ:/$olIR mu&V=IkYVܜTneB:v1fl-#䣪lHL\+E[rqQ<|P&6We<|PV>Mk0n~皑#-pEmMZ>78L\-EmMZ>9?jIk5]kJJXnURYߟJYnUeUkpqa(F;Uq(hIRW Cʪ88Pl]i{>&2"H[wU6 prj±cMDk95#ɹSE»^&HY;V.H]gRjzGs=2L.*nUU&u, .*nUU&u4D}f(,-+ه WSrU\-]MUz>#oCcspMP xu7$.w|m ܬUnqBSTuG(Z+(Q#G,&+{Qm[]|+>V1Frzd3Nyt苅m7*IXc6W 57*\+;h1Tgg 57&iXcJXBCIUL%!s9]3S u*JYA'.ܪ*u4-XC S^O@+r@=pr9 M3;-XWT!udvsQՐUbug.($­5'6)(VFo382at nV. kSu+K]cs(D|~WL$|˅a*Uu4°mʪUrshdSBEkvn]Vop'[Unx2JOVvy=Cy.r[⃤V&ڵtUB1s dʏh$\+ UV8, .UVZg#ol\OXؑv\Xz#|P#*nUVJu(F?(5Bn3c pu7'[XMCzEwBpm oMܝ)ǪHaonRzW@yDQx7Fyt@7Fytb4>sCeϜFT]qα+mu TQ\+_(I%TZW(PK1'c}[ai%Sa'c}[ai%Sa/݄f'gyMFb~皐V#| a#u b7ȮqWXH;YE ]7SAԍ8B(jIک7// #d|(9SɹSY9SɹS>#6>#XXHr'@2Li G as(|tx5yunX9>m<<:(#eEe1QYDrDa (rzck9dLjo9=1s˦ *ulEʣ==0[?o/*~Qte/*~Qt$3+r@iIcxWOVjNb:vsQՐY)G@NNj:%7Mk0n e7Mk0nɷt'&"?oNMEuy$/ɣ9~shdќS@%gp:FW<%gp:FW+|WsSֶflTemB< /lG=dۻ=onRzW@č ZOF2@,4xDԭAKuB6Qe*鐐ZFzRXY'z1'JVۨN7.|4 6x)^8LWغ6cOe5ҙEJr&r#7ұ#S55cE ~%n(GREv1f76$i,=i]JA&`̫jQJˊ ۯJQ5S`quM Y5s-J7)\|P&b֜KRW^MFb}'y2d2ZR($,2ZRЎNIGofF#Y\Ra1aь)ZpLYlc:D{(%nL8B(jI/gCZ-oiOQ F3;^&yBJ–GC@wVgfVf6ԭ4)k'9Sg&r=NMc8ӺwPXYhqu+' ,ac9Ȟ  eϞ3[, Abß(LQ^O@+r@HA`֣э.+x\Pq73Noeūn$棫 NNj:3`fZnR22 s-J6Z+gpe7aɂMRG8dY*JV#ɷtIɷȮH^+Ul7t[TrI_A=FrM b%Vԭ|PEAbKF3;^&H1FIY'pnD.̴c8Ӻs mUz;8hۨc$*=Fng#ډa1ae4J87gewR(F]OX#⹚! $N|^ W<,t[(G'%(1_,79pVxUJB{$M4>pi!Ohm-֗ɷw{ܥ9XIx; STgIs@V(*[m8/ARnW/=)'TQ~G&9+n th:ۍȻF3ws0[!'MoMqOi5%&&mx "}Cy3OA֡3[%7V9U2qLKӤ!Y?Vh8lEΚ95Є=H aܚN_+16#'se)fR$i9M3=A!l9=3=c- f9ոʳW՘H*sp, f0ʍ'x(t]O %+a y*F .ICeϜqYsc]*z.8XJe"^ r ?d J~f76" YmquMYmquMBk0nf$e7aa'yIo]aIWXYX+1FU8mVyCgrM/s#j?Њo9~7//م|1ܼ2, doڌZɹSY9SɹSFQOX#D#;]ca#9ȞAQbs4mF6 `cc[e11έ G(Ƌ#eEe),y鍱. (rzck9dL".U9||\3 ճfUy cHeWLʯ$ܖ2wَeH׭R2glXr(+!YtJ*g9:Vj`JҤDX3Ү>A fQ?0Q5CtQ.  %U]A eOLʣcd7MFbIjFgJ%djΕV WXc fp#V&B2떉)|$ڬqCGM/DfΛjZWxMVhJ*5+&&R^_ Y/Xڴ E+U =iz973t`*BV'W!ڐhdҪ Cd|GsKl$|G9 RTȋˬbӕ%I #h1@i9f֕viV$Үl=̡o1986rI&zcLgUTHtP-G(Z+(Q#Wd Jꮣ r.)*jY.W rOX+gZx][ djN*KʯkIaG5hЍ[Z6ORv`e2<Bբ u^&X~Mw^ta^#HhQ.\79.cwOm5vD-,jg~Mw^&O ;t*( IaG5o@( IaG5o@( IaG5o@*,Nt0 Kdʲ/4EFBJRm.TxlN+E*nF٩5ʼnERjB'ѪS C%h*[k' r-[yG9t.]7uvXXwx|䄶崩JKHZtMܦ)Dǰ1M7Km-hb4hL6Ts,iR\{o$.{S]DoZq]1k]&&7IoRZ[}"|nM5ȏ9ʯcL4mu_k/-$H))V-uAɾŽkb~Mw^&O ;t~Mw^&O ;thNq,S]&O ;tНN_ƤݲXCqnӨt%W-u=58o)qc{d}tlB$/\z da,o\o1:dBXKE[]ir82Wc}J7US%5::l3F]ojn0 )uHʖU -1ɻJG.=#YCIDi vRҧ*Dmls&O ;t9QɾŽkIaG5Ex?(>Mw^x?(>Mw^c7] M)5YDeke斶j ly3Mw^sx;[{19oG5OLRHDrKһѮ,nwAn$waJr,Xv۔+"h6, PڗCxt_ڗCxtPo 0pb:N+e!e_N7fpml\r tXiF당[MmF5i vCEflLj6CyyvN]Z,9O YhA4Ftc%wwyx8ޣ; "2nL,J-m$Gkx$BQiRCjȔ2ZxEС.qm֕.]8'3Q'W;@,OwuUP zDnM UCeRɲuRmXZcn7ºR$ȋ|E5#dJT9 A6 mjƮsqphȂUi;7qnKRܩ!ui E5#kG,4Mi2bJZ1Y~։ NGmm9Zʱb5M6nlQ$T% R&;]dr'ŀ%FfGTN׍^"7)c k\*<% Y/kG 8z>xK@<ᢚE5#^"8hDyMp었dD΍-+*ҢQ~JQ eDe/3jʔq^]qc)}-J*Տ!w5{SE5#kG-/bES̎\5%]K62b)-ƚ,X'"dh7 ̈́t y 6w5#S覸DyMpOa伄iP ; ԑ7tذm7c[e^GQ]{ dY"U=e"K5\ =H5US\"xK@<ᢚ rg!5]қSvԷo*='dD)NRWɺ ~'=x80Nt4rSDz3A9151:{hO~TDiv,8㭷#ZsZjWasc=.2VgEXu7[7 l=4KD_ <3iQ 1\SlƲ^S+aVÈ8g ۽;mM&vܼkܶ[D?5xEӓ l),*Skշtgh\)ǪHEI%+] ~i+~S􍃹wK%[#bwK%[. [_, ߼4XxwK%[. [_, ߼4XxwK%[.smK:&;ϸJqZ[S;6--/JqL<\mC×W؏B4j[%9ER#k8VKXݬ^uS}\un- \x' .*$_ɣo[ `tl񥶕_a7tRq+EI7Z!ܝrn!Z=YddE|[Vb%ڈN͌ۍˈ[ͥIW i+Ii%eeIV"# z0ヒ'oA}ONPǘB#` /}_=;(B#`; y/迬"zvXD; y/1PwEaӷ/1Pǘヒ'oA}ONPǘB#` /}_=;(B#`; y/迬"zvXD; y/10SoK.!Mvm B ,m` s)Opa}0F<Щ4b"[oS+[k)R [y;^lni$ AYJS 7l6PO7**e!n?S[E!tKr:SkH=vm^;k/G"ov(=J8n:h-{˽BauTh[9h첍SMkzv''z{V''z{I8 ށUiI8 ށ|wGhZ_|wGZ''z{V rdHB\J$)*A: oٸ!XrN\*]z|1lnR9)mǢ!)1//.s܈M2gv"7Z4=D9TϢZ٥V.TԧamG7y[JKB8jc(i %aHvK nrr8SDȒ[y'死vz#Cenq4MtwGhZ_|wGZ''z{V''z{I8 ށUiI8 ށW)RC#:P[n8AKu&ۈ'^2hP Pp&mwI4zq5 w00~ǘ#``tiȦOgM?77w#D-t<DP-SIJ\\ܻ#`;yN\IC,'! Wჽo5À.Mָ_y 1ͯ/q1?Dc p#Lq 6aYBl#k7z; Ƿ"b S!#QRT"$1234CcABUt56ars%DbqEdu&e=!Q"1R24r3BA#aSb$q ?]XΐbkJo&SG%϶qaݨRAZҕʝӽbhciZ}HջNJ*@$:UT oS/.$c&cLxLNxP_}g4.cūVrTDV51QoRAͦ6'uu=DQ8iRGͤ0kU[,QXIh gTT#iIR&aEi"ΗV4ne$a)$l%x\Ep^N&O% aG\ծ{3icx\segRa.ֿ#.tvis7ywZT.65li+UAܾr:~%‰2G,t6[_6N9xA2)h )HjeXB4c lIS5@t>2E]tBqbB\ʭjÄx&zlYy~JZ\ =Is21˓y!ho9Gt7Re酺 %.1FIp~S/;m}6bϴ㞦N\1IDvtFcֹ%(_ 6e?#Be FXz_4U+Z֬yξ zOJ/s !;r;vg=bņ̱ΛhFKwery=Za\LYG0m2O~jwUq[<95o.h>xu5t ʐq]GIX=YgeI+]kh|VUl\ 6Amrr!AgF_\aéJb+⹲][Z!{Go6\laX\ mka7Zη-[:ЖX݄䳀N22w߈@6v[4kQ {gr1BAJ+.aLIv$4=(9 ω 8lqqWY[NI6dK (cۄ;U}[Z!{GvmhBJvmh[ )GhVֈ^mn 4hVֈ^mV#115)5&Ntz{- #L'aYeQɌL6[e~V={,k^.92]Ŀ%*^3EK.6BӳG$vOF r2^qٟ"m.8;2ڵ%P~FEߣ~Uw{E}3 2B*^}*^q;3\v|N6WlW;Y/h`/h/|?Koo~Uߢу?*\d*foo~ZfaG]7Wr4qh0/J?{|EZ`ʮ/h~Uߢ!W7[{|Ed`ʵ/h~Yߣ%!Ge~ϗكG :뿪~Uߢ$OIjZ3Ѝ/oo~Uߢу?*\d*fooݗmڮM%у?*\/fWUf5;у?*\=0gW~\l^mу?*\N6ьt{[W/OI&|'R?{|EY`ʮ/h~Uߢ!W7[{|Ed`ʮ/hfnE.7Y#\3Wq{0`u:n㎸kF r"^j.;#ߣ~Uw{D{`ʮ/h ٛ"هBU W/zOX`ʮ/h&s>iQ-djw.;#ߣ~Uw{D{`ʮ/h .;'ߣ~U{E0mcj;h3_~OIv"q־3E#ߣ~Uw{EUq3E,;0HѲu\]o\7YU{|JuF r].^q;3uĵd`ʮ/h~Uߢ!Ofnof JZ0n㒄'ȱ`ʵ/h*7I/Kз"=0gW~GF r7[{|Ed`ʮ/hIchQԼrBphBj{#R\uF r].^q{3u\vOF r4N6WlkWW\b`"1iу+;dh%kY3:[Oy"\L־x$u%jYm5&XpD)@"HWJm(Ǭk7t>n>mfwrNγ%|\5" #$d%_"aZ6xZks*0dާvq-$fPsFQ{s> WT~5@ n@.0-fM2A?bT#d}hʖ&zE4a%r Lk84jL!Z`XC!Kcw|d<(Pdb3vk\$2w||tS-r֠6Y$1㹏Xg)~? M0(ˆ(ct&})Gy sH!^+*?yh|w]EZ?AU_Ažᄏo׋a,k^,eºlkIZS5-Uszm (>h$>2}[b+eTt^n-W۱8|@H#PiRִ_Duij"ARc "[v>.dzt^]O}h@y#KTv"+\yrRQ8 3"E%wyuԑfzՓ"N2}E؜d֩z4_n'>N2}L,$6dеBKwVNa+b/TNJK'>i9|Y:Z7^F؜d֋8W=HXvIX]ginIWƗ]O}kF'Փ/'K_E؜d֋8g7ZFLZ%c]v>3)4~V-fHudkKzv'>N2}YՓadm2sy@%o5+Z$oZglTkOz(;'K_SEΥ^1NJUB@ѫ^`t^udkH@v'>R M"b㧴FP7VNYN^*{dN2}Z5m\ Փ/'K_E؜d֋8g7^FiȤxuk3%bqeiR.oI&{>pȆnWՓ"N2}E؜dֳRudk r.=*ZY%aZcmǻRcʳ: ^]odw^FzQ8 }@#]AudkY:Z.'4]>z0|$=\uijG\Ŝ4qk]Djx4Tn-UZS֑[Zxf /-hX&ᔂxQ GDs֌wj?ǏUstY kVg˓bas$Y\1L80΅Z?j",йٮśdN]qteM-ʐ󹒮ҥ}_u+s(dAmdYu'dl4QN|fC uaߺ6VN`<$1(!ryx5P;Fx_*B#.c\R Kg`իjYRY0Vf]%2{'[ dahƳfڲ_(C(h{ا lߝV6lC*кQs疇U\oyUD[yx;Ƶ SʤǙcs뉭(;%s7궿uՓ=6Ǯк't;gһXg;XhP.1YlZ3 3f;c 43;;G1*zm3[b)byˢwAh]_si]z3iz"<ZK1Ҽк'tĢPiRSFD=6ǭ(6Ǧa\ĵʻt cVf]Ff]^i]z3i]zτs2zDWkgk 1x5Ze_; 喓$Ru)BG鴮=^e/b9tN=} wAzm+Fzm+YHZR^144. ֒ ifzm+Z5(DљD׬WkWkк'tΎ\%2n|T;dJ]ꖒYtN=tN=zMvMv<3.[=yMv&xgxiެ%abV\Cv,GtN=1 eT]JRIGgһXjTs2zDWkWkKy.VDs1qӻ8iX[jxˢwAˢwAzm+Fzm+Y| wA靧 v;XӔZFZ>>J0f;3.yٴ=HY}ek;TD<JKZԦUi0&٫hw'JdV"dŲ G ܬЃ9Zϖ*R7yxZz15D3uukֺ\(k:)m).6LtJQK\ܘHB!ǻp<{#i11@skGDq|%cZR{QG>0`F>xԍΑ~ЃtLJپvw'bUV@gKeZ'VMῙW78ԷA*NTTnlO_7:F(%5gAǍoyϫSb,5_JRoѓ%#@S b{OYh?[KH?TntOY$}Zd<2/w:[#@S!>bZd_:Y'%Ao#o/#@S4?gctyϫ_;}Z4?#@SѺ@ slE<>Nh't5_ZTߠntOWAg#g/#@S4?R&mMh|x|cK{}RaA=)+_KJpO-ԮkWR;R4?#@Sv7H=fkEǔ~V/'꒭>&34LВ$TX7 $TTntOFH?TN.}>ziS-Α~Kl?âRVt -:{)9>;;RyϪR .Uh֎wS'Pw:F#AVVntOYX0QHGz`Hl.6ɤke<׺~.q/"ϫWk#ݤ҆C,{t5qɲOGİS,xyg|H&;TlJEad.Fz~1T+HԸPw\LWrF=C8g`R`(0#jָŢ M y ǻQR30b🨥VEEL*!Fp'[Hfzd_bdtOWh5R;R4?#@S-n{OYi_<ŋ'ƕtOL'È/zo7n@?[H?[KH?TntOY ~,s]c<9=Α~I =% N~~8A;jd52%e)Yvn~yx1Z |8GFVFFJroJ]UύKwuxUqY"A/G ֎m|oh'Zz'GԾw>+AuKV[*± գF"xvh{I:\>_w31$zϤ}K\CG JuG ֢>#N"}#X_3'!I0mjtqwɓݴ7E^"}#GzR:br%vh{A:a#ޤ\dR[81E}?;NJ<ο؃m6>77E^"}#F8DXC";AL+XҾ(r]o#xg|οd:{&S9McKiy񽠝k=Xؤ՜cK䓦=ўe!Wm6>7 yϔW.K_%OiLjI*q\CV炵_">m|oh/ZEύ%V(մ!Awu [F~!i'1|5`EjSy''йrkq=ύSFے29P:`{?X4VSTéG%p1E6Qhܗ+617z>S(t/@-"ڑ^y@g@XrI}}#TCy%dKqe6[0#mjro;8TaEύ%YFByu?8cOkT[bkR_m>7ZsxxLY38"G MύGm6>7E^"}#GzR9iy񽤝i@cyXQ#I{ӈHshLyVbQ%ˡG ֎m|oh'Zz'>#^"}#Tg_ ]w>(g_NCa;4xrFG ֲ5ϼLY_z9*8Rўe!JuG ֢>#xR9iy񽠝isQJqb:O7Iq'>ݬ[ByOGƮ20vh{A:MύQ{׈H޼DGԳg_NDm|oi'ZaG=D+\:8s|> i/zqReyt+&>QȴGXq#m6>7osգ"N[5w)Ւ;V8t/%L뺾)B3Jw:ǰ s~+gaodcC Sv!!@B. <>;(}}v?5G}u#sϠ~pM%zOFpM%zOXp7f֡u)FDsϠ~~ UՑ+ ˯IF]>u#sϠ~KpM%zOFpM%zOY&@S0>bZd_;M )FrN]zINĵ\y7z+Iv@Q:?TN8&'8&'AsϠ~H'RǜI^ќ^S p2Mh֙WsϠ~v&}|2Y^_fR?T"΋.K01%~ 袴f|c[^>.:Gyӽ'";IXcjS[HFпV{7-$b1G9*涹g3/|zφ .}|PӮ6hpS=r/0՗\`Kn@T9Bݢn&a}bZC6]j2zJWԐ]~]F/-lF)|1iA)-xxZ8_j([\-x񷂹NJVA9u90gq+~$^bv q&2iR#=#_a~K\J4=ZJ7<ꈽ=螰gWIy|<ږOYr@! >u)VIrGVa8JJ&@Q:?TN8&'8&'a}1N 2]?T2;9wr#%u-S.@Q:?TN8&'8&'K7<ꞙZpMXЩ@Ϗ8"Q^gj }w0EF>u#sϠ~KpM%zOFpM%zOY&@Q:zLZ ԕgW̍JU-%| nyտ}'RÜ^WJ$ɹ?TNnyc I I3=2/ǜɓG%/R[Ki+zѭ2ny}DXi+z3i+zτsϠ~C=^A}{7U^,!;uH_\kE>#sϠ~pM%zOFpM%zOY&@S,vjҜ'oё) I *Uz+K`[}O]o كʶV%qrI˯J͏pvګZU;D2PuaVZð s~+gC Sv!!@B. <>;(}}v?5G}zӣgAc 'KqX=aOIaBS#~fH?TVȩNA5٣NA5ٯ#@S4?gxr 1fE_w:{Ii^H?T0O\Y'$ 9fq9fY\TuRRݎdy:<>u=TVp;TQsWk&{5:ʲ)h9+h,U 57@E j]aFC͡G|PENuf7q}F{Grųч G%ln> oKiJ [E m &zˑZ J i},'R }<#` DB7@?Ƣ#_ jf^ը#@S4?LpNP5-b3FzV&{5>‚zR^0'-Ժ\=&{4c&{5shR7:F,бNA5٦3+3ܿRV.~ե{#@SOĦEIXZ-x ' ю' ׍Α~HԳBOxr zb^opO{5shR:EԬ" gR5Aj8kR .Uh֕Pw:F#VNA5٣NA5ٯ#@S4?W= ]|7KX=d@=3_LqqS8ϑ~KFS8kF8k^7:F#shR= X=ei6m &{ =ZU4?1R}kApEȩNA5٣NA5ٯ#@S4?gxr 0k\1c ifH?Ta#Vu)B~z]oEH8r r xԍΑ~JX' ю' ׍Α~Hԣ=&,/OKX='L1woP7:F-EOxr r xԍΑ~K<,{M`iÍz|~,ԘOW]^֋["q9fq9fntOFH?Tz=&{4:־z&`]Ya_p^Utl7X|'ѓեt]5٭.drWU)Tͫɭ[`aG >lyHg2 ̨"A05#0wW +b^G+yL>$_W <6XdgYn+3$7L _Zg@nj{!'xe?W3z9Lf6F<7 7J*|ɥ+B}|/{uyH2kGE2kGDjQ9rWTeʯJU2kG^oEѓZ=ԕu&IW)nUܪa+go1Ufދ&{%i9G;^Qw**ɭɭgf,ʻ^wa>)8w+8td֏djڹ#]ʯJʻ^Ttd֏dtd֏dRHWrLٜNRW%]5&]3?RV.~խl]ʯJʻ^Ttd֏dtd֏dRHWr^W^ou_)fFMhK x2xQ앖X@GR\^PrWTtlU>OGwWըɭgrҪ2WU"]5"]5*$漯~Uܪ!Ѳs1 iFiu2kGZ5h#e]ʯJʻ^Ttd֏dtd֏dRHWrLB6W|gQoEѓZ=ei>m&{(=Zkkf@,UzUFYܪ^&{$^&{%z#]ʯJ ՙY𨷢ɭ2Fc\1c(kIuʯJ;^Ttd֏dtd֏dR|UUWrҪz.z.=H$[]ʯI9fg9Gtd֏djs w***UzUR/EѓZ=/EѓZ==I#]ʯI2{/.5]5&V_6>Qq rWTeʯJE2kGE2kGY$|UU3b;;u_I(ɭ2F΅uxO G'Z%k e]ʯҺ+Zmu{L]5.9Tuk&Ru 4]%9>.t-Dž$aVV! !BB !\քσTc; =R8mcZl?tgUk^,e<Ǚ8J*W~śsdswԢէפw6G7~KE^:~u+€@wKeZ'AWw2G7~Id7V_3߯~"HRN#TNxEפ,=l֡})FE,h!+u F\[O FVӖ; .B62V|0"V{'8'M!^̌#j ;ßZdz&OF~LEq0)7B0{5ZBx+˔*2N1 [~<œ~OI/׎$/`]?q%t˴Љ9DFF^:~u,$9DFF^:~u)LZJInHI—=^߯~y ;#TNnlnQ:kI^τgȥ%"'ҽ͑ߪ'R`>c7W~u-PIu#sdswԣ_zH^:| 9DLY8? +2DIפN}s()hM͑ߪ'R76G7~J5פIg ;#TNlwtDP׎%OYiP4tUZVA'+͑ߪ'R̈́Ow+IxxFA'sdswԍ͑ߪ'R~u"xU&f0>ݦ1?F nHI\d~[E 9DFF^:~u,I$lnQ:+N(ִO %פگm ~Lh.#TNxEפΑߪ'Re0IP>Y:Kҙ`F߯b]/m͑ߪ'R76G7~J5פIgI'sdswԍ͑ߪ'R~u"xN:g3=2ǜG%.u)1\F|/䥷_hH$lnQ:9DQ׎$_zK>I;#TN߳U׽axn?߯zI>ÿ_58֋KX6G7~Hu(^/׎%$lnQ:,!Z Q?FO_zI >ط?vEitsswԺ=ek3㶬J\~uWF{o钕SJ)[vn~\֭KEu$JyYyX3&>;-|GukZkW| -Oj`HpDT~Dl/ =!2QS.6mZ y]#)FMs6Hܣq7^ 7(M׃hC/?\͒dKv /y >nQ1\ĭLy+AM"@)FMs6HEѓ\͒7$M׃h7u*g!~.l~.l&nDnQ3 p7*Kѓ\͒cq]2Eiw| (Qi2D2td3dtO3d7u#rx6<$ea>)8w+8tO3dXvy[IX;|=_K7(M׃hjr &$e"ɮfn&F䛉myH_~$cx7JL=WK(M׃hLXq%z`zX^,e"ɮfH2kF䛉m&nEz|]/`|[ӳdQzkoN ּ%ύI7ֹ34J 2kS8&^g*m^@&$_~$nIn&UBFKb#z]&6EZ^;npsޱ/uj ׃hjڹ|Eѓ\͒2td3d7u#rMx6<$/?\͒ci>>mߋ&{pOTa7^ eiYŬxt3PszŢȁe'뙲FR.lFnDnQg2kLpmW*X͚_FnDdzY(."蟮fH2k_w(M׃hnIS= ]5#)FMs6Hܓq7^ 7(M׃h 3?Y_L=T_~$qs3qL_L XQhյr &$e"ɮfn&F䛉myH_~$|k7׽bx n?TQ0lFJy`sqŢȁu'뙲FR.lFnDnQg2kLe]^fh7u&X1gZ^]k _~%о=m\m[L㾎J7u.8xzڣocᒴuIUrc;aodְ7Bx_Jq!B;BB !B\oyt {- Ažᄏo׋a,k^,e๫:g.@"1)๫:g/๫:g+AavC~3vbUnlұAz^Y>oXm#TJ-mgʹI%qɊRl:H@0l7yCJTЬAm&IPE_32y7qyX,WܥෞvDX0jH(4f}yd^v.jΙжC24)๫zr6[ӑTCM?q%`Y>2 f%lY7A'-aT@3<5oNF๫zr6R4)๫zr6x.jΙl5\(?KS%*LJmk~^}[}Ņ̂\ս9Tgڪ[ I$ 3?UX,9C%bw>fx.ja찤3 3<5oNF๫zr6RHi3I_XssVkLgqT{zuXqfTL[ӑFx.jޜjXoع:gڬ+Vxyg+*¼ "_9?vR\V3]\yJ;5gLTey\ս9Dgڪ I3XNg#%}dJG3LQygޱ.Y>h W2HS3sVm #hl5$4<A \՝3+JPxu\c>=OX 6dgڣ<5oNFgl5$`F?jÞ }eRYHͧ v.jΙ Je ׄߣϣ'WEa揽ol๫:g.9je_^d%jT!Sβ7Bx_JXvn~' VV0K*i1xBguIenLx(:\Œ(aKiDK7!KƘ$vnC Yel:f*U 17&dZw"R,E[n1TM7cT ;a㛌~j.dFf<.2|&-S㛌~j7&-Bаq?jF㛌~h.%gKUDv1.sqڢmQ{'jƅȨq?jF㛌~jRhXؖY[I[ߊvHKcUf44-\n9Q6sqڢmR*] 9Q6(َ?N8uhqdTDڣq?jKPt4,2sqڢmWXxyMVoJ+ȁdҥVf*?LFJ q?j^p|z^Я"[n1TM7cT .dLlߋwcޱ/sqmcy95֊еr eDڣq?jKPt4$eg&jLJLl*$X??WV7&n1TMZK#-7&0$1PH*ey"Dڣq?jKPt4,2sqڢmQDڥK,Qfgn6ccĿq?j_cBܤ]EF[n1TM7cT CB-7&0,VoE~Wq&xCp-l>n9Q6sqڢmR*] n9Q6 &lVgHFOXi yؿ9+Bȃ㛌~h jſ/eJsf%揽olv^e9>nt-Dž$aVV! !BB !\oyt?yh|wU~Q,k^-{dG+V+ PR+ 16)o#Bxt/Ԕū}\|ٟIl orV~-_kfR;<Ζgj՝#Smn`Ghַ0+Bw3{%T wzYW )։gك Hn3qLOe`TVxϤAECvGJTT pvٛ$_ͩ]ܲn*bBdk92k(NR͙>Xc,ZR }dKTnѭnbS{!Ya k+6ǜ s_qIjδ=H:EX1(u*R;)82zį<5gHT!=\l8')h |՝#Q}78{L}78{L}όz>jΑ31-svbx|YKw8{L}f(̊ǝ\|X.,Y>:Gڣsg#sg*qY>:Gڣsg#sg'a,dV3+¿~>-GY>2X8ķsg+̾}3VtFiFiT;S+IXXgjP_JJ8nihA<5gHTgj')h')h}e6P83|{zķsg&S >R7+ӃzŤj|՝#Q3c3c|dz>jΑ &{՞QiYg{xEeoJ%JcOW'P3VtSt5 1I_Xq9LDk<5gHTgj')h')h6Ds;ݔ}|՝#S+"97b]ϯghk}3VtFiFiYGY>27eq׏=b]3ALm(htӃ-X sVtFx>jΑr1r1>0:GڦX5(upߣKw8{L}ePIqygp;[}3VtFiFiT}3VtFiFiN00(y3b^>OKVtSysӃG'(NS=>h@gj|՝#Q3c3c|`3VtLcÎ3+ޱ<.?7Kw9{H6x{yOoqŢknx>jΑY>NS=>NS=>g=6gHTeLݔqdfiLb(UϏd^]gjFtg}+HU{NS=>t/.f[Tui\r#dRU{D2Yvn~npksϭ纮~:__3sa~^7+aZoeڃXLՕ1iT\_W)̩ f|l?ڣ>g6T[ A 4ĕg6Um3sa~-̤%FP$l'{ OW(9jHfT3>g6Q3-x,!8_ÍbYGU&}2UY܈#qzE09N$)9jL~sdX3sa~JQ&lǽVUdyN%揽olΘjϯڮ8jɒVmys з?쒶z[ I[=[`>ʞ.S !BB Z?AW@~ <žᆱo׵ƻ  6.,!$&#7*FI>j%UW%YČKufGn~T6N -9rWQE;3_03rqT[wROEڦ`2LK$NG7c#EGc ds17EakSc5/Ae)-:I`<T|' ܿbUeؘMRȚuyhede_}b+V.7啚0F^+uַb'٢mQlo$4]Ml ˟D2=0Dc#$1LU'zq|*dǏ e%\hkVʏ G)O'|t%Xχ&1݇a02ZGd7Lv}5Sf0}Řg03X|q+p`KTkޑiBoc|'٢Ql_%{<]vhޑi07hV|) T c-z-9IH`DʐuSq./ʒ.NYCF k氟a82GZѽ"F?bϊ(K8Zz&RH[HъWme *yɍQg BJSg "G`dHd̯EGfȎy#ITLǓdOTӡ"ӌP6ؿ*hTFI>jڡzHX#L` APqE#23&>§AxCQVM)=ʰ?;ذjIagglxL/MBi%eH`wc&1y\h &ӐlLzJ(Y`x҄ nj%*K4:DpFD`@!Bp)7bW+VN/7+UPoH sXcsv} @7^LiXc$o xOc{fe)f{*r;٤{ fe "T FVK4f<81d'*bץ"әe `IbwߠFf2O\w u{8{].ŶKrLѝcLв2e2.S(K";Y{KVU^Jvmy+JůCzE*&7O@dO!| O(χ{b'٢mS CdҐ獯ߍyAeS)))xB\!?R,2 TR Q78!d L["cxqOG# a —*B%ѺRWڬZZs0[|)XEz&םiH1(r:!3'`&;?Krc5vI*nUwcK4ͨ .Cṇibe"3'1kQ"Әv;xchr6Y {41/&S=fR_]'Jja30ɏcSɈ}QSugHס"Ӗ[Ug0HcE#h`/py(]/r.: YD!ӑLZ {ſcgJ!^iUx5)4p'ge%xASR+e&pO;'_6ǯvElUd&JhKLIe2w9%#ͭX5ktރ/1Wiޒm8Y;գqҘ݊umT6/ʒ.SCFM}m'ٹ௶>qC~Hs+kžBI$X9RPNK.ga6hnFfpq3-&da-iOlGd2IO'e8NAToHL* I-;dYkAR}|2UUvVìÊ;%Jx D%IzN zU[7ʒ}.Dqkޑi'`!FӰ5sWbq3qIZ2ՃXN`JHAHeP>F>%L#Tôu#D>b{ qR"@pHX#&S8$|L'>"bס"ә]NJs_ cKȽdC2J x/ߧ?a "kp5% ژYK J2j݉lU&Jh_LLS)sS_l3-%6hV1Vac8Dx5ф)Uq7Bx_JXvn~spnGd;=!~\r2LLT iXp JÈf;XwϱP{nXL%Ƒkr*})xд#:%iċ@st-%:H΅It}q"8 IN3i)]vHN$8gBSɜo m8w&5wiĴg}ŠL p~g]|M3JmυRA"G;E@<̉0~d>Z՜W_hξhp5kFبw|˄!F98!eG;}• &qfnKєMx4lκDg'uD@b kTIєdmbmre QmB9v8e+KC"YɏnNt-Dž$ k˅2|Byb&2"oͯY*}C1Bݼ=;y={Ev Kvk{(,Q Kvk{(,Q Kvk{(,Q Kvk{(,Q Kvk{(,Qs vk{(Gy)^g!2@+la(S6)w&K(?_ki,-\$o.Ta#2iE2|bBCQ>QqRy#\'y5x'$Vi4c|~VA-=GD̹.1&OCDGHs ;^̹2MrY?DRd|{Vc+GJnX~CƷv-(DY*4y59׶{h\xb_P5h@Z/kִB#psFt/k֎쿔Z 3…@o쿔Z;oP}k@n.h΂7 4gAoP}h@ZP:(\ѝ@Z/kִB#psFt/k֎쿔Z 3…@o쿔Z;oP}k@n.h΂7 4gA`™C4 (V:H $e1RN浌yN#p`FtlV >sz2Ђ9cKJ+ rp& e(Ҍkuo/H= 0*@`%d6g!D/)[Z ++EP^43h|Z @}C6ρ>EP^43h|Z @}C6ρ>EP^43h|Z A9KƹQ+n:n!,(,%"Ɉ5ξ>S&V28dX,f2<'8e2o4u,n|s2-Le@;ʸҵlI' [S;L'9Ƀw #9ׂ)/.)r12KFJ#)axF\ݍHd)s$y)$ |cz&a(!ŊqG6 L޺σ-zρ>D{P͢ը@m/|G|  -Zρ>D{P͢ը@m/|Z㲅)礀eek2OX5cB 3r#8hֹBuHL8M ԭF TZ>w_NFr"]  !"1R#2QSb3ABTc4Cs$art5EqDd%UeuѲń? Qa!12"34BRrAbCS#$ ?WO ,teQ> ۄb WJ#E_Y u@SY~t2\i0NiLu>)&\qZBq3*;QFW-Y3KͶȊmQv&U, ҒҲ-(bHoZ\<[q đթRP:S3qoR"K(UGI̋gHoԽlM>D&YJ?H#mԮFgYўlVxE!1-0Ëzpym%]3$yQ7KvKIF#!RSG4s6nCzEafLmlyBAeϲxBn(dK4[U,Z@xUv#s8:&S,?A;1.b` ZJHqSrF6)_-v۴H&IG]?rҤQ/=12YYjʹU)9+̼HbRRnUJb+FڲĜU?G~ҿX8>(jgtO5'G/X-0PRZy^q5QDm +C60&BIVca/tvfr(9q`2NeFL-ZwAʅj -Ua1Ym 2ed\Lpe Glk[~<K<'-#bm*]SB( dD @YC7i᫂IH[h"H)8nR):S"-CnTߌXX^^y-'B&*UHpQTJO,E.hաS@vvv}x*C1N fߙFe\ԁ+D$&*,uA#WI+ Ud.i=s(3=KTN-S;a]Ǯ{E|zQijsl4rhϏ\--S;`Nt톎^wEslΝ.=>=s(Nt9Ӷ9x@^|zPgǮ{EΝZ:vG/ ػϏ\ h9Ӷ TNh{yAZZ:vj  /b>=s(3=KTN-S;a]Ǯ{E|zQijsl4rhϏ\--S;`Nt톎^wEslΝ㉑qU"BaD:捒Vj1ps CǖҦ+ JyL XE+)rVqDkŷ=*@29/Ί%K VgkӢ릝lqr5j;KY\$}Wդ%NIg(Jϔڊ2VY̮PjY-&@hn1Z2eX&\&*7H[aj@zc}KvV+e RI2. eqИk6='Fʾ-Adӓ@9ij0A [u S&$ U"֐\i̊fv9V_Y\9_EFYghZ6,ݖqX9W::^)٦D"4T ݒS=iBwMh0ӫ=7yF[a`FEcnqrӗS2|V*#@"bsk7Ƹy l!$\'* 94 -2$IrͶb8鼪␛vcU--ir8g ;ʫ uh :mZ7!["hTviglRf jĝ"nkٞ ۏJrT'Aynyop0U=@6֓ja3j2zZvbJ~f8V6gܝ_Н 9"K8V6,90n(P``;'`'`+|E ;;![rv rv B't>> n(NU 0}0A P``;'`'`+qBwCNNVܝܝ ;;![rv rv B't>> n(N}0}0A P``;W'`'`+qBwCNNVܝܝ ;;![rv rv B/t>* g`+qBg`0A P;;![ g`+qBwCaO JpLV]qŒe[qjT+ wUiDN?<&L5$ 4Rr0R-Й6۶g^hkTx$KR2 2ِ́1kJ ]*\<|kS{O"ӃsoN5FFJՐv^wA^jIpnZLlO䔹̏ پm+@lkS{O#uiOuZF6FndyAJr2:>9D3;8O.B} ɥne|Y4xy)Yll暵q͛qO\[c([xQ*m]32aD:Ӎ+|^ Hw+u/fo4K:AQrѣdk"t 2FMe_ K0Wq1ʸIyE̪}Tv'̇;'ِqzw=>=sѬoOTv?̇;'ِQcR@w ~fn2Q;2fCwO랍bώgoOTv?̇;'⯝9 廵PZl3v2(b测-7.f)l;z}vd=!?̇;' x{E|zX97ޟiU!ӻ'⟝?t3v3X3=;z}v?ӻ'⧻)rMGߌ/G[/Dj:rNoz}vd=!?̇;'3ӻh(tzu9o>Q;2fC떝e>;Ó|cQ}ܹ ||[v!ӽ'()WRg/Dv,x{K9&ʫoOTv7̇NfCwOg{Ezw=|oOTv?̇;'ِ랍bggP;z}TvYwTAG-ݪm ِ.n,_X h^S~3ӬMdޟi5!ӻ'ِ9ߌk,@iby7ޟh?̇N8NgPgǮzu7|˙ VI7cfC\%$}B$D_!腹랍bk&6EGczC~?qi`O\,g&!ӻ'ю[#pI1FaBprqm ĀU-6~Fha>ӢwGJt >vd:wr炓asm7<sm74iy4Կ;2;~?M<i ~#zC9vd:wzu)5}܅\G7qq N깣]7guЦ+cLUSϊTɧwِ|t ooM~#zCy#sN emq*)3zQF7稺bX^I)iwZj]-9]Dç&8B̌'a mق6ߗ#tx<5j]f&vT71,΅] GG*@ێ으iMmnaKp"id$$Y'_y7Yva/xgѷ[ep]Px.va|!8@"d@pm&ۗR :q [iTɤm,6:ՏNгt 24R>RKq|krfeh@[X؟P'_M6h'nUS:M8j@8H!e&JF;L9I3JНmƎHɜ`v&*YHnˬnKKşr-\3$;n͐jEïשJM .HFƖ/85ܔUɷ&(H]e皗o7w,~/StC ̰MWr8DVOid)4o+ʹNx0lhns٬{MS46mU s;h|(^.m8-Uښi)"BWZE4Rcqk92vԀ6L۬>j/?+#H̺̋ң-q sn'.2;TjeFb7Frѹ\l9tq3ܙmV70~dCn8K}ۍxQT ׉eS¦y8uRrTQr"aCq.$'W ,zi/4c}#PT߉`.1O| 4jy̢;,;,Hצ 9VfIrKdg~%rsc2S*>}1LIHؖؖ$gd`@6F9ՙDwĺ`߉bsӪ0w6F4%B_-݉a98IaS3-1$Ytč \T`_zlMG|YtC> O>).L>.tѪ0˃SOWTbǜI wb]0wı#H:i;Wޛ#~e)Ѫ0guTa~`K [,ʲG3 |6FfYS->h1RŴqR~%?=e_zlG| 4js2@İw*@6F#O00AR'~%#K[Fda;8H"*xo4}mwb] wb]1XצQF|4MG|Y`߉tDNQ00\TR_3gKPS**.H#gNFnj$W|KM:R}17Q.;,O| 4jHצ~f-%KfS-A%yOQh$D;,WѪ1Hצ:(ؖLO| d`)Ӫ1W\%4}BTDXXv% K6H芗/0_צQ{m$v%b{W^#| 4MT䬷f\.\|pFi>LMKJ'r?mc)R}ײ0y./1\'|K+]zl+M:Ď$dbJx6F/O|YtC±Z˕JgP>+M '&\ϐyڋXlmw]0 wX4TSŊħ?=e pyNTy˝4jt7:*R#d\JS.JZOLe12ӏ4݄5b~KΏm1Ĵ]cl ww>?IQN6LmC19-.vc%L2S}eg[f7ml3/;GQBIٶIT n^g-pL`))IK4m0ү+ܳD 9ͅbdR2mmB$*1/G6TJ!Jpݘuj]{mUdzܼf9 &ѩk@ 察^𗹫s+h0N Sőǜ<2LMٶ 7*riDVay L4 2B6XeaeZʵ]i C e,G?Hsc2?HsctAſ([kčZmƼHdS¦yw7<+yy!Kw^l7pHUȹtB^ ~qG7GĤ4 3hՁ^ y` O&4sFك<р6`/X3P3Fs\LT<Ӏ6ac3V_[ /(ܦh0 q~l`" Nك<Ӏ6` yu pP022Xa[ތ E,2^!8hq~g:V Nـ^ O.Al"g@ѫ 55R%Pamjy5piWD o]x{nyiՃ<Ӏ6` O.=≻3=Ӏ6`4` ࿋ `P3@f` bƵC3vOQ3 ໋Ûպٜ5`4 3hՁ^ {jy5" Fك=]j{ $ oNنGxm#/'C uG(e⥼Fs~yhՀg4` :[<`,EٚP6`4 - `P00rA8/N0qrN*g/Dvw[pf Nق:?x {vfw gz0X-@сn TVҞksF2a}~K)31iYug [ϨqU/c9?<ӱЩTNPL}5@G>UڻQrU/5-#,R30aTqo(]٧%鷩ng;lmT&mFe,hJx?HbnnM83̌dwĒ64| !R,+蕉!S@׳)ZIJf㪩© :N7+?~-87 Ble[PG&^mךhfmyaw=iPxZmP$ck;ڀnԄ!SrR%*MP(K/9lܨL0]bT\h(y4WJt S-70ح`mE a/ ZvY{䌳˩̛nujDd6['( Jjjbmq[d0?ѹʅP+9{bԯ #eEhgM𲲙sW5~{81M0pygnjEhx~̅0uɗ\`7T8C:$2 2IPܔrA[nWI5hԸ¥эSHsc#N9ñ ߔw-n5FG-Ro6^$EO G&y+.[DɓTU=Xm&y+.[Do-%_r&H-v'`s̛;~Gw/݉nϰwן`K^Jy>qwc'Rc[ySnS@l gw/݉nϰwןboĘG/݃nϰw`9S_3, ;~3qkt F~6fA,z]v*DoFF~0:ǃU-_._:.9MgdSUAxޤ^G/݉מd߃#w},``=ɿ@aU3cgWy_S7>^Kf|Lzbxy=ɿP ܿv#"y>߀!lƝhkm}^H` ueSe-Dks/[;z: ܽ=XyF&s(/w27}F~(*Wgw/݆4RS:P}޼/nϰwp#<]v##|؛$ysub8~NFG0U>߁CjflA- ^_nKg5׋F[vI.^BYbr7}磙7ןbo8~JՃ#w^}=<ÿ<%njr*[2"T xQ 2b㮖2;X*x4DD|eSjKfVZE@!%j4r9-2R*J`PH% -<\ ,JjIU~<~ӲOH„čy&? ˃4z4&xB0#wr؞._BY|H>*ia;0ۀ)Y\$º~?Uyhτx)x!We ˛< 9-+(9嗐i3uآ'ٶMfL>4s4S(>6 $L>!˃0]M۷.E3 W|saߋʖ2J9.U׏D(\ZIT.QYb27};7};Gp:'jeo\Y=ɿ qDU+S.KlUL捕%xgwTIWfZ#gyʠGҩ֓S34ѼB#]ҨH"; WSHPλBRR ,pS.8 6cpu~IQ+!JĜtt աFeÆESm8l(gCk7,ӈ4}]r$i 9Yѐ2i99w\Y쌩ݘ.SnO?D*rla/hyb+ ,s2(ӮwĨӲ ]`k#+G VnfU+wl0hD&fD%@:)[mL^Br&0p( q7X `kČyL/8dZ[Tuemg[V@OI9*ٰNǞKd[K6h2役!)Z𮖥ȳ/[~r,(<9 )yY.E;|_mxH:HYlUOJ,A h9|QL1F+CwS`Q9AgmGOz A`M SN ڇ`:T#c-2Vz_F0e\S>wGE Xd&iQ9AIQ M qJ*j͓QYX4kGBER dl+ħ.JZOLgYoLgOуU/c/ h bpe[r.ӱEx T7D˘ʺlM9ii`au=Ɠr^h&iDdY7 d_*Z])~T/4:ʠ'#k+$hZvRPYbN~b]qQyw\Lsǔl4I52;QUٸ7'![Hd{soa2lYJVug7\v]e*jeWJBLKtG >J<,j쓭09%/GgnrvӗS2& oY˨.7ld拉8`Nw ]=gei/D# `喌! :8,PfI7dߘqDs5a=\l])ehVII{9rqjvgR7 |7՗pRQFˁs* /4țnDVl71RN+i8=ˠДrJ2$ȊK^d`\rAA$s=g?xv:#N9ñ/ ߔw-n5FG-Ro6 Sƭ6@u-wqyO s9)J§*O˸eD$iXy\v8ڻl_p6aUp&Ʒ,o3[ X4k86f k~f5GHq>&535r< ]ߊ| {F|G3)9Rp 5%x'0> X_"Wozً'k~-r2Hɭ׆ xm9]=[O`OhF s5io61~ol5 *_=[:څxmNfb < h߃ً{F| N2kv nUssL{L6b wk~/GsQ++Jl˳;`ƊMochr\ {Ff5GHF6Hɭ؃lbri #ً'k~#ٌo@ %& ,<61~o394!T[|o^:-mTcY݈4k&b :< h߀x00&P3]`3[qL'kE^_4toÓނTqW(x叢; Mn4d7Hd|c|%o_Œp:a2eoŴv0K8m U-laݹU4W4ͺ6fI\n~i-9!&h[kԼ/tTz6"h䋄Bjr_yu&n[7!TaW^`+g y[S 4pe^pHC:bdBf Qjz&x+485l{-O5f?ߡ!z_0Oi ɖߴǁM#[#鋰'k~%~nLnօO.Q2if. KRHܗRʪBJ < OhOsk~=rpN\xUU(i[hɸAGLUn>j&wP3[8iml5k~'(la*ox._/o'ְ"eeӌow^:Ks5mFf^c< {F< {F4 3535m9._/ox1~o@P3^pѮ0rUle(\S>p6cQ4to ,VU.[;F1l`)5m66b ߊ _߈>'ל4kt7ŪU*B_͓Q| M#[;.JQt ƣ&z#KΕT;Jy-]Ω;crKoi%;caI02Љ+̭vrn3aF<*C%_ٲ[E"4]#%q٪>n\DjWme>SkAmi:,\pnX͸puyZB$%rfbN~V\Bp2컭 " =vbBHgonm\o KTm0oČ2W%#8>s0Qdܔlm궙/8?D>(J˿4ZNف.nTn >Ad!`]"-e띜Y"fiǥ5'ٳ'16K7ѫnq88YA?LͶTb$<ś-ˬU-:G#҃^f'S6m Baq7i|kA`ٟH;*@\"L|s=[QS5_814$jRpPg']TopL}%x;>5hr3)Hҕe)i6yˏ_%iȇƱOQrYKpno*Cl̳1&鵞WV۴L8c{ ӄ'rZZY妪-JJiw;2M͌.L%1-%8 <nWWr^| v2Ϋ+S.n Ff_tq'k-nZviG>4ݖh 'lF"Tk%L_g\]D LA@ABG?Hsc9bmJN!ȗqo;j#ao FHeS¦y8<2SA\XP\e$&KO$*~x'^`nG7GYӿm떍btrvr 5r<Fx[Eh+;|WrvrfsDLbʅ-:w-RsKc2rH_܎L)mF|wc-x xs3Jsӿi(3mU:|Wvr1&,2'a`Νh94a3-⻓f RtNDg~2(gP7 ϊNnG;ብ9떍b|"}R%X=.@܆\U}Z2GDmcw nVWu̺D&f\LIKyEN:ڡ%_-5ԏDDFXn=;bgNeX+:5r+:ur&bt(Ϗ\'=;b 3⿓P7!|16J⢑/3; tZuPSj|TϘ>R]Өѷ)Dߌ'>.@܉)⿓5CJs-Νh5r+; ~f-.Zߌ19́nyKu"N@܊f$>;bmWOܝ̢[ENEY]Ө_ӨW<%$}B$LB_W 3ӻh(iYGDrꏫBԞ+:5r*csؒ;Ai(>+;|]]:%~2(eBM"^!%pJNnC*iU_˓;GImy[E|wc-⻓gw'NnDQhJt[E_ t )O\k1;eYkLX$]Ѩrele*gvw1"Zu;EY_Өbs2s-nuJkG5WFnGC|RU,?Ȃ?͓Qr:į?:gwTI“}BelRj"^>[0?ҩ֓SßKki%; WS]|'(*L꜡6*"j.Rr-nKure+=& LMKΝWuvjhϙ8T21ZV[9Lی˜Yr#HRhiYeNf[@eSm~I@);qU_$;e$|e0(eo.IKiG[F$$mJΏmH P$Fo/J;lKMM9\}T 8)t)H:R6$6D83v8c tkԧ\!!)nҾ7NI?g=$3& OK[,Nxݣ|z)ҮwH7䬁ZrW:Pq&_Λ~Ͱ33RzhR~aљgeII$mK:wilxu*e6 Z)״^L{"+UbA;pfjp[eIm[K-80oٵ Y*iRNR11l2铕j?b0A  fg;t"G=Si9?hwzq7jmƼH([kĎv^<+ $ny'%S"*yy!K)p߆$[ }2^Rߏ+objb==~f̥߃9K`73. K;x]߆2oK]o^߀{K~:6a2`{~K`߀_Kio;4/z_=-{[~fi,2/ηK EV Ur&R=xmF*aGIg"M#'TCLDI =mKPRL}&M>u=ɀvE˯2m~L xb W'-5 PܚZиq|6lV^A|SWuzFg!%'ùgUL *4KEPg "]~䊗h3[ו"z`״psxt}Z^W&1O&rb(]tBL92ǎ5L)9tÓFu*BUKG9n`!rRZ.{L֠f]^,a0ߋy3cZ㙻)t=x/yM%߉SP4u jsߎwQ#2`{~)S' 4EFp9[3 Y{Ɲ}JT5ׅ_{O~/LTt^aaG[~K]ts27`<̢3{~*Rۦ=t=_# W8oDw e.z‚})LK}.:y~:6Qjߊsߊ{ 5G[~ .Mtc.с-A]ŁLO[~/́jzKuRGi!G[~ fRoۥG9G9;g)vJe/zNp`߉'~`eIGJku:9M@߆<%y-~R} =m߉SP4-{tco߆t-N!MoWׅb= (7m qKn.Ro߂.=?D)~RoēA>7vfho Yj3v/Uׅv{qԱZyLݔW^:,v6_4 e/M_tA>7Np q:U+x2Y5󜦠=ye\ɮc+oiO%]~L~)6IɖV 7(%cwU1c7*Ma dkzcm; WS]|% (*Mh'"fܸb)vj:~dqٗIY#TcbwhPl+(0ӪU&奲9eчT+5H̷Dij/M 99][m]pKLc{ IKw$[uj{9}1aGbni GXOS4Qۭg`գ|vR3f8iㇼ҃JQ"`JtnY^B8x5̧tVeuD[hNlߜݓn:l_:FNn'ضlTMeͶoZf֕1Ԅ̄R*2.:쳒r@K@FemN/.6? x@㍲͜UU>B M>2Ch\lmmK^FtnZb~]җb I;i5igeۑ7շ L K-.NJ*dwreoPG.%nWFzm˕de30 pN]d0ef mli "0JcK=.8N̈K6s -IL-G%m_7ZEqKܣST.zЀ3X~lV{ʝerœl#&mϑQ?#W%&3l^vfaPq}㟔w-n5FG-Ro6^$EO cd2gr D'x*=%8q<˗-d E}/_}$|@1a=܈ީȒň~"kAߎ;J6{cX.{c b-߈b-߇8 ,&pJxޤ/=܆`37J`׏jx~@Tz 4cji8GN9i-1UyE_iFK"~fш<*8jƲ{T/{ O1i6C"rBR$ˠnFIR2V$ƼuRp#֜2}4O^G?;#KȊ߄r @5NP/[UTk0Τ.ţPw-E/ueP/ q܊kOlw"j؋NT sR_k'\w"EPwj؋FÜL0=܋H3cY-󇠙Ea[fLj[3A3׋HD SѮ; ߈~ Z5~ n';'$r$AT Ө;~ȿH-*R }X7~#@-)Ů$ q܀H.zur"]jv"Ө;iDW SӬ;5'\w"*i~"Ѩ;@ \^*gI;ԋ ȿD-!x][p$W SӬ;$m߄r)Ű;Q_~#iD SѮ;ۻ Xjv"a,yKu!y_0p6 %hx\@-:ݒJOF@a=@hv"Ol~UX/zur)b-ߊEPw29D, SѮ;˄"˗#]j\60+vȊzur v"*iJeAqCWԅ"aAqCD}_^.^EՂ';'\w"j؋`w*؋NTFA\/z5r lA_~A5'\w!Zg&1k Xj1ʥϘ>m` Ȩ1a=qM@ilAD SѮ;&NRQQ-[j9kAߎ7%JU^?ʕ&u^%6X:5v)EQth7j-)Ler2|p⏧iYI1([bfL ե4LnyOanRZ]ej.Vg'{4݊ ɥjsxWFjeoBᛳl:]R̃`s$[w6i4S]p&]dlY,f]iaT&YzAzY,JYͥLw!ʙ:-%Yg\IqA}fXjZb{7lVJ8*exs«I<3 3, d 9(sffg.V-8%y!x)Y]g:ʁ/+-.y\nrFʂxٛSNNgv7#VU,ں-2ߖ!岤Cp\,KF}/ 7z Ԫ2Nnڷ$m7TmƪaU$[$%vm7#cN9ñ ߔw-n5FG-Ro6^$rt)ScYLqRe\c YUʉ^XPe\a#S7GĂLXǰ"3dǹK%܉͓\4u#@%ǰ"F].=%܌AEx &PijT9h$/ ¡ߡ!~lᣭ 86#q[gR*\6.d<ǹǰ".zۑ_=ț%G1A%ǰ ͒anDv0܅tÌ{r/e3cJٛA3ԅ,c{r7.qߋEˆ@^L%ǰ ͓\ts,{r'6Mp܈"dFn9c{P%܊sd =m]$ ~1{Ɲa-)qRBFanE;,Famt=ȁKc܉͒a%O[r9ݐ)\tNnǹ&{ۑVl m]PL"8 WЅ!p%O1C Y L!x%O[r:495O1D~1=Ȍ5܉)d{ۑ 5G1A%DZ3d mY..ȡ%q_ nX_t_ W nX_4#Ca$f~1{ ]{܉͒a%܎wd͒c{%,<ǹlc{r$a (eFQ_)_!z䅃,㣘! E})B.:ۑS!m%DZ3dO3fv0 ͓\4"nȢJ]1c܆TCB/3DWaMmȹp۸`%DZȌ.=%܃6Mp".ȢJ]1c܈&c{f~0 )d{ې"I͒c!)c,♿!z/͓\4u!)c,]H.͒c{$b=l =mȂK񇽹stǹpJ*Ȩ|Mtkt72QT"qeoj6W6+ħ>JZScgư7[?f6|]0t*UGAAA@A'i{~cn8+ X +hrYIǁUjYmb{^,2|Z^qeU Z5rK6y!2,6O:r̸q8Ï=b§Qw(%%.+ Q ۴hm̆/#&[vg~fH/J;jă:V$8A/__6KDQG 2`TlpZNh ls!<0q^++P$,:g \??FT9oUxi.VѴ*mJ񅔑Dz\??wOIhsZ߀hsZߋa;@Gv(r;w=[l2GZuJ [%v@94to &/S"/xK FC> J>¨&]RK QF;w=[l2GvӪPf'~(ryGk~'w#GJċU;R2;R\wr=[$sm/A3ׄ$w`--JlU,Uz pCjOyk~-JD[%dzT/hsZ߈9jċq;ANAi(_.J;խ'QCKlr;R졫Ixo4豅-Ǽw#GJC܍=+[j2GvѪP ݀s#K|H+[miX3#h(S4qUT<+ *eT2=BѪQ =;խSOJċ|[%dzT.#ڵ hj,_ʡ{/ 6\xJG~(eAɒ[L;旫 msZ߈9|H#l݀N .{w=[ w=[lG~(1;R\w:Vj̰ฦ~Uׄ݀j1+ dYkLR6 ~=+[ w=[m NEE"xD_yϩk~: *QtK]lc#-niFPG+rUlJSouqR߭)S1XwU-ҟ3>*X:*#{    {~t s=g?xv1D[ZmƼEZmƼHdS¥Gy8YUDUDq2MCʸOIy .INeq!#ήUyG句+o+͎'رPrF2"iG-w6 hY*0]SUq=~'9Vi^Å!Nu|"UH~-`$|cQ{O<׷,UʢjTJ)͎'Q.ׯlEzǦ=;$+YkKdl-)c ^I7*[]֫}T,wa=e'Q.ׯlzl0͎'Pf~([]_Q1.p,P{%lzTȝ[^؛U]aGOd͏'$y uj4l6{߄JS"K)o!z#P[]<DŽ.^*Ot[c BGaxONEZz/][]_Q3 sջlQv4U`ZmwĒԩ]C`bo̢F;/lO|')t9!0gP_$zxD%D5 sվ࿪1s?JZdDwm\RI@ĺy3ިl T6&'=;.x=]P3 Y!*&^;.x)KS7EAŮ{ hK|YtgP3 0N~x/l3mp܅)giEkm\">2*[S݉{`݉{b3C``ϗT6&=;/lH#=ӄ6  CHc,-i/jg#\JV(Z}ÊVI-w^ ;/lFz0gpߙE]=e q}NTImdsz?GD|ݭER"qbUlSWs*iO򙍟øҩo֔)vЩTASAA@AAG?SHs#cN9ñC@1Iә\f%Yx<;%Kr$&@Fv&/Jm|HHtIj}9Po4sQyvlx'j/Q*OÉsjac |RLjۖ~fPq0GLp{<$͸ү`˾Gp$̴-2@UAvotmUKyD%B$ߓlM{6$lM{6$_* ғa(  <+˓-n;QTɶKҦ[€)$̵32F(mdqYNxxL66RRHԒja-r®M+nsؐLYoq:v=+,2/nc'2xՔ /_pܬj)Mmq8bZQIHoɶKҦ[~M^3߉P2Ec0=.S <> ˮAIvYFs#{~M^IfČw1(.>2dX8;rZ8Y Z[m'9=Ԓ`Yf}➒Ck`4ӐMN:(8UCi; ҥj2y;G-+ೳg{NSL7 ݛM6ck^yE'$$u7%S>ͭ?&/Jmo`XI+Yyz78G(\Q8fe*H&J}iWkk Zm'6;&PE&U'dD^ICr950Xy27x8ܳ,ηfmf"aߓlL6$#k_RrH#&/Jmo7IzTϳk~'CNvgʓyVZBP}C@92CNۂd/=/)Tyyq}zDpK4aJ"):M=潌pN S@11rc*7NPRDPtfGfd6ě7,Zkbc8MRRu]zmḷHa~.M^3ߌ{2rAM7IzTϳk~ɺKҦ}[7"I?7%&V&mV<dz;0)Vt]*>r!/-+_*WK㢓f(ZR^agL[gDt*2oU4qg,"K\8۲6-d\acjE7Rq\#&/Jmo7IzTϳk~9`XI9c#} άEҪ-p6qtL6),s3 NrjUqK>3uZ׺XM/_ܻ3ʉ5lŢKnY,#GQyn]qmameܳqiX*7d>M6ܴ͓`jl8{?iMHU.sb 5lrq98׸Si9$#&/Jmo6zT׳k~'CNYE-Y+٢'-<\!:#"?lL6$f%@VydVĄْm7$T-kVILFg8X&raubHԲq5^ENxugJLóS*nn~FֽNPHoɺKҦ}[~M^3߉P2)Cʁ#jHW `oqmF_YV_6Ug-u-6 .w1e ݻO.-d 4p+Mҭͭ?&/Jmo`XI8<ݓM:Y^DY)xrR+R$V^e@Ӿ?F}K?>:65,Kq0m4䢴Z㖘9#\Y\<[2H#k(:~gcmEͳx+ QV \J`Ӗnx ]c4 AJц3kժghvuׂ{m]Lqpiɉylxn'l@,&UGKVƈC,H*'rI'* MWey*{6n:7?D48FT_Ǣ1@Rc_`HsuGLz+W +#W +#W +#W +#2edQjٺqIMUir']wq%ߤ_$' `mMAv[~{[>sd;?ݯ.;C @;n.!] {zi#O18UJE6MZXz,D["&Gt:2yfJaQmə798՛z#gHdVhg'(v^s&pq -ńN3N艪7-BnX d.UʿLtT@OʢW銳NT9:d:d펏UH3N3NT9:d:d펏UH4;PQKH6r/23-ZYz8Ǩ_>e$ \YEկ"ivv Idg奎ue& &Wx.k5—[0$enmN6mN]Ƃ^mr"ՙ'l'lt}T@vvGH*'l'lt}T@vvGH*'l'lt}T@vǜ@je7n:NFtdvsWm35̤N6:a*avO<̜oֶ-׀2%oBѭx,T, Z8mqGVpLܲYKUK/uwg'Яk~ k~I8(2L-T.xQjӋď y[ђhr cvZͼVnWgЮ[𮜜aȭ$.(6 Vs+{;*iO򙍟ݒ9BF wYrs9:fMiog:@C3 {!ߏ!7L9t~0Fsd;xs9t[Ùΐ=Hw iog:@C3 {!߀7L9t~1'?jqHwpԈqkkSqG t 3nb`Q+Fnnd\RSM;S@r_6s]׌V5>fez>.)omG*hPOxõPEh+Vn?웂g 8<&ʢg6YÍ:u܌=+G-NT'_).n7wK.ԴNn b*i  Ē rT!xf }!_Hklc@w6`l_Hkl`Wc ;B0WRaU\Y`q͗㞯u: ك,tA2Vs}+8 lůeT}%;Wa:k"cJ!~<{f͛2/dBZJTWx<`fKe? !H16O & ['U@8d =r3͔G8&/˅-*de `<<,X(lN`u"coEj2 Ijxp p:ְR.pe–maiQrP P!TxH5[rJmSyf|a5 (=*"®k"ג?K\}S=*iHCo,*8[xIM+טPlVn*9.5x;Y,/Kޒ.x?DZ 75+p[V/pS$zCE0%+-U,l("@m٤[bܵ`jƢ<O^YsEMdա=!ux o~\(9OV/_,P^V0S)Uޫje/~MĮOۇ@rD $L/OcbsJ~ӛj]FINZA`?0x!0#sS5;x7l(_.X+NaS\@~-h/5?._z9.NAzS|lbW2`mC.S?+pG 2Æ `.P.*[^⤢s:מT$)܁x #\?0OeEI/ɫVY WYK\Pl o/HtKt˕ HE`7ޏ"rQD:_gCqG &Y%ߐ!$IENDB`opencolorio-1.1.0~dfsg0.orig/docs/ociotheme/static/clo_res19_vd16.0101.jpg0000644000175000017500000003655113223553423024215 0ustar mfvmfvJFIFp"   J!1A"Qaq #2B$Rbr3Cs DScdt47!1A"Qaq2#R3Br ?:2њN~_>҆tdXcl~_Zal2Hly/J1ӺX#ٰ4h_v.O9]v̻'$7C-.BDE^Ǽ'HBUζHe&Sk_ȸ?|95 BSFBZh)[PⱵJ!T'Wgvc 4UAmVG/ebs%6/ >DcF"f[Ha6]@IX4Vr73>FV6>lN>RW =SFSZ,Ʋn8JG%+YZmEYnنYyDkG Og QC]+pʭ]?5_1o<=t75̿%{Fa!HcSQ^=_J:bj K3Xn䯎;:LFږzR5? +YG?BL5 2H2Q9QSTI=V /5#&/?VRY!% PGVh3_M[/332U# !1Gziҗ8gރӻ=h0u`AC풳XGnW϶# [|5~k? M2^lYM1{]}ob;ߝDYS⌞P%eV $P:Bܹ,M+-ca7/It /zqiݦۨQ">v5KyqD~k4Wy;!u"D<ҫ^_L|b>53xq3) P)*A]uwNY'n }+v3{Ƒ5<\宆"%љ6#6I m%-H9^ihqPjZ_1jyI؂f@9MTSǣh͸It\;bVPt@1V}k\ȧ糙R LεpU!*[ }DWI.,rFC5=t 鰗V:DgE2'A$6=ڷV"v_L= 8H4?R>A: 5cݗvwv (g/նGO?~osvnTĝ$9o^XqQA^|h͚tu'OӼ}^FH'㻹[U==7Bקvd#kCA9*9.=6b7 \b]0ՇJT~ԡbD}zL:D3A]!PX+ġC»;э{d=ڪFđp+D<9|hmXFc8؞HYxHXF1I -2tiћqd9ldk( H Gq.t-*_Q^%{%HNҀ5ՒPv=B9"r604'R,i4uWSJZ|9psX6O+L,=0R{~\gk{YzQѭjmMnZ 8,(P6# NN[s *3$ )=>8tNp|5-Jt+c3}Nh[vVU 3NV:пC.K-Jlȕ!xdw$B/eQrI:Gc4/*H(K$6 oN|İˋJ] FzIǚ]\6 l)fP̬Z\EۯYJ1B-%źѪَzDYe'D'IU3ϭV 4yܧ1GshVbPLqGiW |Q%+AXƥJU.9]B8Vre0$%X(b+B\Xuu~+II#W=б'r rjJ\y#Q{S+@t:0ӹݥC mXTI^"bx* JdqBY}god݂m,oM꛵^p5tt[r^d J+#W%DJ^t Y,Nŕ˖cVRm^V fk1)B)nv_郎GR5C[R@Q=o凼q}"AkXQ >@^[Z"tII4~lwv$} 1F>Nj'NǼMmB{ֱ~G=ˠ޽6350dDп\i>F9Ymg#_R^"Xkݰ?i1Ozj"^YIbN D^A_W#V";Q):T? کd^),ګ_=?{6fg3Uy'gr$Y(_1VǾ\֍aK4l)Sæ6QLic!܍rIdwxIʭfD_x\V,2FᐑZn5~ Pţ*7)^TGFX4jhoQNl9a)l.*]5qDTh<[ ,P,4N@jn^T@)2;1вU+j샵;C1j! X;"XĵTz#~Pv=2e&ZE&B!dRV"%K~\#DW/hdmCI 0Ec/"#wn{onV0/n'K_=Zb#b zAaq(ҿ{JL 28گ3!i: 8PȬKe #u,yyW##ɞIӄ/_h/MrW (@vջcg 3+V6~J( M@r@[>iy{Ed~1B71Kï2A=>;CϻϟؒƜ]{w6rSG?@((ZLVjic鲍+fo0K>t8}yY޼qzXHUaa20c'r^Xeq_O{o'ǏfG:^I\p4K+<ʮ L ݰFeN.JbF   t_gki{21S-a% xIçǦԬJS(0G#"Bw|>x;;]j$Mٍ,x1& <|!k 3In$Ad{<+Id̐0m>rfZ +$PYd(Pܴ(s#eW{N>߭jp@Zi94%YQJ0RA=ˈs*=ocmS ŷi]嬴YL݊@5 ̺=Y^Nj:S5!Iۣ#GU8Hx)[Nxlm*<ܒ *$dX4Jxל!Th"C:~{}qsf7=}DG˫iؕP?t{=,+*"ߨan9^GX ɠ,D<Đonoܜ7#qDY:ܬޥre]%E4RB!GO?Cl; )N)G]UZJorv!"3$4ش jq9`13u^CN¶4rĒI5%df>]S3ubQȍ̚Z.@x54=z޴2 5zhh Z_%O JsEvx֑L,*6̪ыťvC^=nݝ*&N3zR5g/U@[ :'iR-@5K.xΠ8x$l(ɛ,.cw$GVr,V <@Ȯ襆htй,{YAZ z҃X`ϗE$<6ݨ7,'VٳZf2LE( 9M~C]> K@&v%bd,RuBIӄh;nN좉U@=ʮtNNpǞT/}4nrnp\jŧv=7G=CwlN"j: NƲ%Y"J&EP~a$CTD=A;yslG2E9$YUN zwGW_'zd u= ^9sV4~j篎 z5|\3$ <ͯ[uɚWZGJ >p|;xrGX׬XIk^%>Y̌@pAO?OGRijSӎ2:d%žWAxIөf?m2H yI7r:w87?m^xrJZMO`5V@C#HYUXm5V2Y=ԓ3]f%9@8ylcEH]d`3쟴*XY,v>ɭi ʤc%d5P6?F/Hx^|f;|eTi&BG&t:YLrL#+c*ߩ$ ]"i:YT }|pnoM0{b8}Ӈ#&^ jaJSi#UN'SOw>xj[luRhٯEFFrH#U%!66=(XvUi`'0Ҏ,$ B4T;!V;3?J][_fɔV(#i#Ih-!%NdУVF6*e'b/tx iJߋ` 59*ʮHP33Wsm+ZӀyҽxDCQ'iaKWOHe9&IIhf͌RʮIv^W-z3'h2P /X%9'Wc_\6e*߆WP ZD,0I1H]&W -߬Ӑ5%Hjٙ sfެoXUFNяeX~ x.|6]"(.@4,MM%7fZBM@ =S:PW?.-Nuu5= {6 GoŦ$obG+c xʋ^0o,4'FhuSߦ߷ߤ إhBK*<+çphe=GdZӧ]{t][F45_鮝v6I'"n?o'JK`RJrp%Wy): (#GN} ejTc4̌kEaV "C(vrSm Q,O74} t'Mz֑2PoSBԩ_>qld:$sƵ(U;+@ۼOKf+$XhEPxvaMV38{6R8x ܿd9,Gg:.)Xxe0JG%VfNk/-s?gdB3Ё@HГ$n7S^icU:'W%GSxA:65 p AU4 4564TH+N; bû9ڧX ,FχZDсi~Lȯu`(G#YljfQvH= |AZ raJUߚh rQ^np#I((IXD bO)SE7xsOk)zm8y-huӨ-MɱE"ԭ>x4&:Vl i}y>{̰Z *1QT}᧊y֢S$ i|q%??v%?rZxpuk$G]:krmv//0eb in`yc*EG`$j3 יO߀?]Muӧc[;g ^YW2M0w#4hN{2I 'wPt*k6u^Rp, ؗqw}XR[1fAޙr;W'sV>6˓#w1kGE'za ),jU v7wӖ*`+.]R WN16ovݞa{9/5+҉6VXVHJŖI/$B%B݂~HD ITpJ~2p~&cf%:}yxoOѱKQkKCfi=W=mU~㑟Gv孿[劭Ut70Tp MQe4밝mɫXE-f1C ߺNֽi8xV\$ȱ$$334olwq.F @~?O>{Y}#/+oHׇ?I2'.q`@'7ox8=;k[BKVCL<>^<䴌uϯhg>c[ 2\(ANpŀ =H°$X7N: 6F TtǢj=U'&@G2KL'cW]4'QSƿ (R(Ng$%xfV)!Nȑ)=G2G!@13zR+;ƀ__ئp!ʓZtiO/ջ%PD  :2:#xry)Kę"(+U+fu%u=:.댤Yy+U$Y 4uK!t/]Ћ,e5XkZPdC~x¤n*QVx$ L즐ٜ@bT wk55‘wn_ 0@'S4ky8BP1L.wS87zyyYެf=vpok|~zme->|m=^&Xݶz7ʊ c 7?lv;||}è\_m9opAO|vod%1",>|6I#|z?d}ZkXkޏ{w)5_Oyfu!ϼ׼mmáG mVH|0^5tt#::MqzO?m'?yϧep6^y.]r2y1;ꪰ`VD[;jYGۑ#W&λ#cOZicXғOvd4 ;q͂+jy|Xgщ>Ns%bR l,1qnZBK) O kmozc㜵F54 =u(PmG pEoA#lG1ʺFp{3t:v$w;|;Ͼs<2zy'U[ RtLF h4 :d2 'UJmf XTιM}ʭO ?J٧I'WCIі2C8p2Šbg6l6,n~Uc1T†=xkf^ 57XwA̞b 7~/0:p6#MWYD ZE!d@?_0[lLGc7aYS[t~IuW:&eŇؤE)@sql`50nzsW&ԏ=FZia )N)p%2HJ#ܼR*K8+#n^tl΋9eG Ԓ=T Zx:;tZ;\VJ^= o0+  ^)"YyEȦ2A-6Z2|n?%84kj2^eY)hȵH:$2KdD-lM/DYkQWI`V"_lF˒w|,->|6w_'l7E# ݝxb1\d,u???VmO_?vͦ,>?|+[TZ}0wvqXk㷢Gݰ#X{'|6[ϟox"6PJ_y [ׄRAԑԓm·6GyR0׿ F|}?쟏ܞT,3&Sӊ0t׽K/J:|}ݢtz=_3.-`OOcЧm'ǕQk<2;{Ibƿ? A> Z8$|VQ ɽ Li&aֲkZ-]ʇb g%kf)JW`X9*}ГxjTA-Ꮏ~J6rwhHzmgv*opaȱ;T,Us(_ڙ8JwP}޴va&,yR*ç<zawPUX_6 3{MJuanEI0YV1고xkl)=(mdMҹzIf0TʶY.uCY}zw#VP8d|dW'Ϝ~+(#lLa8.|%Mx fLMv+k٪QIdI!؞ d:ߢ:t;8kpPKIqJ*h:$3oЧݥs{v2f^5bRiX&(0̊}-TfxZ$ D Yy¼G:bA^ޗBohLӗ|&|O%n:O!;sO^u)iX ȭ~aɖTUNZUu}Tmu[_ ֚|m)1QɹXy*ٖI`"z)ajasiy:ʪ2d=ϟv2 QRA#N~…IuE<|1/ld9~eM? c]2tȢ.=_`Wp'q᳙̹[p73]P$2VxJTIo oٕ ʣ*txi!ۡv#|Aۓ^w+ڂOM]A</p4f@ EU+BQIw֞(\'^-l^kUMb>,O\Ňb0;>}{Nެ{^ԞO]rd-u'ϟ>;j&~[x/޷(wǘfx{}l/lXkM+Lf𴊼rhH>-6ON7%yRگqͱhopencolorio-1.1.0~dfsg0.orig/docs/ociotheme/static/alert_warning_32.png0000644000175000017500000000204413223553423024327 0ustar mfvmfvPNG  IHDR szzIDATXML\U o((e &`uUvlUcM7mhbDn(u4F4ta1PB(-TZt޻y3yL;'}ssszX)`os;\df7x᜜z] FUqDtNDDԖsO^+239*zKΜ:ϜH24=g )@N$љmWPmGwV e ,X`Hܭ9S_Zt ' (PggPK4@*Bh * ;P@5) A@9 eunjnb..R-Q[ًȗt30'fQQpʍO8 P1avʮ 37 /azM,ýv Ä뭼eCp` ^=_}mBt4 B*cl) `A]Trh?~_Ke:p#dښiFPVt& cn*p  trfrHi`[BA"!@ (/)lDn)"s Yk%b"cl9| -l%IENDB`opencolorio-1.1.0~dfsg0.orig/docs/ociotheme/static/ocio.css_t0000644000175000017500000002114313223553423022450 0ustar mfvmfv/* * haiku.css_t * ~~~~~~~~~~~ * * Sphinx stylesheet -- haiku theme. * * Adapted from http://haiku-os.org/docs/Haiku-doc.css. * Original copyright message: * * Copyright 2008-2009, Haiku. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Francois Revol * Stephan Assmus * Braden Ewing * Humdinger * * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @import url("basic.css"); html { margin: 0px; padding: 0px; background: #FFF url(bg-page.png) top left repeat-x; } body { line-height: 1.5; margin: auto; padding: 0px; font-family: "DejaVu Sans", Arial, Helvetica, sans-serif; min-width: 59em; color: {{ theme_textcolor }}; } div.footer { /* padding: 8px; */ font-size: 11px; text-align: center; letter-spacing: 0.5px; } /* Sidebar */ /* link colors and text decoration */ a:link { font-weight: bold; text-decoration: none; color: {{ theme_linkcolor }}; } a:visited { font-weight: bold; text-decoration: none; color: {{ theme_visitedlinkcolor }}; } a:hover, a:active { text-decoration: underline; color: {{ theme_hoverlinkcolor }}; } /* Some headers act as anchors, don't give them a hover effect */ h1 a:hover, a:active { text-decoration: none; color: {{ theme_headingcolor }}; } h2 a:hover, a:active { text-decoration: none; color: {{ theme_headingcolor }}; } h3 a:hover, a:active { text-decoration: none; color: {{ theme_headingcolor }}; } h4 a:hover, a:active { text-decoration: none; color: {{ theme_headingcolor }}; } a.headerlink { color: #a7ce38; padding-left: 5px; } a.headerlink:hover { color: #a7ce38; } /* basic text elements */ div.content { margin-top: 20px; margin-left: 0px; margin-right: 20px; margin-bottom: 50px; font-size: 0.9em; } /* heading and navigation */ div.header { position: relative; left: 0px; top: 0px; height: 85px; /* background: #eeeeee; */ padding: 0 40px; } div.header h1 { font-size: 1.6em; font-weight: normal; letter-spacing: 1px; color: {{ theme_headingcolor }}; border: 0; margin: 0; padding-top: 15px; } div.header h1 a { font-weight: normal; color: {{ theme_headingcolor }}; } div.header h2 { font-size: 1.3em; font-weight: normal; letter-spacing: 1px; text-transform: uppercase; color: #aaa; border: 0; margin-top: -3px; padding: 0; } div.header img.rightlogo { float: right; } div.title { font-size: 1.3em; font-weight: bold; color: {{ theme_headingcolor }}; border-bottom: dotted thin #e0e0e0; margin-bottom: 25px; } div.topnav { background: #e0e0e0; font-size: 0.8em; text-align: right; } div.topnav p { margin-top: 0; margin-left: 40px; margin-right: 40px; margin-bottom: 0px; text-align: right; font-size: 0.8em; } div.bottomnav { background: #eeeeee; } div.bottomnav p { margin-right: 40px; text-align: right; font-size: 0.8em; } a.uplink { font-weight: normal; } /* contents box */ table.index { /*margin: 0px 0px 30px 30px;*/ padding: 1px; border-width: 1px; border-style: dotted; border-color: #e0e0e0; } table.index tr.heading { background-color: #e0e0e0; text-align: center; font-weight: bold; font-size: 1.1em; } table.index tr.index { background-color: #eeeeee; } table.index td { padding: 5px 20px; } table.index a:link, table.index a:visited { font-weight: normal; text-decoration: none; color: {{ theme_linkcolor }}; } table.index a:hover, table.index a:active { text-decoration: underline; color: {{ theme_hoverlinkcolor }}; } /* Haiku User Guide styles and layout */ /* Rounded corner boxes */ /* Common declarations */ div.admonition { -webkit-border-radius: 10px; -khtml-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px; border-style: dotted; border-width: thin; border-color: #dcdcdc; padding: 10px 15px 10px 15px; margin-bottom: 15px; margin-top: 15px; } div.note { padding: 10px 15px 10px 80px; background: #e4ffde url(alert_info_32.png) 15px 15px no-repeat; min-height: 42px; } div.warning { padding: 10px 15px 10px 80px; background: #fffbc6 url(alert_warning_32.png) 15px 15px no-repeat; min-height: 42px; } div.seealso { background: #e4ffde; } /* More layout and styles */ h1 { font-size: 1.7em; font-weight: bold; color: {{ theme_headingcolor }}; border-bottom: dotted thin #e0e0e0; margin-top: 30px; } h2 { font-size: 1.6em; font-weight: normal; color: {{ theme_headingcolor }}; border-bottom: dotted thin #e0e0e0; margin-top: 30px; } h3 { font-size: 1.4em; font-weight: normal; color: {{ theme_headingcolor }}; border-bottom: dotted thin #e0e0e0; margin-top: 30px; } h4 { font-size: 1.2em; font-weight: normal; color: {{ theme_headingcolor }}; border-bottom: dotted thin #e0e0e0; margin-top: 30px; } p { text-align: justify; } p.last { margin-bottom: 0; } ol { padding-left: 20px; } ul { padding-left: 5px; margin-top: 3px; } li { line-height: 1.3; } div.content ul > li { -moz-background-clip:border; -moz-background-inline-policy:continuous; -moz-background-origin:padding; background: transparent url(bullet_orange.png) no-repeat scroll left 0.45em; list-style-image: none; list-style-type: none; padding: 0 0 0 1.666em; margin-bottom: 3px; font-weight: normal; } td { vertical-align: top; } tt { background-color: #e2e2e2; font-size: 1.0em; font-family: monospace; } pre { border-color: #0c3762; border-style: dotted; border-width: thin; margin: 0 0 12px 0; padding: 0.8em; background-color: #f0f0f0; } hr { border-top: 1px solid #ccc; border-bottom: 0; border-right: 0; border-left: 0; margin-bottom: 10px; margin-top: 20px; } /* printer only pretty stuff */ @media print { .noprint { display: none; } /* for acronyms we want their definitions inlined at print time */ acronym[title]:after { font-size: small; content: " (" attr(title) ")"; font-style: italic; } /* and not have mozilla dotted underline */ acronym { border: none; } div.topnav, div.bottomnav, div.header, table.index { display: none; } div.content { margin: 0px; padding: 0px; } html { background: #FFF; } } .viewcode-back { font-family: "DejaVu Sans", Arial, Helvetica, sans-serif; } div.viewcode-block:target { background-color: #f4debf; border-top: 1px solid #ac9; border-bottom: 1px solid #ac9; margin: -1px -12px; padding: 0 12px; } div.imageBar { font-size:x-small; text-align: right; padding: 10px; margin-left: 15px; margin-right: 10px; margin-top: 10px; border: 1px solid #000000; background-color: #DDDDDD; } div.tocBar { text-align: left; padding: 10px; margin-left: 15px; margin-right: 10px; margin-top: 10px; border: 1px solid #000000; background-color: #DDDDDD; } div.content div.tocBar ul > li.toctree-l1 { width: 400; font-family: Arial, sans-serif; color: #0C3762; font-size: 1.2em; font-weight: normal; margin: 0; /** reset the margins back to 0**/ padding: 2px 5px; /**text-shadow: 1px 1px 0 white;**/ background: #ddd; font-size: 1.1em; } p.caption { font-size:x-small; text-align: right; background-color: #cdcdcd; } div.sidebar2 { width: 200px; font-size: 0.75em; line-height: 1.5em; margin: 10px; /* padding-left: 10px; padding-right: 10px; */ } div.content div.sidebar2 ul > li.toctree-l1 { font-family: Arial, sans-serif; color: #0C3762; font-size: 1.2em; font-weight: normal; margin: 0; /** reset the margins back to 0**/ padding: 2px 5px; /**text-shadow: 1px 1px 0 white;**/ background: #ddd; font-size: 1.1em; } div.content ul > li.toctree-l1 > ul { margin: 0; } div.sidebar2 h3 a { color: #444; } div.sidebar2 ul { /** This is the selected sidebar text **/ margin: 5px 10px; /** padding: 5px; **/ padding-left: 0px; /**background-color: #cdcdcd;**/ } div.sidebar2 li { padding:3px; } div.sidebar2 a { color: #444; } #bodycontent { padding: 4px; } opencolorio-1.1.0~dfsg0.orig/docs/ociotheme/static/clo_res19_lm10.0101.jpg0000644000175000017500000003027613223553423024204 0ustar mfvmfvJFIFp"  D!1"AQaq2#Br$Rb 3s4CS3!1AQq"a2BR#3 ?]O}2A?oŗ% G-.\o印*)j1cEbCGt/J?";Fh8 jhޕl}}omS>b}~`?[cZuT!N pj#`?4*=Iu?ivp40o_ ]Sjn*sc?L0[9QpVa SOmyc閝N~ӿNsc` H?j_B\<DFbt֧+w2G4xem,<@$g(t)`//@u,S3)G 7H̰<`rLJQ)Հ9HI" #{Sc9Z$7,ط%.0=$9Y,r=5"~+3NȨVZA?H ^V_Y-LSfzvC6X㑥aΥX̊軝r$(y׆u'XDʒRM DmI Is8c2BFc򍁞S}*bjXFGtE'tƊq`ESiMO3 TUdhsíJbb#k ^ֵv\YC67ȄR+º($3J:(N=~?v2}WʬM%O_V+HFGb1I ێׯqtEMMIyJK1 xAשiNP!+`:;nsWctҥ0ߘŒ^|qq_^*if9`H.مGձn:lo|&fr5]DRDG͐I)Q-u,SȄ/!_&]s/4#y[Hll:q?VF^VW0Ȱ;7ߤRgn(ӘfL ̼n|d\h-6Ceyv- n#4 > yap. @f-eQө|smt"р,ri0+RɁW:ۜlkzz$5ׯWۚolTaŗ0S4BU #}b}lYr|K:؏]scSkt;84G[gJ4PGIJwݫaUKڼr"A:jHCpf6z #;8)0nNInaP;aQ̸gzR$R˨:eK_V6bBz5` "@ FC iZv"oq޸&M|-/v,F* ym>^UOxӨl `鲘ځ#uMhfMȹee76#  /4tf`]N0 8a)Kas3:[x걝uEFP6o\;㊚I.bʢN*pI78HuRȌ롣J/mtM쯆ZMp蒭 (ee+ 6%ƒ]cR YeXuG+bl^l1qm(5*n(*!i 70UM%<6bIR'Vx 9Qrы_QO_< IT<\vTIf0[eQDJ\cE&Qkס6!i((YJ"\UjKClJe8)ԡBsNڲXp?b>Bé3-RBz eHzǽ,ԱMdYb- )dEb;S2f57`Q~W$Tt[,Ikq>.2ˋ*mRD- \]{J5!JdLO[3H%uTCf[Zol&5| YY;<`Rŋ77u twfl煗J'6jBa O>KgN:z^*et&1,4pթBI'M~I<}z𽱽KU!Zodo߷ժ)" 'TݍTiƞNE\E%w m7e@.5}2KfYڕ9*b, X!=٨s*F ,mwAau?l|[:jL⭉ 2` -6ë{ BAs\ɗ'B^LΓ|( vАry2RF kgg0.ըQ3RPGRttK:$jxDVD p, _^ŻJΪ+k}uK1g3IVGdPQ49MD6}:a[ٵH|q)Ȣ3sFaZB ^bͫji)zy*"i>4g}V)-fA 9/co*U::Lm%b7ɟ!?6@JD0R'b:c=SVb,֊7,GQջ]7ϗZo,ay9L0 :;D#[ `uT?9&i3L.2t2-7Y A6 wUY*vny6`4L TH˧E=ȩ#IfkH. c&2N7Ҵ8v#0<)*O:<Ν$:zfmBzJLYY\fgN.y6$8&z7ZY)SEWMS+~m)Gª~WJڂzUZQwE ~#|Yn Yzeh)y9 W:1A*S;M&l!$[$ͤ$\ܙ$b>MCMRRZJ;M*ݭ)'P!VQ=+G$QB:P "$|&q4UF[*4&X$ I] {=InOϦV8)B^ S^|Tsqn:Cbt?=QΉlA$;x տxŐYT@_q"` D̀btӁŴBO"DklzW[>cˏu {-5 1 1 XܖrXMŭ12UC/w6ĺrxB$cGK!52:/|w* ͆HD/:$Ř,d0WMlmE;P:b2AT!.AaK /kUkNDS.ouӤT̯4ȱNӦ|I)YVa]q0տQœ73r -Q(,HJǴ$7. \]KMey=:#~0ԮI lU]EۮlAJo'd}@gʉi++iw4QShcZb*em@rHd]Qbق>\꣜5Y3A4LWE5?ZJu[2ʌ@qYR3ej: ,Rj] .J,v[dyb%zzYDXy1fq,1j("RT!)Vr3MITIhJŀӕ/T9TeӳI :"kPȧP7CZfFjVTVzGJK!H@ v9,TTB?ųwp1EƱ RI'I1TRQI1A"Lf#P4d1R G蔀& q1 i*LYvR̝ HPF]PCq"A2ĜaX掠 űW&d{Dm>kEPJHV\$Zkd2L@F60#[:|$jG3f̅$u#Y%iC,f!~iBJ&`yӎB))05hvq2i#MSꕫbYkO$XbJ6C 4.'^ Q@Qa܃bA/O|~</i/oumt>߳nTPFf/I4fݵn7lkfcm"^=6ĞU@X|`7zH_-mң{R Dl5UN$1r9-܋68cxF(*Q$n;0,@WqGf6Y(7tuuf/'rHPO_v#2|3$ST @Xr& 1;z1itj#7%(ċ 4Y0E$2A#U:HGTJY@NVF\OMM,֞-|i`ӳl) Gp)k0pÊh0RDk{,Y$辰VVf9aXw _5A6${x1J˸ WZ-R4<94e%I& J6Iêmus=)1h`^}j1S^xj@` =og~FYp:^g|}<˒k|$E*Y V 0 t=/~Co  j{}m(Ǒͱ[u/&,$̀i;$^@]$yt6O8R3GU8"FTl#O:C(#7_ <@o4`"Mj1[[qA̦{E5$ K?2o_ J544;Ă HvLXxTߗ ,׶% Ԙ/!t>V8bX"(I$f$텺uYPL! " ~},nI|j=l i]DKDH9Pn,X]1> jjR"^ZtJh@ܻ ]XcPY:EB$]ćùT7k.#^sE`LEg$X|Q$ r*rHW&U!6&5Q.T N'FY\Ckpl\:(e4ʏ!4ίԒKǦ؂Q#]bV)uF[ aO`6R:3Ƭoc o j^?NT~ oH +RhHzH}%2sR>ϙԘʵFʹi%]Jk=Xx.Y#,ۢv ԍU3marnl:HdX{[\lGh/);ڗ>%o^<~hVe~Cx8b[BEsEUx{<#o#o<5vQb\b~}}3T9[JLaNG~'z/k..I6fk&)=[t*Z"|X\ͅ ne/`fP|Q܉JA꿀d()6"}RH2Je3Ӹ+ik{X1*o#*T(u#K6cOj*$I^v&0IA|[No"Fl {ygJ$|_jd$B˴#X#0Q+LTmVŶ ʺJCJEMXTd'e_M3[);@dU< ` }V ?a}2~ܭLƒ))( UQ O/k\C 2B0$&A>AC("p-M\QS%9PHa .tD@hb TXfYK#x? kW17}ӦUzEm~ğ[a(FR.(s 4l ĒwĞg;}=|Gq>+g V\mXU*nk`ZǓ}zlcǕOEzO]1 Y)Gq-x[>ovC])ooYs>o =ǡT'L?}2דq~x7Ǯ ;و>NǦ eW c/lG[ ^"/^W_;J1,nҸ@5dTm ޷=r't[ E~|{'qo5E{:wCHgʎ?F.k%2?9Z6ncHDi""[;\r5s^f5y(YL_NzV#,$ř1ȌH8+F7_$o3QJ| ؼAN >W1 ReaX}1Hœ~ad U*u;zjbct륝-([ᎂdD(D sQ{i#v=q/wYDͳj:Y^`̪+TʅKN.Uy >nc8ϵ%'KI)Dt]RS&$.5(m˒3pA1#A:IDrF7k%oe1IIi3DMe@2_RWb11D\UPPFMzR @(lHy%627ֆqC-R|GJ~E>\ff%=$+h0`#lM$$Z,fY F^B%eidfrd[*YfbK;řXrK^ {ٵ>pӴH S WjbᆇnȤ驜Gp6@2$NCN*Ng87O_eLB71auIL7nwʥ30$_ӊjncΡX[珪58XߏeZFgQ *î>|JCaaa]oroPmqq/o!˕dc (K.x!([o=~j-=~{}8}Cs| LF GP@Tq?>{cwoKuAXؑz ۅ6 (淈ڦ/$ȓM$q] Mʽ\IB%,CQf&ַڤ * y=}p%!@|ʂ|R͢@znGYr,;GxiA%T|yt1po`1aSU&T'Qoyh2R6`ZP@l>W!x35TR\'D߹/u)q K3Լ r"E$Uw+fB{6 owa9 ˓tfy|7Uϒ?[W3Wxd*Lna/MoݨB@S6 1"\NCtJjnd6`ysj@U Xan[|r%RIؗC$6!Ywb$ X[n}'xrAGZz%ْl3 t?(3Ļ>Ò v#NՃ8C%Dy@?YE8Wˉٺ S kW}(e7_^6nmUk၆eUr}zvŀkKw13lx/=S D W t||1_Sghȏx<j[YWP/Q}@4_د0_QňTΫ[rڋwӕopencolorio-1.1.0~dfsg0.orig/docs/ociotheme/static/clo_res19_lnf.0101.jpg0000644000175000017500000003222513223553423024206 0ustar mfvmfvJFIFp"  K!1AQ"aq#2 BR r$b%3CSs56Tc 9!1A"Qaq2#BrbRS ?GO ?[݇&KIx-%7O`#h=a?v ,_wX~^<f |Pª領=GF1r?Ӆ#Nopo0Ze fnCp'n~H@H2^iIۨhGu鲍k> ?e5m@6i&/=5ϟhs4|>I mg=5n???G9W2fqG)H*:0*6%ˈE5C{9i٦U2cCɚRUJ)hI_G7@ҍĄE_fGPUӷ/ H^Cpʀ% ܻcJZG4YE {(:zOeT|#O!P_$%MED}^Gf6G[.ךZ[j)s)rP%Ͳ 3 忽B?XFF!*.GDĕZ5J3H(օhj,).vJ8*-Qn#*VQ->kZ](ٳ,ʎjZ|ƞ*I!~ `q?p~;/ .9*O݂E`lg@'ix?طZq꺨uQNԀ$X-P`ɳycmQmqɕSF }RCL(ynϟ=p tv=VWzL2*gy48`cW% TFFHEvC7 H@ ^ 畷((+l9okkc#Q( ,sBB0b9]WxA@ 4( #g7#E6 A8ǞyՇzd~Sn4š_2GD[>-WMb_݇f! y[ӗWO~^*e0ק~o?K}R%AklE&ܔ[#TJw!쥔w`@Rv(gId [zL'gpY>c8?cSEH<, *V{h}m~DXZ&̪dJxgpڦ@|fڼ[u=1SIb1;IX!'p>^= I,:eiSeF@㶿ZXx<&CMR@85hKJUd*?aqiM[Q7jt),`- k BG,8X6(7}DoM<{_s&jR]aȀN+Wif,-Ӗ86CWmۉ&}G{d'`l qGO#xxu)>H0riv3oo]k"_Էxt7I,B@,6+,;TmdZ-_bm$h/gR٬C(qbY)h-ʦ eE"Vh`IKq;+n&zrČH/dNcf6,iXR#೨y:7r,Um[lHJfe =z&k~@ve c]vbNc{lͬ, 3~]{D%ClE,t>\m{ 'NKP+6FW>75vy4S<{VPT[a@T}ߠrkǵvЎ׾k_k},jad* % 67"`H7KNfEe)$ HK|d1n0f#2kzS%d-KV#Xdi%NCf3zU $& ao,'iy(ZYR TV6☝ϼ?ﴪχW,A_$VoM_AB v%Q|Ejޔ#l#%*B7+ 7`~B QuE$j$ XX2@eR.:42+9\3c}OjG,PHs}Ȋٙwilo{cC| <RC+@eHǰvat7`X1T&̳'@#Rbݥjq_?ĸm/u5|2y;T1#GDU `[[O}=LBXLrLkHdqnT;tn'+]n,1 U4HT1$nqak<6*>W5c_RziP^:j2uw;ܔ眿_6grA:3N_ (_#c@-ٵ4erɗd.gʁ6ͩc )fT^Ǵv w%nC'_3%Zj jR:L[QJzԽlVUK1iR\a$sH=%^C3l(a<,ꬩok]쓶LZ+\ꣁVZƲx֦#rҢO#Epv>"Eih$**:>b,u%]H7H&t1| x$R crAͬIԗY9{4Gĝix9r3G+*#- ragd]75,[!lY+YSo{27&TiK DU9E U~ p*. 1so?9V[q*Aokeais1w r$KA ̧ݧ?"zgL̠"h^D)eHQw$ /GCMWrZ$ɦ˲jTQdELUfjQ2SNNT=;/D VCK2Mb%H$y|?KGC_E=,(Wg`.jwW=cM#G)ؓV,Ds:EɳzW$Wǝd$ `We-Ok{2dwPi_Urj!Q!j"X%( Df RQWn"9FahBe`XG\# ɭF7V*1QNhO uqCe?I!XZzs8W7&ǀէ+CTAJ/SIFB_26w33 \ םfrt˳j: (jN-4 kR˶xBTSlIhn(J5q*H;0 \EUg \b)<&8W;Br,ܳ~Y}jI9]M %.SN)29!v$cyzQmxy̅<Q`9~X]PgM ]m>ƼyzdӟNcJw,`4d[/6#5Iu':j~EHnc|;-\:&ޱ-5ETjy)L9X[ w_NgN-n0cӬw:].6Xνg[ғ.aԴګ[i|Z:cTᮣjoHe1 8xG5w췛?3,·_S'T9t6!E@dSnX5]݉w*YBʩ.X?}),cFg$(=u^? YGE5C9ͨk 1ris,$fEGcD曌*v@duJG=#F({_STTgtmSa 5!U A[U n TmĉI7[X;X+אÏ$q dj6f'0FUgc& < ?;Zk&6 0^lN :%OPbw$e,npq:g#B5jvTf*ѼyIED,JVR=&zcB\8zݳVWTP]._%.sVNMX4uSZ/X E$F!i yl1 Jr3X,#F~rGhv+ n~7;VF吪\6hl4tDmͶ2 [˛,4vJ+Ggf)áW^?4%X0[*@!v"P$[`A@ĶKX\78W$ˤ1P)Ŋ`Kka@TL_n2𐫛%؃ḅ=kguTbX^mK_/7, t}U8gf=Lѹ#48̦ߗkh>G7_=ey8Bo`Oa%+oZ6kzhrz_=:s\}> `~٪S4*A'7+[yJrp!{~7G͔\oc˞x=/xco/B}-IR!2(B$E6n[@9 ^Y"MQP]Y69[0,7ض;=[ڸL0W]ݘ$53PEizX5@SL n H0,{X{D)Û64gە0o \:0@ ӝZj589BluiFU`5͇4fcal9 |Ijjrgt,[]4 m& ɽ Akue$ZiTaĤ)rxbPw\Xu0tTR`Q ٭Ij`YfRM$T XHbmҡRT@8d2VMCRTUpĐ|;|{:jy(2bzh}b*9ڦd &i 2ƱKV6|9aS.*jj%fZvI22F6[[ q4cʌy-UR p  p06ӹcwۗW>~/?r{åe& Δi9Ycěw+|%$wtW_6혛:B/OLQDQNJ!O:S9V:heڱ^AH~xqIpTk|>#C^"XR/k=4Ҷ$Mv|u&QhӄN<6Jc'`F+#7&ضug.(dQkWS ڢZzi%h4#f"rs\uDF2 2k>ZPB6 ϓ/o]z{.\\FWebAAY^T%jٙEJ@o,uUK::DPdRzkvGKhw(֨*ZZgKQ.[ $SWWVSDKW{)'LGuh%5R TdRKZRYISKRyަ7dͫ꧑ygbܯv:ai(l !nWKF: $~]zsko})z(89]K uLqдgZn***&ᩧy"!u; ‡5mRpn,fiwy}V&iXD5Y$XcH8U5n%b7<|?as>ΪXSxҐ;Xqf3{k/o$մtD0܏d|J2Iaj^˻tUuw/'J/}G 5t8 ! 1c?+.YmE/ftM(kԔLճ1 RFǿv aNRLpͣKӼI.1(Rpϻ]R}{ngi*ifj&u34SCQ“Wd,C hǠbYu*IS&iCf*wǚFN"ܵ=Qi"sRENc9)Ԛ$88NiVa2eƫԲdeHW c3{'q\J?;E~/xʑ@w>kxK SI)n@,˸Kק+_勇0mo\5o\Y^Ù7k-lL+ڽo-bcCi-Lu3{puրṶ̈̄{ŏtŠMaV?lB=o u4D_k O+-s~]21f$zߐ ][QT3-U~AnyԞxbϬ lO۟3sI#]*sh?fw1w|ߟ/VDKWN穝Kc߼軵cG۞}d kpq88sO=ѥIZG#$遡MZPzG/?'6}>+0.ThT[Z_O>>y8w>8N>XZrB5 *K!m ck[$ue8$J3 ~1/aIț!ۧ-詢'9y6P5 rjbIq9r>5߭gFәU%"F,#W,T_oQiXY xc:=zS;@/bB4y ĩjY8 ं;Axs | w^>/8'h; #KmKN/jʄԉ{y7 ԁ bNȍ5ұĘ9؉V<ϟ|o^&qw}t2/@厚u*B˒{h,+Ut*'11vu6Xr==3d6XL4ݯK"{V|*' 5KyQG2~jXm4>m#[Nw]KT N HOٟ7gRRkmU(3<Ɲk$ƬϡˤXah*"i r#.`uLw_k *|SZQ uK1.%{V=25r x^x`* "# noٔpϻ('zY9 *́Qu4S,sf9A, $v4i#@,2|kQ2$`7l<!u5MGO6gY3QSI*JhB74hr/?`<2 D#k- 7?Qc!?l XH`n‡NOL5N.Y4DVUYȳmX&`&,B7.*\ēܻۼa^z]39,#wv7fgbYى%$|J]mu$4gAuʼ-MA&!27,Ak[@V_elő{::@POwvq̫QH( u5 $xZfͬ=U䈊J*@ rڒxcQ5EA5G"gQ.zz 1YwYt fzZje,J˴TlF~YO_> ,[6a7_>{5ulAA$eá*=yxC[*~'_'RxF177oo鄀QoJklt,:5` .>|}}]4#/A]tqNXY>_~)o?ƽu߮!#ª?уC)@@1{ v_ӿݍ1ZZܗ3t}GU:He"hkDBƎ)*Z9s,GK3 y/4u$ 3pKsJTUlrXǪ.rnKiS-e.r1X77ULdLf.EcU/ُ G5؄V -kʟKkj)םc#]Xa݁| j(;<ȣWhGCU= S&fsǯ4~2ǩXO2>#)Rk *F9.1:'z͗(d1L R(Uj:L7[IcՙіF7O HGYcNE’v kwr0uVGQMA[XjU Wy? ȡ{MK ef{7~g1U>70ʯϏcV{߿WiMya[/?s ꩯϓM!ǿ-vC `2}*0Ydq{CK[`BC#^opencolorio-1.1.0~dfsg0.orig/docs/ociotheme/static/bg-page.png0000644000175000017500000000024413223553423022471 0ustar mfvmfvPNG  IHDR hJrgAMA a pHYs  tIME +3IDATHб W6`#_Vz#  &>AklrIENDB`opencolorio-1.1.0~dfsg0.orig/docs/ociotheme/theme.conf0000644000175000017500000000042013223553423021137 0ustar mfvmfv[theme] inherit = basic stylesheet = ocio.css pygments_style = autumn [options] full_logo = false textcolor = #333333 headingcolor = #0c3762 linkcolor = #dc3c01 visitedlinkcolor = #892601 hoverlinkcolor = #ff4500 rightsidebar = true opencolorio-1.1.0~dfsg0.orig/docs/ociotheme/page.html0000644000175000017500000000232413223553423020775 0ustar mfvmfv{# basic/page.html ~~~~~~~~~~~~~~~ Master template for simple pages. :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} {% extends "layout.html" %} {% block body %} {{ body }} {% if pagename == "index" %} {% endif %} {% endblock %}opencolorio-1.1.0~dfsg0.orig/docs/ociotheme/layout.html0000644000175000017500000000400613223553423021375 0ustar mfvmfv{# haiku/layout.html ~~~~~~~~~~~~~~~~~ Sphinx layout template for the haiku theme. :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. #} {% extends "basic/layout.html" %} {% set script_files = script_files + ['_static/theme_extras.js'] %} {% set css_files = css_files + ['_static/print.css'] %} {% block relbar1 %}{% endblock %} {% block relbar2 %}{% endblock %} {% block htmltitle %} OpenColorIO {% endblock %} {% macro nav() %}

{%- block haikurel1 %} {%- endblock %} {%- block haikurel2 %} {%- endblock %}

{% endmacro %} {% block content %}
{%- block haikuheader %} {%- if theme_full_logo != "false" %} {%- else %} {%- if logo -%} {%- endif -%}

OpenColorIO

Open Source Color Management

{%- endif %} {%- endblock %}
{{ shorttitle|e }}
{#{%- if display_toc %}

Table Of Contents

{{ toc }}
{%- endif %}#}
{{ toctree(includehidden=1) }} {%- include "searchbox.html" %}
{% block body %}{% endblock %}

{{ nav() }}
{% endblock %} opencolorio-1.1.0~dfsg0.orig/docs/ociotheme/searchbox.html0000644000175000017500000000067613223553423022047 0ustar mfvmfv opencolorio-1.1.0~dfsg0.orig/docs/userguide/0000755000175000017500000000000013223553423017212 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/docs/userguide/config_syntax.rst0000644000175000017500000006226713223553423022634 0ustar mfvmfv.. _userguide-configsyntax: Config syntax ============= OpenColorIO is primarily controlled by a central configuration file, usually named ``config.ocio``. This page will only describe how to *syntactically* write this OCIO config - e.g. what transforms are available, or what sections are optional. This page alone will not help you to write a useful config file! See the :ref:`configurations` section for examples of complete, practical configs, and discussion of how they fit within a facilities workflow. YAML basics *********** This config file is a YAML document, so it is important to have some basic knowledge of this format. The `Wikipedia article on YAML `__ has a good overview. OCIO configs typically use a small subset of YAML, so looking at existing configs is probably the quickest way to familiarise yourself (just remember the indentation is important!) Checking for errors ******************* Use the ``ociocheck`` command line tool to validate your config. It will inform you of YAML-syntax errors, but more importantly it performs various OCIO-specific "sanity checks". For more information, see the overview of :ref:`overview-ociocheck` Config sections *************** ``ocio_profile_version`` ++++++++++++++++++++++++ Required. By convention, the profile starts with ``ocio_profile_version``. This is an integer, specifying which version of the OCIO config syntax is used. Currently there is only one OCIO profile version, so the value is always ``1`` (one) .. code-block:: yaml ocio_profile_version: 1 ``search_path`` +++++++++++++++ Optional. Default is an empty search path. ``search_path`` is a colon-separated list of directories. Each directory is checked in order to locate a file (e.g. a LUT). This works is very similar to how the UNIX ``$PATH`` env-var works for executables. A common directory structure for a config is:: config.ocio luts/ lg10_to_lnf.spi1d lg10_to_p3.3dl For this, we would set ``search_path`` as follows: .. code-block:: yaml search_path: "luts" In a colorspace definition, we might have a FileTransform which refers to the LUT ``lg10_to_lnf.spi1d``. It will look in the ``luts`` directory, relative to the ``config.ocio`` file's location. Paths can be relative (to the directory containing ``config.ocio``), or absolute (e.g. ``/mnt/path/to/my/luts``) Multiple paths can be specified, including a mix of relative and absolute paths. Each path is separated with a colon ``:`` .. code-block:: yaml search_path: "/mnt/path/to/my/luts:luts" Finally, paths can reference OCIO's context variables: .. code-block:: yaml search_path: "/shots/show/$SHOT/cc/data:luts" This allows for some clever setups, for example per-shot LUT's with fallbacks to a default. For more information, see the examples in :ref:`userguide-looks` ``strictparsing`` +++++++++++++++++ Optional. Valid values are ``true`` and ``false``. Default is ``true`` (assuming a config is present): .. code-block:: yaml strictparsing: true OCIO provides a mechanism for applications to extract the colorspace from a filename (the ``parseColorSpaceFromString`` API method) So for a file like ``example_render_v001_lnf.0001.exr`` it will determine the colorspace ``lnf`` (it being the right-most substring containing a colorspace name) However, if the colorspace cannot be determined and ``strictparsing: true``, it will produce an error. If the colorspace cannot be determined and ``strictparsing: false``, the default role will be used. This allows unhandled images to operate in "non-color managed" mode. Application authors should note: when no config is present (e.g. via ``$OCIO``), the default internal profile specifies ``strictparsing=false``, and the default color space role is ``raw``. This means that ANY string passed to OCIO will be parsed as the default ``raw``. This is nice because in the absence of a config, the behavior from your application perspective is that the library essentially falls back to "non-color managed". ``luma`` ++++++++ Deprecated. Optional. Default is the Rec.709 primaries specified by the ASC: .. code-block:: yaml luma: [0.2126, 0.7152, 0.0722] These are the luminance coefficients, which can be used by OCIO-supporting applications when adjusting saturation (e.g. in an image-viewer when displaying a single channel) .. note:: While the API method is not yet officially deprecated, ``luma`` is a legacy option from Imageworks' internal, closed-source predecessor to OCIO. The ``luma`` value is not respected anywhere within the OCIO library. Also very few (if any) applications supporting OCIO will respect the value either. ``roles`` +++++++++ Required. A "role" is an alias to a colorspaces, which can be used by applications to perform task-specific color transforms without requiring the user to select a colorspace by name. For example, the Nuke node OCIOLogConvert: instead of requiring the user to select the appropriate log colorspace, the node performs a transform between ``scene_linear`` and ``compositing_log``, and the OCIO config specifies the project-appropriate colorspaces. This simplifies life for artists, as they don't have to remember which is the correct log colorspace for the current project - the OCIOLogConvert always does the correct thing. A typical role definition looks like this, taken from the :ref:`config-spivfx` example configuration: .. code-block:: yaml roles: color_picking: cpf color_timing: lg10 compositing_log: lgf data: ncf default: ncf matte_paint: vd8 reference: lnf scene_linear: lnf texture_paint: dt16 All values in this example (such as ``cpf``, ``lg10`` and ``ncf``) refer to colorspaces defined later the config, in the ``colorspaces`` section. A description of all roles. Note that applications may interpret or use these differently. * ``color_picking`` - colors in a color-selection UI can be displayed in this space, while selecting colors in a different working space (e.g. ``scene_linear`` or ``texture_paint``) * ``color_timing`` - colorspace used for applying color corrections, e.g. user-specified grade within an image viewer (if the application uses the ``DisplayTransform::setDisplayCC`` API method) * ``compositing_log`` - a log colorspace used for certain processing operations (plate resizing, pulling keys, degrain, etc). Used by the OCIOLogConvert Nuke node * ``data`` - used when writing data outputs such as normals, depth data, and other "non color" data. The colorspace in this role should typically have ``data: true`` specified, so no color transforms are applied * ``default`` - when ``strictparsing: false``, this colorspace is used as a fallback. If not defined, the ``scene_linear`` role is used * ``matte_paint`` - colorspace which matte-paintings are created in (for more information, :ref:`see the guide on baking ICC profiles for Photoshop `, and :ref:`config-spivfx`) * ``reference`` - the colorspace against which the other colorspaces are defined * ``scene_linear`` - the scene-referred linear-to-light colorspace, often the same as the reference space (see:ref:`faq-terminology`) * ``texture_paint`` - similar to ``matte_paint`` but for painting textures for 3D objects (see the description of texture painting in :ref:`SPI's pipeline `) ``displays`` ++++++++++++ Required. This section defines all the display devices which will be used. For example you might have a sRGB display device for artist workstations, a DCIP3 display device for the screening room projector. Each display device has a number of "views". These views provide different ways to display the image on the selected display device. Examples of common views are: * "Film" to emulate the final projected result on the current display * "Log" to send log-space pixel values directly to the display, resulting in a "lifted" image useful for checking black-levels. * "Raw" when assigned a colorspace with ``raw: yes`` set will show the unaltered image, useful for tech-checking images An example of the ``displays`` section from the :ref:`config-spivfx` config: .. code-block:: yaml displays: DCIP3: - ! {name: Film, colorspace: p3dci8} - ! {name: Log, colorspace: lg10} - ! {name: Raw, colorspace: nc10} sRGB: - ! {name: Film, colorspace: srgb8} - ! {name: Log, colorspace: lg10} - ! {name: Raw, colorspace: nc10} - ! {name: Film, colorspace: srgb8} All the colorspaces (``p3dci8``, ``srgb8`` etc) refer to colorspaces defined later in the config. Unless the ``active_displays`` and ``active_views`` sections are defined, the first display and first view will be the default. ``active_displays`` +++++++++++++++++++ Optional. Default is for all displays to be visible, and to respect order of items in ``displays`` section. You can choose what display devices to make visible in UI's, and change the order in which they appear. Given the example ``displays`` block in the previous section - to make the sRGB device appear first: .. code-block:: yaml active_displays: [sRGB, DCIP3] To display only the ``DCIP3`` device, simply remove ``sRGB``: .. code-block:: yaml active_displays: [DCIP3] The value can be overridden by the `OCIO_ACTIVE_DISPLAYS` env-var. This allows you to make the ``sRGB`` the only active display, like so: .. code-block:: yaml active_displays: [sRGB] Then on a review machine with a DCI P3 projector, set the following environment variable, making ``DCIP3`` the only visible display device:: export OCIO_ACTIVE_DISPLAYS="DCIP3" Or specify multiple active displays, by separating each with a colon:: export OCIO_ACTIVE_DISPLAYS="DCIP3:sRGB" ``active_views`` ++++++++++++++++ Optional. Default is for all views to be visible, and to respect order of the views under the display. Works identically to ``active_displays``, but controls which *views* are visible. Overridden by the ``OCIO_ACTIVE_VIEWS`` env-var:: export OCIO_ACTIVE_VIEWS="Film:Log:Raw" ``looks`` +++++++++ Optional. This section defines a list of "looks". A look is a color transform defined similarly to a colorspace, with a few important differences. For example, a look could be defined for a "first pass DI beauty grade", which is used to view shots with a rough approximation of the final grade. When the look is defined in the config, you must specify a name, the color transform, and the colorspace in which the grade is performed (the "process space"). You can optionally specify an inverse transform for when the look transform is not trivially invertable (e.g. it applies a 3D LUT) When an application applies a look, OCIO ensures the grade is applied in the correct colorspace (by converting from the input colorspace to the process space, applies the look's transform, and converts the image to the output colorspace) Here is a simple ``looks:`` section, which defines two looks: .. code-block:: yaml looks: - ! name: beauty process_space: lnf transform: ! {slope: [1, 2, 1]} - ! name: neutral process_space: lg10 transform: ! {src: 'neutral-${SHOT}-${SEQ}.csp', interpolation: linear } inverse_transform: ! {src: 'neutral-${SHOT}-${SEQ}-reverse.csp', interpolation: linear } Here, the "beauty" look applies a simple, static ASC CDL grade, making the image very green (for some artistic reason!). The beauty look is appied in the scene-linear ``lnf`` colorspace (this colorspace is defined elsewhere in the config. Next is a definition for a "neutral" look, which applies a shot-specific CSP LUT, dynamically finding the correct LUT based on the SEQ and SHOT :ref:`context variables `. For example if ``SEQ=ab`` and ``SHOT=1234``, this look will search for a LUT named ``neutral-ab-1234.csp`` in locations specified in ``search_path``. The ``process_space`` here is ``lg10``. This means when the look is applied, OCIO will perform the following steps: * Transform the image from it's current colorspace to the ``lg10`` process space * Apply apply the FileTransform (which applies the grade LUT) * Transform the graded image from the process space to the output colorspace The "beauty" look specifies the optional ``inverse_transform``, because in this example the neutral CSP files contain a 3D LUT. For many transforms, OCIO will automatically calculate the inverse transform (as with the "beauty" look), however with a 3D LUT the inverse transform needs to be defined. If the look was applied in reverse, and ``inverse_transform`` as not specified, then OCIO would give a helpful error message. This is commonly done for non-invertable looks As in colorspace definitions, the transform can be specified as a series of transforms using the ``GroupTransform``, for example: .. code-block:: yaml looks: - ! name: beauty process_space: lnf transform: ! children: - ! {slope: [1, 2, 1]} - ! {src: beauty.spi1d, interpolation: nearest} ``colorspaces`` +++++++++++++++ Required. This section is a list of all the colorspaces known to OCIO. A colorspace can be referred to elsewhere within the config (including other colorspace definitions), and are used within OCIO-supporting applications. ``to_reference`` and ``from_reference`` --------------------------------------- Here is a example of a very simple ``colorspaces`` section, modified from the :ref:`config-spivfx` example config: .. code-block:: yaml colorspaces: - ! name: lnf bitdepth: 32f description: | lnf : linear show space - ! name: lg16 bitdepth: 16ui description: | lg16 : conversion from film log to_reference: ! {src: lg16_to_lnf.spi1d, interpolation: nearest} First the ``lnf`` colorspace (short for linear float) is used as our reference colorspace. The name can be anything, but the idea of a reference colorspace is an important convention within OCIO: **all other colorspaces are defined as transforms either to or from this colorspace.** The ``lg16`` colorspace is a 16-bit log colorspace (see :ref:`config-spivfx` for an explaination of this colorspace). It has a name, a bitdepth and a description. The ``lg16`` colorspace is defined as a transform from ``lg16`` to the reference colorspace (``lnf``). That transform is to apply the LUT ``lg16_to_lnf.spi1d``. This LUT has an input of ``lg16`` integers and outputs linear 32-bit float values Since the 1D LUT is automatically invertable by OCIO, we can use this colorspace both to convert ``lg16`` images to ``lnf``, and ``lnf`` images to ``lg16`` Importantly, because of the reference colorspace concept, we can convert images from ``lg16`` to the reference colorspace, and then on to any other colorspace. Here is another example colorspace, which is defined using ``from_reference``. .. code-block:: yaml - ! name: srgb8 bitdepth: 8ui description: | srgb8 :rgb display space for the srgb standard. from_reference: ! {src: srgb8.spi3d, interpolation: linear} We use ``from_reference`` here because we have a LUT which transforms from the reference colorspace (``lnf`` in this example) to sRGB. In this case ``srgb8.spi3d`` is a complex 3D LUT which cannot be inverted, so it is considered a "display only" colorspace. If we did have a second 3D LUT to apply the inverse transform, we can specify both ``to_reference`` and ``from_reference`` .. code-block:: yaml - ! name: srgb8 bitdepth: 8ui description: | srgb8 :rgb display space for the srgb standard. from_reference: ! {src: lnf_to_srgb8.spi3d, interpolation: linear} to_reference: ! {src: srgb8_to_lnf.spi3d, interpolation: linear} Using multiple transforms ------------------------- The previous example colorspaces all used a single transform each, however it is often useful to use multiple transforms to define a colorspace. .. code-block:: yaml - ! name: srgb8 bitdepth: 8ui description: | srgb8 :rgb display space for the srgb standard. from_reference: ! children: - ! {src: lnf, dst: lg16} - ! {src: lg16_to_srgb8.spi3d, interpolation: linear} Here to get from the reference colorspace, we first use the ``ColorSpaceTransform`` to convert from ``lnf`` to ``lg16``, then apply our 3D LUT on the log-encoded images. This primarily demonstrates the meta-transform ``GroupTransform``: a transform which simply composes two or more transforms together into one. Anything that accepts a transform like ``FileTransform`` or ``CDLTransform`` will also accept a ``GroupTransform`` It is also worth noting the ``ColorSpaceTransform``, which transforms between ``lnf`` and ``lg16`` colorspaces (which are defined within the current config). Example transform steps ----------------------- This section explains how OCIO internally applies all the transforms. It can be skipped over if you understand how the reference colorspace works. .. code-block:: yaml colorspaces: - ! name: lnf bitdepth: 32f description: | lnf : linear show space - ! name: lg16 bitdepth: 16ui description: | lg16 : conversion from film log to_reference: ! {src: lg16.spi1d, interpolation: nearest} - ! name: srgb8 bitdepth: 8ui description: | srgb8 :rgb display space for the srgb standard. from_reference: ! children: - ! {src: lnf, dst: lg16} - ! {src: lg16_to_srgb8.spi3d, interpolation: linear} To explain how this all ties together to display an image, say we have an image in the ``lnf`` colorspace (e.g. a linear EXR) and wish to convert it to ``srgb8`` - the transform steps are: * ``ColorSpaceTransform`` is applied, converting from lnf to lg16 * The ``FileTransform`` is applied, converting from lg16 to srgb8. A more complex example: we have an image in the ``lg16`` colorspace, and convert to ``srgb8`` (using the lg16 definition from earlier, or the :ref:`config-spivfx` config): First OCIO converts from lg16 to the reference space, using the transform defined in lg16's to_reference: * ``FileTransform`` applies the lg16.spi1d With the image now in the reference space, srgb8's transform is applied: * ColorSpaceTransform to transform from lnf to lg16 * FileTransform applies the ``lg16_to_srgb8.spi3d`` LUT. .. note:: OCIO has an transform optimizer which removes redundant steps, and combines similar transforms into one operation. In the previous example, the complete transform chain would be "lg16 -> lnf, lnf -> lg16, lg16 -> srgb8". However the optimizer will reduce this to "lg16 -> srgb". ``bitdepth`` ------------ Optional. Default: ``32f`` Specify an appropriate bitdepth for the colorspace, and applications can use this to automatically output images in the correct bit-depth. Valid options are: * ``8ui`` * ``10ui`` * ``12ui`` * ``14ui`` * ``16ui`` * ``32ui`` * ``16f`` * ``32f`` The number is in bits. ``ui`` stands for unsigned integer. ``f`` stands for floating point. Example: .. code-block:: yaml - ! name: srgb8 bitdepth: 8ui from_reference: [...] ``isdata:`` ----------- Optional. Default: false. Boolean. The ``isdata`` key on a colorspace informs OCIO that this colorspace is used for non-color data channels, such as the "normals" output of a a multipass 3D render. Here is example "non-color" colorspace from the :ref:`config-spivfx` config: .. code-block:: yaml - ! name: ncf family: nc equalitygroup: bitdepth: 32f description: | ncf :nc,Non-color used to store non-color data such as depth or surface normals isdata: true allocation: uniform ``equalitygroup:`` ------------------ Optional. If two colorspaces are in the "equality group", transforms between them are considered non-operations. You might have multiple colorspaces which are identical, but operate at different bit-depths. For example, see the ``lg10`` and ``lg16`` colorspaces in the :ref:`config-spivfx` config. If loading a ``lg10`` image and converting to ``lg16``, no transform is required. This is of course faster, but may cause an unexpected increase in precision (e.g. it skip potential clamping caused by a LUT) .. code-block:: yaml - ! name: lg16 equalitygroup: lg bitdepth: 16ui to_reference: ! {src: lg16.spi1d, interpolation: nearest} - ! name: lg10 equalitygroup: lg bitdepth: 10ui to_reference: ! {src: lg10.spi1d, interpolation: nearest} **Do not** put different colorspaces in the same equality group. For logical grouping of "similar" colorspaces, use the ``family`` option. ``family:`` ----------- Optional. Allows for logical grouping of colorspaces within a UI. For example, a series of "log" colorspaces could be put in one "family". Within a UI like the Nuke ``OCIOColorSpace`` node, these will be grouped together. .. code-block:: yaml - ! name: kodaklog family: log equalitygroup: kodaklog [...] - ! name: si2klog family: log equalitygroup: si2klog [...] - ! name: rec709 family: display equalitygroup: rec709 [...] Unlike ``equalitygroup``, the ``family`` has no impact on image processing. ``allocation`` and ``allocationvars`` ------------------------------------- Optional. These two options are used when OCIO transforms are applied on the GPU. It is also used to automatically generate a "shaper LUT" when :ref:`baking LUT's ` unless one is explicitly specified (not all output formats utilise this) For a detailed description, see :ref:`allocationvars` Example of a "0-1" colorspace .. code-block:: yaml allocation: uniform allocationvars: [0.0, 1.0] .. code-block:: yaml allocation: lg2 allocationvars: [-15, 6] ``description`` --------------- Optional. A human-readable description of the colorspace. The YAML syntax allows for either single-line descriptions: .. code-block:: yaml - ! name: kodaklog [...] description: A concise description of the kodaklog colorspace. Or multiple-lines: .. code-block:: yaml - ! name: kodaklog [...] description: This is a multi-line description of the kodaklog colorspace, to demonstrate the YAML syntax for doing so. Here is the second line. The first one will be unwrapped into a single line, as will this one. It's common to use literal ``|`` block syntax to preserve all newlines: .. code-block:: yaml - ! name: kodaklog [...] description: | This is one line. This is the second. Available transforms ******************** ``AllocationTransform`` +++++++++++++++++++++++ Transforms from reference space to the range specified by the ``vars:`` Keys: * ``allocation`` * ``vars`` * ``direction`` ``CDLTransform`` ++++++++++++++++ Applies an ASC CDL compliant grade Keys: * ``slope`` * ``offset`` * ``power`` * ``sat`` * ``direction`` ``ColorSpaceTransform`` +++++++++++++++++++++++ Transforms from ``src`` colorspace to ``dst`` colorspace. Keys: * ``src`` * ``dst`` * ``direction`` ``ExponentTransform`` +++++++++++++++++++++ Raises pixel values to a given power (often referred to as "gamma") .. code-block:: yaml ! {value: [1.8, 1.8, 1.8, 1]} Keys: * ``value`` * ``direction`` ``FileTransform`` +++++++++++++++++ Applies a lookup table (LUT) Keys: * ``src`` * ``cccid`` * ``interpolation`` * ``direction`` ``GroupTransform`` ++++++++++++++++++ Combines multiple transforms into one. .. code-block:: yaml colorspaces: - ! name: adx10 [...] to_reference: ! children: - ! {src: adx_adx10_to_cdd.spimtx} - ! {src: adx_cdd_to_cid.spimtx} A group transform is accepted anywhere a "regular" transform is. ``LogTransform`` ++++++++++++++++ Applies a mathematical logarithm with a given base to the pixel values. Keys: * ``base`` ``LookTransform`` +++++++++++++++++ Applies a named look ``MatrixTransform`` +++++++++++++++++++ Applies a matrix transform to the pixel values Keys: * ``matrix`` * ``offset`` * ``direction`` ``TruelightTransform`` ++++++++++++++++++++++ Applies a transform from a Truelight profile. Keys: * ``config_root`` * ``profile`` * ``camera`` * ``input_display`` * ``recorder`` * ``print`` * ``lamp`` * ``output_camera`` * ``display`` * ``cube_input`` * ``direction`` .. note:: This transform requires OCIO to be compiled with the Truelight SDK present. opencolorio-1.1.0~dfsg0.orig/docs/userguide/contexts.rst0000644000175000017500000002617413223553423021625 0ustar mfvmfvContexts ======== OCIO's allows different LUT's or grades to be applied based on the current context. These contexts are usually based on environment variables, but also allows on-the-fly context switching in applications that operate on multiple shots (such as playback tools) Typically these would be used as part of the display transform, to apply shot-specific looks (such as a CDL color correction, or a 1D grade LUT) .. _context_per_shot_luts: A contrived example ******************* The simplest way to explain this feature is with examples. Say we have two shots, ``ab-123`` and ``sf-432``, and each shot requires a different LUT to view. The current shot name is stored in the environment variable SHOT. In the OCIO config, you can use this SHOT environment variable to construct the LUT's path/filename. This path can be absolute (e.g ``/example/path/${SHOT}.spi1d``), or relative to any directory on the OCIO search path, which includes the resource path (e.g ``${SHOT}.spi1d``) This is a simplified example, to demonstrate the context feature. Typically this "contextual LUT" would be used in conjuction with other LUT's (e.g before a scene-linear to log transform, followed by a 3D film emulation LUT), this will be covered in :ref:`context_per_shot_grade` So, we have our empty OCIO config in ``~/showcfg``, and our two LUTs in ``~/showcfg/luts`` which are named ``af-123.spi1d`` and ``sf-432.spi1d``:: ~/showcfg/ config.ocio luts/ af-123.spi1d sf-432.spi1d In the config, we first specify the config version, and the resource path (usually this is relative to the directory containing ``config.ocio``, although can be an absolute path):: ocio_profile_version: 1 resource_path: luts Next, we define a colorspace that transforms from the show reference space to the display colorspace: .. code-block:: yaml colorspaces: - ! name: srgb8 family: srgb bitdepth: 8ui from_reference: ! {src: ${SHOT}.spi1d} Then add a display alias for this transform: .. code-block:: yaml displays: - ! {device: sRGB, name: "Shot LUT", colorspace: srgb8} Finally, we point the OCIO env-variable to the config, set the SHOT env-variable to the shot being worked on, and launch Nuke (or any other OCIO-enabled application):: export OCIO=~/showcfg/config.ocio export SHOT=af-123 nuke In Nuke, we create an OCIODisplay node, select our "sRGB" device with the "Shot LUT" transform, and this will apply the ``af-123.spi1d`` LUT. .. _context_per_shot_grade: Per-shot grades *************** Similarly to LUTs, we use a ``.cc`` file (an XML file containing a single ASC CDL ````), or a ``.ccc`` file (an XML file containing multiple ASC CDL color corrections, each with a unique ID) The ``.cc`` file is applied identically to a regular LUT files, using a ``FileTransform``. For example, if we have ``af-123.cc`` in the ``luts/`` directory: .. code-block:: xml 2 1 1 0 0 0 1 1 1 1 We wish to apply this grade on the scene-linear image, then transform into log and apply a 3D print emulation LUT. Since this requires multiple transforms, instead of using a single ``FileTransform``, we use a ``GroupTransform`` (which is is just a collection of other transforms): .. code-block:: yaml colorspaces: - ! name: lnh family: ln bitdepth: 16f: isdata: false - ! name: lg10 family: lg bitdepth: 10ui isdata: false to_reference: ! {src: lg10.spi1d, interpolation: nearest} - ! name: srgb8 family: srgb bitdepth: 8ui isdata: false from_reference: ! children: - ! {src: ${SHOT}.cc} - ! {src: lnh, dst: lg10} - ! {src: film_emulation.spi3d, interpolation: linear} A .ccc file is a collection of ````'s. The only difference is when defining the ``FileTransform``, you must specify the ``cccdid`` key, which you can also construct using the context's environment variables. This means we could create a ``grades.ccc`` file containing the grade for all our shots: .. code-block:: xml 2 1 1 0 0 0 1 1 1 1 0.9 0.7 0.9 0 0 0 1 1 1 1 And the colorspace definition to utilise this: .. code-block:: yaml - ! name: srgb8 family: srgb bitdepth: 8ui isdata: false from_reference: ! children: - ! {src: grades.ccc, cccid: ${SHOT}} - ! {src: lnh, dst: lg10} - ! {src: film_emulation.spi3d, interpolation: linear} .. _context_complete_example: A complete example ****************** .. warning:: This is incomplete, the lnh_graded space is likely wrong The context feature can be used to accommodate complex grading pipelines. In this example, we have a "neutral grade" for each shot, to neutralise color casts and exposure variations, keeping plates consistent throughout a sequence. To view a shot, we reverse this neutral grade, apply a "beauty grade", then apply the display transform (the usual lin-to-log and a film emulation LUT) We will use the same two example shots from before, af-123 (which is in the af sequence) and sg-432 (in the sg sequence). Imagine we have many shots in each sequence, so we wish to put the grades for each sequence in a separate file. Using the same directory structure as above, in ``~/showcfg/luts`` we first create two grade files, ``grades_af.ccc``: .. code-block:: xml 2 1 1 0 0 0 1 1 1 1 1.5 1.2 0.9 0 0 0 1 1 1 0.8 And ``grades_sg.ccc``: .. code-block:: xml 0.9 0.7 0.9 0 0 0 1 1 1 1 1.1 0.9 0.8 0 0 0 1.2 0.9 1.5 1 Next, we create the ``config.ocio`` file, containing a colorspace to define several colorspaces: * ``lnh``, the scene-linear, 16-bit half-float space in which compositing will happen * ``lg10``, the 10-bit log space in which material will be received (e.g in .dpx format) * ``srgb8``, the display colorspace, for viewing the neutrally graded footage on an sRGB display * ``srgb8graded``, another display colorspace, for viewing the final "beauty grade" .. code-block:: yaml ocio_profile_version: 1 # The directory relative to the location of this config resource_path: "luts" roles: scene_linear: lnh compositing_log: lgf displays: # Reference to display transform, without reversing the working grade - ! {device: sRGB, name: Film1D, colorspace: srgb8} # Reference to display, reversing the working grade, and applying # the beauty grade - ! {device: sRGB, name: Film1DGraded, colorspace: srgb8graded} colorspaces: # The source space, containing a log to scene-linear LUT - ! name: lg10 family: lg bitdepth: 10ui isdata: false to_reference: ! {src: lg10.spi1d, interpolation: nearest} # Our scene-linear space (reference space) - ! name: lnh family: ln bitdepth: 16f isdata: false # Neutrally graded scene-linear - ! name: lnh_graded family: ln bitdepth: 16f isdata: false to_reference: ! {src: "grades_${SEQ}.ccc", cccid: "${SEQ}/${SHOT}/neutral"} # The display colorspace - how to get from scene-linear to sRGB - ! name: srgb8 family: srgb bitdepth: 8ui isdata: false from_reference: ! children: - ! {src: lnh, dst: lg10} - ! {src: lg_to_srgb.spi3d, interpolation: linear} # Display color, with neutral grade reversed, and beauty grade applied - ! name: srgb8graded family: srgb bitdepth: 8ui isdata: false from_reference: ! children: - ! {src: "grades_${SEQ}.ccc", cccid: "${SEQ}/${SHOT}/neutral", direction: inverse} - ! {src: "grades_${SEQ}.ccc", cccid: "${SEQ}/${SHOT}/beauty", direction: forward} - ! {src: lnh, dst: srgb8} opencolorio-1.1.0~dfsg0.orig/docs/userguide/index.rst0000644000175000017500000000053713223553423021060 0ustar mfvmfv.. _user-guide: User Guide ========== These guides will focus on a specific task (for example, writing a basic config, or setting up per-shot LUT's). For a "broader picture" expiation of how to use OCIO, see the :ref:`configurations` section .. toctree:: :maxdepth: 2 tool_overview baking_luts contexts looks config_syntax opencolorio-1.1.0~dfsg0.orig/docs/userguide/looks.rst0000644000175000017500000001362613223553423021103 0ustar mfvmfv.. _userguide-looks: Looks ===== A "look" is a named color transform, intended to modify the look of an image in a "creative" manner (as opposed to a colorspace definition which tends to be technically/mathematically defined). An OCIO look typically exists as a flexible addendum to a defined viewing transform. Examples of looks may be a neutral grade, to be applied to film scans prior to VFX work, or a per-shot DI grade decided on by the director, to be applied just before the viewing transform. Looks are defined similarly to colorspaces, you specify a name and a transform (possibly a GroupTransform containing several other transforms), and optionally an inverse transform. Where looks differ from colorspace definions are in how they are applied. With a look, you also specify the "process space" - the colorspace in which the transform is applied. Example configuration ********************* **Step 1: Setup a Look** A look is a top-level OCIO configuration object. Conceptually, it's a named transform which gets applied in a specific color space. All of the changes below to the .ocio configs can be done manually by editing the text, or using the Python API. Example look definition in a OCIO config: .. code-block:: yaml looks: - ! name: di process_space: rclg16 transform: ! {src: look_di.cc, interpolation: linear} Example Python API call: .. code-block:: python look = OCIO.Look(name='di', processSpace='rclg16') t = OCIO.FileTransform('look_di.cc', interpolation=OCIO.Constants.INTERP_LINEAR) look.setTransform(t) config.addLook(look) The src file can be any LUT type that OCIO supports (in this case, it's a file that contains the ```` element from a CDL file.) You could also specify a .3dl, etc. Once you define a look in your configuration, you'll see that the ``OCIOLookTransform`` node in Nuke will provide the named option. In this example, the 'DI' look conceptually represents a look that will be applied in DI. Other look names we often used are 'onset', 'editorial', etc. The ``process_space`` specifies that the transform should be applied in that space. In this example, if you provide linear input to the ``OCIOLookTransform`` node, the pixels will be converted to ``rclg16`` before applying the ``look_di.cc`` file-transform. **Step 2: Update the Display to use a look.** You can specify an optional 'looks' tag in the View tag, which will apply the specified look(s). This lets application in the viewer provide options which use the looks. Example YAML config: .. code-block:: yaml displays: DLP: - ! {name: Raw, colorspace: nc10} - ! {name: Log, colorspace: rclg10} - ! {name: Film, colorspace: p3dci16} - ! {name: Film DI, colorspace: p3dci16, looks: di} sRGB: - ! {name: Raw, colorspace: nc10} - ! {name: Log, colorspace: rclg10} - ! {name: Film, colorspace: srgb10} - ! {name: Film DI, colorspace: srgb10, looks: di} Example Python API call: .. code-block:: python for name,colorspace,look in [ ['Raw','nc10',''], ['Log','rclg10',''], ['Film','p3dci16',''], ['Film DI','p3dci16','di'] ]: config.addDisplay('DLP',name,colorspace,look) for name,colorspace,look in [ ['Raw','nc10',''], ['Log','rclg10',''], ['Film','srgb10',''], ['Film DI','srgb10','di'] ]: config.addDisplay('sRGB',name,colorspace,look) Option for advanced users: The looks tag is actually a comma-delimited list supporting +/- modifiers. So if you you wanted to specify a View that undoes DI, and then adds Onset, you could do "-di,+onset". **Step 3: Get per-shot looks supported.** In the top example, look_di.cc, being a relative path location, will check each location in the config's search_path. The first file that's found will be used. So if your config contains:: search_path: luts ... then only the 'luts' subdir relative to the OCIO config will be checked. However if you specify:: search_path: /shots/show/$SHOT/cc/data:luts ...the directory '/shots/show/$SHOT/cc/data/' will be evaluated first, and only if not found will the 'luts' directory be checked. env-vars, absolute, and relative paths can be used both in the config's ``search_path``, as well as the View's src specification. Example: .. code-block:: yaml - ! name: di process_space: rclg16 transform: ! {src: looks/$SHOT_di/current/look_$SHOT_di.cc, interpolation: linear} Note that if the per-shot lut is not found, you can control whether a fallback LUT succeeds based on if it's in the master location. You can also use this for multiple levels (show, shot, etc). Advanced option: If some shots use .cc files, and some use 3d-luts currently there's no simple way to handle this. What we'd recommend as a work around is to label all of your files with the same extension (such as .cc), and then rely on OCIO's resiliance to misnamed lut files to just load them anyways. Caveat: this only works in 1.0.1+ (commit sha-1: 6da3411ced) Advanced option: In the Nuke OCIO nodes, you often want to preview looks 'across shots' (often for reference, same-as, etc). You can override the env-vars in each node, using the 'Context' menu. For example, if you know that $SHOT is being used, in the context key1 you should specify 'SHOT', and the in value1 specify the shot to use (such as dev.lookdev). You can also use expressions, to say parse a shot name out of ``[metadata "input/filename"]`` Advanced option: If you are writing your own OCIO integration code, ``getProcessor`` will fail if the per-shot lut is not found, and you may want to distinguish this error from other OCIO errors. For this reason, we provide OCIO::ExceptionMissingFile, which can be explicitly caught (this can then handled using ``OCIO::DisplayTransform::setLooksOverride()``). I'd expect image flipbook applications to use this approach. opencolorio-1.1.0~dfsg0.orig/docs/userguide/tool_overview.rst0000644000175000017500000001205613223553423022653 0ustar mfvmfv.. _userguide-tooloverview: Tool overview ============= OCIO is comprised of many parts. At the lowest level there is the C++ API. This API can be used in applications and plugins Note that all these plugins use the same config file to define color spaces, roles and so on. For information on setting up configurations, see :ref:`configurations` The API ******* Most users will never directly interact with the C++ API. However the API is used by all the supplied applications (e.g :ref:`overview-ocio2icc`) and plugins (e.g the :ref:`overview-nukeplugins`) To get started with the API, see the :ref:`developer-guide` .. _overview-ociocheck: ociocheck ********* This is a command line tool which shows an overview of an OCIO config file, and check for obvious errors For example, the following shows the output of a config with a typo - the colorspace used for ``compositing_log`` is not incorrect:: $ ociocheck --iconfig example.ocio OpenColorIO Library Version: 0.8.3 OpenColorIO Library VersionHex: 525056 Loading example.ocio ** General ** Search Path: luts Working Dir: /tmp Default Display: sRGB Default View: Film ** Roles ** ncf (default) lnf (scene_linear) NOT DEFINED (compositing_log) ** ColorSpaces ** lnf lgf ncf srgb8 -- output only ERROR: Config failed sanitycheck. The role 'compositing_log' refers to a colorspace, 'lgff', which is not defined. Tests complete. It cannot verify the defined color transforms are "correct", only that the config file can be loaded by OCIO without error. Some of the problems it will detect are: * Duplicate colorspace names * References to undefined colorspaces * Required roles being undefined * At least one display device is defined As with all the OCIO command line tools, you can use the `--help` argument to read a description and see the other arguments accepted:: $ ociocheck --help ociocheck -- validate an OpenColorIO configuration usage: ociocheck [options] --help Print help message --iconfig %s Input .ocio configuration file (default: $OCIO) --oconfig %s Output .ocio file .. _overview-ociobakelut: ociobakelut *********** A command line tool which bakes a color transform into various color lookup file formats ("a LUT") This is intended for applications that have not directly integrated OCIO, but can load LUT files If we want to create a ``lnf`` to ``srgb8`` viewer LUT for Houdini's MPlay:: $ ociobakelut --inputspace scene_linear --shaperspace lg10 --outputspace srgb8 --format houdini houdini__lnf_to_lg10_to_srgb8.lut The ``--inputspace`` and ``-outputspace`` options specify the colorspace of the input image, and the displayed image. Since a 3D LUT can only practically operate on 0-1 (e.g a Log image), the ``--shaperspace`` option is specified. This uses the Houdini LUT's 1D "pretransform" LUT to do "lnf" to "lg10", then the 3D LUT part to go from "lg10" to "srgb8" (basically creating a single file containing a 1D linear-to-log LUT, and a 3D log-to-sRGB LUT) To make a log to sRGB LUT for Flame, the usage is similar, except the shaperspace option is omitted, as the input colorspace does not have values outside 0.0-1.0 (being a Log space):: $ ociobakelut --inputspace lg10 --outputspace srgb8 --format flame flame__lg10_to_srgb.3dl See the :ref:`faq-supportedlut` section for a list of formats that support baking .. TODO: For more information on baking LUT's, see :ref:`userguide-bakelut` .. _overview-ocio2icc: ocio2icc ******** A command line tool to generate an ICC "proofing" profile from a color space transform, which can be used in applications such as Photoshop. A common workflow is for matte-painters to work on sRGB files in Photoshop. An ICC profile is used to view the work with the same film emulation transform as used in other departments. .. TODO: Link to more elaborate description .. _overview-ocioconvert: ocioconvert *********** Loads an image, applies a color transform, and saves it to a new file. OpenImageIO is used to open and save the file, so a wide range of formats are supported. .. TODO: Link to more elaborate description .. _overview-ociodisplay: ociodisplay *********** A basic image viewer. Uses OpenImageIO to load images, and displays them using OCIO and typical viewer controls (scene-linear exposure control and a post-display gamma control) May be useful to users to quickly check colorspace configuration, but primarily a demonstration of the OCIO API .. TODO: Link to more elaborate description .. _overview-nukeplugins: Nuke plugins ************ A set of OCIO nodes for The Foundry's Nuke, including: * OCIOColorSpace, transforms between two color spaces (similar to the built-in "ColorSpace" node, but the colorspaces are described in the OCIO config file) * OCIODisplay to be used as viewer processes * OCIOFileTransform loads a transform from a file (e.g a 1D or 3D LUT), and applies it * OCIOCDLTransform applies CDL-compliant grades, and includes utilities to create/load ASC CDL files .. TODO - Link to more elaborate description opencolorio-1.1.0~dfsg0.orig/docs/userguide/baking_luts.rst0000644000175000017500000003054313223553423022253 0ustar mfvmfv.. _userguide-bakelut: Baking LUT's ============ Sometimes it is necessary to write a color transform as a lookup-table file This is usually because an application does not natively support OCIO (unlike, say, Nuke which various OCIO nodes), but can load a LUT of some kind. This would currently include applications like Autodesk Flame, Adobe Photoshop, SideFX's MPlay (Houdini's "Image Viewer") Remember that baking a LUT is not a perfect solution. Different LUT formats have various limitations. Certain applications might apply LUT's differently (often incorrectly), and some formats simply cannot accurately represent certain transforms. Others might require carefully selecting shaper spaces and so on. Be sure to carefully test the generated LUT in the target application. Burning the LUT into a test image (such as Marcie!), and carefully comparing to a reference is often the only way to be sure a LUT is correct. Config-based baking ******************* This section assumes you have a working OCIO config. The config can either be specified by setting the OCIO environment variable:: bash$ export OCIO=~/path/to/spi-vfx/config.ocio Alternatively the config can be specified as a command-line argument to the ociobakelut command, ``--iconfig ~/path/to/spi-vfx/config.ocio`` These examples will use the :ref:`config-spivfx` config, specifically the following colorspaces * ``lnf`` - scene-referred linear light colorspace (reference colorspace) * ``lg10`` - film log colorspace (0-1 colorspace) * ``srgb8`` - sRGB display colorspace Remember these are just for the examples - you can of course use any config and any colorspaces Log-input display LUT +++++++++++++++++++++ Say we have a ``lg10`` image in MPlay (maybe a ".cin" film scan), and wish to view it in our main display colorspace, ``srgb8`` The available formats are listed in the ``ociobakelut --help`` - for MPlay, we use the "houdini" format (see :ref:`the FAQ` for a more detailed list) So, to create a LUT that transforms from ``lg10`` to ``srgb8``:: bash$ ociobakelut --format houdini --inputspace lg10 --outputspace srgb8 log_to_display.lut We could then load this LUT into MPlay and view a lg10 image correctly! (note that by MPlay tries to linearise ".cin" files by default, which can be disabled in the preferences, "Convert form 10bit Log") For most other applications, we could simply change the ``--format`` Shaper spaces +++++++++++++ Before we create a LUT to view linear-light images, it's important to understand shaper-spaces and preluts. The two main types of LUT's are 1D and 3D. Such LUT formats typically require input values in the 0.0-1.0 range. Such a LUT would be unsuitable for linear-light values input images (where values are often over 1) To address this, various LUT formats contain a smaller "prelut" (or "shaper LUT") which is applied before the main LUT. This is used to transform the input values into a 0-1 range (typically a linear-to-log type transform) In terms of color-transforms, the prelut transforms from "input-space" to "shaper-space", then the main LUT transforms from "shaper-space" to "output-space" Some formats do not support such a shaper LUT - these are typically used in applications which do not work with floating-point images (e.g Lustre often works with 10-bit integer DPX's, so it's natively supported "--format lustre" (3DL) format has no need for a prelut) Linear-light input display LUT ++++++++++++++++++++++++++++++ With shaper-spaces explained, lets say we have a ``lnf`` linear light image in MPlay, and wish to view it in the ``srgb8`` colorspace. To create this LUT accurately, without clipping, we will use the LUT's prelut to transform from ``lnf`` to ``lg10``, then the 3D LUT will transform from ``lg10`` to ``srgb8`` Sounds complicated, but the command is almost the same as before, just with the ``--shaperspace`` argument (and ``--inputspace`` changed, of course):: bash$ ociobakelut --format houdini --inputspace lnf --shaperspace lg10 --outputspace srgb8 lin_to_display.lut Allocation-based prelut +++++++++++++++++++++++ If your :ref:`allocation variables` are setup correctly, you can omit the ``--shaperspace`` argument, and a prelut will be automatically created based on the allocation vars (see the linked page for more information) Since the colorspaces in the config we are using (:ref:`config-spivfx`) have their allocation variables set correctly, we could simplify the ``lnf`` to ``srgb8`` bake command:: bash$ ociobakelut --format houdini --inputspace lnf --outputspace srgb8 lin_to_display_allocbased.lut This command creates a very different prelut to the explicitly specified ``--shaperspace lg10`` in the previous example. Explicitly specifying a shaper can produce better results, however the allocation-based prelut usually works nicely, and is convinient Note that allocation-var based preluts is baker-format dependant, and not all formats currently implement them Config-free baking ****************** You can perform baking without using a OCIO config. This means you don't have to create a temporary config just to, say, convert from one LUT format to another. Converting between formats ++++++++++++++++++++++++++ Say we have a houdini LUT named ``log_to_display.lut``. To convert this to a Flame compatible 3dl file, simply run:: ociobakelut --format flame --lut log_to_display.lut for_flame.3dl Reversing a 1D LUT ++++++++++++++++++ You can apply a LUT in reverse, and write this to a new LUT (this does not work for 3D LUT's, but will for 1D LUT's):: bash$ ociobakelut --format flame --invlut logtosrgb.3dl srgbtolog.3dl Creating a grade LUT ++++++++++++++++++++ You can create a LUT which applies CDL-compliant grades:: ociobakelut --format cinespace --slope 1.2 1.0 0.9 mygrade.csp Combining options +++++++++++++++++ These options can be used together, or used multiple times. For example, to perform a slope offset, then apply "mylut.csp", saving it out for Lustre:: bash$ ociobakelut --format lustre --slope 2.0 1.5 0.4 --lut mylut.csp output.3dl .. _userguide-bakelut-photoshop: ICC profiles (Photoshop) ************************ Photoshop is very focused around print and graphic-design, industries with very different color management concerns to modern feature-film VFX. As such, it can be a pain to integrate. The main issue is current versions of Photoshop (CS5) are only practical for working with 16-bit integer images (not floating point/linear-light images as is common in compositing software) The second issue is there is no simple way to load a simple 1D or 3D LUT into Photoshop (and its API does not make this easy either!) A working space +++++++++++++++ First, we need to decide on a colorspace to use for the images in Photoshop. This is the colorspace in which matte-paintings will be performed (likely a different colorspace that used for texture-painting, as these have different requirements) The working space should be a "0-1 colorspace", reversable, and for matte-paintings ideally allow painting values over "diffuse white" (in other words, to paint values over 1.0 when converted to linear-light in comp) This is a facility-dependant workflow choice. For this example we will use the ``vd16`` colorspace, as described by the :ref:`config-spivfx` Creating display LUT ++++++++++++++++++++ "Proofing profiles" in Photoshop can be used in a very similar way to a display LUT in applications like Nuke. This proof-profile can be used to apply a 3D color transform from the working-space to a display space (e.g transform from ``vd16`` to ``srgb8`` in the spi-vfx config) These proofing-profiles are ICC profiles - a rather print-specific technology and relatively complex format Luckily, ``ociobakelut`` can be used to create these... but, first, there are some important considerations: It is important to match the ``--displayicc`` option to the profile used for the display. Secondly, Photoshop has a lot of print-focused color-management options, some of which can cause problems. Determine display ICC +++++++++++++++++++++ On OS X, launch "System Preferences", open "Displays" and click "Color" tab. The currently active ICC profile is selected. If you just want something simple that "probably matches" a Linux machine, say, it is easiest to uncheck "Show profiles for this display only" and select the "sRGB IEC61966-2.1" profile. You can skip the rest of this section in this case. .. figure:: images/ps_icc/psicc_open_current_profile.png :align: center However, if you have a specific display-profile selected (maybe created by monitor-calibration software), you should do the following: Click "Open Profile", and right-click the icon in the top of the window, and click the folder: .. figure:: images/ps_icc/psicc_reveal_profile.png :align: center This reveals the current profile in Finder. You can drag the file onto a Terminal.app window to get the full path (or, type it manually) .. TODO: Is there a standard way to find this on Windows? Create the ICC profile ++++++++++++++++++++++ Almost done now. We can write the ICC profile! The full command is, using our example colorspaces of ``vd16`` and ``srgb8``:: bash$ ociobakelut --format icc --inputspace vd16 --outputspace srgb8 --displayicc /path/to/my/monitorprofile.icc --description "vd16 to srgb8" The first three options are the same as any other LUT:: bash$ ociobakelut --format icc --inputspace vd16 --outputspace srgb8 [...] Then we specify the display ICC profile:: [...] --displayicc /path/to/my/monitorprofile.icc [...] We can set the description (shown in Photoshop), and as the last argument, specify:: [...] --description "vd16 to srgb8" [...] Finally an argument for the output file: [...] vd16_to_srgb.icc If you selected the "sRGB IEC61966-2.1" display profile, you can omit the ``--displayicc`` argument (it defaults to an standard sRGB profile):: bash$ ociobakelut --format icc --inputspace vd16 --outputspace srgb8 --description "vd16 to srgb8" Loading the "display LUT" +++++++++++++++++++++++++ Last step is to load the ICC profile into Photoshop, and enable it. On OS X, these can be put into:: /Library/ColorSync/Profiles/ (or the equivelant directory in your home-directory) On Windows, right-click the profile and select "Install profile" Then on either platform, click "View > Proof Setup > Custom..." .. figure:: images/ps_icc/psicc_proof_setup.png :align: center Select your profile from the "Device to simulate" dropdown (the name is what you supplied with ``--description``): .. figure:: images/ps_icc/psicc_select_profile.png :align: center As pictured, selecting "Preserve RGB numbers", and deselecting "Simulate Black Ink" is a good starting point (see the next section on "Other color settings") Finally, you can load an image in your working space, and click "View > Proof Colors", or hit cmd+y (or ctrl+y) When active, the profile name is shown in the window title (e.g ".... (RGB/16#/vd16 to srgb8", where the part after the "#/" is the profile name, "RGB/16" indicates the current image mode) Other color settings ++++++++++++++++++++ (note this guide is based on Photoshop CS5, and written while checking the OS X version, although most of these apply similarly on Windows 7) It is usually possible to get a matte-painting to look identical in Photoshop as it does in a more VFX-friendly application such as Nuke. However, as mentioned Photoshop has a lot of color-management related options, many of which can impair the match between it and other applications. The operating system also has some controls (as seen before with the ColorSync display profile) The settings that require tweaking have a tendency to change with OS versions, Photoshop versions and the phase of the moon. The only way to be sure is to compare Photoshop side-by-side with a LUT-reference-image (ideally toggling between Photoshop and Nuke): .. figure:: images/ps_icc/psicc_itworks.png :align: center The most improtant settings are in the "View > Proof Setup > Custom ..." menu. The recommended "Preserve RGB" setting works sometimes. Other times disabling "Preserve RGB Numbers" and selecting "Rendering Intent: Relative Colorimetric" can be closer. It is safest to not assign a profile to the images you are working on - this is done by clicking "Edit > Assign Profile", and selecting "Don't Color Manage This Document". In closing, of course none of this matters if you don't have a calibrated monitor! opencolorio-1.1.0~dfsg0.orig/docs/userguide/images/0000755000175000017500000000000013223553423020457 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/docs/userguide/images/ps_icc/0000755000175000017500000000000013223553423021717 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/docs/userguide/images/ps_icc/psicc_reveal_profile.png0000644000175000017500000007417613223553423026623 0ustar mfvmfvPNG  IHDRy_1 AiCCPICC ProfilexwTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf&" pHYs   IDATx|\TlY;ؖ;.`t :?= =BI %{ z5mܫ\dIWw?i~W|IZݹ}v# DN:p%MQmǐMf[ [{ a}-[n b0/|xIĴ9548!Wc! %F劲ZG.]6mA(nKF}ұ (L'Fؼ=JI3*$#aO?5ۯkw.ϝ3o?~nǟ}hH0ș7}=zti.Ι7>i7CGؽPRbt ? ?cv}vOwSfp>5.UT70_BH PR46Q`h2e$!P҄ы 5Rܚ"&pJ ͇9O@qg#uvHܠ >shٲ߱cG`K/4qD0>/dZe2 +W⋰#|b`ҥ ~ iLxB ^xCիWBERa{J6A ;O׿5#;1:Gy$>xꪫ6SI&s1%NI7L'5^%ʀdϟxb.8mFhמ,?tر=@ܹ cI zŢ":saÛNX_}W F [+jݑ@[@ORx%}e?v8C!_۷&ïE?,jӮ熀K r :[_K\JW.xH`Y$^\Dҍ [xhN/thYTԩS'Y;KUÿ[_>h駟~͇~x)`#%Cvp 6lڵ륗^ZPPqbŹ}=CaǢq S0#hLc0U{>cnW^yveL!GRj :(F;ߒZb D7x#׿&[C\%ح!'x[#4F#p{}5ʃE Fk}{]zt ̜Q6uG^nmo';u !"]Lad'G:v% V<oQ|OfӐ},J;nSN3b^yMy6 Q ) X`UD#6zH\4aDezJI(% LdbO>轖*JT7u=Ĝ@p@Gz 6JD|7xs壆VGado?> /~O}GqL0YX 2~?_[v&{]BL$!0 ]|wܑ /vRˁGH8 <@袋ۼҕcV#0~9#łK4iO=T~\|nX'Ҥ)F0ayXDG 0~pNЏ?F ._NA+/Ĉvݚl44{rxѬ@r‹gLITbELدMOlulE [6ԿE:L+@L$ PU0A04p xH*NxTf05EyM4?{rӰ,yI&R ݚBgϞ,|4l ÓO>LkB_$c,,Zqq1뮋qY5フFKLvԒ& `n@:iH?GqY%=C`O2e̙R|ed3gx)w/Ewu[nO~ho/v+65,qң*TKUAX+Q?$ ' Wq1 FkP}VH+T38Gm۶e]ѣ,++Q}.X(WCYE0s6mQ`Ų&K-Y@-6-lR1o4IJZ7k6M yu܊_hu^t-H QXS{ˊu-nl(nXYb5%ҜhV.Jj/$1A%Ť#t#1d T!#  %$$U'?H?eltѧr >w޹'ܵXA/2-b׼UV&CoY1Y11 pT9B .bT\I%#$@A5 bܧɒQ9?|3莲5Vɢ͝;}`x;]_62Ja6I|47X8]3+@>C JE.4PҀx!`}:tk+3maa܎5 "iZ1b7Dx?a=ꫯT/` B {xe 4?dobKc bKfF80hr[#4AQ0s Ř׏cw}7Fj +yg3à(oC {.yw25B$tmo8}HY_U.rrZUliU@Vؙ`AX&re oeI(Zع\c SئȪE9@X W a $;Y iQfE skW@VC'hf R)"J@BIbr # 1 E xF@IF5$xKVvTpgr{XW?ep{fn?{$ >l\qB~AEرcU lc a0^Bf%ΐ0v`䴘 E r D#0OzhduHv2^( 1a 1؞y)JULǰ L=CQ 2PV&PrD,=\` ߕW^y.U=~w2FkBLhŌ鬳Ռ'3 V@T!vMYKY-(z8Vc$|EMi)Э{gonJwZ-8q^ڨEAK*rM[/XPhrIi* /,r0jukwÊ`aVe~9͚6,+۶]o bHV7ғX0RX #+)ᒀpcD (QЀ7$P!CVBa zhHg-4 LaWvBR@y7mgj } to8, #SŌŋq)fἂ)00Fа  Xo%7~hb2̦M=k3,0$J,`&Pk,0p|B W1NJ]kH;s7w^#RU\( *>Knq5)F7@NT^ SSBwY߽Ǹ kw*o.ܢ%mگq\Yn:ƘHE50w]Sz(0Y\̺A3O"`_06x bȜ]eOqk-XEK>2uEaaG3!ۤSCt)M^d6$AvwH~A+ȠZJ׬Iz\'M8{O :qָ&k=>M+VgL$MuUN^\`$P$J %GYJR\D$@#?%\'Yg D| L;Ȱ̪eHLj& BscnYb݂ A`"Y**4D!j #c&Ebshb$!)4XxF̼pE14^13J¾#!O\ -􃈞2?Tzճf[:ٳUyuC*ϩXhܚJ΃YnE4$h-CA 0p!Y8P>gą+f*aK/ڪEm:ٶ}ʅ޸'I(K?"!PXxbJ'&+K“e% bJ($?rä#;|¥~qsh>}t'e ]~ғ\Z&#,_q*>󒰎cMuٳڵkI!<\t u0#Aᣅ-]EKo5 0ig>HS>>+aa8z!v߰*]44ʩ)Xjk|Շ Ҹ tmiN0wlZK&?u~M;"oOVjmPD0gi9G{~ޛ"[46uiܩoU3eaveY&pnFQtn/g.: KXʛ.}}=bF8N럠"풫T:4;RhȎ}rf/f](~|Mi`~M 7C'Ʋn PbjhA}`.ul?Z7 螓4 q-k>tD\V<\-vZ<5Z6\BXopE580ܮݩ-D+d:y"yq6}yF:PoLɢxKx3oـ/ +<1dž]|1ٳ5ZyD&Ύ`ѱMhds"B^+T.I0%XVTIB w\,,!EWbGL*h:ؼ x+孈xKmI*G|6z x~Ͷ+-GM%NF /_C7cKܓF U ٳ'o U /l^M,5J FTrJ2zb<'oJ29$T%:|55̇+N?K_N |@E+M9/>6oМw9sqt˜g8l܉s"S,11WUp:4/|^" ު nXلx[?D.<68rXE9wP5 §wƆ*%k2{N>pNɿ8OUW|8!*e+5 / I$S\c&0Y!K@y_-7 Ԡn9S.6^o*&[Y-M׆\ͯlMiyWT.t꣇,Wgnt .ď403Ruv&KVTg*?2Τ: 11 5kXw2Ms,0F=zRboc.+Y.wDG˗Cl"\EߋB?LN.w7aAȰr7شeX qY5Ͳg::+ a~<F6d[.[ ~,&uYrVvW'?~?.x羽ouA'Lޣ}?xA#_x?d6 y{}KFOčW̯'Lҥ?Qb܏BczY]7 |M _bA;ı }Msŋv-(p*gvM <䧓ulJi^9k.l*:LmA~ikEgkBPx_E<* qY'cFk.#!nL4_|ṡC0x#ƿK쑣KKwAdZx1@%pˋٜ`mex/zh~&&9+c^a/|?lވiϋպoYz %ҵIȤfI%cjl+{زOe;&M~ۭ7|3fԹF!~UFzƛX%+ H:2>CcQ34poxk[tC+ІPq$1،Jʌ|$F!?wy{?#֭;)v|W*8<_?S~189˗-%͌ӛ6mr'B x ~m|ⳳ [[BT]'Es󹃲jP7LAhy&'2y-y萶ڡ>6`wL9K'ʳ5gҥGvlE\O>$Q͵*.^gV xsؕ7kޫ7ZVMOnkǞ< _nUi7b~sR>ڹlٲm٦ tڕng|ҋ  tb>ٚ󚆬V[傣=kK$tV֕mV [PmݻwܥK{_4ޤG5I!5P L,ta֠/,[-o-%d$h-bybkҩXk,F%'`BxM ry8(Z+JLd,S:M@rINfr&qW\qEi&gyh'UnqpR_] H3Ւz,ᅬEejQ&3, WK x^W>S`6[ JXV-ؚ+VK{o ŗ<:97={c,|;lt;1G>K{`.R:eQV}ŦWUC,᭲rzh,UEH0d28!R5 YxxnYL{y͛7go3ϔ N:!Aq#>K|} s+W7z H{BL އ1+!b4%cY`]CP>^jo>A!Vua\2E/ibSBZH%IƘJ`dkZt^sG.\SOuuf ujkNxssG<{G"AC+#ZqN[8ެJVS-|=>5H1kpc1"Sr}X- Kboqvm^z)I^9@k(]_ŋvaW^y%˴/KY\\N:$ٳg?~xy͘1oyO8Yfw}p!.$b|RX?&FSj >Ҕlh b}@RSܽ6yyV k&mKrIUJ17>&=d1^]DI,IuiTG0&<>aXOLZR.bh΃\ven>|~̙/Y?Bb&E }r<2yO ZtM C;3*M;J5c]{^'<9b$`aa_^X(C.zW?1c;]JyW@^6ɗ\r 3M)T$v>RUFH0>$I* xɒ#$}2td!q@ HB&FECO3<>S ())&>aRqY't .>-ǞZecU uLG+<{ECZ@żz9M~n/Wqq, W7ވ`r)`Ya2@L;#i f IJLV#ZE[Air)>'@g5;%8cm\$"@%khpaek=Z%3o!m H|24а?ߟ IDATcO%ZҠh:VO[&DTKj'k~uf\| "4i4hiR. {z׀ƀȆ௼<o߾nAX  <ܲեqf_6[l5P5ح+J>7,:<Vx[~^C[osyӡd[G TtY[5J8y-N |%lFnF~2)|üwϯDk۪wM|0' 8=qAy6q|)$ⷲ3P#ox+{U=QI}twCIw6Ѫz&Dvk!]*PѸ VćLV#"4 |M22=ljd@J88?G}sQ- L,fBẺoe,n]ͪAnyݺk(_5M𾢍1aÒ+2 "2#)&KbkښI&q q7wQ9lS'>uk 5PFvTWLPܵsGVf*) <4 -@Lu >[MM\db-W&,8,Ӝ,B IXa ,2r]b~.T >F}\ouE:ssӇ>%XjKf'{tvL3lVIXD="MOtm֣nlI35.ƛPH_YF&jjqIa.*hOЕ;dT`W݇`9:_ 8 k4JHQenk#?(dP;,Lg^OG`O u1zR/,LXVjgWՈUMBv-E.K8HX3g$Ȕ$xcA` CHb'#C搧7ءݺjlJ\dz XeqE7X\15~о}{nIc8ʋQ\+.W=C yUǕ+nK&^>ԡg}Vw|`|H.E>|=&M)r}TEܱ H80庱e! X!JrXd4 V"MǓI29714yM|'L\x^-..f6MdE> ^`k&p&7<\뤇z(*#?/ Fw?ݵ^$3u[,WLjY_w֭ג/YL2Fs]gŴE_X@Oߣ 녱7LnƱGxy죃K{𬹚++^Ƃ.j! X SXYⵤ$vYDI,b !%Ј|` K|R&`Vo w1?5nÜUKz*Z f襗O4RTNĕC̍f;'1c=Xlqg.v{,.,Cdx߰q팏 W탪 &lY pZAm߇a! F @fu7 Bˊ@4Jhx" c܎ϙeË/\* |\`U3=2x^~6x$Wj՜(S3#ʍM ɐ>!G3Ja 2: *)Ydeɚ%%+W))YZ뢱*ڇ=;XČ_nhk:QՒY(OcH \,!B'j`#& @. eH!&c+ha@KidZÓd\W5JF5i.&^%gcb~ٲeɔJ%*)æ89AWZՖ46tO'6Rd=;7 ´E$6 {cWrw xnA'C7yc񸳧`y~cxJϹo&׆>$e<,6kS/5HaD l\c-```,"i\%%taW<c*\,fѼ&*u#cmƐb=C"iC**0F\_8 a\"N&B= GI]J_/K' 8շW:qD[q8!&rY풅b̌2qØ0p#a8`r)#Pƒ1ak^+XJĖ#PGiҌŤM09>%1u8 ?lfUjz&( 7UCPk*"\^Cһ&ĝqƆ>N^e@bf!?ؾw-@h0\^C|bʳ۳eCmfہd~%,yRԨfFUD׍-D5dFkFWۭULḾ&Ns%(G J>MAlH3$3Ld}W c_dԔsiPiPaMkfbO71> 7spEgq[[@D?'0?b+@VceTI4Ul7G=3L*|M> hvB bΘ-@ps1,`<ٮ~0UL8‹D SNہƶ a duo-5S+i 4$L<5ob8X:a)[1Y(3LIS%GX,Bqq1[| pc8D`=Y{X0J$M` x둥!7LS̹溘C;̏jV=ˉ$ :*0VVYP .S̅Q[wY af0@pxS |8ي7le@o칾'Mۜ4/-YU$Ě]l{ `aS^ƒԃH?dF)bd@h HVA,WY08˜ NM +@ޡǦ/́(9 9șrgg)^IbW`r T΋E (R| %ˇ&ȕc <ei0?_B-BH.$\nvB7>$؇u%gW]O&ټ$>NrL +\}+, <"^>.2{紩AՌޞk< KЌǚv)Ae.$حB^whX1UՑ+*+J 郍Z0"X .Rt)EQ1C Û)Xe`#Ԇfg>A?l ģ OG*` cKPw0nʋ!08:J-{HK0$ʂRYꤖl5u ݤM-?f\gaUSkO˂@bMIJe$[ы+ B xEREO'650(eРʢ a|嗳;k\j{852}G`E0`Q.7 2#~\T0.0"h81YEVjBLN"Ff˞ʄx'k0.#%:(6?|Bj|z%;F^γ%ާML;#sÜ 3Ff #2!c' =pvqG)Z0nR|7@sJOFg>7ܤ=F<YuUr5%e7 %7W]+8YgMݝ"Lm #a,\3Q1A =d OwUL鸜1o(1U>m1$٘Zn& ~{Z L%Cz=,K^}(4jC"Ls!t7Lt`bWG`|nrijCB+|e.ètb"H bXn2r{pzHrFk(6{68gO%^}Kl-λ9⥒q+VXB_TbSr̘1lpy}q!M  3&5,8`м<~DĖ2 %Ҋ{p k„ $Y:t($&z'!Œ9c p%2Gld>=[*K&*^MvXg\.Fp4q /PIDx#1׊H"`y4e}&oEe%DJI7LQ(ga|&W-$WyѪV[>mg8I>8RSv'Ti¡RFf5᷇/c, r:*-}ęYyRΑ(0UQOѼʱRHB>s4x74i g]PZUښq&ׅ-aV GR)Lm߽¾BÉJX0p&KAbQ|Sb|&}HVS BR.CX"}:8v0pG73)+,VLG+Xq{Ne|A^V>]DS;Q{#(/. G)EÔi:Rԑ-|HNVY(df@8Ï!f#F 0 gg3Jv1L~>%Ƽ7x/8s2-u(2F<KN>Y3NKQ)̓dBϊFPgJGiފ1Y[Pf@ EuHiy<"!.xsϹw97s &p巗6۲2+l,>N=߷ĂB`H]d7 R298?ügyƧ/F]ZcD5Xy aMk1l^B_45uڼ8 a&\7\ĄJc8`t"e {D0evd1{'+Ą/xvL<矷"@hHspO`SsHqY4ZӃ Ws$5ЍZ(/%,ːO7FP]z{&r +b:JBH\}Ħક,:( ~&\:x EqyExM ž{̋cV&3@L'6߉$on0xYHÄ#ҽ4&6vp4;I\-8&iyu,ܱxRIr I\3g9%1cR4 Y0%abLNc!mv+2O<*Ekc8,ʼ2x/eu+ 4^]~& @4 L7 LnB fk\2^>&pد+ŤRٳgHf {.T)&cv@Rh cP@.V:Iax$Y؅{)b>0(R2BX:_&ɨ%-9 LvUbt]d0'\0G QƷzx8zy籋DAo)\Qjd[( (Ν2{,q$lNt0&%0X, -e*'dܕ/2G7c :䷂"^en0|I=!qwV30n|-G[ш/G#۟j}aiLXD&*in\V2F,; Z,Q|Qea98Ml:Я|t B9ژГIn5. CBՄQL!VcO* I*ɒ1.7 ʭbDd8 Qc8^47mh$C G8,e0L2dJ]sg"wB ɄL֘>6,`ɲ=/yak%ߞ+47<ǯtKvuFP%lhb `2в[QQaĎgnr>dvJVK lCHIl%Y%E@0zx ~9X+&jLD5Jac E F#]H2L9V,Ʊ5Ղϔ)Y"1{I^f`hʼE2'#kr%@aĄHޕe`LHb|asz;}>٤3C b2qڥflNOaST\<̷{';!٢딀Z^:m:. $SKZ-$n*2F.O~RLXdFk(\HK%Pั7 N[pJ*v^Y948{/_ya#MՒ./Hm<$v%Y.oO(3Ԑ(%35,YH!f}kW0= 8pŗeL<~Kb:s2BiFm fxKNYıJltUHGTCq tF ޞ2hĮ\+%͒K/إCCK)dmڴiV@F &Uy2Lm Kf4MWI-R7٘P7!q*9xm԰یu^>>E17 ^+a\NGW[6^VA. xK`)r}$}{\iPH d /d Wxsrv&#[# :Ƴ˖6Žj*R&`.B_GokSȯ{(VG$VŕF c7|@5z F`hX⪯ؕX +L%ZR'͵RLdxHx#&5G#sոa4pO\KXJgЧ8!PZ .1&J+G^a9Sja55/:HI7˧v V0]2feHe)$& f殀SAkZŎ%8K6 'OqB/0 p|2^ 6Vd;'t͂ǟ6Jr58a i@-V'd 6,XRR#}I\ X8ui7^ f]ͷ][G $ xVs G#5ݺϙZCV-oOܡ˰o׆HMn-Pw&,߰! ] pԽo/l]}{*hS6{߰ʺiX?(zՙa9G!P%0K(_]˩E^-Sb  xMn-ٚmtjt3 Rp}o|:(̛xE+f [?nz8B0nM<}57c ,xyw>]0e^m' PW%Ob%ood<[Ӥi򕫷J6an|GU* ]Vav7BCmb݆ww*n clLzr>]>5.U}π[#{yJ01=/EG.K:> }Ҷdk]0wDW~3*5$zy W̼A>[4 +>61HxuY /4?W-]jRYj5$JyM}î&7?x@۝h¬Oh6D1fv{Yѫ(" "x Ty<@mY&ۈ; (!"x!d7}s7hOӧթіAAz, UС%S-,^KN;-Uȩdw?8c҆7/{EfNxwxvWm]%^~[pmq"'XfB8gEo};焺͇5rFAW3AǠIR7'3@X\.;z]iW-2nML sYYv4d`-,C݈=w*rI &Yj_EN!᫠z]r/)!5-(v_&]w%(|JnF9r1پ[7yl,\Z] r@`G֌q͹b'@,I JW_|y㵇>'?g][|սH}!}? [G#E`[wErk5oa9?wX.> q*=>q &\BEd'. !v!WY|)"b3+CAvǺ5MCzp9Њʕ+pGJLjdE?%2#+8x$BS%\튍y*$$+M(ͽ~uPK/_֕0a&%_Khh`jU;^aa_40SřԞ/:W`3]3;44 GmgϞ,'\O.sJ ≿[7.w "0aʨ:9>5uv9L([Ig{+|?oXq1{ ~ pՑ4 IR%s8<|OyAF};8DTʈ!pUY !H/QCతq$$*+r .J5VBtxkL@,0ϟ ftL_ 44[*|8."hdrJ`rǥ슙*J(YYESh͓%IENDB`opencolorio-1.1.0~dfsg0.orig/docs/userguide/images/ps_icc/psicc_proof_setup.png0000644000175000017500000002656013223553423026164 0ustar mfvmfvPNG  IHDRa@DQ AiCCPICC ProfilexwTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf&" pHYs   IDATx`UEր_zhRA@@DXk[QWWeEQqi?XRD`W@z@!7#1^=s̹gfΜ93^ _ KkNԀpv:Q,]&]w0 u絅ĺ [?"!1aof2e c[ivt Aӑ-'4mzq|m2uؔ)b5|m67Xp?i|ͷD]}{رmvy|ɆF2?r.ӧ=+UTK!^K`pMywϟ;/1W }lo5 (;ۄVh:|"oHٸisqM#ӕX۷ߴi l߾=%%ŋ%Kukuܙ=3+ۭ.NGJF  ڪFd9'4ٕk@qf oʸîs\#l"ϪZ7:R+@9>ZusMKKX,@}[6L5}?||ep^܆\7jZXMar&fIд95ݰc }BDğx;t; _-ңE̓^U]q MNduulp@}w/^<6&Ǐ'$$`D{7F!yƍ{մiI& <ד'O3-gU=H7"I-%sɒ%]tWGcI%țG~oEcབzLqGTM,kw:E3)bimaŌ 9t¹aew&ʼv TU45KT]Q sl;R~SՉl޼I&!Zh()nݺP`jZsε>… cǎeWRy{РAaaa}v;5P*>>~`BJ*-\rXzu !5<0!))iOIvY`?YxԩS/] /ԩS[nFPP>fLl̮ݻy晝;ԫ_oȐ!ȃ+DgWJ̡"VCTC[_"j4Y|ȾuDҹ:ֱ%޷Ch~IkV2*j0O EmZ޺e+Sz~d6} xfww yLӰxѢ5j2Ə~A Zj-ZeȸqX݆75<<| O4jȑ#'N;|5k)X˗wڕJ~ϟoӺQe6#_,#Taӧ}>wމ" ׅv5i~kHR]vȣjүyԀb68qVGߎg?Z38Qp(~WH[]D(e*3;Y+7n>{Q?,}L0m+)!r3`[j5af3Hǎ[f,ʂt]fV\bŊgLI͚6mS Ęo:5Uӱ[4=gӧZ4of 8O>aRRS.]8<$m׮ݜsdϿ|̘1sa ~ J+z*UH\8F!qv]lو#$=yHv-hB5B0ں$cJJlXA# :rڽ/٫HKd5 >t.Q԰lOqG[dYqruke{iuCgխG bD +ZZ3f` âp}aQ"+u)&1UnݺUm6j /cǎҥKsh2a20Oqqq,$%W-N JvyV$$(% x--Zj9Z˓#RD%YG۴yKaCcP$$$UV0i۶~ڮm;0:QEn3k!`0j(,سa!'ѳv,Vb^ˏH}@ophM\4/T^ &a_+]G]\qGIj1+v$ Qa+ lFhJdZXa&ə@{JnݺG~g_>bw0/SJ\}YQ)Zyo{E竖 >`Kx .]>7@hիW/_|EB ߿a 06r5Xo6*1辡 a^==1k)ZLf6)ZۢE?` rrJxаkbW ` :`-!%4M *)9IȈq).}4΀Pi_t8~SNR[{(O?wED9%Cv` d.>99Yja" rEE#j(Y"A[J%$JZD -Ƅ&]Ŵt ^D׀r*SPBxV 8\Y-ZA}[ u5@Фz|{a Ss+*g.2GdcrqOn^gq{O]eœ;vH]nI@5<Ϋ`~=UX5P85w^틂t{fRSX/kpjlhM.2ZXZ)ut J](M8R: m4 ,WN 'B6X`i/Fv6oR=CA'~TP_6vY:D2)PBơ[V0%7ebZK3=z _h[TOZww.N^p#k$f!7<Ұe_{TOI+~_&xS1m1=CyaFȚ?[WՔp=q絽~- ȡ]|E}c/*s(Զ#eOas'p%Hk5@<"/)lL}K؂FW U+;lQX7u2>O;앎]G\>e}SۙKW;Tr{*i^] %osKƯ;R<﹂1OXr>ֵoCƦ*ǵ47UQ *B,Ԫ |"{]ܣI}C|bYob6hfOT7>oLHRw`}rX14c~I}cː_.^5?ܴi.pLvv]MD @var-[dh_F~mM=h2w~hAv4R7y>"(eK ]03Y xIG;blPDE^7U60V4疋*KкvnlA~$d[^PX-v aWX'fzeoJ/o sN쇅dƘC͐QC8)FZtZ?$Oq*Xefymf@&(?B蘛_qt ReYFJ^Q!o}[̆LMjVS Z1N#\ijѸzU7῝hILvgL5LDA8g\Vta1W*']aEsWI ?!؊+fK6Mr!Bj C#r榍qƽݏt2*n! a"[^ec U;/7blQ2m}kzY&γNpP*= w_6. }#~w+VQC*3~sT,m|}%bv( A}nUs?s,-b&Puz,3>[g!Fý죝U_pr?~SʋM1HE!(V?c{j3왨^li-fj(]E쩽;To \6sc}<-ͼN .vƪJ&2:.`X1d{lǏk< V ԾҲկL])V>cS#ߙnKI3/ͮA쩍a>^8 Y==}ۏY_9Ğ֍qU1Y+f?G&'zXfneIsӡg_?;Z~:9J/l(?ζ/9+1n<~-BQE-5:L) VE BZU Tb_H:p5Rנ6W^UV'S 'qܓϛ90,SH#~7 ι\3> iO5䰏 ԢU42%oSAŨ_͸pƇiXk5݀Wڈcs↳);! j"yqmNmvR9mZ+ވfNo;1ǻcE5OUc+Nw~>){7Ad+ym\@J)so׭ p $3 ǎRd6Q5hm\@,8ɞV^|icr7 HH̙ӵk׻K @ p@p[ ^m4AŴ1u1P˖-7J%&&ܷs@iZtCƽر#kKL&F޽kժECN4$`J.\H,Ffҥ+T@q.ŕ1̢F0dѢEt>,&FJ HX+-HؤIU  H:'@ɒ%q +MLv .-Z2􋹡[JGրGYm .KqFԮ]\2 ȡܹ(udr@$c{2,“| C*&44RJb#+&1ZI.]DeoFoⓝHᡰAݺuvnSSSD֥9;t 8p?їp%_d*R &" + d"!S d5Zb2,q#ue#URErx"#VƋEzz:2 7^Rpu01"WX "'e' ǨAF) _ 007RWhvf!p$_@qAKL PKy|7\UYT}`casT抍L$^Y6[/&Ldq0f͚)A$.PTƫ^d%N:J_I@ ͛73+0q `CO\M6^;hAORIhaȮgG-{A5gIDAT#6$#G.X[`'+O "#dIDR [,Yq_YH  "b]0;bV$Rv"\qrƕQNaeht8X>|xРA4̙3믿&Qf_כVr6_X˂~́̕K/s|(oی= H 6dt1\`mB\F8`&0@, GZCxb ZΝ۸q#48`sKxCVD"`bGE A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf&" pHYs   IDATx $WU_]{[-37W4U+Qw, (a }O&ozSu_7M&o&==USltOX殹VuM7s9k9^W5=Au]Pg<=S?<;;ۃ?//v N&O}\.E ‹^={xwRLG|˷| V_җկXXX(AÇ8 w|w&R'Ng׾($Gp-o˿Ko|«_|#L>noxOtys̳l`699 ?}//ov|u3o9KX ÏsA+ \׽PЌp;vyrՓN_יCG?QmmF^?~\x >]TzxQ12lҽ <#`^ep,%fDX,NVd2)Þ*=#0l /֭/ $7d!\}^qT$ID~A<}_=bbK&0S>'qvI tС{WF*kVlmrw*&Bo=br饗rbܵk9wa W77o)aE[_=D#S/g_8 [YT%A"Sn~о CRǮaXBU"A2zG޶|,M&:7$MYJ2C=tE p dHq R]&K*O |܊!1FJ(S0 o7M@%cD1II?ϑrQq)>$gI'h5R,PSaO~{W*g&F2+~6n0N z=l}FrA6xZ8O_Y @Ҡߵ=9kܭp# c9ug?Y 5۷jvGpxv L =$dSzzs&ǩ=wzn2J7Iw(҄zA" O N SA~ IO( FHy-^0l}"Bʯ 9+j),??DxENbӄ _g"B!vFxDW@7K|㑿HuKQdq$Uq2 A!. aZNu`zNbװB`3 q$GBg}5@opJ71xBa6JOF==\r__p@%{(IMκT!m:\JCC-\wQ0g-u-4 &P㻱N5S͏9O1jP?`Zq , 0ݻ$>X< qºV`g yL3Z0|k/?ɢh] %2PrML*򇷱8. 5xy +詰2 vcI3OH7Yك9^C#C0=)CQcOmqA%Bd`N )CD9%$_k4F9Hq^(6z:{qFr)Sҋo P*ʨ5[=Ch^A8^HҋZ#BAfQ"CtJ#t@Jx(Qp%rz>DUu?;99+D"ɉ"VM/0%6<;DpKgce]e3]aluOpo5[=%DZL)ƺ@Jr(l`!ŒY/ x$FN'ń a IlAK!U|o+r@ M8 `D[$TqC`zp <0qqVD!='neLX R<GuV4܉nN]l&J|{Xb))flE|3)Gx:pYO* Y6_;<[z*|"֔zUwc  oܟi|A}͵\3^u<`5'YM&Ozm+YOζkf|Çd)dvNvृB6J9k3keAj4R8dml~ $$ D5m:DU2 4 l>}w~b>f{՗NY,"f:(?  k49^tҋo,A64$DF6삡af.i`i\!^EmJ^D+ZފϕC"Y"/ 3_N$b+cT>Bfm˟첦nYҲHL^wj*OtLzo z2^q$Nκ;rVj֖ݔ߶e?;a֕JuiuoZO[U;{H9WfFF,1iT0Ov~j֭CMo5 ˯VQXYX^WIWՉliOӆq-Ƙgؚ$ŏ/?rv>{4С_w}ͮ˯`DfF#uo/RU9x>}Hr(큽w?tϡ;&v-vGw5Ax/pO-i7 p~`/  gMb3R\FB-Π\sOb,)[q#s!6,0*J@AD0@ 34~DPz t$ѼQx0Ɂg kDDÙFə= M%g'3_pp9[7+dmzg9x oovSC7yKGRm;,HK>}hޛ~;^|KkNo}{>.G&UO`JD rn%(6F|(@6zC2'؝O*333#T#b6xAJ)c.p''y^ 9 :"!ooh|+S#/F_h` Jxdooq-|;I~\D=X #]37NAz=OA?".cǸ훛Q.F vy6"Ҹꫯ&' 63%1,8mA=$zܽ3SN iIII6I˅.F )RDi??-Q{Z˫F%(!Z~"c@''/~ oAn'/N{8Q Is Y,QOAJH%FC uT1YqV0Ί3%<9" _= ߲0~m]A2xfʕ.'jLGlu唗a5ӧ?ת;`jFRM[ݱD~޵2 NK9'NvIP+5ZDR+q|~"aC`2V,}_mw=x!4Nr̮W_|zC7x,L]7~Ɨ]:v%ʱ{;vѥ7lG>^5ƺ/Gi"o}[WR7pK^6ԭуȾ}hn:xPB!ϝD!I`!s* 1ʯL %=I=)ްMʯ dd{%4IݿeFP7'g349"o|Ig:Ln q#YCOIWĄggy$Y"iž/gLC2)~6 AȊʈr ǿ%]j{6j%ghl$ގPbϦ*~.yxf6]Z]ϗ D>Yi|EM?pk+H w۶ϞsԒ.FV-N$R0lN{0CV` `;.g&}uNi(]ӮשOrlF48+(D|؝̗ցD*B߫e_dw⁉ G'/dR0MZ[͕ZĢ8XZ]Kj\Q*52UvA.u!= .rdΑtU턾njvP c?Y,1-/NnlZM^ms5S=%yA= wm$XG,J3@OO3vg Ͽ}{|Anbg9EJH/än'R%͂2]F]9"=p\Qȳ}dG$Ł??dc^:"cG-S9٬9|PCBqɪhnj \N)?0T&(?DG6Wx&[d l!C<  z"(%/O^O~▣'+G/ԇ\RHɺNZ@rR+w8QX[l$!~b#ܹL I4'o BJ uHCG=ȓRW" m`<2&$"H i #SXqHaPH6S"ʨܓ6Ex"RK&~k~`Q" MMI{r2~H1$IS&坙T=sh}-6 g~gLsd> уOv+Czg ݷoh͡f=!H$ 9"ȶT}D +H4${d) IDATS&ndha*)8ᜤn00 &*40$FJ ),|H. =>Ѓ!R0"}a04  "ߒ[-|YlIJ}AJ.pzd[sNkZS|xͤ>Y!kxZ٘ rScڡЬgdw-v r-j_[2iY#ӆLH.2t1-Cd* jebMbYŐxDsxufK_gfνԇr7H‡Y8W`+yE;"8e($zT)k4p՞L%Q9<,0%R bJkM(ȕnR[`@91vQE*<2`]srř 0I?j$="2}V_5WX"3RLr|+3B`?R 6-\|a2K6tRp 6d\a'?F9H7E-pdw\SEF?! &` ;=\ W92SFEqdğ* ,A' ?3$>'0 ŖW=2k~>cv^%ʫ=`- SCYol hrLyHNCcvxBxWұB? =Ҁa 1D /]q+ngƿ 63﷾ʹցˆ>+z7$ϴrƜsnAU%|#(W~fJOk,e``VڹvPM$s.^0D63Xص 8XJ9N¥KM8# >:rօv2UsR'*.% =#HV>pcKAz@ZːeكF8α ,|-vsvnUGYk bN Ѱ=+uyMa/#8rxjz pN BCc2K>%R6r} uq ;%CiPI#"jJ,rɞ2=3qC;J)+hV՗P}瞬u֛O6f342CjV˦n zO<ݷכ1P_sd|ubFsUW= fQȂ'k]Ϩ$fFTfoB" /R0}SANN"Hd=}+A\sTp۾+_遗}?04\:ĨC ! HX)50,I6 \߷o&0 ")/9j~Sl$#SK~62bR Xj/jIɍ&xDpq^1UmdT$Ho% A296CLZ&͢~H(1vCaMd2 7FLD&pP 1| ^[b.Ia#3BB3s!=<}]L|iC5N|{DOn (qOv~ W=ú +ӆ.(<bE ޳g%R6Dt9g(s.9+*94J9@T7p1L6xFܰI=I6naB @Tc`q gx!@?q z׻(ɬ~~(iM7݄8Z"=Or[Dd Aaއ].Ä+>#[2q zI$ < Xae0DqgnO'VXH6`Y֣z7vs$NTsJ<{hnkfW穪z^UV]GM6jWpMHj˗_._RL&lTN;-Dy xP2//)JyY܋qg\ C"^zH x `qC Y]@8Ⱥdbm"]~+fo>4jW,[5RyadűK&4.C `/[Zax0\;wvAHyĹ@SO)6SY$d/g6n/wi' I0E,\DLwIFQN@rRP ,n` Hduğ $ c%V LNJ4p'L+X0pE!o@BݑT08FMq[!!4b %h< HRq=pdBP3_6oDY&W0 Nx8 P%~"HaRl`;)0Áq('> =g5H!:x!0pi-r\2HTC9 q^!T`@="/$34`7;NrI6lB'%gLC d XH&$8iU0x\G %'CVIu{9+607jPYs9?VuJ#?2~E q/w.0mk[m;f3ٕlV;flȗrKdbtl*VP_x۫eU˙N;qP:ҟ%<@~\9kɂR 24wd,KnRJy"KK ,] YbYud3vz&=(,BRȢCŒ!,6mR%o1JZ A __^{;AqmR1$ %\X6ÏⰘ1@,1z40xĸ^x4=U1shb]M23kpLuDTrH E逌_D!h Eip!xms̒c V㏇X|f,?񇓖ٙ "0=ڐE0x8IOr,ӗ)Fg>*hs#(:a97D1J&ʭ5G\EЌE O&QEހ!f~L CLg3aÉ)@jsZOp0'I1w9/ AL#_/<oq=FLqINesV|jU:ENna֐"|D! "+R8hrLEs(BT/J 4!1ͯHݻ3,ȢF** Sm1Rk1Zr@;q,tMQC_5YC#qSg"r>BĆ΢b cQ<P-NKOV\TL<(N>#Pd_J?h}(#~k4ؒ 9-WLw+:R5-^rtX/YX$\ܨ˕!ǭs,ީ^iee;?FS$ 7Չ(F )c`z7eoe%!K$&)$ P%P|4fHh6.CA- <4x0 YW_zƴJ^"0A0ٳ'PQ. 8M0PцQȁЀiB N&EC(D0 xL*z{Y@mh6xQ-7!!CP*x^@h~DMD/d\}fs*x0\%HFĘ`qL\%1' ܯoϕ bc_bRQ_]pUuWJx£!:jj(x4)zb;ER-"*3},*ףi]%qNBB>&a.^LiJOܢKq*pTT#MZkQX't8FO ѩjĢS?B5#=ZZP&M +ޓJܙ6hz$qo&k=JP (Ԝ`k"j2gſ6.fVsv=zp)[ˍzu{EWNX<{A.j*bj8> m5}*1tv"]%a,FZ"*ExNXd[; V^#9ymⰽfr2R>ePx x,wRQ٨SN*d>K9pTj'I'{6+J&+_. zV7uv@w}ڹ 04qx-R=`D`A֋uV%6RWN`VSAa,}`EV ؠQ(k6 uCͣAHb#VpȇnZql"Z4A' j|k>VEY)l A"8t>.$vk,*B9cGw,;,4JдpE<1,OPqϵ+⏉P`ЀHwJQ[+(3x=)mv7V~>T!]* IDATVS䗩t&'b`//VkS K+˧@l;H%,'pa '-;ӍVbnvb:N᱊A0X '-v,9#Agĭ g):Õ Kj I|bQ.θEV;+48պ Q}/nEt,j1M% D֭.-HƇRb>q1-:`<I ]'ӌغ,J0:yPuCidD+Fv+n$X}b7B9NňMG$-5ȺG&b?ϭ'䐟tաR{V\56StoV_[Y Jӟq^u8j6$㪭Kx&$m 8S'DZ5rư[ș)(u/ /S0)"0V#Z;6xJRUGQǖX(`QNQIqhzb`u6%H@%ZL+*/Zj$őژ`Eb/$EbDT)$PJ#رhp]s0cn⏲b>;sq$Yhv(wЧt j9BqEXPGPbGk1YQzOSZ+Z*4Gv/S꣉D("6z:`uNmNTpǢسڶ@'v4+{ml4;we9UwҼΧݶv<8>L|Le2nVdL} F7UBt 4<,3V_Vat *+sLj|0g u-Ɛ&"xA0;r:++^Ygq0DԤ`hY~11ѮRZ_¤C4EPzERM;}ʤJ RP86t#"QVE_-xbF*Zb P[C M (4 uck"Mt"hJRt}ƇiP[!ږ/JU s) S |5?5U-Til~ͥܜΖMOP8=Sy68OnYuQlG@BX`϶AxrF@4t IMpU/:0XƫN«aĦ2PEM} 5nB{ k2 a6ȖeСn{BFbQ0wdO|%Д.k K[Дpٺ1GM 78zJh0YTJC!<bcQCP0bfHbӌT1)a; jh챨L+3 jX4{cVٶy xT2]<5ZQʫN\M<é$T #X-}H=z&Z_'nq HEd;tZ2/::at= 1+Jp#CϢEy.εL*HdQ/BF=w *b};:e L0)?d_Qg/Mj˗J9qZOk켙vo4S왝;6ϵrTd l~{*~e-w>oWob7DDoUʫ* &w]&bʻZV;V`msswe-zG[N]“x>j-I(Fn;  Wj5iY 5TqW cŗ#F@T( "0FdUVZf3BU&|TWg%LUjSl䫤#2)Ii*cQYтE"Թ ُ'ԋ"Ee@.EឱE@т J[WTŦ'‡1F['Z0A:)bQ[ K(BHmGԍNezu"+bKFu樽RC@GB0Ge-HDF23r5:miDX ]N⡹o~fz׽e٫~z>kuk|A.m W{yʰU`ZOhUz5I%x&'!%yպrm$Vl.Dr$kǬ?6 l9|Hu,*:m #]9SWzER:}PUY?SkjLSHA)O|{a6|jε]WrXZ\NʋTz,sw%>p=ʬսņl mW/̭ye䎑Lʚ(q PI>2r+Nln˓%Ym3pƱ7 Vl5X Q`[5OgIqU* R˭Ńv!K):bQbN3' FvL.[,WG| sɼRvyN|}B~{>_3#P98[=Ũ\A|\&RKvzp-q:elNhNV:+/eLWlQ%eWGz6d0Y: Vbbr[wCAFMWv^;K!3K1EjjA AΪʰ.&YG\sv@4@UMCpU#%CVv` Tj`L|4Ʋ%3TeZq*^;s~|DB,)_%fHZWdݮ{>gAZYr/UFLBR:RDgCLTλ(e2GuzUNRIWLr͢P +1Q] FBđ7şR!LZVѱh*`6l`ռv;.~il?wjT桇Zo>o|?˯xCh6]qĝ~޽\^=~+^w>LIh>+N5X{'€z~j[φLFeng=qC:P8S<jeY&q gUZu ?EN$QBLJKW$ۅdвr^I|s45s^ZsHJ\Tɏܒܨ9 ?ȑc<4P(x^ѣG;>7?hffSAӟAoy?ܘEF˱^C=w;Q,nW?؉c s'`b?&^VU~n/ËҪS5[BD ډd.lh;Cv-[z vA:F \<%ɺ*1'lp"J8 G3a>y g:7J,fˀ*!sA5)ޤ}'IԶ5yYz R͊PMz2S$;MYMRJN ؠd%ֶaM={,I%UU>PJu:Hΐ9"^GRh))P4¨Na #AzVSn/x{~(Z;(lnWzndoa%Ge}K__퐞szI*H ]69|*f voq"gW68qLRulpAX/|lAUQ-$KrȬ2B=6C#j;r?rsF.pO; v$]g-Īn6sv"/ϭ޿ 9Jql15<4-H5OE;da`>YY?)9\{.U2VH )r(턓qͥT(mnS/QO$CB1]&'rV4:]r֑w٩d!F4+>J:6oTcK'ǎnj@=QmQ\u~>v"g\JnսVTV"ħvmeɖB'j'I^ jQŠ%fzȧpk +AI+j2J94Ӟf6}~$w"Wz{jL adzm9Ulӽ%4$E}i"CŐJlu97pb6o<ћRp3zTn• sgs^tgƬf8S19ϴJZ^w|Ҕf1)I},'[a"2<=:œn\9/1CT`>,E}xb$̫2gi=Qd`'AM{*hGr4 y)?|kYSrnZڇ3+WnliBm]h\:go",rLYAYZ5 ֧GvRyX8#Tl@FԤ>;;gz-?|2N v.p%4i doIP;-;iJZ4ճWeːNU}fSwbP):sTFEf>NKxXe򝀲`% _ w{ 38&YTuN_s46ϗW63R.]_Oq;w+uFM0&H= k\yf'IQ{c@ne(2qY}dvjpddfOU}f EJ\0ai+~@NrrY m42!Un=ܹq[cE ;I N Wg =}VS=\XaUBiwo6yE1ilCsRAVjhϖUJp.g}xTd-QD ;EŬgV1jk2 pjޒC? '|P6׵r[Zb :EB`q=e5*iet[-UOVAYdFr7C֌FCF*Me37h5Ԇ+=YW`J Rgk3ub,k_SY\ܿQ{pZ~M9_0/r{=Kjw=EGg?bfA!;x8; I1pdC4q9>Z"`O[wNl<;/CI:M]go{^D(G7 'Pr0&VPUc`egnhІb0up <E+(#ߚ#IãY2l0)Dmxe!ip{Nힽeg{77«N_e ;)9e($K-8KX70$+ N(Lgti+=>:*''pCNV syPR 4X~ 4$ДT,j,QeM,?$̴l4W T'qZb}vx9|X̧|VZ4r^X6#ǧǜ@XIcFdN4CU AeM/5DP/2ACUz [rn祽?NT,ʤqkwgwZXq0}4Md abyĮۇ1!g_~fHb UpYէBxL rΥ˃Ιg(˓ <2?us#a&4eQX RF"(AjkEk1pnVH;f8QOQXأё8;UbuC\\XMUz}{D9ϻvNm֝ph+}sؘ 10Օs+(]~U. ')룅(r>Og i%DGe;3b`QE~! v^xgeKLQk3+tCT1x 44( %|! N=֩t)LLS,@tubcBTȀ>GGilWh*gwI0_j0:VۑxCv7_w}̪5R?vWV\+*%IٱW+)Np!VNŬe̒n*CHڮ C}yѼ'1xYci5agD X S]q_hrh>f/v+lY&`_L@p8*dVɤllL}(5lal(Zxz;grX9YE  nMٕK>ml\E{2t [>9wܵ^1D>4nȝ66:[`b:]ԃ2. Khf},^P\-LogAK' <Ŭf'_]#pU{siRnM'Z^+n\|u󄃧N?JxG@]7t`NN5F[YFq ?!1G ϴ>v;n?lI rG,4g]W?88LRȉgf)@6|Ň9Gc 7-KDL/+ط0<:I\XlqE%9} $:.w$>$&S1% 'xgj8qfCpػt.%!RK27*qĎUoKu{r\?`j.Ą>햯eiaA:V )Gߞ"BJτThSɝ - D-V,i{-`aŖm a Vw )=Q :E ?u@, b*G%N08W9ԕWbS;lȐeh@HQ&<:ճ ^2kq p6ǣO<:F1))'4FY?"h6.[B,CBLRAZ,ˑqX^ '_ίy )s޲j8fJˀbv( en5IK=-Mwv`0|V̜L˨,XmL%ak,6uKXEE[< )=u;#kxWP0!'F[ 6hmO< /3I % E/}z&U/ OW3|lGhP6mk;`$Ц~YG-X6z 22Ъe^vZҪ5 fjiL7 <2V&_I1,A 7\4x͹rӓ d1`զM߀rm]jQ?QCA;[OϧTY۳9Y ZNEC!MzMAX--=m_M<h@g4~ٝN?- 9tx@T& !4pPȮTK1XLf:n5BH-m̩:; ;?,K!B41 eBRriwikuVӏ6bߚ\ȽRd̒o8U$X? 0X -/ /Y[p&(M*aw14HH̋+LnޥP+KeZb\Encc(p^i1:JjfpѼ7X 4> L1aMH¹>ZBV0NNjN;Fz AEC~"t|{ ] 5UɴV7$.t[IXϛ'M&^xf",+3ŪecUmjTueOO/@yz+4; /}Zo&zvz;0\gubP)j(KfHyaEZE.ӎj&T/?6(+OAXY fsB,{5 >8@Ù;ÒEPV6}QvV[NhK\poA$ "](zALØNJ'h` 9}/GJ7/6Ôc*kmjFUTHX^YP*H+TWGq+ aę<-+.RT``cz+> 1$7*贋?XbXD62?&$*Rjpt룈 ΗHVZGS4Ŗئ<Ǭ<>k >ja4t /Ks<}/s:lENt0Ol0.IX](6H"y3x os$Yq%e01w%|wAi$d20i[ք[r$&W)j q]0" ؅z ^+QZ@T*xvmo9t.rkN>Y GY7U$ =i[Aoe_\`p 3R vmvZN Zva5 쨃N*-ėY~.f.ꩼ!Z`E#(1MDbV}JA<⁁/sg?/F( #hg%zbˢ Dvp _Xkk#OSf k>2Sn{r&O5g )ܜ o45e!MMQDfWUeǷ|?lqLĉw}wST$oܔl _b øWDq# IDATFUZ8%v0 )֣j`!A QhQ)($Jn lKI2gf+SMX@x+;5 C2# sX"eUkEC>e. E֙ngiV=̏6޹lB(rEU^D˜$9{v`Mn ؍-p0K o\.a P#LBޠ-ظTX2x1CzZ$Ff܂GT(CW C1ލl9ijrbبAFC ըYpϡlr.@Cfl7k{ATuVY`qJ_[5f-dzN|k.M4FPהdAƄRҾvw9IdDya3b ]]#dYLCA¼ L@ b &JӒDaRo` Y=BOte惍BV k#MWs&03㞱ʦ4^6"dfy'o]>MMADbׇ>"9qŏX\[<~\iPMu^a!eY8" Au; Bfsg?DfGa˵s(3Dg?hP y.DƮ6ݸ);~76EARKF˦vd7P\6gr#Y Ӡ'f-1j.o;*aydxfd,˻)^]Y'׾gU4FCr????گwgΜ[v@*mE/jZr= zCYLP!jlWU7 rm6ALmhNǑL$7()v}rC+LRPJOo4@,㣪,2l-;{;rS# @) Sdp#d[L0-.>GT8pu]VvN'Q9sShp][ƍK h8y=VbFeb4_dZx;,_9܊E1wE%$~˱ :X^KNh1m0\ ^Y BDG3Y( Xn>و(P/pXtD9A| /)>4d\X vޗ. 8DqPS0r`Y,ێW E|u5X\C1 \|3}:s\4ϗJh?ʸҪ˫4g͍Us #ᶢ,Yn|w1QU!%*Y Go#x+Fh 0ޒ6ǂLuEwB0@؏& SD"@э5C"f`473o]CcF+6Fick6az`B_|~½ RμRaK|+) &*R;$6cD[)Oj,/!M"ۙIiMcU8 Az[ģ"7CFݎc56tlDP:VS68 qUyխvAp[^ o4即wkYK{nQL(! m{cRiq:_fsC̍fy&,Mjm+O[1kŝ%*[3)Eg_e1o;BhMGGGswկ/lc}򓟄{ʕ R~W5%p4 _e}ܼy׬"-,vzx鏢 W??h&](0N)q"vCHCTR*YpY)w|!WUk^cڄ$1-3j-̢vcX, AKRMyS˅?UP` coPe :e?pJ'av|b#3"HҡLS^K6 wg -@} ;j: A1< HV Q@ }f Z-At02 Ѷt4Zyb~dy*zi:^EA5G͢XEJ,J.9M@rzd T]@ v\hX@PV>tŶU u0_F=oQKT L`]8Glٷ[_uA^V9WDe6[ۯ}Ϝk0>?wx0?D!}IVvsb;OF=nGc <=N̚Yd:F"\l~e<#7"ޗ?d., _N9Pn4 RA 3K(0"ϢYKʙed{aAGP(J6܏xkzjy*~ Vh0Pb⤴ZD-ZpٚCQ/_,Ɓf4hM`0Yhb!r\&Y5(,;g僩"&wh~dj_ذz)븃d0A,&>@103 =-tiI1T?5Ů~rV + z8ޕ eSXL"=d i\Ke4C 1ʏavUHOp <[1+f(r>@j:!U@K-l/U4Ĥ5ƺr9ALjFd48^>IꎖDVܧ5i;z,̦A%6WY,d} ^8X.  dF !R>2_V=\O7`ABa#Zo2\eáEǨy\OYW+tZ6zu1+|# 6VnsQLFh6Ϟx)rq@GKnd#$,Ȃ5=r<׌)\&Wbf/T37e\b?,:%VNIڛ(W` ڙDReaP2NBKm5L9fҧ*BV鴑 h*d&,:Tٝpg7QJ{?N'sDsDȷщ_7?ůߟ߻x$)+ Hڐ^ٹ9jwdR:z?HMѦBDKl-+[r|dN^Gt6-U#hH4=Hr @ZU3>f-'rgļ0}gfVlV-s?-]v<[p eѴTC{cvc% !nn s-۝rQڌqוnr\7) t9j\_&Jȓc)p=U*s4\DzF4)o ag6B~ _[nx_OO1~9XluvNH{u[|^#+HXuP Aaqi"$u* ]#@C*r.^")vg p@D;w#!W;/Qy0F)H z3YoMnd]^)M3MZ"ZF U,e<%Q?M3 jϺ  &%Zs *-@D&yQU:)\& ]P "|lA=:" !z0AEt!d Ͳ̿VTd,b.AI-Bp]ԓ[W+oÓjl~Qq&*:-@R] 3YhuI 6/2  j4 ,] Wt o4ܸS./h^dF(@𷇰!2WHV To0Tq VĎP a83r]jFi3tMC"4T&67WXzԬ/$k 7j x*ڛKIzhuz߰xe5c> cnw}w++w!2FEڰIs<,fc{Xbv֤(eŞ@„a럵 i4Y:sY₊dx~ ?wƹrF'0:ڣ)He19hLq_  ҹ;ahC Y,yYM"F~uFã#c)?@^d 0e+P%U '$HMvU\w5+V2Ɠx4ECE=78(S (T5,׸n&x3rԝvM\MؐXSl՞CdQ.,k(hz/ЏvI5@r˘B該f "*W_.:Dŏyζ@hCHn;C+ 8C‰%.0 4+S8!Gx7!HD,ހz97聧¬z`&]sК&Mh=d^6kLgOvDmNaF @rfmÕ= {cYBT`HZ/l$ %Lc *˰^I䡰rd2*C!ѮST) 1CU}Ӌȓ8Ϡ6l]Gn9i|wVl Z^{̂6 >tl^Yyut$֛LYOY=8R)4)YE9a1]a zFĆMF>+Da0`@AcW3IU"  -@G3#`ވ?`-z&$58U_!>ZJ+@ +as^Rד\ ~rpkc"' 9bGK."\ScTr1X0gd5ScV>5Kse2e~\&ẠcTiYAd9v<_>2G 3~zȗ]>2Vuܘ&jUMr]&P eX :4̓5}ɳِeQ@+OH=sb;`xJB#zl۱GL쭪HٹC)6V xȄ7eV ]|;"q'i ^Żĉ5?y.Ʌ X8, Ŀ+#KBcRcѨMj=\-GF $kB*r[}e vxݽ׹􏞀Wv* DbІPRk+4U:z):}e5e}j$ -rbϠ\ )y@ 7QJ@Q4ʈAF"2e CV 5 ªlThzLq*5 59O; fci>ߟUɧ PMe :N<OY5ޖuyW5;fyʸ,XsḆ,I.A·1,4^(”(loDP^uI DF:d,*#'ghCy!/`Ћii<7͵y13fr@mw%̾q&dfl:E{Sx0?[̗hd#'ol#;~LR8bˡ C`mYӈAim@?8щ"4^YJ[q>m,f`|IJE1PF&iUɑVDFpm,xy;E*Ҁ C݀i2Cʰqܢ3*'03$uUpd ;<٨uA66cCO&9 ŏu{0+Cp%UՌeU'f2My͒.Zc}\ u2JPi(c2rlD+3f$*F~ЌA*r2{1aD#> >fQFY&i4a$1`,jNQ Q<@ʯH oi#K5!wQ SѝPeeO%S/d<ϻ܎`ZݨGe.ir jf^4ס`!WhonFGDza<|?@:P/^M &AH-jDH݀k{6 ~i_Fd\BNm /DAlV@c6Ul(niw0@ΰE%2Y !6U0C8ωQQGr^ҹ+3=,i[LpU8=lg2M15DDŔWE+) 4c&fM qY4RϭƘ>07rqjRhK)nΛ2VVUAC%VKO+^}1S|꧟u4v}qD x%5 n^ aI=^"WrXh 4.&i&%K JDLjYr5;1*'\GBBHVBX`+<71S`]X޴ڙzUH+wl4)ʪ ^|AX5^YΡ[حE J -)&k/n5-3.\jh2::9!R?f VT-~Mq9 QF@MGXA/Bӌ/EmW㷁IER;-NK6 LS倹6sĐU_H4Z_"F8oϗF(?hx!.Uqqm`rѕF\ձ +8n<ᑣta}/ިf9s UE` v1껛ǓSaf jg H]<(597||lum WO=#4}b6$*:`v޲c|\,9`Б7YMHWvJ 0 S".muѦ5o^@D '=+{8ɇ<9ռS.]P+ 4G &Ji_z F+i255zx5$N@ОajDN]_PFSb#B3"p]kqZDKЈi%$'|xbk:D pD=넧AѸ!Ą*wT5DZxq{ v_cF  O}B`v4L2{5( F?; Rw~P@mukDŽCLdfCT/67jd!07Of ,Gzp=_H:ٚ?SYd'׹snk^tȫ U~雮I\Rί~|%pobzs n_qL_'ع16%5ti. L'2:s#ȟjfT b*!A:9܂[=qAUVYk*c[n Lhab^|8"D,g4OZu;)B"4qa9cI9* ng)T͊NgіۻEAot4MJ$QPl\2CU6l0v[s^}2r %nw{;n BN`]f'355wu`[ '@HiaZ x7]@\L^6ir40yZd jmƢ9-r6J<X*Vx&z5 Mae'N%cg`0LJe N fJh50Md2[PQ⍡;K?v1} QcW7nЊs>{p8PxlޗRYFPwᬋw2-Bp%'&8)b` ͥm +* ũWT% 8XvnwD~5f\cFX86 `5ZE&ąJnbVtwM雚3F.LO07t&\WΘ*II mF@ chq0CNnBЋME9ms0ȲڝSȌm4ԡ>S9&84}'#+|fB-4mv'MG͗~[}~n{opި-̘92^W"Oisy>}`!>3r{%/q" O K`:|v>1$YX`o^o??]يұ :V?ag֔Xy]1A L),? Mb4ʘxnL/H"IM>z6禃KBtj-xZ\r1B \ ӴN$cgNdpU:9s+mzM{1Q8L.N[;|i{:C+V|މ6/G| 5C|OYAZ:p=6)L.g]i>):SɲU/pTG1įj0"T_4|>i謻 GGfYN~ DO$x衇~~Ih4(s++a9@nnrZq<q7IWy//O*?myAVtlW 6qe/`"O).*dvoG^-$w p҄EZ'6!LzU9_\82Zv )XXT)Zsؚ6:%ڤK tIg6TѶCO}%+c9!Z SX$VfI'StQb}EmrVU 0&$2.Hc> PF$ϑn)y`Ob ĝR!1=_Ej4 &SXZDG 'A"tb$I|t ?h:V6Kg)dc1tc/!%( R\9yHB`; .1l4CNcZ m1O ;7SssIO <&Zht7m|@G~2b#'3AoRYhSSj`<D!|fɰ magXh:e Gw>YQ˚,6LS YL7׷}hXdžVU~H?GJ=|d޻~m?+YpKrl.>7?_`'+} C|nk߼2x`sQvs]wny,ag̷ ww?(cwJi 'hb?\X[=떞]xu oE)|j+Ӊ:3|a W`] "0 ўroU%^J9ybzV{7\h8Ǒ*$rCd7l`t=}zYUMOr?n;pĽʗϿ Wirhb[- 98ts/Wpʌ`4Y~X"bқzpWzMy)4M M p(&_rnrpE.afh}gRʯ LSk_pԊ[U5E IѤV޿0L9VWIOv U PP ͊Zs!V!OUKfҷf!'B`!|:m`b%**E#B#iC%ƻZHĺsv+F6;bJ9{AAu{|xU߿5|nuK^?hMKGSivkn} 6{//WbxNv~/}6wVur6IOx0 XEJԨۢhqei?u;QN[͙Q3͘ŒH fȉh6ci.oD:W395 Lf_MC^s4n@4bsxd7- MP\굯}-'TH19ͷ-x~W9׏8ˤp4e2p4q4mޒrrB !" \^Dr4@ IDATRH!9!I9m꽼o̵vv \sxLs>=y]-UC*g/x*qF+ĉ'|>C#ykaM -?" xS(cn>)RaJ#0k*:=@c*ێ2P4K+ gk j^x-X8сrdGD p^e˧BWz T`43j"P^,*MpM8Q!bdQh ׄhbf<ѧLC8N4⋆ypb{s{NK:ŻKzg:[ƣւ)-J[WF)fWKT,s}U -M!zLcD{;@#B0S2}ڕF!_8ao05iOPN(cEoxud uYk ,@S1hSf ׫Չ#Gї _ꗷ*M}wmܼvU\v;gwQ< %BU8뷦N<-λ֛O~_ -A[q8BLyCOs'<[1HaJ We%pXp^cxẦюxEghq2s=ٔ$3a*֚DYC o"&}"ƛ/%r5X _^ך!/PGDD4aH.0PQXxZE_8s-ߘG EjW8aƈcuip< :b#pGm`*Qҁ}e$kD1}e< CB I. VoKQ0G'Â|.y^J ! Lѽq(:+vE*G/doue2@])*!uZ)Ъ2#RWTEfěҜ C*VZj["K,Ӹh> #rKE-Au=Do"9|L~Y%g6n۬k3=++(IZdu{A{H'6Y"X@r 2(lRT+W9byvi6 -ڕ=Z(ze2NJoY8LC#v!rgU/XRiuDb\/zؚW~WpÚ'JBBfrh0kX-_H@l+VZ1l5VߪD$y1'.MpI+W8~`Ւ35&ljxx>˵R8 6\X\Dq6K\c]f}|ujܗ]2ҿ=mZeI[ *H.2ozӛ$\+Sp=$gW}NQSN#p|~Ӛҥ5#wP6͛o¼ N`]?)\!^![Qbxx].y? ༴Zq Qd :"6DQ\ʣݘG nf |{uNd#/$> H[+Ѳ&` (׬Qzq@(`UIzj2Xسzl#]c^6?H/,?|D|v.[ 9C;`U7t"һF*X8D"~HKJzFnjVER `l;OKV@E!+1[8˳\8  CAVQ8TH,ڝþSHԄQ,X iTBC?RP8"CȿDi ΢3#I/Q< ]Y6:=7oKk?Fє00kaljjՍa2XJ߽GG\} =7*l~z8al}0+mv^b;#1nhUtإR]<(dt !БПpQP Y"x'0-%poȏN|{ <ͪsf,>RH֪od)CriZ4U_|~OiB,Ci*mV&Q4ZĿCmRJ0G$h2P ^a(n-lЉ˨վBl.SG xܝ6nH|b.%#7s3uѽի_t=x+ng+A yLlh[w ~ӕN1 AK?HN)We@<CllbKmebPQ-"X#RfvfFQU|;xE]cvM}kPŃDnjY$0u,`ů[BARQ.NDIW[ 6$ ^/Z=bW5b! L: >[Ys`\!PD|8hnƵؓSo~P]̖OLWCbZU]Aj;ࣶ'˰Ju~zYA%qn>֍7V0YlfLa.E4@C"CK L tEIC-a*-?ڦ>Kc Bŕq,OɚU\? 1yxס#@8R ۩AwتY.'O^vevzdxkюk%ueV }=?cÈk?x`OU#MPaTQģJW*WrV(uE6L<" RI%PNd &YFhC);<@ӴiwQO.-䌄wT2c"V-c[7֬^}UWm݇Okq!H "y=\C2 gH*v ^X?<F p DYTyz@fZ^jsL4hٴ16XM3ЈƓ"ji&%bܼʪs mC+2 t8BY";@(hC%VosӳOlh:"J'88K傞`^7뵑U4$%!߲Ѭ#|zZ_fM*ʲLEV_/˹ [C,ϤER,|zv4^VSɶ*Z#p4("塲p" j҅1pN@0oѓ`[@4FM2h=k=~ձMC*nxˡPg>gj;G?|8;'?r|_-x~O>|c[_W?㟾ݏUW=|׷?[r>賉ipyL*ɘ"dK1af|S fHa:aA+8^Q]8-4M9\Nfl^^3#H?ӧ5T?l4 =ux$ c&Q? b_18_|1㎫L? { ,sO 6t%1bk0U7Rk@+$5/K {R|ZT^ܰ])5lPq{JqDjKb E!)=tgx9ZJ%T0˽e_ͯ}+7o߼X02t*\* V ];W;L:]΍sx\f#9(f &V8c뎝sA$³'>/Ͳ4_H_%Ne&lshtd}O$rh1)bĂE <,UKa3AY 3z$xiкcY>z}` R'Ɖ~70\͈ߛ fV[ {DU!|_i3ڬy]unt;ƫB hRA g3|1;781 YKFӚGǑbqO*J$@V1@ IDAT-"™Y|_G>_N8Qbe.4,4. Mwګ[l*[LJS Z Q #Pi5'D|Bt~jDT䛼[B@*:6-~QTqH^PYE@F‰<8R_ֆT_X_P/Y|˟V'[KO*o:X}pq=_9qo=~H:L?5 ~pc[#ON_x}nLzp3ɴg4rZ/ڝ?t9|\Vm@3$NބwCv„KW"lTW ȆH{ndi)Crgh@Y@]bD&`V#L8ea "C IFctH,@\T7OjU F]J[(\d<$H&bH 4#Tr)o 5Ot2LdK9`|W> ]X4ETnḥxΠS\`e+Iȩ'Oי>| /5zdg_5 ,[nܸѣۇ~PB6b?c=,9<ųdg9$`c0+шZgV)m8NX`"<=6C?)8) LicQSZ3}J>!{`*Պ^ۙĴatvl \XN ¡=uJ#UPd%/zW ?vcǾ|_k]ڝf:H{WHa>}顁M;ϹeX$p<4CH.ѣ K"Vc7طWX܁TȾU PPPȍR/y2ېzkR1gÔ/#DoJ4a+=A)_lV%%Ba=\n_v: \7`P1@V}t[3AftAa@Mvߨ?iFa;WQ>w(4nB%/8CCv(0?3{Í1;[+e­k.p: fu p2uyӯdSi{us7нz4^E4SQ!Ne׽|#?௼e.µ}(㣻?Wh <~4}͇v܋y:trzx`UXKpfS#؀a]$!7 'qj.X*]`LIՂ6XeyZ( >`u! 9Q( Y!Xi9%MO`8% ߸q+}6{WZ}ꦍ?]{'gf>~+HDSs/:o޼*۰aH< &/f3ս&uOøF~ 16WcjzZ\);z ;}5I$[ώMUZXڃ4DdbHO4FruB$g@6 v'Bmv6$mdb%0]A+0'O6Gytphj_cCWk}TaeK6TWX! E?P&SH޴>1-H ם8suaK/ 'g#V=z?@v98{~NK:U^j~sodoݘts4Tr&cԬ87U+,-h 2G[2ʥ$vR .w09tWo+svVKV9z"57w;޿f$il>K^ru-sPFG{cnmMHkcCݯ޾V:t|-S|0k/ztޣ;Y"!tgr!_̒C6# B)kÑ%C#㧒H._Bl%_ӫ-$fyQaԏqQu{|i|ML7CQA8X\'G0k>SR 06F#\jKk)UHN20$aFyFvUsKI\d|᰷ë ?f.s71S~Νih9\x]ީϯcP͙Ksʣ)|DjӸg/%e1FuDbfL~xZ@ K<:yh>߳d3&gbe"Y{e[ʵ ڂf%n"f' uڭΠJv gs/4쐾4"}44 HGlFP$-Trţr& AZ(PU~)``=x‰c0:~ `#\暗>>?7OJyu7]_L~xϽq{e($S\."ñS?bUbjK@v"-Rp40~R$w5 Īxsr-Ap1P (F+.8o ՗M]ԶXa阫;rdrp 8Pou%X5__\T6o?sӓ6 vn޸cD,G%X}-`{M}UxM=0I/ .;35ёxo0?K.l\r7q5WC!R _gޞ0ٚm1eQ%˜sjd5PHR|l&p遈-5 !r^VU@) 镱ܜ}ڤ=| b'9hUel#>Lҍ2P Z?$P6fdh/areLFw2$Wețrk3Je~U`k:rUyS;@S[\f n#cZnZyDsUz+A~&D~w~7C,. Oe~Wү+Cuu֟X_q}Q$ g #_iy5 a$AD>5Z ] җ*]@#ᥛf ĤRPPP:IH$ٲBS {׮v%F+^zko ~pqM>z{N5 |C[?]vzJRC~Q}N$zZPBY+7(y$0!(ad^Mc-w^Mj+Sbq]pO[f73p0{CwC_jOB,*ړܩAP_*Nc{nfbFjd@;8DV#S(ޝ=DԄ$9oM>l*`2v[b .94eb#eoWvպ^Z$Zfpt(@1.C1Ƀ#}^N.X-U;gR9uZH/A?t\RʒܕU㹮w;SiY])(H;0;jW: \D` GUq~9c_HK yeE !gUx$WG*W3nE%]xz?~-{^y Wve%')YG{}]Dk=\}ӛ{qm#kƶ{wGmhS]Ox/Ld0PK>ͻZΣS &L)anLw*R˿ԫC0AĪ>MC/^x#\UM0~t3˺uopXS K>ի9#)6aO宗ӹY|< ѹHspюs2|GRBMyV,~@D޺iρl/Z2ȍUM"|?9sLʬd!X (hN͵&\ʓb !qQ!/5&{ ==֢&>jc7]so=ڱx4DPyӕRq!tq+}=;dtgpq)Jt/ED!Kw,m ]a<(9V DjE@$öX,k\pV(z8D Ś7ԚOOmf9w}2v+<e3b>?5~*h#;-.܋e1:%v\ev\'a{b7@GUv}&ܞWZRWxX*#WN(ꉦvJqq899dvC-f"u-Ԁ?w c(@H: f..˓Y3ӢYz4yή{\Q$S橊5Ӓ]RZ)cѨ8n hЏ0_^4(ҠnrrW - §Vb!pM \)"O96U ߴqm߸ Ц 'kbzhxVWhŒvSrwmR]\94zSVa_8؉VOب|DľHz?Ο8T ؗ`^5u V|߸ȡ);=^w}򣟜'c&hU*Lvrw1<خ@N:U5*)NULBl0j9G]IfFY'n $df)ҵN|/G7RNZ4QGkY'HJZ EPpUUX 6q :JkMJvK׀Oϩ?&m9K7fbp$1^0/t$va(MU5D*i3dSVԕwz_%5a`'L]9[H8/]&S.xs9M_ ZN_H/Os$:߻__rR{HU deby/&0 ?@>ƒU=dra nxڗ]nh E:=wW=40WK`Ǝ ?Et=HK$IB0Jn7bĺռfVt-jی]o YhS`|\7nW 0$m+@˂&=o~̊yLS#!=W}B R^^[3'g"p5eoVW^|sS9x:6B??boL]8Ȉ{} WS.Ft`bQDgM ƽ~]͆MzUi6|Ǜw~/@{jsPʰ^څgsNK:a%sTpozэ'O62sz_3gF"\(#ڮ\z@*,U @^ lKTvܑz [t;--4%o1,&-rZ =˴rîH;>MCIFkLв]UM_ [>+6/AV3o0aPyb 7PIoDžSœ:X(}(@s ׂs9%rE'ѩe* q3}N~7`WPA5=:9#f`gP( o WЬgj`/|<ŷRPq9~3g \ݹM3kXo,'q)Ц<:=8/ | )_"vD .žL >C@*񄆧6&S_ ug2LN~96]`ЩC\TW)HJY&qD\^O`_ Ņ=Dgs;#[|MrA== : 0bM4* lbRЇmrAÃ,DhW+k?Xqg ykt†u8-.T$%>QSYSQJM'ާ`s̟;Ք_%PW_Wq-B:ՂˁuDtBD*LKˑ4PK_!ozkn-:\[=w=眷˲䪜:zl-\5nHu6%f#s|?mWl7JHݶdnb IDATSʥ\t 'ȩsn"˝sWEbЊhFTkoNzF=y}Ko ڞ|(=t%4?}_=r$Wo-YN?%NB:-;}ZVRϟ8:QO2pdr ̤TH!_N뗷_})kJeł( a; |8jXgigPџ-,}E"@S:Ŷoׯ^w)2I<ı-cS= ;LM-x̡>F_4v=nݴN\B5͒;xeF4X lü%*TNcD4s@Y< vDM;GB;iQb*.6~_NRz'6 (M5fr02N jSY0:ɘ` p9h` ν4.9+Ir bUZ%45T4]*zptWŜy^Nȟz^_י$ O ~~{g>󙷼-}{?# 6p+pw#e˖EZCJ3ihUcGP[37028>>jۥj5ozcN_ӨOLJQ_0,8p4=4M'GV ?ÃɑсDtj~l- 7Yu &ʅҊM谧+FOSMSC׼4j\;$v*&:KdѮZJQ@6k#!1T0ir62AS8bSXljݲwb"rħOMs'?w6|^ ckv3N*f--S|+}kTi|ptUЬAIpV+ژCO>"l:ΐ;˖jV%AJOP\+07N :ҒY2idc̣z^霘- d_jז߱ee'Rp{pcWSOݾGp܂Ofuey=q G&˛o+ o݋/>?Ȇr\4W-eXm/E͝:r}rr2w7*0 5f? gx1-zu;BTX2]Ufg*C܋R[yW8%f,x5@Be$̺lF]ޕAf@.&D4 ljD`+nz#Tt+V%iٕ*(O/Ehs=_z%Xj4pD0`QX`@xdz׳g4 Ll'hQyˠ]]=tMe=ZzEdЯ PP9. :rV)_C1:tu ,E: Բ٠ĊBE8hr. kοUaiͶu]xg'AD fȨ"EO'ܪråLn~d޼a-zm%|v_TV RX"k94Wp[l糱sd.>˲Gjt(W6DoCgG95 N&FݿܿUf'Ojܥ;dPEM?| ƒ3IXV*\L\P?V(/˔(Ν>:.2oA[4mB5VbW1aV)*jzC[%U~hD([z,E` P[\D3$^|@)@;H|`\N}nmj4MnIƭLSZ=HU2ONon*}.u9cj'|JHa/^YQf9k;v,Qky ~"nV4P1ַeP믿^!@08>(ʯpOQi }{AaO< t/bU1P8C(_pX-,`nWvF"0I<G5,# ypҗ{EI 6P1s0i *4'go3iݦh#1\(n=;5Jūqc{Hr\(G^wչɅl<Ľ?؛H&W=uĆc7]} :z/J59;QGXq}?ob&p[sڮ ʖyjn[D.A̚Ir#l6S"sj?p"_V ehm9m|/2Xv bll? Xh`%TuPF` XǰM_ L&'OV/"#qJjvnJ^-!NZqT oMWc.rUd qImnA[q8N7Y i>_Qh` Z%\ dW5Tƭ640COzsK?X[ȝ|hc$nh_Ѣ|>]A,* K @ 0g+u8P6d2PNԂ R{>|g,d%7 p|*:M&N;4{N*)x_2t2S\d.)"_%!tO}ڟghͼ|x*x@8˥j>S%3! E;8:ȑ%6jdYhP erNQqЃsUt~`vmg߉Ny.7Cٛ|ϥ%aƱ~TyāGkpHj˹^tGd<Mk-['g%{r r~Ɋkld˖ T^$J'8q}Bo0yǹ6JwGu(bf 9a:eBVj8O nNh^Z:ytRU+Qg(W1E"7 DMciv-":f2·"6Bxf>78H(HF~Z=m2tnZl^2DB .[!HXз*ZPltgp-_V;]0cxޛwpx: f5 Ճс;^n{g76mPIDf:k0-RJ1ҧ1EGF8q2eA5i^䆎NKg&k#&KM/Q7ܴ}ֱuCKp0 0qe=xjD/ܱq/d ,v.S0YH3PI,a*fK>oXȑ` aQw{c! ]V;"k77 U]vnO嫶@!kl?~UP@Y!]*[^n?g^#ʁZ8B(f+ !4,Κo ˔l"Q 8aGhtk\Ӳ4줩%DƁ;.S׸II]~|7[zr=w gXj)")P~ԧ7~7կ$@:\LHLK;nwߜ\R8 *Z+)L'k׮%l&-S뮻~C](0$\BR* xhR]P! %+?WsbpӇۗHcǰpx.!j U.dr`%B4'^[U Xc FPMyC h3VkR&xCI,*A@n=!OzaǓ_jtCcayUT<@d4lYx*تmq~_Smn+2zk/ʙb /LeWxn|^74í*.ݰs~0>x{߿сX4KlVꨢ2{WumYKZ5ttj]1@C S:3¬H\."zDFgTh,dж~Ű!8$'hqDD[IU\pd{DAuRRӉoLԳh<|9|hEAT`0&v/3b R(dIJ_it|+챪3:ٿOҬRf5+Y2hr_8Sk_'Э z6AAaի!g/ԧZJBtMP``d PSLZᜈVѱl0X;u;^|;>9>BˊUrf.Nl\.WJ)ԭH#RFU[c Rg&ѤM }[/΍?ţɡ-FFE4P̔+3s~+ʩ$F2el|!("X}OW+D\媫Bý{^' kv-[lx߆/Y b)v> |#l$mn &@cf@&c Ld6ju tDZ6kL$v/fKhe؁92RqۡTz?rrcV!$|+zGƢ,hz@_W:73ާ^~yW^~r7s#sS $T*1+T؏`+[0 s{`x0V6_W,=~KS3-;:mh@: q IDAT@KzggOM-9;CDS=K-dOhz;h <% }SF7(M2IʿI[E8l!,Y0i| Spz!5JQ-2sg,K&>QCstњuSf=|,^F.u&6j @',vylЃUc=!zn2@NKp5Zv\OO+p 3ZA& 5_&uժQtTYAL(;AҩX]<`/C:P&Bi (Z{ w^Z4]W 禦0 M`k`u)::"c`@z[qqy=;׳c\ώ3R'6}[jG4aa;DkĄ8KL)2Y !`^29zK 4?\թ/ڐ4ֶQAwb;Zv!FпF붚.DZ(KdhцVB < 5.c Ml4xCаm>u$l>/=N|1K+bZgVC#O=y|!ca6m CQʄd?iSa EACZ0w^L,3)UN\Fk܎]\/jNB^Dd; U'R@}a5Pc۳a./|S1皇~S}*J=\G]qM/.FcNGVWsF1u!-& Xݹ7_\[X4՟2;H^6-Nޑ.S׋%@ݪ&|nu|۹=YoVN:Oyvb B&™h_^HɊf\1u49MzQߴ4qUӎCoVAl!UȮ1­D *e7p-f ihw|,xګsźC/@Uح2IۑC}  ͮ[n HVaݬ[?ifrfݚdh+.E! X!Y㉤ns=W9g ذه\OHE^az RDڛ] X7\d`0ɯ!amHZɚ2joў4Dyن+ L(uAK>eğkG iY\g=~<-}͍ {aޫ{׼Oq,=ae0k^'ZFtR-ez"l] Dhأ}fc56jd:lUM#:4Q.Zjބ]) (SO0գ r Ͽڨ*G 3Syȑ'`;?m}c8.4[O!Z vWkzs,Y㎠IЀx7,+Dx(aƒ~Uч@#l"+؄ h;j&ǧ]" z#[+sbV:ڽ\XZ#t} ?Юfgc)ݲũC3R5yc=tFjZPwRX ćR;MK E7 x*nv `4=)r7KO|wbz vzsop䖓;X8h"-YCq}l)ov.؞.+ބ/_5Rey18tA89WojQ&ezuR-Ro/f^fi6n^}k>u([.p?|hL++_~kQoO[;zt~9y5unz-׾'~ob|u{߿?}S_wf,J0C.NWiRF#˩:T\UP+fM:xThלFy7y%:pL2Ήs27Y5V"TZr#6W89 A/im/r@! 6zR3,PhUO HѪLk‘nǮRd.j v+C{m R][͝׿cGX+Bv!{;'"4/z Bm:+8VypH@3d- R @dʠÊN0GZI(/P`xX'pxTOwd~_CV2~x;݈UPPAJR#O*3<6bK(0yC ^2hz݉>,W.X› jcGW̷^Lt *&Pd;k@X U*W=!H@pAf,Ccڵ_= <'f]kZqzKEZM·uh5 v% twkɺv@tu?<ѨULW";= *Z&FpJC*\y@F5ʝ̻yЩ+J-(XҝNbvlW7kFQr-W*ZNfm</Th%Al(5JaHT_r[^"GPJ[96sZ}E9!GYع;ao]]jh)VZg4nҗ~~n 6g?WggctnͪR퀗 bk^ 1vYȋnVY-p1 sQ<;=P,VYR Zگd(kOFq-h䳶$gN?߲'l>XCVD+¬bptK/K^ HNh0R5O?*Ha @"=g3%a/0Jq FE?C&||0 ^%jǒ 5,٤nMzx.d[4;PNISp(Zگkn1*Jg{OU8vDcAso0-]ڿ̋t s&%Ka#T1+]j)Te"T zŻ^_~zT\iu2t13*H2c1noþb*e\Qp2U1w䱉s\7X<}N\~b 56 Gq6oB3K遞r)g|cƵ@K:|DCt n{[j)3ɛ*Nz}COɇ=}hj=3ǏëHPmT1h7zeE8kҟ?~?_U/7ݳ'؁YOؿwwzH@ Gi{j͖F]a@s23xmE[H+iͪ}|Zb3OAXVLH5zqQNVtUut\bL4X(_r&5Q4]!y SUfUҮRZfGʡ]!Ӎ!HI"XiS]J>˅H_i"gX/.*>@ʱO?uoV?`Z(X!FDCv'Ov*}6Ьrjlll|ă5'xFN}3yM`ys&ηbdB)&Y`~$FzX}⊖8 q7^dz6gM'YinY CPǑ4Z-)&5r$V T.E^Br!! +$*F-\Qnl3_GD4]T%W^<\˯X<򈷑Lx#'M=! gIǁmQ`kVZM&{#! 0Z | V6:D-!quQszj<PX. OzQײBNԖzɁm5#iO89}w߁.ڻG~?Y &kHPLOW<ckUߊ55O3MdO]@K!ZE!BpSjj(qCzMXDaA%ڲ8et+ ./cـHr߳Ǭmh5K銵t71%}Y!>qfVs8[.f( Z 'K4aeƺ#++)^_QE'R0T[VN=5 `C]{_yٶfhWtx(APտypSQ0S^[jd U3&٫ѱJ;pō1\3zcӆ m gL G=}{%{}|12~n6PzፗW14s rNfz/ăw@5vBQ=ro<=2R^>:K;a +bQa^˨†t֨ߺPR}Q;h`< Lo掻}{O8wGfuuszeinH(Bת`̕ftvQ57 g 9j )NXq7n}>*Φ쬴 Vkn1cA@"~EڍP\m3uPE ,kDvEyc|k,$(5H mËT";$yϯF1 SV!H"䊒XnH Yҭ$VJY싓Fn'=-O ?_%e>%D|; ~}׻e#,~l^^^"״IR7\&S4g1d[~^*E~ IDATH'7@0j+ )W]q F NpequÇzꫯ6^Jte=>LnyI!Z݇-""9,颀ViOцE@"l%Y0¨֬ewsaHj̇MMz;_}zqԁX88׆zïyqznVG&2s1ES!dH8Xx +ضpRr!a0EZ! 师P M?kH^F6?E& Q6Ks\nĬZ>A 65NwWpv+QTZ {&*:zn2mP' gV%H_n}| "=t#{(2}aMzBߍrY'CYb A!b1?q˵_ɜ\tK?g{χYnsSڞYaC+ Jvf$.;1{+Ŀ>aůFG:8vea~@iM뢽"պ4R4sZ1X0,ښ\$sL:JRmX߸SVIZph!_< }ctbQ 7eUьá@ft$­èPz.:=yPAaLFRNNM&nָ[)fMw{*LZ^_j({&l~iAP]& kU"O ēU k4Q|K*Hxv± &V])CˇI87Em;ql^~YoюPrRk}s~ѣ| t|5˰/K~^5F%N/~t"*mJ+.@3U1D]IˡA몙 5'zXzc]דIZY;H]QUNڽV׮o ydݟgDn3XG2Uċ$3k%w c1ikg<` f%\ Hwڹ(n <<J\HC/}KS!Rya8 R8qD훡6o޼y~~N̬8\+JX!B2 5A=dމr"8t%KX:iQZ#bZ#D\sƍ:ІNRlk2ge=X̣6mM|~llկ67r>yႰݨ4s+0?YWBTxX+”Tt,6!/¡mCT.dnpӅrY%Yrirb5"GMaa+Z*z 6튰)7{]wwNgDjO^7QUcɅ WC=0{M)z6 i q+t]x%XBTʥJ.ߑo"Jo>hǯ91W h' PCRrm@`¶ {;>wG4BTUpuÍjvp/LkiaX*(/!٤8,'XTy3גX>X2uIU:nCnJ;JjN[)  8UBcvdy#HGKZ$OeOmXp4~g2SsӇPkb643Zf\)ŰA _9^xpNf'al< XD^{v< :1Jg"CMߊN'8kESdhAXWgJWڇE k٣Iwn{{ޔ׃SìbdRaf ;PfC:bm̹NN xVU8|x=Bq Aܷ]k~?;z[.\+;=A'`ˈ21:!GUf1\r Gz~d}l(U1^]w+o .w.cׂU׊@J~ICC+pF'5É Sa"Zza7):hq`BhuПmU`ŝy{1ga +#T\ Sg& vPBk`pa6状\o91QZ< e_kdn6B ` ؇`&YG~\e y7.tVބ/ԴÇ*^믿W'BJ=kF!v?`.~8߈2\JLhgşk!fG$C 0oIfWðw^ɍuX pK﷫}^'5DڽZ`2DH;LYYF1#Z%)j$ Hw9zl9o\3'娱h H%Pz5MqR10=[5 ŋ!P Ū?S7w R~uq5Z>=^Go$QG!M#3HoS0'rWWOVObT U߭WM䙍VV|j9몼`\Z_0c=ttd|PK/^:9ʔ{>>$u[>;Tbe}1ZzsVؐN?\fHzI`iɋ^*hEBl6Q4mGjTO"7f%2QW3Ļb A] Ds7(EjfHm*> `W  M/mg/0gZlю^[;Y9Rg7\m\u&Z23ߗ=}N.ygdxX<`?6 #@hGI!LDu,'X:I4]0 dqM 5aa$>M) U/)mپ{̀=^;}Q_ϦL3Trbѭ! UG#UVsEG%﮶nx 6JTū'pPk;ΔiF$,`F7խR *H @%taERQJ V 12a6*D5[Lj}!+Wwg^[ pUuc`^?# }cc^eSWK.߀^0d˿19mlVWWI{@aqH~̌Цj/*U7WO`V\yu5FCbIjJMfpB/!YB*Yr!*Ed"=4y#.!oar}(ȮSZ;zAt dl: żw}wWu|T=2-6+J&1Bórб͗r]ZZxᕅ)y☫U\\+> QڱlZ@7 gnxۆ jV|>ʞ::y:SiyR! cúQ-mۃ|C`$cQeLM%;uV[/+-̴O򵅩z/*eW!\;6QwY<vZpU_.-wuщyP;/FÛu?4浯}m[\-# u* \GzEc}EFW0jU']@KͣLqBZ-;|N8Loxc匫G˜SRfZfHN>[ j*]*Z:e ޻5܂gaUX'%g^Qk#bʒN@F:+ R~9(};fP#Zc~>|# 7mڄݺ Dl[[bwTN:r38;; &E' 2r W7ґ#G( aKjQ$b¸FK:yY_׏o~327񍔃io^ygM@b̭d?bt\ϸlg=E21mI2r±znIijniqL\AYפwssu^_V"?I=?W}xVvfbxR{T3X;v1vĆ+9t[o9}GbSɪƳϟS/Z`I8ώ?Sz7n`cB?{H^7lzӟ&?t_t:͝mLl?~~vp~Kŵg~Ƀ5ͶoHCଛ=LUrVgĜ4 z)_{N׿mմ?Tѐ0+@(+ºWJ!VoIpl0J%(S&o?oTڱ${.JC~(fzzV&FUl#~@̟+:7 3ky "`WOꍚ^\-/MڑLTNU,TIK(Tj#z ȯ|Trx^Yhհu:'PʂKGC K94HOʇi'0vnVW-) "MSyynK% L޷{#+ܱsK}z޻=]sOL^~ǧHdLD il y7Ȇs0L h XCEK[ IDATr 3MV]q*qW1{ ޔ1yI= eF`*_4)/hba\+7FBT߭0?σY7>\o9zkyvoga0򞻥ѭ+`Nnr #ѐ#[CFfOAn~E%Dh5jEoUK CH\Cb'.1ripC>i Ivmعp(.- V-1[BӪ9\U7^ѻiO92_-BvnU F1(.ίP0‹woa+akS'K{ؖBtO/} -xNТ$)cveVMn.SBTwkX50 FB?zb||hӮ *9yFw$jch#zGԑm[;e}&cm6-bCu=Of,خ:hp׸:~bfmM؆ƀ^wnPh ,J2bZKuatbOܔ :RSLfq䑓~WW_Ƚo1_78/l(9/-X!uM#fg_Yl .~Ps-4xT}vUp07cE 1=!85*G K͑ANJK B#naodks'&7oFEROȑZ;9^wViWVV2kNw!,±pXsZxBشsM(]VjU4zşqq igI'vz7ñzF*ھ=k.OQZc`5ŧ7ˇ_-820{ϖKWP8ңNg-2=A)9YkW`bU΅rެP .t2@p;M_AJ+B?:Sj:{6<4 *Ux/;+5jgW0u#NI 02uZ%iUR)IN'Y,8j'~K2+rte0Id7Jd/lq)=0eXy8`?ͮ~-ѶD׍ Q'T$)[ gFnxĢbB؄dMozW_Em#wʡ_WAYbXqEmDc(NkEsP~%xzfz^W ĢdWӓ2wo0 ]T@FzY딫,Ы`r`^y.)1IXccUWUY},wSJW/KX£!T^tU&9/|J|g>+ -gžk^qkB;z䱣0\$#tD4"|FVA Nīd80ۗYy\a e,Z,u**/TZ@iL&'iCD37.C(Al\8|[/#z`V<ַCD|{d&QmC>.ݷ߿| frua;^̕n&hZx=kBUthnv62 j93ghhh;@4}ĕzBK9c4]uJw+XC/YR!paIUJ<\uڷӮ8筿~W23󱴟鴇'fnmc^Ԕ[ٚYj](T@ k=YѬ@LB76 \ę q'TG ̽7++*Zխ&g%jDсP<%),_Ign&rW!ɽw7n_.]J잒d17,fES~3aaHwk_J#bJXSE}կ~>˭?O.8S2x`Nsuбo{~ ?wbrO0AU>я>`wtt>55ũuf/Ĭ!Ƿ?>#:<{,_lqLvx=fp=@J/ٕduުc_&E0)"XOoS'!5V12s3!@r_Z=uwhW6,򊦜:6ssP\>Ʋzl` ^S}p$A$j9W [$V=) Rezd!YW=!F-&Y/.7HnуR]l=qu"|fռe8q񈁰E sT,EmP}ɆYJW\qqj=;7n1BDQǪ2cU(\񖠚*̤J@`˺)k,HWnX9ߺpUfʒbb .*_5iEE@2(g \,ʹRQC^wרꙹsK8_w~KgOBSmiq?Ŏ\oʦEW;5 TyX/\˳O+cHꇩN?hW0,!u#pXO9SpeMӟXD"^9QMڥy]xPx}p ]ksEι]͈]篮ܱs϶;VzcW=e>oC82:Nn{EݽљuZX?Xn8YMJAfo@u.b L>ei p q cb=MVXDtH ;ffoYOlW\k/)Sh7Nd7+Jyk9-~_)YaLsn{!9+Mb e[$#io1]ǰs!jE7EaNv` GWBil*Hf{40f'5y 46[}C Aqwdߍ q7¼Ɵ^/FC/[ND++S?lߙ[^., i QN /K'jbyʳVOGI wy}]w ^{xzv/42M@ޤE~ uBEНiOiA'OfɍG17eꀜ}Fv"T23.PcDȊyjp"P-H n -H"òMqaa6Ps/вuV {l1],$$&v̯_ʰvF "RZ–%x %HkHDLе A֜<5R6h%P:bU'0 r6oG<m`PSClk |SK/MONpP 73Ͷ'x2?}iGL7ѹ8[l rʦx1b ݥbPxz2\J˙l rt־HQ|57\œYm}ǵV3l )3eΆqWxPDJC@)WX.wTeU 9fu985[79Xʭ,W*{IrwY.]y] @tA%%2N+".2ZQUw)x'V'%Zhш f0LOk]VfeKRzYY|X!{aJ=wm+yRR$Ɒ앃GcEbf.?ȦQƚfӸmMbM L7@gm-3mRkɱZ*z4hjK^̬֯OnQEd Ӎ@zPm_0HzzW:qO|A7ܝ*7կkה٩$F;L\ѽݓ&AP(DO~򓴃T< Pu G4ݳ$,.zP/gv39HpP, d}/pwYdq*vbu9bw҉d2ӻ_ynx[֑dlƊR5ʕb>W7f̡ 5#VHbt$>f& oLZ0QX/!wTIOMϞ?{) ]ciQ%5THG76 ?t @_؃tzvlhb:mTAyrMH@T;Hjzj_Ǭ)_H(xne(>yytラ d(k>W7B w.f}H,$؜|83$3K3f"ar1HPtlpTqs 22+.Rth@SX$ސ^qEd淖pDS~㏟׏|>u)FXmՔa6HsG! #$ E%4 L'A_AP:]OS$ MhuEcuosF_1 ]@Y' S,G^ Ck=e5KJes?ɧn:+)7w*;I_"-Ŋ*WUs#DdRsm?˦p xC>aƖF J7ZFY ,tz[Z{߻ߴZ\XX7OdϝSQiз&b'=[^ȵur!6L0ʥщᛉlM FsjAL\X\1V57w~cyZ6ZP*w"R ̮߽z[Ou>яc`G u}kT!W GiJZX_Y43h5{FiZ` CrvD^mKUi?A*=G+Zfl8_>{qzO&1:c u.Oܖ;y]/QŴMk Um;x.N6 Sb?29"uHOkݦcޟnTr wإt c]lfYTV?+Flv@A>O }m 9݆ذ"PeB`.8GuWznTѫRݒE~%*vMt4<9X]mZn߽¸@4徉;;ʹ2퉋9_##uWUӕD+7%؎g][K_ W'^_e{LowCs??WH(80VèV=o,uя~%>&1!C v)1.ʈTr"bPwcUq-.-O +utmHOTdVY{n?069KG AJ42r@V//r߭3 .;!N.N0&evn JnP8 1ď$Y-:tAyWA\7dbm,mQ:0b(84yxw2{陚uc3lXeO"HQ&NȬ:xd0rZ YNgiT36sXy̓^??LϪNdbxb/ Mvg Ϗzmu#`R"e~k`G6D]( b5}js Z9[NXއ ^ (S0&aHQH@=peH=1FYϼr'Oʬ;՜({'b{puJiҋ.oo=}+[*(>_K.-8Ғ]|~/s2Q+24̣wܶ?-n>m>s/,.%9t"jף˱dfV4Ul%2j06<4zvYxGnRܪ"gu:}d_zN}>VG+# p7 `P2U?Бp%`{&k«NGV$fUO2$dFHL_x 'uY\Qd Q,5nlw{i^sppO]yTtu[t&ʉֶ[qƌhtϊ4E%ݳ;W~mw Msi+_;^{M}c׈ 'A FTCUḚK7MV\q@G .=*Ds49-Fvǯnѳ (+UD%t2 KދpH ۷vipǬᢏ蓙Uող:"\@s-hjrKA6MƇg0`k8(NBT ESۈƆ\:~w@C %Gf̆SP<"wۅOE0A[z][ʼnA_L5!Sȼ1P'3U+Y< _xz)   &Qp}JFcw.~'.Ύw=oo+IR(W2ħ9`5{@ =W~xebZ om0?*W4JPG-9>=;@y`؆XlXA{JŠ/R/hx{ӟDxxyU Lg\QY>NggMC9iMT96IDIqVr_n'n>c@@J8*b [bGc}0f#~qV \46\s>v_[Wx=쾁ߊeP+s>mXЊV+kK<|o|(j^4'Je>k id f 5<5lK@$dQVWvv ꒊׯd6q,&]V3Wt|jYY)tfѢHm(MfJ!ʊ\ѶW܀{TؾIg8uDWz8+M*Iw8k]3}~7x} ׈tg;WX6SDr-zz𷐲pƧGz; @% kGFgcᆖU9)0BRKɀu?T$'B8? qExc0 X*k?Xayr>/52oLQ)7{ dEcFއ0u- cSSuЩ+BӖ_=(mbprlг<0b}uo]\1K(S^0še$v_NH{(Jr(Z޶kWۮ{7 ȹV}:fQV\k^ _x/~uUxٞOo\4[/W2m=T@ 9m؈yVp8p׻3Ǧ?&I=} wu{Pn? W.GCi_f巖V] 7:66k"NtEV,YM_+Y8u9XI( csvukh2PXVjxxRسϭ7.@aSh|" *sz({c=6Z5fI@<IwJ^9ߩzVPj]uiv85I OC<һg{z>NGCƊۻ^cABRˆ%i zm։q^tTgMحlh+NOu'ST9N1's7fw({iq5ϹEA12v? 5u\-__DHO)=zS|'? ݻw!]SU@tkZ>~a 0a]tU~<2wוeԡUx  gLV4VL}ȭzS nb@8B1' !'D҇Tp 1Ѷ.Xtke#Ypv# o1z 39!oUhGT,l&2I#ϋs|gr|8kQIV.W7]Od=}oGDZ)d$V* < zG+NPaCv^<7I ,DZoJSŽE(R%5hct^ɓ>Mg3{~O|w;D'VB˾?J;ѧфyi&4ف뇸ղڍU @Yv{""r@bi^"pt,>\ѿEѻbVcmu%^Rfu㕧 zյKv1ܕJqR"9D1v#r߮]ik^O X *8l.WFGt4,@&,įC0XÓFP8U-UMKg/ܿ}hv{0 WT)oϵ |ct^*rCo{S.x%ªG ~m@¦S=R.sb@}Q,>!O?$t"osCy1j_ژ7T"pu*(|L#B\B4Ju`p4ЎdM$Vr4h8ʜ'5UaQƄN!6"jObTYdwGt >P6=A\zUBطW?MobܑS> ƂvzJ1qplr-4LL-~Cj&.sfHJ ĹQe!b8=NȌLgKEȌnu2EEW3vip[Ieťxu7Wtn(ou+:UE)翸HP$WđwPFe-,??BBuy(vEBDE.I)sjff۟>}`էHO*_qٟ7 \''b0[Tވ(-p###W9pb#kcc{qj~M*zK+& N 1"$ #u@! ZC-f &!WaWЧ2f 715кϟKmm/Lx57mv~FR+ V^ζm[ 'GFRz, a  Q)cy̦jj4 /j5\~Ⲧxzs?%%f-r85 %Zksn}oYBaՂ'7Յ9y|rjӱ#fj5y5_SԨ_K!uDFox+(a7 < t¬p}I][Y{u\Lwkv!nYm-*8I1Am$c `3iU:/lRٸ@(K%&1_>:B(^0m`HLؾCc Z}xl|83t%! 1ד7*ؠr._ZmXMf$w0j2g立0eJg:oP! S?m۴iy7Fo2'D:gӎbrW=RTBUnZƝ&:ҢA'o96(lv]qWqJ )#Ci >/}KGo]QQD[`7+qYavp."/d>O}WWY!"x"v'(7IhV$O|f__P \]׷@ U$c~`Rݏ=ߗ4ti}Dv3HLlC3^?;G PN9KА:VW!p 7|B%'z6PZd`zA^|o|[/zmzn5ޑC{SnSD< &,bJY`>:9!6̶ٖ2J}imWU mVcj$*F}]]/oaWu \aٰ>p]w*Y'}yVwm Ϟ,\)(\BJ~e !kBe7%qzt0CBF/ `$aQP e-:S&ʢmMd!AVݺhzŠ'XiriWML#HGJKW |>ͫOw+Arҹ'u5U+)yl pՈGGao+%&2[8/Ɨ M*\pH^sGߍZF 8%#&ZuᗔYwfn]|+W78TtsUd8ȂDx@,a1Ҽc2v$?NPS!c }~D^ZSfQZģ_(g6wBXT'" [kZXѿVUq_}/s18vbL;H|M@]r*VV;!= 'q;YL4Y~B٨ձ 3AlWWJFm-u1G9DG =VV#Éz۬{ϝY a0pcq ǂw%ӂ7-{%٨4]ZY ~S9/cT.mYΕ y˴K8:21;"{Ѝ3Z+ ksT;7VDصjų"^t,MםbΥÉ`|xggj} <1V+bZf.Rj|,NmHjEB6<}[ ϫGl`n|+"-\vx*Wn;o2d,&nkhw|{^0·dn)A%<,W"V8 ou*,o+m BEt*@Ze\#+=xb n+B2iA 'zä1:|x'2U}TwY$ߨ̇Zb X~TLOC@Z@,L IW\X0q s ]L@~Ddʥo 7*xjUEo'֖L}A@Gu9O(pz;٫+-#i/݉"ã߱;F=$KPunZXjFC\* B l6fo;? Vaè 7`P>_Ұ:V4 &~~>4}h;V 0GCƒrbʺShpgFZ[F㵆9uÎEԍ]KWPA< s uӥX@ʡSv'@rGyzw(D"ʟlkUHWDF Mno,-mӧ)!D 3êtC)|*&l" U1 D|,MP"HO&Y\c6,dyo !OA@:^Slmْ縝BC;JU1{ZTYgnEN)ѮSevw;Y7 +n{o& R",9lyM#gܰn;nT-Y{? >#q"X[*#z\7q{Ęr\-1@J57{cH*? &v?A 8 |t$9l_6nǾF/j/wt?.ɎuX=uQ,4-d[guy 8;; êfN T3ZCaX*] NQf 5lt Aܶ 3NTBW0WJ|R @-q5 IDAT'1*kS5ji8T+ X^֖%L4͗ޗ n/kO,СSd2[2~((`8ALNQNIn!8mt_Ai‹mpJ>wm5FG';W4Jj[?kl3Fz}b @6@]Bp@??9:m6O,ˡW\bc^ !\+O7":ʅ,2X;sVu݃vvXvgR!~N*W> TiRfzD4~YB9Pp`SvlRPȊ!^>Swh0#ug8}F%!lM fȞ]V`qc+?2-,qNHZ:LnJYyvkn= 1]$ovx$Y+u۵@&Cm ~E/:?>w>+sn1V5hrv,qvO> f-.%JtlecoT6?ږ^MP&ytm piY6FomH{if׋DRMO__蘪>=sZ@{Yћ C?035C00]Únp)#ʬ}H$(Vw P82(m?[YӸ{8wu{??tHgŗ(UQܑ yر[pۿkZpW5SDf%.w#mDr7 0et ;5@Em @<91a!r< 8E1u`YO;7s5GG8r$Sc`p@X(`8ʰTXirtPRTu}ymz~^K߃g^:Lt{PJ$R~P>QmTrn4aE, kb Lw!vGGHts/!}ҟLos;zSr'Jyw\q\K4!Ѯ>+v |rCn DaGd}e G? <'A @.t=cGDf [%X//Ⱥߣf+ԟwy' W/J&*??6} [ Fi2/^ 9^>!tұc ׏|D˿= ?vsy%Xf%ɲo[FrVH^nvdV䈞~}:A{M{or(F|Qr#w!7F Abຏ%DxE h V8&4B,|HV߿FoG8ZN ~]t n+I 3jnm}t~bj~& Ҩ4oay ]^t\o;t[iU/Y_~sU?Z<|"e P=v$z: 2/-ꊶ>|"!AH]mŒ)\!E6G %}Ԣ `r21Ӡ CѦ\wC?"!{@pZ\Zը}Wb])g*\"td.>g3L֒.^ln +M$j̎g z hl=(tVW!*w)'FU D@AWAuHDC%>Ĝt.aq(x'22JG|tfIneDy1H K (FpLԙɆ.:Da\BNTkkA⏱&2ڑ8D4l1E'1U#Ƌۧ޸/c?DBA-2 h?nx|p893;O tA5陘U>/%qa͙xݼЋ O˅sζ{Ma)ldHg&!5 ! J ڻgbn:M0SkzR˽mV0?ld+^N a(uѨU$\ݭnrkV ,ٗ##i8lcRo^%hm2r2IP+Y bI92Z=BtQB42B 〤kz֗^Ffu!OZ<]+ UuoQvgSYŻEQqQqbUk$Q(!1 kueHҬuŲV7SgK8@&Kl@=LX3D^YJu_b6v&wVs3Jתw}m `PWB3ljq5,\ZV}U^\ٜ7;]76*ƽw8v$v?27uiZ6D}J /.6=KrDUo>4_,6/l-LF«88YӰA>|Yo41l.P+Pz9m}%U>mk3Aȳ3/Ij`-TԤ]+xm7>'Op#ZՍɣskbV.VKKjV[*9zTQXߌVQ$3Q#؏j C+g>#s2O׿~s~_2_$,ةhD%. _;yxy؎#t]%;ū{XvkE_t)EFrD/v.Kqts7).zw^WeA! Q•;I9u\T|r َ*L4α}MJ4\YTh4k6I:%ItX~SO r,,J|x-}UzMkzMoxt4>.=OH>t}B+_# QgI49)la!Up+9I܄{-uy19Џ:JSnj4O P.oL (c##M&x'WY)߼U-AkH4 ,Tvj;:6;ɒҌ.\I) EkgGΛ3Oh 喪G,_Z-{v'@?PK6HC5kЫxr `g'T Lj5VQmq4pm +V6aqA(G C?{x'22[]Td\,Τbee2sW'uΐcv EY hjJLNXJJ6FSaAdJPK,b@c$:6}馜y71wM_bV cVM [U562;܉glYޯV6'Z%k͏Oru'%0FozGCpuuLF2نa]oWx*QX Nj= VKO<` Z-ƈb obW'01 ZL,F ILwCD 3sP,@=v h6p~V>ϞLzvӿxi@Rh|̹Xg7xd%g* `wKv#o4c6 "^0˞PbOZw83:YJW K/{Ow]?׿|ͷ4#^@v ϾaiFwd/'H hGV/L ߮GPNGDLϢ/L!YG?:"}y$ su[ieU( :"SԹ 12Ӹ"nr΢W߹%Agpb#qM;G+E'X^q;I#WK&2+}Mzaj lY+Ar".Eoп>Vn1DWJf%Mۂ{j7*nEs?L؄lȖБ)X|HJ1.&V6h҄wUDc~¾xu͘j8KdjvnfXh4^&H5V5#WUʛ ,syqNLfRC鮅UB.5j ʅt9mBiP 3#u]UdTG"CcZE7xfZCF%X3}#ocO-LOdvRXbpP\+pDJSp.8 ߚMQHڗVi%aadgЂ{f/qz$zۂaYH&Ѐb :p""BЎЭFq hTvx`XV-|;Db -Qm*@!7-hd# y!`n?.z9x~` D v#mOFm7~|x9YF/pjs;"YXݞܒ;UTӒXɝ2t,6./}ܒ:҄ +Mt-պ⌮܅S?s,CrptHD=5|z]pBveBB tA^~;tڶcL[zr=P,03 3N.ȑxeu)_hu3_?FbE2ڲ?JJUigyv}BfMrcu#ԋPz2jpl-/绸VRhȰ cN"0)kA'RA#"Ɩ]v0 v`llYtsͮB3wlP@¯6f׼ GFnʅbQd9fL&Z-b|R{& DB Kj6_ꑄi4=zj(S=U9~X,ϟxabx|gּl,Ee5 ^kKGdԨMxZ/01 z y1 Ɩ x`q#5No-D}WwNɝf?M][I1&Di'+12D;hJh{-^weDWp\+h{+uMפk|5_`7 &/(%C̐hݫ&4 ZwWqϺiwv敿7vWʫyP?$u9^VbC>)?.7bM*Xx|0P3 '+K . "#73¥!w`@ySᲘ}ᷞ~;*}m^`h3^*rL$Μ7GoǺ6zX@]߲E]~+o-Y74JP cTaV a[xfyl(Qa9:k։'=rbDdOtޛpc~R8V1W׋j\6V6[ã#da4x4yvcR,.GLɡ[[1=; d(]J0@,@؃JACŵ'O9ȂS0*НV(6nǂp证Zm0,l [>YRQ:eoX5PTl IDATu`-ƦdZ},^˟` g x=d?ÍE@ -ہ4PZp=nL..c0Z&d~iADu䃸*l `bqEefC2.~ndVguhUcM܅ItaWrѩN!gMwTеX=mKe-RL@ϧU0I i_[4Iu61KO(*=cB{>|[!e ̎40 wAL#d!Rd,WKO~ILF)g ڿ͍-Mi5UrYXlKVY-52,bB}ϑ}hwt@#c~Gl<#*D<V/\je-(00AMϢk7Ia}2R+T1hz.F*p}|!QIGƋM rCYƫ/]Y Tof MWHq"ۺч:MHQ(W\R&JeIWeTp (*`xCH`F|S'¹z޾z1'8|M#Z"9]kFc*o JDY'W뱘 pV }?TmxhY{u(X:BNtdEݎHc:i!3Mor?ΛSbo$JRB4ݎNEb;WrG۸hw#o uqqI,A\C뷮o>~}$8W_?n\Y=$oJBLݿ~WS{Woff$AqAJr-/EW>nqB&#V  AkW,3x69:2IhQ,l*%(4b0$Zu$3\SOV>7?׬R  v%Yٵֺ?VnTjdǁuƂQXp|MBz7 s,upׂFadjZus  P X`G 1/:(A,gmt>P bx9}ΰܭ,>>ͫQw)·;9EӉ̼@ׇªt$Mm[f怾'wf&e-ffDe*ٔBٙd#ѩz=D:Z|oqhzj~hQf o##ZD|UZ q_ޞSq[+a4-2M@c`` Oɹl4n #OThlQ0ɤlIC%1hrd*3)5(OPvW1=%j:Bmէ؞6!%G#z12|KCC\^< uWlCh` |6_h@*GLϺf5(#{g"˰C'6@?2= X>o!2X;ח~2lj޽yj@y^zJKH^)Zg]x'rv! c KVBc02@?œ`j5AJV"q IJ$hG 9._c%z:1wjXr|mgNvqz-LX>ӣ ϰ/H|L2B+F 6^ ' "9Xn9A\ ;ۿ~qv>&4ǓNd2Rob<RX>AfΞ#P0㑁5.OYG#$q0pg{DP^&=#WU SQ4kC;]okv'/~Fε7oD3ۓL!Vt\F3h{n8t] #/|`=TgB6V+Ͻvw|ivOr k~0){_ݯ7^}G,@K,E+w`޺zC1)JFJ-8C2E=1VB8zq-mQBuzəվc*f%U0v &?ݸ*C-TAum8ʥ֨])Nz ̣gCRi7::j9[/M7ǘQV[Obv\R3% hh.| ͯ+kIG}ԙ{2odMf!kȓ)4~^ζ[y`nضmV7 MNLuRjlk!xTwvޭVR<$) T g@BP w2' g:9aN9ް?5 Myk: F $-&t쑃:폦s46jEa$5Rj&`Ɍv!J\FِE &g5ˢl]⢬RO$.RrTvQ!\qyin %m5He./&}˚HRd;9l:)vYz_'\37?X č$5tGqE/I~^pµ'7 NZ QmU8m|dsմZӟU3ӏڍ-0K'v?xҜL+zR >x@ɑ߽s/~n{*Oݨiyx4-b]T#*;Y=#roop9=Li8#gb?(QJ}+EH &P{=(hXه_.ĴFX~շ,f3!JA7 wjz!_^gU,N-^]D=7"9X9W< G,G.(t]ܴ~tr{'SBY.- ]$Jb?Y) 8d0*DqoSS<)2z+V)g@03e*|^{1܊/0Q$Ǔ4X1`oƻFVp3Y-& 2BˋEr`S_ynW 5=79A0  ӽ݀HKtQ`0~V ǧϐo^s)kjfXI04W42+]jC@m0?8]TS'^%o}<>u,u~'Af>Mɫ<>SRhUU4Ȃjhh`Clx ;֖ O+dRd۝ri!oGNX\dRꕚ;ɯrJx2WKvZӡ{eqIm2Bt!FU.*d&i2NYdV$3ٍœ!*>(jd2B,^B2K_{h.*Vi oWW(rY.V7g&?=7_|˚HrEr$eK-vY2yiNib>aJ&r6Fؿ4EY0AL`AILDF)Q+lĠH.OM!EsFKXms kp4,YV&P;'f6<=|֡)ouC۶mm}_›Pjw!Bww_Sl,-Nn;-:}o@Sxq{Q:2#R RRVG#rn3X㔟qyƀsoVB3^5ܟR~gg(5r|.-~H~I jd=uPa0F/oEYl$pKU^lb^Dbaュz-4k` €eJ?Kwn>$+&tp%QN JMQd /  K+}XT;g_!@Vk@-^=;1xc% mp) XZ +X. n|H.`\U\{2t_9;nX[0&OȻ!k.hbCP FRq#Bp`N4U1;+KEeZ(QH#O?_P+sҔTrR}=5M_;NZ;oyZ.d1AFJtZR`|h>uB}ptxûfVn윌r:pWdO[T.'[I@hl!n)Si**;VT3)7cQ;\j,[ P,X @xFqن9Ff}2JuW*Zoҕ,ֵ?b|}WUQ~Wok͛W.C4c:wA|Uvmgխ{ vL4{Qav Z}|)~.lU+;QJ E",ZAI Y:eȴ>|N^\+xՙK@H"]U9DeIdJvse9_)˂qk'Yqr.4rfL|OYKs0 >T%'[5oϨ"B^,Ykko@5N)ۿ-Y|CX}?- IDATQ "?dwWTPF#XXֿ<:+&RG|Jr>5C`џL i(CC9aZ[ 6`uXq`euTr&f8qyM~Jn7=Mq.ԏtR棓ݓSTBoken-Co~b}t|?NU7VV31@6 5/QHd{$JI)@2WjD~KZY^:NB `[k!.>vk^JuڹA چgČMI0FCO<\-O*< nL) |bWG୪WSKp6L,8o: l: sL~4:[@29JңQXl*e N0 С`?E%P3'3h8^+s8 k?Q *ܕ Q8Nht_q&ѕj#1҃gNZӓ݅ł㔧xFx{8sŐUZA4$R{?UJVI 0uLvk`tIܙgE,z/22臕alNyWGGN=;*r wVTK[Nn)0[Zikc6qeER UO23_vO^TYZTL^U2h%mltvǻ~{Jמ{w펣+mxvvҁTestz"V*ec Dlt*Q mH&,10#BJm"AIɸ\(W袱*5RO%V*^ ]J~IHIRI^. ωկJ/YY$B+DWS(Ğ(o)[[r-!X<Ԝ$}?S_k]9ur"}ŭ^YoQ)B&%,g? [tlsr?)ېEyȶu~V6t!1x=7q q2xT:/ P6+]0 NR& ɸU2 Igp "P{pu=tF FͽrmTZg͂4x4IC}yN恜etkq(=޺9mvp SV^Z1Dypn3/5*ǝz:#(\,(`IZ3uJ8Ax$A-M$v &WL*z$5-UJ؃S+>sk+)t~_ʇ>D}7do{UrZ9&1f8 s2ʔA6R>[LZ#xLD&M%r`%cHN,raXb~OqM` sa:0cv~wza_&TȅDb#btTi4]v Co'!E\IaIDm0Vç$?9,8#[oQC2o $ BgNhGs%Cl~'/tXL. c):P Ү$_^Փ5!sț&ͽo]:L}}K3]r>e7o˷nC֯^>?)rfw를%^+=ÑAѶ[m+N%X~4˨#M\sAPQ٩#b(}A&/-R %t: 1q)IDt%PqLJw56LG_㨛+ƙYԚ =-_5U-N;r9?=:DŽ(j-EB_Ivsvym;<74Y戂*e mӠy,n}Ȏe1O󩖤6D8y3yS1©eCzռ{6%OPW^'ٌXNsOrZki/jӣNO2xHlJ1E[پm c YVT @1Gn]`>GZQ˗dz7ԋ%Ŋ kTӚEYژkv*a?sw6xCB,0y!xۇVj3Xtqf0ِ jgcu$&ڦ JQ2qOVv3MX%q\\qK.Ӹ/L.KJ%oyOtY^W60s79e^V+J/~Ь 쀯—{ON5iM}P]lh3׍[gg4KLiepeƭTӡηEѭW-.Ќȳ_=T+W?XL:6^;4lZ|o}ա VFzҖ z'0t"ȕOA'LzN@7s/t{㩞w`c|&8C7׮]1 gKy=O}?'6,փPCCH8Е E͑:< 7+Pds݉Jo`!2w)!EZv3g|(9{%L˳)Y%:?xW&ռBEÈP[ϟ<)s~;湾(HRI̟O?}PrĢyP 9E%1&\I6`]RKBXF&ŰR[.iGb (̵l|HX,)XI&wBO+A%Fh"SF@Ff瓂9-XC Uz~8 Q-K`ҌsPxn=e:HY^_Kt|F>WJu"hO[`:map Ycgsy;_٤TxsZya_yΰg=3@Rb5{;]8'+)'%SțK Ft>=t:=<tT$g* C&JHj2vF^EcZ39N9檇jF!C,1o(ӔlΊe.:{˷yx{b/^q3^.g/@)$ql5<<iNޭKS QrK/!Lv~&݆LS\d1w&pܗ wvW,|^; Ʊ)NКjʵRFT`@& FF#i/Lu4H7tJ D EhFaվb&sZ,S%+ckQ|w>弩i|.aRaJr)B:An^`HMH:ry QMrY{Gݽ{;̘ A8`c?Q ٨ԋjʪAP9 idXdFoU֕q)03Q,CT0j! N`v+5KhQ >ln26regat!Aה켤*[G>Ԩz9ݔ*(x5HGaYk2!Dg ׈Bn?@4Z1n%2(oܟO 4Bt \Ihm`ml\+{ښa;~bwFԊ6:,!*]'x\Y17E:. +\Mx]삵#N̸ePa*"iF! 7c-2LTb>RSÈ1CMSЙNjxCoav?䈡:nĘNO#A<:XYEU#o$vr8 '{,cT2\Vю9\\'~ڝ3TJ6 A g\Q(X, 3[[X˙|vP]npwm''&Vr$id d(zGЇ6vV,gKfE@P΀ *%]=Bzl3%pĺ0J JO5;^鵩U_jMKr6gbgi ZK߇^ ø6 E]38`<'w?53ưkhweBukOa݁6CF<6-M15L6ՀgQN; B`H i<l5``C(" ]1iAL0{eJs6,3q𩊊=8,Ë(Vc#k,sId4<@"@n9=Ğ_C6TW)bW8n:h|x4Np0).cc\9AvwwlM |ӂ(_XF9mG>%`g_Z '>! s؏)I?1oDLN'w$3GB ?{qI7 <],C vUЗo _W1b~vШ` jN$)6&TڼgE_KcZ*bi(;LM eF`↼EdV!Aa:aLʂYƑWtv[ljG^=$>mڕ eeiȕ촐&>{YkX.%J$iM>^B|v|˺!CX)_@=)rzgx N-)J/@`1!cP?50 VHWͱ/(“ph9lFxo o>44nkW7T }{O~ =W2Xd'W XOȊl6mz\[PQ9sH\:=]oN9ko#޷\mi}k_zFzӼȂLO;8{8-+ZnϦy!.e.JB`&.=1l1Nd g2AB`@"[.?+ gri4&Ź.% IDATxx\~\bޛe<~擏?Q^}rp)B2^]~VvxɅt<>vƂX~B6 Iwtvr֎!i,nX& ,xA4vƙ\-g{Ob1G!Sl?f*n4蜴#+WGVb55{  "64j:Q9!Ir@889Ȇ49lcME5oC߸ 'O޿Jop ?uN t-} ׯuh>4~(%mr5N4aM &Rv1''t@LMmq/]ӕ -UVZ08$~Ա.8V S꠷7{wFcbZ'zԲ=zLX$©73TI)2*嵔U#?k3ZF0Agk["S"[u,^sqd%Rr}^F.\.N.=/r,MP|-xKz󲴴trrr B{{ao/O|:%:((W^-2.ZSO 9PvY|R}A9ȒضD6ׂR-ZpYd$ HurSnq"Kj8W?)+`@ _EMP}FZ~b4Q2`sNq n^.ULktzI.Y/"/C @:Ů}"|p />{LaFeЩ%JI2UʋvqgÝ0mk{ӳɛmmlKf@;Or&KhA`Q0:Njjb{,ڣ4""6p;V=_sccQCAR@ R`H^5uLZQ&rDk͵fvԾ q>pp||WP9.LÄg2ਔҚYڿxyknjTV&_=.A0ZJ&K&D$eJkKzN{%\ dȮz(=hk0fV!+""K퉫 KOgr+jX\'>G^N.DY+Jٙ1i_z@4wν|&ji J[wvvi:Jr`&Ul?lr8z7+l2Ģ HDPq*Rݮk-nPVk=ohsG!Y"ܝKœFcD,fEjZFͰΑ3Nf/-p?޾= dHtE7= *CTel@%%7 n dCHDK.Kd[C.yZarSF,u%ox?DE;wi~YF޲-ݤN\FNT~Ʌr;va\bD8g4żoB˴ؖZ'O.&c*&lu<|lfEZCit3%$>B١4謈#n}_!q3J;=x\Y=`CI="m||CeN G{.W@+Ӥe5Zzrz:5O"q{{U*s24wCc>Z젚ddCE )cѿ" (/ An_+B HB=!,U&4pl)G6Ow;G_}`cmsZ;V֡FUYYRA6͝=ڕed|*N*rߋ2ɬN7DBhgvVy4I<14 l֌4y عeUky2l*QYT;ݞ=iaܥ&~묛**MRVOA|Yd0je+ٴf#j09:*<%qꤠlvi(`6q.R #^1:MEKf:m\18m:'w6J?::qT/ۦUB.֠l\m\.]v?񏵎OÌl{o_'XBn*CN:rLfjUǦs-^2,PdN'XD&e2 ^,~9)1'c R"mHH4_).Bry|MƕKM)^rܑzr!%~ ޢ,~>,Fo)h]GL7Y7DC`N6X %@L4x_0rǨDbHA+8 f%=%h VPIH7s0M&ʝS S#0I~ѕM ]P5.H(};wʀXC rm>Nw w8lӒ9$Lհ*E&,/dn+T`8`7Z'TQȇP,3Lb a1,}o&#nr4dGQV?70%C4EpĒN @ pGhj6-64Xѱ;C%NRh2SWIJW+7-ַQvc!{cOgS k&}3 Zn= !Mx3Gp.xZ/63A~'"1-k5 :vfkYƩ^ƍϭdL`|uu(ƐYYߛ,RQ0&k7(^ۘ`wluX;u&VfR NdiـIh:WΙRc)c2 ɭt:xy`02;PO;]-+9ad !6HEMEg͠7Ű%*U/Ӏ@4Y-D}ళm/O][Wf-r|pD ƵbV+Û2=?>a%gEV%CJU_8pb2F]ɺ%yIjƣ2ˮw|0XDRMrEIDZyƫXp %/[*O/IJw|KDD,y|deTKM&)|Zl#HBx,w\7n'8]&/{Ge6+m 5Aѵ7TܱvjVi2"<5q[_&iJ+1O!Qػͧ؇*kEnQn{OeOn8CC$nrnИ/8|a09G~X^BcE8G}ΗlRHӳ/>y˵%BDthJ{;D ;c / AT*hdk,L`ZS<jx]W PWlJfﺂ"6WMsS_$+^SL` Iqto2&p4LVxrxFV4׮*i @\B>9 p"S bЁFj:Uby*W}^hi^hGG/}ھ炬A5 u7z&t1.̲PXh}pB/ "~C2 +LȖyY/HioqV^mfhReelKy1T3V W4%˹Bชgz+vo?Hy/-Nw*+%ľhYOv^ /@ Δ'q!a\/@zE2gLX/'`WYA. c1 ,65H\qܓR5)N°Y(3dmHA9A~N}7nJA0M[Tu[vZ{'nFn"j*y \d5FP)/Wj?d̵49(9Q--DCu:,nM4W) $ >LF ̖P%LHd֫V5ȑԲȻM?No-U F:( hCw c4AGd17lD=ߐEƊ_Y]]y` Lqu6.PNwdJժ7\9كt+tyG,~L ػuxSҖb|:_?zs([ɞgG/gֽ{~'šGJ <yDR,ZӃwXz=oCt4euìx7^M+EOs@UqEjqT!D5dq(% GGG "G0YSGׯo-7Z2IQP #̝-u3돈9aygGI=W,bbu/7G}t9Cnwle)8CbD(_gwbq,%OЪ Ub Y늮_Jdv4)z2%jI/aV*Ṙ@Uc%Ѝ)%ǚ8L׍`>@ɴ3m\е՗8ZiR-Q A2e`N߫.(g>j)"Uk;;XҌ`?QDot@USIE*8C af4 T"Ҿ;gao|`K]Q88:z^0&G?8Xw"(0J1f7 7:eiH}]O}n<(%ge9?ll )+&A1n5Cl;_Ǜ }}3b)$5rWOh49*m#^}kdx^^C^ !ggwIXIn^:8= ȑ Vp9,LrfBvu4#$Ͻ 6tcyy˕&0 mjl9=0 G$כi#05bBـ-WL8DҜ#<%ɂ]htWLU2fM7wvU q@GjZXi <@]C)Y"8'T_3㙒f,%@;b( G^Vѡ'`"aVUH@؍)[M"ȤDD| B`>'b`[3gK3H2sYd"IV70^|77W_l?{1@oNR-VT9Ȍ. a rKbeGX<? $dX <_rqa,kqX1bnJًT1nϛmݥ\,L *y}<*z= H J'`G V)Y0}ʧ>3I/|V[oY'jr;3_}'4"iXQH2DgFc_VykHub1nb *d#"hҏd:sObaJ--SO|A0McjU(C3 Z9N~^oY9+Z IDATb3gbq }`ovA,h\̑`lbp$-O‰6Oti9}=GJb;̄8Uᓧ%"6 ]RŃH`WH2-0|5]P[rw)BJh=ɀZ yWЯ Guᄸ6,7Qkȉ%uv=|P -&0!h[Ѓ]'zxQN3NKv[0<6;{.߻ |7;﷝`"A eByx+!+L ) y('rxd>C:G !Yq/:UR8$|#~C^gI㖕FٍYUKk~n\ŅUIY0cZBuT8kx2j. >W5?&EPW `+s8żvmyl U˯n4*qB?l,P5*x3_if!$ As &n s@~ӳ7BVi@i#cXs]p!ι6QzT6GyE/{o+I{w[k/3LY4P0ɑ`Z`/O ,")Cbΰg9KTuwUWխ=cˈſE=ͮ1= ȊEdķ'!LXVG& -EAQd=жK~@goo gJ*_͊>sD x/|s. |P(ڍZ8?"`Y `gKnYT(aRCHƩDH".z|>?f|SL܂KtCsk3U8+EV$ 49bSJYxR?Y7IQ?(_YcQh%oEazu1 *bbLT?…8b{.)~SX/$ ՔU &%CJ^PLu Dz.n8YL@:' ['ibL+&XOjWni~E*pu.?_ MYa L*р$gp %sE},w(0YFN'GG5π Vm81A[jLMh,w[^C^F푣(beˆ ai `ou\i_h7$<#W'%䪙er!ʚ%rq G4?V`d䯵Ĩ,-Wt$֚ ᄝVX=2b {{aqnWQ}9ɀֱ9wiĘsgQ'M{d4M$i뒉e  n8N0 .(6h+T0cbؒCSu8ȫdUFKY.4gȯ=B:SD)G,n.u"owDe% t"5ˉY]zuM\j=/$#o<|RS%W4\_/8]qb4 7.Pp@},7u+Y)E[jE6Ը}{gnJq?<3 7OHVc>~[kw= k#G8c7L, .̷1?7RQ<"-)}zk'<&M ,ω¤Zu'7Gw*q:QobbCԨV1Q~\l%4eˈbP%;^P|WZtó 7wfScԱ]rٱ/1뚋 -NB,T0ǰxV %zT>8b̑G_ˊaD3̼@tvSZU88mbr?8S6ۆk zFyJ44-'$iX1}p/%iE+v^BA65@-f.ԪҰ-_`q C8޽NbyWwڻ015֩䉙-]f&}<;GY'İ< ˳ ΑiZG~2rIy&wwGu{E,eXV[R+@].h&k<"=QYv4Y3kW?nfCfrِ*QI:EcW-;w~׾1Ko~[isko}ڕk՗;U#Y[7_aAJ, \$^7{'~Ԗ_X M6Iԭ'g~lu6j='Z-ʹAN5K$H2s# `iҩV: ttZtK1EpIjuz*}k׽R('R_k?zV_[ѷ[d.fX߲+gɡCO.}*S M_7G$bK i4yIx 0Z֍l1dHq!'%VN c\t2x{a]bLGݹWxZThėݽvK>_f/o|y丸|x$@9as6@4IM.ZGfH$CRUo,88@SLɉ2Qy"TP*5V) IAί TV#7'+RU,j_=]'O7I9Tvw;g+dkW Y& ɿ}Ϗ$_0A[S%NMUawOO$@# GC/TȂ#_"Y h*(N^'uO᥍$[ɷoSWc1:! I+u{8'À 0c%5C_07P#p${l!s<#~ 4k >,FQ]}ts冎rЁ6L-$BC 줋~źF xB9XlMEE|0\`DylHV6[[lB'%v:L4~.*NtL3p hL=|u+x0X"$ѫᬆ.?N0$cApa`xI1F6׮]X&v7[ &";Y!X ;/%00(A7MKfZ2]$\OyIUJR*G<=v ~VO/m7CU ^>՚U;οPD[mRen117uk&LRx=~܈g:6ܡ@/a:G%ƕtt{ϼ/omX{_ij_>|7}~xnX/6Y (-"KihŠ-v@ƻ%[ܱmh'^ELVmʖ0.)͚@.=2*8M̲i_EWE(Q1ƪz+ &iwI֭4 jmj5W .R!OI_8Ɠ1 \Gةp%kz RrfJ Fn Wibb6e׼ֻI1~ɲVO`q|+"ٸ:`AZ !}<VKtnY _U#E¤6j=p0[4]d>W 643ltxa ĥJlnV,ٝu]"-;&?{>˝k͝O >f[&pGg_=Kjg5LxF{Yh?֫1>KTZn-[N7.o+ק)WpB#VfDIƤN+geFz1BxxVX_냓)55Ka1E/ ̼P4*04&@wkx0 ϋ$zI,O˻<399;o_"7 Bik=5'Ѩ֥$EPt]l ?8a!nt)aaWtgV2k ŝ[ڭ"+ܼ} -r/3c4: A#1׵R9xt0$d,ݪ2)uyŻ?_KΊK~o\ڽ#5._Vqyk~~0I 3b8?wCq+q|W7*|_墊U5WG>*屖]}!;Wˇc|R;yOߧx֟N']]جxOs7??GHH@O\sA|ggn}b_ةW|{~UʔTEuclw49;:VEa{zvQ폱Y%HF_œLu* u8d8G^~z:ԘT?/kNN'ܺ>Y9翱[?<5nTwW7「dܳKsEY-2&|[mY4UG&A;Ě^ c$! qSN)G<]!nk3e,-kE[L'Q12^V&d С'Rxog>@Vk,VA^d{Eb).[j9tz' a.2QYN%` a.ҁ ?4FӔ9n(DsItxt_iA8>s0z %0Sg^pꍝ5ý6IKd77p% ̀ҤD̮ y%ì%5bJ+5X?IuZf,r*6ɞ}|cdV͝&!U(>ZԪ/TrIy&_A2`)@f>y=G?}NcpзpjMā=#cm޽\k#QCj8x$MH@lE),+iҚg5h<{Zrk`!)?D4 :ɦ {cۗ=s"1I:tPPm4d[m#q %B\&kýGX<1 eK=za As0Jvd3@C0#3`\-KZ҄{v1 23zoga4 ) W(_.U~p}sxaV|wʸ"tt.: smEnA`xgz1ʫ@)̐.W;iMq$mJeF Ppc!{st§>o|yIw_pKjI!H8x9D4@2?$aT*{#/Ւ}?^c`,#<yŲ*۫QV6eQ~گNMի3ɪKꢀ_b4kt8g4&wr dܗxjev>Rk{cQ7~xQ*uͭIЇc9ۗn2fc sJWpZ| ]+(P΅l`mEȐa\ 1i oF,:>:Mk5E(n5F<[B3\#1⮓Gh_RNɌj-t$+r CaS~XcvE v8 0' >VL̷o'B @[Kq^(9! ^nH=ZXT\Vukֽ:)ZT?%~Hb:Ҕ4U1ٴ KAG >Ⱥ`H␜-۶y R͘DO;+>XI?)*(mYV6lj8(T.ȌLk_l:rdaɻʪ4Pɋ"Q~>,TpZa<1`E7koogbX L@pπE+>#L>`8"LCا@2-rnuA7UeoRS* 8AVw=)wf$"xaYVX A/D#tA -9rnpJc h0b^g ty 6(|ܼ(͋oTɦa `{uf 'J Ͼ\u=z0Hq< Y'ƴBIAwʳo`fռ^ Zc"'[Zy]&ah@?;:g?5`An\{!PJ.$j\L*kׇ6V: >y|>DJ~z4&xD|'Ӂ lOFG{clMTNk2x'xeaT5K#J'I!7:u T TtpHLpKZEe*(ˈW.Y5aQ $,h[B}Y[5G kn)wׇԀI i:3Fe-F)? gIRI(aU`Ɍ0ڈG{e)[!Ø'p>K_sYmSnY d`HJ#N0a\TlH^3blh5TLTi"FW鋝jc'ʼD!婓Vw"WTG :bǮ:#'_5<+#dYl{.6/V8?ϿLՇ?@J7 ,HМB3c=?蝊ӋV,Mƪؔ٦4Hx($x"je00R4:bWR&K.Vlv>eaʈ$]%Y Abr Jgd1V }\aj7Bt8::c)4&0'/ +LK[hQ f&IZ IU4vuHIIF՘[!=DkJ$ Aʙ~SR q zbwes vɔY50V\k8ب Ƹ (B9AL8cYtȷgM XIi4JQn ⨿}y4AԆ8ٵR8 [ -Xj ;:~#)"po}n}`{F鍳#"M}\|, RE~9%Iu U*sG[qu<38>1<;k#9?PtiyoUC}PWŴeWDLc!3bk'5r4>ܿ_$% (Jeˮ6ڭvIP>8/V>hp ;_v?}F t~fw]`ah/*v21ZLp"\DMtne`x* hta6$Mt>gB['h(8L#͊ppa{-9V\.^3F-=G"\|BH@*E174S:NJ,ˠ䜒H,Ka.@nevJqv1bO-w;Ԭ tUeYdVSp\s{ A0YQtJ` )2pjqZ$i`^iX(k'f1VÛ0~mw=$E=)aqANxAf Ph5GK/'.u U~30{2Ңcg0-QqHqiUE^oa*Ap5%B+L"RpBJt@L!$M MYEີ[m׎?Z).9El#h_p[R6o((Xޘ,uϚ!%ID= Z:3̰u9 QpzeӝzaEqj&N^&̄J SIEA?%94Aċy^yIhd,4t!`/I8Ҁ(ω<@zYWϜJ Y4.i[㶮מ}/ݲʥ;wo( %y4`EYKybLD JO S$4{A1O^*G}n6:" BeSZdNk)c~#|yDubEaMZh֮]gAPUַw |%#QmTk߶׾=7?妶ܸıigOk[M{|ln:>O^4cAV:dm-%͊H^a=8=Bp0nel7!*Y4ZО4kDt^J^#PMpL.5a >h[q(EbJ yiuK_1}*%BVs&- $Z{q84!M=8U mFZB{9u.-/IP5 9%tζ'JAq>o)8r߅|(ker<rLR5R=$UaEa-FLqK¢BNeˊ|JŔ%XRCRU^NXyQļ8uc'+W[ʛ VǪ՞&大˓r[oY𫟿\X_xMtω LyK7@nɧ$ u+o9V `ekG(#UK "eXX H\i|IęζZKD&`Ja`,TFV6<*0 Jx6;c&f[uTkj`.d%n lO %f{\$*{YJܤaΓ28FTX3Yzkޟܻ].C!|.J?_1CS!Y͘^0` Isdžc:bSP^K}tyx*ݧ U|Uj|0[ޏZHy~:Ah @7%zX zE|Q|2H_Wd~?8~Pw`P/=}yt׾~뭇~/'_xsfP֗ʯ|G?{8 znU%bٕ擠#vl6[Gwv,Km^'~}|nK[ l0<=eVY]y P;ԫמy GhТaӀHRDO,]tECV" -S;uk6<\&pL##4xQ"<#hs2Eay@h(MSN*T7kV44P-(tYGRÅ-J`8w72q1CڄeM`-ZQHGqnluǖWgH.{O.M&&8G PCT]BXH6JҝΓ8C = I4V4/$L U*e>(qRZRU>J%<,T=WHW^]چP"XjSȁjg~ty?O1EiD!I&?0Z;WtwnN٪Usv[b< 5# ws@@+BԄ1N0+׍¤3%l\rA2xV_)2:r)ܟ )hd"Mn:ܯ֝70=0G ,(0pE)&l`i]WaB ZnO$i ?MS8 (?16ө& C~tQl*^sm\9̮XdM$haFʭ*!PNXjW*@Oa$8ɀ='8Rl%] uh\p0$۸]*ȧsTC|~w[FXIտ{~~d<Սӽab&tLi)gD}᫟~f3~{uo#D"//Q~ˈEٟQm%fkT;m3/ǡ6.r[6eb iKa|RӅ,`^RKκI4kXL<ȥkXyFz̲oA̺P,ʳr5ZS@i\,5Y0MA 5\=3r tQ./C0C^tK˦@`)R«5~uۍS͖VSo}Usƛ.I mw^<;^3x 0HnzF`AQAjh+A&.qpƧ R*?SUfAJ*T*- RwTvK핂rZYR'IWWo-OVWP9S+# _JY@}]ؙ<~X*7-~h"|ar[Zl1.nsmUAO^CAH&"( Em 1UYӑ3 уcgK-,XjT]H"tcȘPD_]aX#,Nv}7ry8pUSuҕ>f3ISd+4U<zM 8p@hgBw[9 Y&BBECYU:)ܻ[6׶k|# ȂO]m8AP.b\2F.d#,|7sC\_V dQIa, ؒ ,.QۘxLs(7#5Dk2q |>;w36ٍUQC$LGra@l>=8+b@v53I eHIӃӶby{89,Sߋ8'v6uL@&O?ڬyC˹.*M}QY5|HՑ2Kźh*KN&*b/ FL]+< _{o` n00>:GE+F]#<#//iotY׮]_ {}dRnK~6#Tc7킫z=C-hةۣ?4&Y|G{xV7.}'E͹>ݿ ;Iv)l4J $*xh(D,g1]̏Nߧ q9謝 Í~-neU¬i&V."i (9) \ Bvs h7s煪̖Mq+2 nI@R^)P^f6[ij(=_]yk4kV$1 aQ+AΒO=ãrc7x5ik9Ψ!UVįTN~,T* O]LgڪTfZWSjl]c9V;?'R٥,<}~@]1/vuH!,?3}~ `i/bJyט*,F U1[fӱ! :)_*yrOTv&gMMB EiFm;W4y0ml:N J QJǽarR Fovl+Pg"xq0ǒ1Od@ieدܺCF?9C^k5HQ), ]w_/N2QT%=D+ \8$ S` 5<NOÒ&(rrqL ѭAiHzor`lTp/E0u׃y(ޔ15woyI&/O` f*ؚ݅Xp3$~wd2'ÓAɲPM'OA:E\*EA0\^пV8< |g IڬjIj}uX3|䐜'j8d8i] I`pXtqлV'}8;R@7l7OCQ,W;?QvܴH-; >sWXb23g%fey:W6v6BRpZOp"d "ְֈ H`P+b5_^jŘihh0_fz1i8P/{kJ3* TqE6-OMQ $ :Vۮfp~dGa$:N,Pv%*L VgadU;Bw;oު6[%kͯVbGI\ _|ûeüsoGwC*-=AZ^FPt~S֨T3&Jp}tuXreeK:dUN~\NVo uZ^Wo2Q³>o/ӦfTK&jh|$(eX4H"$Ә-=jW0<ܼ (Ǟ}S'jx34MRG η_VCsh4'S@ E'iBmS:I'T 0:ѹ9x=;>J2VRY q>T^"BV~S^&gd\H"W #+6Zj)4L5x G(pFO zRf?鎢bZhD& sC (_i *qHa| h(>,lleJ,d&\4GQ2Qf+smC"HcjlYPHe,!qKI3q IN_֭9k$p;# r8F(7r\py|*lSABͰac#mՋ`aWjO'Zj&c3JU_Kw}ɑ1燩@ۅ7'3"T]tT\gF%hxe}=HqMR/gЁ Qtp?yn7o6k7VqXd Qrdlft)C( {e]'Lۣzic7u6:wӲZ[φ hlPhCamVcޘȶ Ra.CG/3o~]ƕNurr3*K0zt0.m0m$eVZ ƞFcj VN PBM 4JUrcTd^/PY\xI]SHb=a1``Qj??nW,`l9c|fdl4M(Hg̾6[^Qv||71z8nuA `A2c\~vs-r{ >)񠉁X#&4aJC0cN._nk 0  &!E҅Fcҹ*MIQx=|5-~tnݹ}Ͼ %Ϊ+ޢ*XKMC*jtb0Vde[!OT#9R}F/vojUQX0U_5`gAFOMr:o!a]N4GˊeG1s=X>=E2F=CUa iL`h*yٷ=zϾo>+7Z nx˹`<Lx)NLRL9J,Bu/-'t.¨x64őLʅHonUy{Xpn<™UDbJU3Er~#TP^tfjV 􋩦Ɉ[-vp0 ND"8h[nݜN'qZraIiZl=L藔\h 狵awzW޺d=< Ζ>W?*xNN9̴*!A!F4:ܜUJ,QuO!QjRJL#ڱDr1ulU:L^yy9R:ruE' {bёH)Sp]ؤ$#u^O?9}xk|sr/Y6f+}jҁ\4{ְdŜ*l\ dQnU1߾{tiC4jwew_4Lbi\z2:5qCmG@ ݕpWa@>Eι Y4VAv'ᛋ!HHQ|VT_ ?!U#'Y }rvu=ETa8A% l1MBô9xV"WZH BN8Z_V{P%ILb5&]]< GEP4~)I^alm$"ȫK sZ|ܸ싔a"XzsHj-t.ҭsKnr\SX6& h") Dd&$`N ҕG+>R;u h W3X+3nugnVtY%F 5E&eE~WʲN, 8|*&9AVcmVNYWK[3eC}9TņC "č.WfW D44I3Ijc@ɔ3/JIX7n),i+)ế';577+$ NZkTk_ggi8ڲu ;VW8źQK74X{A\NKWq[>єi T4l{p ˟xyu{rƆ1k1 \Nx* - [ !_HxJO3_6Qs0E:`HPQ 2P=;vBBB/QfE4r(uI2I1l:5h6~ u?nm]kxNNskӴ fl^A&Uvfs-FZr #ʼn/%3tRSKب9t<}գYmQć)_HuWP~lj/UŕsYD ءV#qrTR(+Wr. ϯ(SWp|<}{O=dI i3XnXBDC"^ݺ>NZUyFY,eT|bPM%GNa0}-ð);@<0պ[=lM$ux?!;\~'QVcTTDh(DP5cKE?9 %:p8px3]Vf? MaJּX\tb]1<}$DkF.>ߪi7i %*ΗӤ`zFq\fCv|q|K@p A.ݵygXXq<|kǢ@mhY'"Ó&6A ɇy *eł'~ 4o!$tNZ:ɠ@ 7B[?ᴵ}i>;>]! '}ȀZ-g<^dn[*À(2`CZSo4!?o$;kA` $mv'XUQuTmOvwT>u{g'DfPPct\=R\S)XDHmsE<)wUKhscbNȝ驕"R_޺;o;>ktA< V5X|ݹfs³jTjknk.ӣ0=U['NOg[Y6D,Eisk_ؕ8f>;& vT~UGdTk.crVkexyL&Z4#*]CZb9EQ;&Cze;5HChѰ$~RheEuXrVÁS'Z@Uv`,2Q&W]ukv}`ԟVuq@s0pʼn#WsoB4hBx!l2 flm_P*0(^+!/A4ʸ/?ԪT->&>D IDATɇEV+/_"jmñj݀9[.ܠ^+59-qDK"|?;6<NcBj9V+B05Wi=\ºpQ>A|h[HF҂Kv=DMa{Nɀ2ㅬ`EO5M<]Sv{ӛbU}'qhGƽ1 R%SI:W(dp+AnW{nA@W|pV֟qٖ̞{O_qFฝY$3(02pHAԄj>zEaYB tOYB /&HX [/7vcݛo޿[4N L^MԟNCzJCE[T1o `#ƴ|aqio-:[S1֢;k5cuq,4n7[p~7J~xt}7*4+v(3un,mN8 (%* ,;Kfh:8Qa^1%hD:hW`vjiYHN Ex#tWݫmW0-+J\R{De8Jݼ4ZPr}+vǫ=ZTpyc=1dXtJ~4w^b5Z?MYGYu`Y-gWКHeHb5F.&hk#%}u6D0'sѼ}>vvKt>r ϲ!滜(]-ro);ɋy 5}Z4/ 8 ^Us1W+$\&LRaqJn0&CUt`g)8#2זjG7{(FSKM3yR"s7{0H9 xx<.gƒISXZw@p%}M|)+L08$HZ[oQxBV=dSRԏ_20 ZFAW25AH+I9L/4$$6i /9-Rxi8!WD(tsAX%{9BOJbuѩ6JՋ;;CPop- ġCIbj v!k✒%(6KN%V#bM`긝r͕& z\5 -jU " 墢p¨9*P`Dg?BM _w2ejCPXe<Mڽ{!u[K+ʥ]N}Y7D$sX~KӦ䒪 SLJ2qm9=hՐ5RdŘemK+BXd/1`%J8 Q9S&eqӲLAbϞxĔ(_{3||U㷾?u|rge%4"zav%5֝ˀ&20FVkFPr4SϿ7h SqxD==`'+-/g,4wp{fol.5,*=1RJb[TU+`T e` qXAtЭ.^@1m9ݞ)6r` ؟*Ÿ/n, Ā4 nРx6 UXčE'aJUЫyþ6YQ@ 95QZaƊesrp'.(Z9rqTWߺux g/sXcL*q#LwS,nWy{^P}KU(F"A[^p9GcP8üʧ|*MSM̆?ge>~r:-O$-|4?y ZK1@DBClUVęY?Z 72xu>0 b)rSr"?G:ln^z퍽#+UKkO=}).f%vpԍ2nc+VupDQjP8#'M,hH)n !zZD>$v7YrKqRq9K4sz1fbBp1岤**2YJEQ+fתr  }C{e;W,mcJ!3IsN@1#D ')z.Oh&Lp!A Za:JUj !;ePthPepg(+ Ponai޻w|y"#EZB:03i*vRl޴Em48?= ioYǮ<L#/`NBTe>--~8p.- ef%Ԣ:@A]">T1*[fy'$0(LFRɩh+ѬfHƟS]oK( QH.>!Kwuy(R!% iɇrL(HLGj+|aP [;a5*CM -b$9Hމo-{jed9B=R#P2`Cg5LJR|ƒ߹ygzIrb7 T*<_:p׸$%!Mw(JЉ$ukw@9#GeK*$[q[?dӽ~qSqo'=?*?ŷ^Yt2҉a (ؔq tŇa͔E{e{;P!YF"& ;Ve]2kXw_&QO]l4jSygm8Mrzu;Ou,*Tlt8Cݜ~U%M &^NqsM"H*yi fDX$=ߞRVNfQ) @1 MA%sUxɜ&l^ٕ鴈m"8T3[(NU,4tFV0% ]J!zaԭU[^/~$t7pxz7;`NDb'@2Ɋ\0^\'  w*Ah5x]7?mYJguQ؏ BEQ).=*{|xp(0&P BijTԗ!s4Tƍ>“/}zyuzׯCyN} D d4\@IXuI#7>(ghsti^*%ejOu4QXHMyXMdq@%1Qț) ӈW#Ƞ%V_sC<0G5[6݊ۗ%KtD RG яJzk6!2=~Er+-L]jbG !ܩe tUjߍYaF~ht85B77 TIc6{0dzjJPj5N->~ZJz8]lGɘgRn4D@kF^i[0~->~X +L$Z_tq`Z>A57oZe훯4Z Q70EI+΃YDW՜2 NHV GvEKInsȇs,8yj'_)9|8;ʙI-.'>5P.gG|ct"<y )Z@ DyX]Sg%}j} x2&"l)j392*4]Q!hWڍhC\SuAUoX%A^#Xɏ*I!\#N jTJH=70ԪbKiW̌ @J@0CFm83÷)~IPP721deR3R )‘ -RZ#v*ѵ|'/!&BSKķ[P &B[E~I8ŷ¥#gOQYϲ DZ?2h@`!ٴ',5H}ؐ]cO&p+FLccsp4bͭ-K&ś {|7I F b_ 9+˯zߝ[:!B0qJp(VĜTP*NP#`1_w}_]>M@סͥѲyVF!`>1s|~;]oqdv h/A1M!$RD<^5z N}.q4XpQeՠT P4*bm8sy`۰vgv^+Q)-Y͠_k9f=Guvaj@!]< 9ƞi~jzePSQu}%yދ/>hH(ORydNQL'k\1?ܛz$X)SyNd>)HWۅL+lV+ҴWqjX+5&M;G‰)_adM@RL/-R){M:\</G2i$V*.or?8.,Th:mp7s<1D@Q'@oP)MYqG}}wt2Ph]G5-)R/"Ęsr;"-a@"f(+ȼ,.<euu ɓ(OSr&s>$%_>ekӳ!W2?y^9+y3NNZ#B?y iZ4I؈qq!)U't GCb6'B(>VԤx')j_[[[_ߺn^9 _GZL}ZlZp̮s6ý-q 6V~ XąB4D#dFv BdZB"r-/et:67b^^3nGYխ IZs4i0x巾tn仄JNFG{e-gMIXR@JS|*faެ+e5JSGr{# EIf-x73F8zG{MazUDFQf=!~C*W`R(ZbXNS,T bQqH *V ~zOAtO y[Zg>gS:LkyECU6~n՟/=0"o1*fw>O_Ll ^I#^l4:>r~P Ȃ0_|`_ZXYH]P4\@4Zm`L֮W.POn׾ήe[%0^|  f{<R}4_L&ahbH9XX0iN)A?|JcAAYh 0FZ;:&,`l"xŴ ƅw Nݓa= F#?0)XBݘp RRtBPmM % 3̋^"4ҥo c؉I+P[?zhߔXEs]b!E6(5fP\H4(&!,,yFzBE'q  x /8նPN ő6Sww>8d)IApr2ع{^yI2N-bM{8wkǬM2o \e}!FA#,.&鿩Pki5hR(‡P=S< B-QN|J>8?j)q@S]C!suMz+CE(;EIJr<}쳟y" >rcLw߁z7R+-Sw[5s G{jPN {xptD&<| IDATbk`IQ4PzKfz ݏ bhj4*g{gedJyTC.*ыTC\r߼Z-nl>Xb8m"??~,-.I oO=sCF}|/a7_} reY_W0ǿ7=͍5&Q ޼GH^f#.@fzamm0-bNќ-,,l^u'k[FcYr\x aCd{|O~֨; ~Y9)pDZꔤ-hq,4:~5ŀ?7a7!`)c./` > Ut$nVخ;zP[Pcqd ZPOidI)<5Ns)Txɒ9X P9)'W/mp̭^vZzԈy#lΈk7 1.S4* 1ւ"jQ0{h7ԪPm*}hTAjj DVb &ƇGʥz)cpZ쌏 9qFNQt ĘA$ ^PfI 6 ܨJr9QIt 2`-!7}R1 FdR6ďr:p?{k=QRȷeQQ)s/6Toٔ~CM1㌢#1z:M5h{bGHKk ,F?y'׼{~'_ ެq-ßQG~// >D Gg~)هfxoz㭷O櫾=OOJW8o?i 0rd혏.$)akvkEn0v]~??'>% qd"b΍vwS3ϛU{jkaumgK2|Ǯ^ƴzPsim,4k?iל8{mV|HQ7LRIq0(f&T_[P&^ԁD`C+R\YF"l'85N# 2Hk8d9bSB)z^T Ex+!Lyba A bBBJZI q+qs#S^ `jP$Vgl#:KnJ𡐁RAd,ϋJ1â+Db"^wqQ.p(@z#oM#q냁܋OLvr{Fr  $lgp: I T0rY#kK5߄Qތ?i=Dx>W #:Oxw~ؐQSס,#Tc^z5K#mr j֍&Ed3EKYbK% ɨv(j;vl-]Z[mtDnw^ZFnP"8d,AEX5"p\P[E 1U;Td>هN< -%:O>Ep~a@Cȗ-E ^*sjbli$0_^8zU:S3\PliHF-Bd zSY{캶N%44~aB< SYJQVqi)".i8gMmV3J)\'96J /a)qa|tS[Q l W F*`U ^_4Md0UDLKvSTity뒬sz̼wJͿȽo}Unc[_O a\&x~<ʮ]6XYY9<0c@L:18 3.q3TpvkWLbUkqqqyc)<<E`?:A+-atl,K+(xDBS]d,Nl8G0R& ,qB7JT\AriQf٦n6jU ݎ-|JH`65Cs!P$IL\fO 7+y (%ndS1s/\"DJsPO%Dܖp $B <6J~ ;u% %gٚKKJ %% _fZ4A41T2M,vOپpY`76 .7" ӂêyLvwNF.\M擼qδoYEXQDm ':2l$ y{>iMӸF*9{p_1>z//0 ?C}?97oiUw6{o^ߡ I4#/#q`$QmB++^u:S*nʩBeU)n6"ZitTq` d@Ue8G{"y%+.{N[sZ޼׫0)騬5kQ_XvT}" %rc`snC/!2N0,2)\[z[^9=}zQ%*DsH"FN, 7M6J0+9NKWZvY_ Amz2խgE/4xJv Qtj1J*FᎦQV=v b7D,,PIYWnePBo*G/yɱg-JRN 3lFh_Zb݋3ܘ̟n$//sCo?J@IYU_Goyo /<}9z~[Z9񼳃OvoO =Q)`GzNxTߣy`| U^#N2U5{2vXT&:wvNI"`*iŻ{lRD"\92@:?\Ydi#gGǽ?DѴj`-LD^:8* g€tʒV }i._P T! qTVDIK|/:`֚CIJ2͚ÏgMp,LS[XXZv_ךo}}-E /D x\fHBddNPI "Hr y,@hɦLMRBd%. )F0<MV2O >hPldS\Πy\(Mj>D5P^}ؖ R[ܰjUwKlrIo[DB$g3)iNBm mvjbłsQWNp+\<D6oم3kp?d״;[C1kܐ|ג_~p_8X6|(:p" 9F"%=.Nj'C_+9)>mQQ wq te4 wj*XIlbl,a̒M.?}wE D .E؇SGf䧆׽eo}Rv;vs=d/-v3).IoNt6f__ 㕨Hdq!ɟ!d ʺL[Ln<۠2 m~f;( u#Zl.@::tO&4$6]Z^\ZZөnn^0lH0E]2`jJS4U%dY<V Q rنl%dd1xrM7/9DV~nC* A\<tؒP5kN3 QL w:[Kf+'ilWG{([%݁%hNxRÁ5\ /'222n3p̰eMczUVy{߬*p*=Qĩ  GTLJER{^a{C/bP$U?dp6ǵLKdLa)MYKF q @!R?Ul[?PNYKLLc9H4  %` @YJE(QCb䕲XfV/No [^LJ5"GR+߶ӲfVPw֮W"^6lR9K"ZF+NgrO%Ere͡*a?99BP|.P5|CE$n`X =VKHVE / Vrnb]-+>SP8%} aTr@<% {( l HK ?/$r&0PF*͵Ѱ7NPo..sa:3瓦k0GHB gʡkxn$IZ3m\)0K6֘|LH/.5 {Gs[[\/+8=r8YrA W$ wH+V\iވU>;|X |(f͛0o>=OA4urξef8Pqo~AEh/xU8~(en;]R,Q)d*K΄=8ɉb%@fmq8IjOGkZR "bH,L֯lXEe6 M4qR 씂 Vj)E} ٥Gt?%A.u Čl8ƶkZYu FHa #dzb]!(Eb RŪViYXX i>hg]!nFS%r(ѰwM~]6rXh!aWZ^̊@ Nb8Tʂ/ +6sZh-mV*֍jRZzȔ ,OKqG >cY0~JH5mF&#;z-)an?Yj?[[ױ9DpP~EFp;PjQ!POF&'bЅ{fB/~dgIΝidq:# onV":;mC:%*e!8)k@ ԃaaCi HT6[ "nOeI\"Kn:~\C7J\)  tܸqi8o6eOlx%@3*(x9Pb6/uٽ n=KJ.P{ ؓ;}{׵hVf)!g`gЪ^~ٴ l,"ML`MM QbZ3QjkiApk6.ddmT \_Y${ޡ*{;{"<Ĕr*Xb'C=ApL?Oh ;H Q2)Sxp!)D. Ӵm3.=TB(h<x0c{eR`&&U9 ]<#^nL`Dlf[ Oi,N)cy‚$]0Q8Q syTBkLToz'w[W b 4ufF ^`aȻFzpӀS[KVl)ڧ'*t.nW<%\e50G>dYtPJ_.ϳqChwK6َw}~4SLt4HZnPJ`1!te2uGT*Yd%((TXXz-A \"  $K0{ff`qЯj:㫛[p,ma¶7n Ԙk.ʳJJ8;4BfEE>gm ,ol5QIJm01JXF3QC:Q1,iVd*r4L@O]]8;{h 勰d`?pv o IDAT/ U%, #G*6u-^U1qLJ2n4gazsf8&I tqj60'>k_ۻ')rrҧt5i5&5 ?u8F'TյhA+wpbVkp)Zb`bJ!NI@7pp^'琐YaR ?pWRZM $Xȓ&\q1NϩIBXIBep(|[:s-z7dfÂ|/q,nj0 xw+s3Z*#sS`+[Nnc0./t$zBJ!N,\80 kOԒ9-=0 _yHKi|~/Oَ|;NaIQE.(> U"1c_1. )#cDc/"#,\ ,lt o2Ap"4泏{<) (JBi6vu̫Oq})SO_[}#G T0MxD薜jQ YkY 1iV:)FٛEfkؐ"̟0m@l\ui:詎&֩E@SÇ唌ۦn$dTyk' uA$XO~PNiAi C>'+pŨ ,Pl1a;zIޅb_Nsekij6_& l=|wi%ǬL2ȜJ\Yx70N/*P)b&μ{<@XICkLVXotsLPUIIj*=b" p㑍t~&s`+ ) 'wXP0=/4,>[&5Z*}n %N%qǤ }+y'Xnj[wq/Nː(c+Z2[Q #d8|GiQQ,FX[Xj_FLVc-lj$[Né^ԝ'\0֍nΦ  *m¿y- E[ )rD:㻶҂Cbgs[{QO-~ xnPWoDC:d9%ϼX" UbhTC=LJ'Gd_ 83Jd i?AmTfwYڸ`$<,EAWժSԎ܋.n{~YV}'.\LZ.bdRO&JmVjP~`3Y29ڻOYUsQV]j݋=}&ketOVNF8f@8%ԭ1 N( $QS8I8ZK&jЪLúYK/ ~_))z a#X2xMĄFF{Z|RI|(J=|!fU< dYL/5Le痖&vc9\ObF{#s8x.IGB7ɥP`Y:xBX8;g>?筯EIWB4V (7n@fEY2(Y2ABJ^%ث(SYjR(QA!Ρ`WO!2Q9Q-TB* 5أ$# 3wø42[U|I, -pHb17ً? =Ie "3暊2aDA:PxoX/ȺY>{͓mR1U^Y}_}>6 ?W ڃ0x)l "\$.rR$W{F T^Uiu/HFp5N!AKh a &jXH  2" Fmw/p,=t .H z_* ! GE L[7ɅO/:r `ُ4,Dj8ko|ڙv5|G4f)ZkUȦ'Yk$9yI}nWժU޾׻q;k1e?_c p3KUa /<@}]d擫WkNg-=0+4҄9ؼ{rG~dݼOo]~䖰T~3X+Š ?x " ]&ye h]2Fӈw]+c%foI̗%,rL"kBͩ߶u5jKwvwnmZl)s>)RTBu꒡܂ ьpD)Z(ljI@ݣ}=dmsRpn?evfH7K$iKu4eQd)[|S5Bb\hAL!?x >sf{Rku{{tY3I\;(eYK l1Ȉ8لrTF}7zHclR>/̊5H o2EL' Aao,hO'5reAz'^dsXA}8:_.T zĆmb;jVǿɏҡ!׀8 ]da8?dzɸ9 F;o[Yy_پ[Z@|&@KH_0_̓%2YDz6DڎlCMU"2+k ('NB|8sgng2ajէo{TY<._v:8\lv*GYZJoP`q+NS܁řڙFQo8f$OI Vө6ASI֗֐VG_~깧Zu3oz 4`\-4>N LH-9beOkE9 Iܛ,Eq7q NS]J8+{3LxXB w`WL9vDl%\cNZdĄ_PD̴ I&M7W P64#[׮tCZSQ~N9#B<ɯ]Ο }t N&D {Zrqg=)?[ |̚k0a柝*,p71`YʀИZ r%*"Lq2 .YAPXhɍ #*VΖKʭX)p /҇X:O.Wz99,]ߺ&(Oj_{ŷKB׊P7p0>Z:=خ [~aq: MٹIŗ~$D"dI% i[y J7مR5MhE7I aCSԌ:ܺ. ScYn,5ΰ΍Yw[Y"N8͢5)UT"cR pb#Q[ m7aVB)#T5;^cRLB9Ghx|l'޸7"?_2">{ !7&[J.v=ky%jEW 5- 5tpBIo< # REzN.ೝ"[XC볯(&1?kmzS_/></, gT{IN|ֳqϮ!J=O]vdfg>ްX @;$+kH&k$d"3NPY!MH\ 2jpxŻֽ;>Ln;x]/]Xm׮_FQazC!$ app h S!HҶ;a$ǡ`*f~δP| 8*$b'Xm\XeB) v=saEsO{$l8P2ud eh΀9 B?oi O*㌙T&TЃ3Io8G}(4B3BdXl;q Im2DQdEv:™q(t0ZaZK>>Bb( +v{<0?yϒ^ 3'E:%#g{ˋx!_Ķ?(EucO[/ 3qfF~[#kf2 \t)> m֊ͼZ2.SD"UZ%aVjvB`G[ϻ1EQ'^\9nT.7<}0"o!qɰg@&>arSL|&F$ƒ1γ0 ]ȗP3a@vHX/}sS=\ZǹԶS]l;k'=y>-8jME+sD\j$ƮtMXPx+iu4VoN$ш5g˪F~HŬE%KAo2+'[_V_,m\QT&\hT,|4S("9 `&pv#VdZ G$A, &tQH6o*Z@ 6+5 yB"A@R(hO*_ <HhڭWo՟X\ZKI/|Nnי^,{y׺WuWlnp54H12l c09?a3Ȱ %h%n6TuocL?'[fwK`Wtu2oysv0qfǏ/OMA5,BX& BZ5{C(Pʃ05T8,T޾|kJ# o~suu1v8_i;˸nlłdZ J4Y+ faE$Cd[`e&iT5dʥ!41hvW0gժT~Ϋ̧/" ɭaAE0@ LQXx6H$C^(RBJFU^ F@WXM3|8葑- mJxX!?l?ʃ|0=C0 6nހT _t5c3W3cvVQ#i Ǖ$'J`;- 87ol\x͵5u8/^'/,,r6YR`a 38"Vv0T̗WC%AucRডFEiړ@!qz۹s`w$= 215ȫOb2! 䨴*ȍ˸ G 6'm%J8=鱥H(K \ӈb%" l&6kq*b£ 1Ri8 7ʼx YI*09sI$pdҖNz~Foݭ]reI8/<>Q@`K.(œduWojVe1 omt"x"+ADʗ:宊JUъ S<r: xhD<8J?Jk>\)^qEF2ʯ?PyeӛW3PuJ5r3; p ViC@@<2ikK{ׯvwx h]ž/n>С&.s44g)fd8+1ڡR9L3<ف8!=XHij`s%  ST 7z=ɺ.qRER,^TK`@D\aOH̃mf^m%NMkLV`=c"說sw]JDǓY#D۪z*)aݫDс6 /QpCxDSlJRP6!$7 %eńK>Z>>JyR2K1|rkQiY-u|ށVLxXHmv  %[UQaUSi.u% R2G,4$˛Wz{w/߱W_Z\\޻g_=n:K홎e}[WWQ2zuͳӭp,7qZ 0]4LjFTxS3E tuk!B<4\}ᵡ57:S;*SL 5v6TOP=%QIL7K|-շ7֕,{~@7stfr >&rZD{2_off=m`n D*a\zH$l>TD/8P\؜p2Bhh">J}Q d:;Lld&4MGt_JJY* ^Md$՝Z:$z,[6Gϟ  mMFND n{[h8ɱT߫%6̭o3X^jv{~gΚ+CB*pp_^ódx:O>+u<Hu+a[EvdB:i I>RXe(Ǡ¸R:FEX1~!~_Aa @́}da %\IR=Ҹ- N>}LӛWzBcfe-GRH-˧{$$Ut;X|0 r ,PTC eA|z jG$yu<4Xd4Hm ĩMJL XvX_yďӄVY ~T!#RBMFL% eO i tLmV AR1֋Il@RUIRՕ&^A||I>1L;{j_\h⦺ao.46att,$b(rYhQ^|Qw1Ul/65 cv!s#-"3q?h91XyH=ȁ(b-Oh.Wd883𖥺=Mi*^ 7t/hZ2lrza!'춒v:k  PzѥԖ=Ju~)=`aeja~Fe6|Ԛ)QbrKmf[oA)\XsW5B`w*tݸv]jKjLJ‡^g78W89hx2ܝMh5*HɜdŕaEJ*׌̮6vT3h,({*iY=hcY]`h-<ʵЃeg̏bއr÷𽳇b: B \V,,peh -%2U@Ķ"3!f2҈H>(,"VY8VG( 7'.yu㍷3$8"O#Qr%$qD,zgALXbתK',p0tHz`;e4A#$_b0 #MR>hrE`z)"2W"+pPOjQr%&UOdȌ|<V%VC,O1Ipr.YtHv0)fQӹFr$aQ4@05Uw/X8|+r2x8yC UqD7ի~/2TP|ėx0D$i)@ߓpd$=(:Ui۽"rʽ Pf!RsI)t1T0M̂FL<5JI=r]B,I%S6mNmP\]ȶCVPdr4[" MuRw,U-5dH83󊱨Sp "!FT$1Š*T\i?*4fD.6uo_~? 3Eyol~kO@\\+K_pz :Bʄ3JCV؉&if˧S*\__wnÔ龖x?fXxo΍hf]xj]P$͸g i`\;h4EEtxZ$Cm5.AkC%4}ՅzD}TAuAVDlu1V\]FoL?t:j,P,;Ml{~?J%ToOl!Tڅ: v~[O.]"͛ IWt&wS^#QVكc#r ?]6L)/ޯ\%]^ChNSʃs6XGˣxT?e `CڂD2' |26<-MuN/08@nB=Ҩe3@T "A|q- )U=(9A[m;_x|yѬ՜b^ +S*Ĥ;ڤ%>LPbR\1u-0Tob5F`<DZbV%K:l*J΁D1ɳzj}Jd-bOeu )-dP쪈 :ĊDN"k.@ vDL{oVlL`VH.ld4_/3]/IDF01 0U@wZTD@=LLxXdmXF-'AgaԊŰ&p{rjO-D L= @}[oS2;hً"*`D=9KC$hf3x**88R;Sd4+[}D |$f=xҠe)bUs⫼ODN(.''%6eg3f+$/CLj #jqU`1 en]V?#]zgΜhЀD45"xH`dt'շ7 CKL.Yɭ.V'ϭm+*(; 䌪Bg:{q`ƴ́5۾?\9y~VҷO e2PۺvgLPg0Gd wn@'%e?ILMpjϗ>|J^U#ӒIAzYH@V~džejX60^d9Wah8 f-w;OUnn",;*5ki%9CISg* u8Ia?H)8FjUonu|jr4<0 iPh5nS:…f/r]\L,Ezt:\<)WH],+{XuNiG^"B ᎇ/|֒p~(KTahH[IX BO1~ŨG0 B̘a \DJt%J02XIB0a-t%c=0^Fl2fc!@TX x%Ca[ObA~r)`؇sr2*Z+ G]a\T&! 2n{ ]˨a!hlUv4宥|33x%)vJz ±P)+v]?%Ο 3M(ZuFe@ ׃BhUIMݛ0Zq08: tӄM+d&넼hGp2b^ʷ_[{\g#+tk+|4Ze%+7P9/TJ@˥8OjӖ;vQ[YZ/'[0hNkU\]^(_D_C|ewˢVRQ;8<#ah%IBiDl7ukAl%By{ąZka^lƲ?vgwF1p.3yjVMF_ѩJ߱Ҫ^C,XcK>Z{s#Fk{hT,)*ÌЬ#FF`TcE.W\:™:k9."~Q֪NHehr%ѳ8*T'Xh1!5;6TiRqB[G=ϢTr̕itIUUKZT8uH:'=Ͳ0T:xpXH8xf؁# s#Q<ތ)@8^$-Lg-su [P+ΔΟԀ d4;w{#rII!CxuB4h,c&1{HJ$&2Nׂ`,Hz2NգJ|6'~YGrrMeW(K.`ňЈ5!_Y>#bJ!gp@8C bHZ/A1E#h~e #;@ =h $Fq|œn޺g L=U@ :#/tEZNK\.H r  DKjS:PVTM)|W{܉ᑛJAPP4Yڰ+nEeOƜ4VqSP30r\1zH); Y^jq΅sm4Ajyg$o(bF!B=!"+b@Qتƻ!A&<2) :,X39˟.>'eZ,Te:!@G p?!ĞMTxŠ #<ϴaoz կyݿ[EU>3;sykknƍ?|-?g>/W67;oܺr;sXxZ]He#ջXʽ&klCoҼ\ Rw%IjXݶ#">'4Z),~A(vQRMĐ9OUǺz~/20h}E )&{'kjձ4JVkys&7(cN375rpW@d'(tg8Dd 4ȵHk԰vzBe2&x)󻗾3<#*&JSuT^Z.77iLkaq?\R9K~t$B"c~Yd\ЈA,g}EWa5! k%3ɶnj5ሌ3j(S#}& e@1K%zy8W,*H3K F3"+E i-4\ oe;G?seAxt~L4 Q>j\ynSg-|/u}`Sp]QEr֏1߃?^_N5-G%~ Q>x4ƣ$cUYpхCs̆>ᡁFD8d+v=b b 1*T0ue!vVc ԕj *CڰDj:B5H=#KS0"}h4KBr` %IFEhث7<.G,qJ<0& d0Je~0>/ 3uN zF`~V+n),[rK?L %$EXX9Mx  9n``dTMf/]slQ_(8M @8-(Ly L-^XҰ`F,'mIdb[@ HX8{"eKN0M7v?7,I, b7i[EpEJ^[( J#Y!#i>1 1ϐ Θ䱆{"6Wez7_<گۜrjQ# zWN ↽I`EystV IDATe0++?V{|}VV.>71?|yy,,C/c)/c{`%,^iZjD']^,6$,S⺂CDJ _XPśKϝW?x͛&ihI9CAx4j#(-=pw⍝w~Ftn!$3f HfL x+cl9B$ Go%bkUNVoomo.9fs{eEt?iUE*)SgWpSJU8Mh1`hn=W=*h`>1J!`IT\™L jUÅ $*\mgȳ!IqY/85tbEaŋ"؍]% 81Sn FT+0ĥقtgƈ)2 })0P@7DU?І^N>WUf+PT, ¬l=FS'.=9y3Lci($]Ʀ~fKD$;xM[ +ɄA;"7qg./Bvc֊Nn o* 8X?ec qO Q l YZPA>҈R!ah,ȓz0yKh8.ho\~{eǏ-}z+8S/?M~'vv,s~w.o| >xcgu+9O |̉uOH-*/]h\8۰+mu|gr$$pt`T9WRO+!r?̂>vOxvdʭw.ݙ iA) :Hñ1͓D3F +P-l:uvʃٝdG䧽jnTE{2ubqѝ0ǓD_Ғ!N'*%`t6OSyS_sZk߽z&$ݼGg_Zm &>H;-So)v-]4fZ$atX?&`n%ZW dhE#! 2*sxl<}zaDNU>ض fqV zjHTᜉc;$YAA\O S֌nI2eUޑfsLGs+g-cT:9,җ ?Qb͘dgz,:S^=@{P#ѝ-zqrIH=b)tQUQ,g](g_({w#~p<^^#Y){z`c/zߒ!о%`LB `śbTщR3Pd}xVvb6gPI ?" "7Ke .r:A&IQ5}8iMFa%>3HhT5t>qWXqYzݽ'&@4FL*k6y&0إ͍y^€]1j(#0 ¨)6ГBKÊ#Nh%!~2Por/AŻ:Y̽N tx8CBEDlSbONXn{N#*  7D \Is'LDܬmĚσhcaBzrVGe/.. Ԯ܋۾vkOqr .׈8"d LIQr5nhX  8(w'.q#&t ;S{ۭf^YYsgdKm%FH":77ޮU]ftlu;&O@uj:B1HQi4b/muE$/Hc1$z,?c0FnHZ`j ,[4m98p/*6QW8\ l%\\[,өVV{TP57fQ2 ¢rk$0a N SH<)WF k:9j"ji &J8;ubk>-[*te5<\?▵Vj\xAeYEW-7|gy?Q$N}}ȗGh!Dq%ٟqђ$@w8D^bFp H  *@)b )-eZJL71p$`O%gr Ȱ@p[uj3L%8.jdw]$&{Ib8@$?( .)aZgw;@>6p@zlAIpV",$JpSM/\@TG!YA[1Ô)ڠPRgL (294?֚'(EX.[b]ǚ' $"t*ă N#7s?L;ona_xAixykttRخR4۫~@4=Tה0, jzPB!Siu7þnЗ \7GU~YmV 2|MNAiD_|`! 2ةت5 S*EF<%(VTJw؏2P2%X]fkřƈMŻf 3 ʊ<]e qDu= ̕aVosEQ)2٨d1B W/N1(Bbhc E@"vX9!A;xsxkY>]> W&I $9^($S&tڍG;&H=[`4_?+.ϣ`?6@XL*LaRV>rTnPn:<7Rrx|E}^v[{H;~(+d/hPNev,턾} [Mןtz㭋$8 ƪF 0%hq^WOU *@Zۙ60.6ovUfcujZ_P@. =cTp(V?k5klEs:Zk4N 8}3A g!㢬ȬFȪ6I0޵o_ RZbZp_3<3p  NHVh6&X-Ht\F!rϸ}\T=~* \Әɱ*r1r45 R@L[qӑxe`f!>iq6Qg86i-%0 "VFd0@Vmv9h pY;WA*TL(s(nˡhN}sӡzkѥ.7۠ԥFI*VYq&u$\?]To)O<:r/_Y>GD;,e=CenwdO?|T,RaxdVp` x"@D,O˦EQ1[wNv֓640\MIe,9]DAx҂u&DmUShh nhOH2ڻ(cIo m1Vs_)vQ:$FEZ{jш1zg_x\ƀM3Hr"qU qr)+ND '`c_&x\QhQ"4˃8wr0*:(Vbf8hb&[w.vG8 ѓ5;wf/= ʊlPago@ޗ"eZ~-7&S,2kʏ]nl+_杵V-88H?.%X\H~MR`$:gۋ7/]ۓXzD P V$ K(ȑD4+(V6QaͺT˘;?ܱ,3^9DuiLyLTkYcuw!֭iX6`8Y8q>5`Y{>NhN/cg:%S\ܙ-x-* Z8_j6}yl9 &DKUx6)! (;,ټ2KUkq֪EJ ްtTKi/IbIJetE*rffxU3V,LnVG3aNOG"2X#1>^$%-#DO 7OҜtl 9ͪ40pM\nV[0QEeFC'/T#=v `"gBS KFөIz\ L)ԧb]>6VrOYw_Pr\u?'պ</}  p 46SbkƇbY 2 J Wx>9c% @ڬ =o/5HTkK+ 'hϠԱ[ sZ=uЌJ" ,|;ua^zFNÜ`j t,X+F ǩmy.\,q<3w;8?tP6OBAXlIR|*.P1aCT#?4#ay0mHX!‚{oU}He:_jY fɳTp2`@ )a:|?Y@xop,f,̸Jx'>jWM׋n0r~뷷n؉d-ެ,J,D0!׊dVaQJc&B:n/QSN<C猚 IDATtX 1 ZV: 5xPgs3'ŵUI߄8T$xHadsޘxHOqE۫p'u* K&lA,Ujc7"7F{ϑ`us2z*KT^4E٤RidJ0yDJ*Y0 ?ɝ#=q'4fo-5:.`oGlcxԷn:KŶAl FLC2 yG jF<$9쮸4y.Ҳ]/XHDK7-sb8A2sYBW-{!AH Dz$ TPi$:k=o._#BEoUncz'`gP'(#+Yb@Vgɩ5D]Z%C*W ֥٪,?d+}o3xahn6#ϭ<}f=B#| ^G^fW$qxYA\F$>(R|5equO|YfnĐJ;7Y;\7(h[ĝX,iceDjr%)t+TP !ᤷ5׫zg΀*~Ȳ QQU r%MC+2:`1ʀ!"0<`2bZ%!X2'wP:(@`?"N* d~f}yVEMG^RMpC"K [,Y2+{W6=Z|äTK.Ǿgv"-\'Z0ys)TmrfWvnM/g&B!a|Sꕋ;{D23TVq`<s/ꆃ < 6G|B%$t9K(X=a_^/>{ӯ8v{eқoxs9{uj['?"&̬FQY; a;|1l1aLF.4)J?>zͥ`XpjktkC:NaJFbBCdPV0wgz7KC˦WM00WÔ]35tM uhBih6p"`ba5=IAMYT򳨄^,~keg4VrkypY\?ďyaJ/ |8o &pi1T ZŀZv`M2̘ eU@*Yd(fH*yDKWWA:Je_q? t?Sk՚)}YvoGst7 sxiin^ktńfb;Yǝj QW$FsIJ$l}Qt[pk>H2 tœb A8: e` CCQAFBl`vܯZZխz" C"C nKv|||41ә\@1ѱ&"䝉M"W(ALqb)A(U*x ($O=:\:o6_yyb]n.ޯ|H)^T)Z5[l)+߱ZꓬbPe1woÍ{(&lu}2' ;wjLN72u) ѼDƩόd'>**3|ӀI~VlU6-X&A*Sx4^]ȣ1reOo2 DU䏼bT.ܔ;CV.>&'>p.ėQ  Y=y k,/7(S[:MK4%q4?}fx6Jf<*?4ӹ1p)XODc<>vW/nܻ`@̼-i`)h3iO/?:Ϟ?W00lYެ=Xu0ktVdVROsdL'= @5Dtn#B _5ZZ:LĜ5g [gSVj]TJ)gOJr <A|Wd:KY׏?]+·~tފ/\h z01%]!EKG@?QLtpf_Lef-Ps.3 S2/dI-TocB зݿ{/]l;gN.hSՍ~wwX\9}WRvR*llWI; (I*%moL6r^ Ya/HS՛F 5Q(~V9^8Vp*6j{0H$*5)Js,7FU\ʓ9%c2%H2y 2;Yw`;Jz.cÙ @mx['o)R@!]ĘQLh"/>pKxUbdܒ1>gMM,PbiIc^MYnm/rx8ȳ*/S.*V 6'XɩK UJQXV-}8%*j VM\ ϝi&PlFWWweY[G ,{"\߹+bDkY.[`Qy]yeq<{VuT+-oBɋwfo:4+'΄֪ ,ХzYE+u\JޅC j/>6"`'Vh"tnj ޿ D$ Ζ;^K9KxۍJZ屲$;s/}ܾSkY6IlZoV[C%.vgM~.f>l5%)M1OZ t7V{I1چ}h=UJ0QOtzȵ6u rp UԨJ<ʬY "\R-{ 2 n~0O>gf6śLwuWvH뀟84(`Jqq@a> 8V5$ƸC!FlTH՘eW_T eƭgˆj]ۼBځ-"'qBa$eH.r4rr;V4I.fRB.UCcpeІ+6bx7iȸʪX bgk}#z}DdP*>D0Uש.x`$٬Ptgn(dIv{I 1ӊۦ Sf7 w2/phEY`vY` :3 xOxgܲݏxoWC+m{MFP1nydU;0 $cB.k:8lɅJk͚UfރXSzYb*- tV[V+'ƴ[ XQC5(UBFX4R*Zq?P>L8bE 'wbqUf'ySәLbxej[!Ob5\PVX:|p %VG[2 O0uIO#_3u!*%{:+NBb_ HY+Jwv۾x4bɷ+Q#jޑ^h1}Vf_^(J!l'p%%Q.vF>gTؚ,C- Aq:~pi[+vX"fht=)w?H 9TX*d# \wnj+#^'Jز^NV)kyB:}+JUAY1 pXs\s~uٶ^NA ':L+iYBE=/9 [>[`h3_/K|o|y| gF%;mQr[Mr V\ȈFb*B)+.3&rX2oL˻g\,̬ȥVUH<- fU LH$3UF-5<4TxPQƿQ ϰ"c 6CP Up&,5cߐRUO>gl<&,9 2prc6S}+p21yk tfre;}S+7Jk/<X< XOXJp&"ȀPc45N%Bx PMQJL{39(C`;wI]1c怘 C`:jUro6;nL'5?NCRٹy$xjQHlTG' Q>ٻ#؅$d%]IiJA4^3:miB:[P#[]J9.4&{RUZxx||Êߵq׳oM?ux^s)džFW1{.[竵B,3\ʁ=N>ʹxI±fݪdgݐ[ 0P)VhڈhkC*C{/1SՒzt ZSzHEUrTU}V(܈~oRХ  JTj;yO8 8dUy/Jy0z"-\,=JBhdmjf_ :^nm<2?2ǡ.i7 D /st೶Xk_a5WJ9o@gU/n#_XVǜ-w(w歗Xguߝ<0u⛪Q *\*D/#l /ӗU#@oU<;a9" Nꦉ/*h$gBrKR;j\PDW,*T1$E_}zHt~h Z,U飏>cH,񶼡D$S#!aZƣp1)g3 `zS@ dz(޲3l`˴$RMt+ҕrߓ [ρJT2N IDAT 0"y1 DO]64p&[q'ϮܭR-dXݭsF]+RLڞԄ@qzbi˃ʆ$ !!bŁ)-0&*WM  bNdjvJ4y(Iq |JPKeM2< xP, `ZslP,>mU1/DS6h!U]ye jԐe[mjʕxF / "[&P`bHv",6Կ%T!tVEJpbV}Od.};Ӆh&$q~oTrU,S00YqOkN^2]v|CPA^ .܂Puy{޹sf윍>#!芅`]֊!DS>|U):9_X鹑TTmv˵+^Wwa{VfJܞ:ph=P")[2ՒݻɕT65O 0 tf wn #lۮZ庾]t W6n7Pmu PI=Ijz47Tv!e1Ǖ+=خba$xg'1:><[-`ב{ p|Qx%+tV۸ cfF~.|r.(-V1 4+rJ]! V7\a1fżb+*2iiHCUK"IuߠHp81̪,2ەj .X8!zǑq[%?n~z~77]$ti:TXDI`?NxY^wk9u(ƞ׽]}ՄRqZ`&3/( (^\=qeNO~h-4I.W^_133HelV"2iNQgPhB])8OS10YnGZY0F)<^gˇvNģhN kX"JEGOer%V7܉` (-רJ k)|ZzÃլ j. rhd@S`&Ҵm'w@wf9GD`^0ţ%J1BlitI1)v;R]r'y Th_ s}V&G[R|LqRUJ+F 'T (` .LHrZ4pS}kC_I"vPVtp aoWMuoU-fʑس$RIPUѬp<U}ʂ܀bYl^p稳 pV:0cj 8 ԇC $LP <:X`5yCZ3 ❢ 1/8ybgև'/{$3 K+HtZ˞vGh cP3406gғg|7:Ύ~o*z~M|ܿy&Sja%nJ](`6nО;etE.br'LwIۥZv֮u˹fgYbFcpr5'+-Bh8'7 B|NkUċRSddGbK[ѰvQ@TU˨!o 'Y8\ EQũ'=7a xMO m DVf d06n#U$*M 'Q4A\x} O v h'H7',LƆX 9XZȀ~1h  A暊5<;zE=[<9Xu)8}wA()7qR/~_!V V7ֳF7}#F *qFC,FuIpNwYwGTb.JXcw,MhkE B~ ,uX9⨰.&?Tkh";q?_<9G_>_n| u-cv 1w{c j|mD*cZK.E3D>@ 8х D:)%b]aWENo?z;ӨT.`p,KB*g(S(vJ81 j〫g6y S4dA@*8UBr /؏HP0)x8tVRҝZA%Glr={LM2_0t6ڭaXѰ'#gDA=1[0;\22 IW!O4Ĕ^ ~!h @Eʠ{9yVz( ͛H:`z(~qḦK3O=VdP<`%*A8X,!D Geqv%QQ Vm( ^0Yp0Q;C6E͍:<H#n;0zU{U}e>qH]"LBQn佘@}4_` 4{r7R5Brlj2f H$We$tPg R)R pj(H6S}`f1k.O[ڼeMsWf?HI_f{TsOe{ tT| Z6Z#(x]{`.{ 53B@53k/v7l-Պbznjol(kz%e-lDG9e Ȑ f6O\6+} 6X`QPS.Y('cYz셡2ԣ!&#rي 'U#C szUpHyO EsL* Hيq BVl!ۄ7jHaPЦ#'FВpؐt]M onBuQ%)PI (.v}c Gh;V=":]H<e "+ =A~B``Oz5\+w+d> hf6Ƌvk0쀻٣䏄40VCY] T(sPYfW5wQLMzD p:ШѯaUXk3 7OuG sBRS^3 #cK;2v2SkwX/p*$s)De1"N8$@D6$'(HڌyR.-*ɱsU GCZFjL}ԠLy eA{EYp5_:qYsp( v~EF?9:,t`$26m',(}鹃ٙ:4?24Kg ?M)w7=- 6e]U8,uU26mo: w1bvwާr+Z9-N.]Lrw0}v"4=(S+tC)!2rZv!O}+A^eUjeIowʬYj 4B8yV V]\K'W)t_B6% =(g! 蚈A58~ rSq?nM=ۏ˧km:J۬^g ֞g,ةƋeݰ5ۭ?>Eq8}qw n:5L/BsCm1{^Y__i>&>zָ+Bm7ZԳP.K40P#hzQF 9/G^{*%E O [,Ay ddQ@*?[Cp Q҈޳i+\TCchkKeLTꅹ*^ rfw>M+2i/L|*X&2T`idEzPl44hE[*a:>~+^wD4!}*/ ?f 2ֳ2\ve}֗{y֞ *DEU>݀Q ps7]>`2tXJ$>0)@ #>G*xt|xpx|e=PgwcfUkP,իFOݲgܷxW^n  PMDC629#"kl7+X"@հᎂA03Z6vflab +D*PZ6[>+!siChٺA}d[c8b>jF;9V(nmY+"1f 2xCxu2@ Lrio[9u C_Y2 nRC; c>N Um0{IaP+@%H(ՊRđ \T`ׇ0?xZl{ Z۞]<@x!o4 $ QJB . ÃvZh%`% H脺<¾oJ> ^y_wkܮ.emي=!&[(l?-/("H&TRjz"hG].)L hDR)KKE4^wܜJytqr*20jM~Be"ZZ[-%tDkf+/J,\3ͺ;%uW\owCLa!mWEz^RĿj~]à&ivcP)%Qdۃ#lXba/Պn \kٻph^.T@.W01cgR"Ά=1Vqojh8uH8Tˊ"u > &Dj突nJ0^}DρZ9k+Co:X Q=]rlGc ʍx,Xi,LܘZY3zyqqVkJհQwylЖESc}۰!7 )h_^E5w |=A.gQDGA^]koC* u)V/IS?ƃAc >xf+k1Ʃol_'DWw-8۬c֡y+c )qalܭ˝Ks$ 9v+hݴBƭ t3Y%>;%]>[`_ W&!_7r0ktҭ b;h$OϱEsԷ TF ¯NtE$7 o^r浸w* "JcY.u<3P7XOdwN_~ }:&EW= b?;7xT wpROG;g(`!$E`g l Hπ` n8d;>HV{~ckьDžW3DX\GZZU6<2hr.Ǿ=Iڂ*a-K &\FT"dµDIKi9PUÐ~8𩝝ঐ- j1yJ!6?]V(O9;k& f3S 콐Lݒ߭}O~k:,"Hmf+ym"c/A#vǏZ.3VaJ`j]sVn)u?Ͽo4"ÒoD9Յpԛ:5ʜL*啉#,Sae'F$X@T89ԨBRY6@z*5z6l-kH$*+ &Rb'ʇ@1v7Q_.P P`KE(CWbyBLb^`L\M3#%?$6a= IDAT Vejb\0숋݋_ƒV`5 /mp47)\[x0/𕨍AZ_j")!Rj. ed e'V0W Si?;p27&R,ggr"\%;> s=%/ţɊdUNݬd*p`׎z`#R/ v5uMTUtvrWmݪU#U1+ڬ`?e%MH;I 0caߥF~X2*;_k6:kg8rggIyq]v+)h݄,5h. lgѰ'%.?8}A! K3_!M*ͣ6KPذm1lsN]8T2X htɁr@zS8mm'跛 X®SCz8Az`ǡӶNDس !gFX,c_/iڙIP]fv Y8%( * .ԍj^l!Lqyq򃖄'O "JDlU0 'փ@xu? \E2@*nE@H1hc bnBIr ESB@&jS_7Kq*,r>㩉LW@ԆKv%P-H4Uy ZP)!-CsDʝ ھV] z< t9hTqDCFDˊ~vQiy >ta:tHMA( rx^ WT8iF9k$[>NN>3Ip1놓пK}|ۻqDV澮Lw t|,dʣU&JPRqkHn鳊efF9i}|9V;E +v5ڭBdl`Y!O=]wZWahsF*0PӍ=%dv;;h\[i[']g-JUp]:MԨǐbG@mE |7l!PצEhhVD*h㱰ވY Rqaj-~|ʱ"F+[ʍ%Bv Ba1&'pp:GԘߴVhc: Y9b,,=_Th!;H Qtc[Pu jb)'zLoOVLiioj2[JBYG_sd.8~ٞwW_py8Ga홃=)lc՚$xt]RmN͗r: ??9dmXmE8 f\zh)no,yA_(b_JTzDސ2WP(vȿ[5I;}VC K'( ]6y+iG<:#/Xh@䍺) &(7{kYKp rjEx D2 I~ C0B;@OT0YK Hݍ$p',+yJBk"58*z$Ið/9;*& r37SLҏq2"^%2TO(qcChR)0̠O܆mi@]G}s'o-࿨^;!\4|a_qB`TgiHfCK=fV;;Oo0׺Y'VE&.$k1 7X⠡,e y}MP'?":6}%슕˪n;g(o`lXÿԺXNT'a/qx@7z9 yL)Gtp.̱Y\"&p1e8&p4e1 ΃+',TTnj-$P;jM5?IB9 O|\}f8qRm62 :뾿.[fN7ǻCoVcpF-[@CB,%@SRH:j־YV|+'cEoR3pKDl $l>T(5Zo"dfP 5f;X`|l>c#[ NgKjTT"Up9 'BW D}!f'>QtY@+0iS!Dh`f,WJOTGa!1Ҫg[.b&l`E7oD@].6GC<)m B%ƒ A!X$F*J ?a!%ʣiU&M2ݖhR4tT]iMp1?RW! AD@LYh2qt=ݨ1& T:@635`5BQ!NpJl"&; b3nMrd0'? o@-;}ǚ Ɇmé]08, !%Ie- ,BYE2S ؈8@>@]mܽwQ"ƍk\3lܺ.G~XZ^Ka 1g*ڝ/Ix%'Mǀä^yK:B ].=1M·Og5Y)%ݜwrގLoS qMtBTBΝZ(N! h::Z?S<:ᒊqیNK꿊~nNc-Jӥ) &thί*4FKssDjcCK1 8x M8NL~vlxWb:Dko[#5MY`EcwKSkN\MX/-D#s,)1^7D,c[_,WתQϦU֏F!dg휝˵f˜54K XFA=k<5ИKznj֮TA!-B_ dB" `z^Hwfl-XʙE!ZPՈ{QUs xJ diBEXz5Fʮ рjvq 3 cUAh,pBJpu Y!_,5󮻢QO0$<6—}3ywNLqY԰NjB$V|`VY ҳ0uyz8%KKVqP@pީ,@QYl U{+6(d[N$6`e.!Y>m-4)I}h~l$|XQs&8ڸ4@fJ6[Fn#!( W&$0$,0j٢r&IHV5E- m/LXk.GYkIZH6Bsl^J'kϘƒg'ctnkIP9wcW2B *> J>PSC~˩6`Syۍ|cꚖ_wܺ[nkfs?o*wr|#>#'z핯& S&"vUmm_WBKR+ۦ{oѹ:IbF?`1R"9qT!&[ns]95<Ίcd"+y;vկbl-ߤnoGTI_]i=mk𷗥ST@U5.UU3-门:GpȩbB].4S X02Y7nc2V9ιlLT'#:W)>юQ-U<̗,r ,mƏB>wNss_{fGXASNffXHjDZz;w͚q8#;݇[+$gABD6E j"]GFv<csdUm=ϩG?Î~̩/l<|X]i /Ygq=ykV]uOLNNG;we/I$M?i ڴG2#P0Ο'>4bk7D">>B)Azk׮1,. - ~|sAWz㛷m'@0O^}y?3箹(gor_KcBŗl;팭 h"SΓR^9LfR?4 )]JIn*)tÔ e_Xoq7r2" ?vMss3ST~8׬֦.ZqU3]:{y`uDžP5a^tI3c Oz֯`y ={>S36:hgc[\;HcX`H,a͍0O<7!$rR;>: `a)ښbkt IDATpyơU=n{E*P{Lrn$EfJ9h^pC4Dyz<)B])cĔo[YQ_IԴXv dғn[2I{B̉/p=5ⱘ5k빹`˟&x` LdUp%Dn,NU MY$JQ#T)x,LݓCL4B-i+`i&BA(EWω. T!Q@NQ"x-& +DMPMYKm!k$ĮK߂boE%'*diW[bwN.]bGx 0z"߫zsu[0_ugbM}LVN""7B^Y["cFGޱkל{y(å݁dW.ۣ%ɎZ9!P(y+WN onX;qSjp^7=u{wL^!z~_WrIx,98_/d%ةa)O40'NOV؃f8j|;o~ˍ|ǮZС>a'i2sW_}-C|-CCt"( ΨN>TLzz^e\=wW"( O!OyYtN&66Caۼ~u6m:֭k!%(PK,lhZ 0=J8¤.'M&|q!Qў$DŠBoY/PSȎ'#** #{(2L\(7@f1Tk\Ek-^u /x*Dfon^O<p~TD\z#5o_7rEAxpcIo$b/5v7+-Et@'`q* T>c,jv@n5qb_?? DE ? f rYS>pӈNy]g&v>h]ib:XVX殓=щ[>pܼ.=c \w*K"g?^^7~#kR('}zϼ'={csB,8=)?~3` /<3ƍg㱻SO#;7n8OHOpuϟ)<46~Sp\0տ庵kKe|v}~ 77|]zm< MMTh,w-z~g v^F#LX;ԧn G.ؖ͛2~7 bbx[fmڴө>9;7Gok+r?߿ѝ;VTa<3=s,IOzd݉`w2.qr;+v<`f~N$OtjT̹ L 3i7 O[` 0{1ض:0qP;<{CRkM' $!X<᭛& SO|l~fVe]ll cRPCA]rC)=h dǞLP{6d dHɈgbbNX< `(tF=H,"t=PDzxNM4D0#N<:0:C@4l5)#z"e|FrQS!7; Y|j#+O[n WIe֏8t!92()*pSS|_ xK/H4\un,!k TS #J+/{`P^2\J"!7!dVЂZphJk)HFV_ %rZM @_6zP/A_Qv}F1 4'M_^?þky)`68M.E6ogϒhΜ{Jh3 ,\Ï]z@"D&IvP.^i|L?4/u݋/Rp>3(cG֑@ ?lÜHxU#CF՞3Y2 <p)n9s۾3?},pZ#seW}b R]WPBw];o|Ngd%jx\BHSt`6&;/Y`4%pP2]{8ErpȲb|,Jނ0b10wo|r zۂEYXw?߮x,v玌qm<"7 ?~wA֢׫ r@a-&^T<5e."VښuC堕`j$V}U@Toq5RT`,X"d <#q HCXhވMH@ZTr)jqϋY f7Vj (KA/]Nͪ:!YW W@UP|%CS_/QW8%?PE-_K8NYLsИ.tPYBM~L(WeQLuEGD4 ^A\2T+].'6{|ǣ?n򢿜o?W~]?]LaRiVw.{-֫N#gկz;nBWl{k.߾ܧ6nk OyS2&is=/8Mڴ+j|Ή3?~BeDN*}ХKjg3_rɶo~|nz[o>YM|dxx+k@^&ᙷ& ߷w@FTPpV\,)ɩI:q=:*Ù9uozt-k` o"@J)ZtYK/p˥F8γJ {T]o\d6L߈ނΗTth,-[i(͚q~za?h% [iPRDat9t?;vb{ξ}'{^-&kԇd bo w|7,2nhmHI"rQ9.O@JВte%WRn}zpzÀTe *!J) XXNgr_a,Xݶ^;i?,dfcpZ@М51b@fy-,ҞEVmt 3g,E d+I Ȩ$w]c}ML ˉ9uRy͙_}}GuJ'Œ(dz9E,jNLvn}<;?&FU wBR/쵈u{E͏|F NȎvZ_gq 8v@ `z-\[gV!&}NN…gX;NvpL\ڢ wF^7c?d>ӛ7oRzW_6&8]`Hi&XA3$C*gX.ƺvډADcLOre(Dj[~5z/+ĠE[6ٷWm"EW|4.kV^5y/`|bW\0juT7ܣ{]fxqKjY/Ў{{}5{i'BH * "X~"J4 HM:%!{㑠?6/wwgΜ33;3gt]/rT@%P"lQ2t<01R m8,SEw$ [lR v`1`$TSJ] J\|Ma h\6rҵkVCTe_Xf噣g1)<>Ӭ:`׃4bJz|#/T +òI4ST\ؙKtdbҟ^Y1`BV=Xt>(PEHvI?=[رS ";bUvPHBa?Re!f/|Eʫ| >$̓׮Yc!\pNO8``,I8Da`2igzQ'Λp>Iwu*+c]wkȚovvm[o+);~cSClH!*Gs*^sQ0T;󠃎\z8Cloo[?e2MLS^m/uy"* Zh:暘kGlG;ۖ,7W$ L2[ $ i#-+Z{@!! #)3#M>oWh0ȅ=ZAENX˱1i}j$ZWI?(4KLeazo`QxB!)+D޶~5[#54k6nGYtOEZU" w X  4`'^96oh%c K<2C A-Kq@~iKёB7 ըSMȀK^lBXd0i X+ВR<20-y@/ uj'A^%KL?@(%7S3`Ɗ7y/ `}ABc]18gzcEˆZ~7^ ȥZޘq8 K@#Ig'R"BTkkd*M) P ;6z|ct1/K'L?tZ-RI5/y_~7^hѢ~S:^j&LmR_ܣѣGqq!̝]_xX0.=+3fLݍ9ȗ(7\\+[Z[4Uks/4i2jZV <<svc\+O&U#"8K"@تw_v%=Pe=S䊽EOႴ袞|}yD򣊧D w=Y[[VZ+.${],U*C&:"+_(ܪ:R'h?p$4cƌ?OQ# 5:nM/hu.bL:? 7Uvx?4n)Z͵ ~5y1MRƺ]S&C!Q5hȭ%X-W4\IC1GI߹o\rwW>^vo(Kx-{g}ĉlWe:̯_~Y\L6eWpP̫zذa=_||ULAj8²o etc`Ssm]tQ>_Ĥ?${UÑlvl1޾O֯MHS6 YIgSd[{XlOk[Mڬy5+wH/jHЊxy5: i4vtsayȐA|3 vD{@5Kgw2n77"¾՘.dsu%2,\4 4)d eR򢏭 cJÛ#2 2)) J?1D+ȋLSټ2P[dl2EF%Mn[KXZ+ 2p0U & R*Y}UEf꒝0 Y@-M?{:E>q3O , IDAT(Zy$U`Y g sJQ ?yjb:!L[6 .83~8ZÙ$ c@D ŷat 1,4#(=a,\Q3ղc>ưLUG(lهj27:7047Hk>R5++;"8xcy3fU'TYCVh p𪳓ۚ̒ /.2vӆM)R+S_sO ͸;;F#IB-Ύsιdҕ\h`ʴ]v_},cOw>pF@3Xײǂ>:K0pS)r֑>ij19jk1cZ>ϿXjE??Nuuvds5׬X?)-,o|Q5\7_$9/3i)W:?3Gg>~n2u`83/:ɔYWbsϻL u>5i.@n"0OR sX='{מ_;{s=#gʋ/pPܥ?i.iq%z Q0L"sVZA*nK;;~:[L܊ ?Go>i_,yQGqtғN:n 1c&7a:P;L&o /s^{m]wivqG?CLY,Yrɍ;+Λ7U+z6uFWc:6P@?hc0Qkx0#Ѡuk[xhdYZ D},NgR p\&Pb)*A蓷ry:cNJ=5)>]ɸsނ/[:6r%ԅ~0n]g- wPV1jV9[׳1OR=;3`_DpjQy@w+SJ>Ѡ{K`tM\֢|~4h7|G\?ϟe=˖-(4MMM{m6vQ}O_N =Ȅ jkAIƏi]|}.hzxۺ|5:)+ݴ?,Dw;1̾kXr2^Xgg[j;JXbZA`dsPbx٧1P F= )}+Hl]G?vJ'm+`Ch*щ,[S0pޚ&]$΢`C}o؞Ul`m`LdN&cMEޒ]7[Z\Uد ̣?fK +*U?c`0qA4p`5Q% ¤@s+$05GѾRtnT2; K >ha[E7* hF*PAQ,(-TfϷMHR4l_Y&)yXxGMR,譙|5` < I0, "AKsf3WM!!l& 0ߢkjmo<4>Č7~c-;J7|#Xo-0jGX)Fcӎ57 )>~1n)jXhtYߺ[Fx1>B99$:]&/?[EAeN-IWU/n-3xxⷣzԳUU*r+r<=1x8vu&Jϼ.#Rñb+eaxxRNCG P ]D6'<<|@ Hb>jY&Vx/FM*Y4m2 kBIU{"l$wVIJh "G !@X@U.cUz)'On}롇GKaaPb+v}k6%4_z cGQt7`H/3k<ڍtK3akE# JF\'OZ̃fۧz*?}ꩧz˗3?1cV7y睷jժs﾿կ4]ih6l3>hsXU7ɫ zkH 3ǮhҭvQP @"fЈG=iTΖ+osHv+x) <#]芵_hU+{D"MDƒԱgl[ˤ sf=S9~28c&u@B6`Q5uq\NhĽ(YhEi8bQ©d(objӝJk>Hׯ\e5\@V`B5Ȅ8X. LhF.X^@ؓThLZR&'0$XdYH텛XyL<=u*@V3Jؓ~6A E,.dSz:ҡ] '7> Yt ݄U_S4)^ElS%2h+KaJE(jZ :YX451VjK>SF<2b+nE@F@X'bԎ2덏5h 1`Q?ŌFcަ.{8Ѹ~DVGL{F>Y蝲1x:ST(gBǵȄTЖFNR("RG,y|X׀BRr|ut+mRMrH w67h#;5?,]M"` K%E5*P(M#iLh~D +UU )pPJ(?k&#PrSZܤT6L(ef Bo}Lzo-* U &فs 7Ѥ΀ BLv˾;i a?O]m)^{&"ӧc1+k %.yL=h}-vmmm+U4$,#0+EQlJ7:+(vGtu^w2v ~r͚OY=LNY4 5!:3.z@Twt NJ% *S?kMP mm(_g>{yCQݗ!*8(Sq&\mV;ڙDnfLR סK8ULaZ_ K0Q@L,ፄpȊ7TK$ @'&6E 4 KZ0ei4pG~ .PM4@9$堊nCWEdw(r Gbx#eZ;=̆ :)vVɸ8s-K^vae ,dBzAJ)έ4^<$:,"Ϙ3W$d&y0%KL`ϊlޭ0,Vd,DaX8M(f(cpBPgC&eaꏥZ{>T魏ܨeƘO^7Ѱgg#``1`,3e 1ݐ-c,cIR/0! UbU3ߊ9<wc{ĬTŘ:*QfXQ*\, ((u͓Eϋc 30#-H1Kƌ6jz(egzE؝][GP%2 r]>2<^4/9MJX A"x".CoC2#@^6|sTIBك;+[󬞐7S)#/.]gWxlCΤ}988U}n'߂kH>lt/;+\﫯x3< `F9:uTV;U+ 0g4=B[:TӰ.`Y)G}d~ *Kь-idxV+Zi܄dA'mnN UL}f2LL70{Q[(-=_wUx1f3C4tDt IG.߀]!ddcf}(2YʁPc:ׯ\׶jɲxg몭e׼(o @HQan,V.ŕ~2FX"ܐ ?ݔR"W8ZC. br*=&*GO7DK;KFCԇ̉XP(&cy? ϣ?9aq)=PN~D}XP4>#OSnŨBd9Y/s8`[ zdE ~SzOpGc8!abԪ2*Rb0@) * * +2]Al!4ϗq-){9Hv]d|xTzѵHnj2WDڻ8IU7Ęxϟ3:?7v<6j2Fd,~Lx|Jݍ!t}YH (!c'ou<#NphAnKIgJ J6wBhpbx55}oJ0 1'[V~cꖎֈ׈zJTqx$`1# fT bmKv=_lgNce)Uur4.e3I6•BٝnONu ^ۗa<(b<^y`(%zyks.oH:C~8ɻ[ d E#I3+Pw-k4M7VJf & cT(Wꢹ6qW1ѕJo-3b Bu{}<9tkFA`ȋbkׄwH8as?+BY&d:*ۉd)̮*lgsž`G r=`u]<#Oؕ wpоX*2H o5khh=x2r,9J0rRA4HͳȀV2[rmֆ~^/]h/ʼngqE}x2Z׶weT.L(BLl݁ZwV@u66泯 ?r/K,GYwu駃>1Z;v,Q;eB=P4iFLdHgyo7%δYIҨ2LKY`>c|Yt.^2YSG'bӧxGi 3&/Y@΀eD\2wT6 ң쌠Gɮ,~hM cGk[o>j*R| h[L's]m--Wtq.mVPޭ]zk CrxW% E|uI]$&;EMRbf?`Kϥ(2D9!f̏DE!JIj`b&ë舥Lmb,襋!JZ;ie'TCar00xGKNB)H ۡeV vU^pA-hRi :gL2HnJrC h>Z*A>n%`JS 0\ҚS(YGSC-(^ @0iG! [!fK0ai@֤W(_tʪGGNݿ{6 ƸFl f; :Vw\hGJM$Ŋwl~rO^51vm#Η%u&z/!5G}EK& UuO5&Po:jy!) |5,x,Hg@WAXHdh &3<ـqHbaNfwKϗ^ - $X(wrEo).`#`DG".k0eK0\a|}=^o@"HЅ516s1P` VM)!׌HH9?iY;0>ؕIr5 k? o>]H u͇>Y s2X-ET\4ntl]WE JR1kAeDY?XDG%<2W!aC@\P){qcm,fl/>hѦ|,=E돢I{D@?O (D#͕ʬ ˴ 0as 1F1 #XHg9(؃)B&>+5f!T(l,= yغvXcZr5LYS#WΧZ(z%[bh>](zYr xy[Ls-N*-OĈjQĺ0&rihWW'>̦NmkvGo,ba#SU+~a(p!;li5,Ylٳ1&orvasΒebS±t1#qz 6Hv6u[Z JFl1}M)hYWL ھ C'5ǥk P6qSM1ǫeÆ54v@@e\ZOFJE3kkhio]ItuC4h3}jZ+_hR IDAThcLʫdC / R m>@Hv=`+AWj=\S)'vjv8FQ='0d LʣaO ]F4(tK&;Y$XEҕGh*2AEP4֨P+J Je,a AP@ٽWtv CX`ha(@SWAa$ pΥ#Qd 4#w HMM-jJLŬATm4lf * ㊃ud1VbkX s/xZ~1t,rI%yrcFxR$:V}`412f,I JFpYU{wyTT\XgҼdddTYݙ\h|ֺ]`ʦYTsj$z(`)aCi3f/*d7j8í|"w\8tS((fmk㡎=ܘsOE9GQ3s(d*qax"!3JkҌpIq:lc_3\Fk^9A- yfbDfRL}4w?>Ey ד(;4~ۍ>8QEIG&2|hư?14`œ @.tqQDyvNfh:Ij{@\y WU OF+f-(,;-\gFl9ff:Ez0^H0G漲`NMG)N$A +hb>gVYJIKcͮ\ ;eHcA#np?BaNcv4^l^W#{v#۱`S^(;ȎEl*|cX_^0Upd$!,50Ѧ<=D>Xb;)6ɡ^\"]hH)A%cMrb6.^Dh~/4_ƣviI0 ,N } W$TPź6<<%~u2ֵj'vGlȰH4dİuSmq m+,郁,K+ٕl[&';T}>=W6&HddTpDsŲ3ÐƓNƙ.o ε0g,ܪk W/_V7]x/9p QV:2þ<-2G/0v{G+6`ǻ^6g]L0cI?l]"Zh/ thFz+@UO/ɫD?Q`胨&a^1J1ߨ; 5’ .lDIHBtT K <ɣaJ$;1%7%%b+?IPJ!Ɯ7c uPrAqD̲^pYKOn1E•WN3.?$*x-aM8M%U ʏ)a1ԧ./9.o=h`n&NXw |גP7ǟ5Ε[Yl =W/0]8^4Ȩf%Ze1rg#X9Oo ؾ31%Aχ `3Qbze0ǁ@yA;+: Zd 檼ZѲ1/.x2:3\٠;P37{K4$dLC ZS_x>{u(T)FܹL6lHW\,EE2{V>}&*8ƃR<g2 nq^a}Q5`+`M:k^331 41/\\(,P3n720~/;0G';`sݹRЕ_os AG|eY{}TW.ژt1 Uxۍf>u/ m5Nt8*(OfT(ϕk;e*:K [a[ 1EL{|X2I/L+B T _NeWBǮ#e}7(8wV +Mgj5S"C+(eV+DpCz 7ftgcGhBM s 1hKw]Jͤ>!j1FmehzdpZ(u&]\. uqBB`ZI VkgB)œLgq^OcLuŒqr] fs ew I_(eji2,Ģ`r g~XІˌ3Ř'7gJ4cgɄ>h"-`3WȵǓnwzJ!$< 5'ң0`Es$'Y\cP_C3`Tb 2]ʓ yȺ"ϐU*`U\whA~1!''bUt#^4/ t.]Y C,F(RD,@9Y[fpQ2ږ͹iiyrd' <'^0OG"F1:=^T zW4ce4$DYg >@{UזMfX7 R=^,\J[Umk] Vp*F q֯kDDg*u XGLMwvⷓ#LhIrH8d>P !4lD"Lvpf8qb $Pp`alXg+niK1NCٶ=Nq`c Zf;XԅT!NVadqTy.w(WMxDX̀.>聰 SAL;OE`(h^԰LdZUE"D]+ekS6D*iDC#'_4]Q,ˆZ ̋73D. -Lɲbe(@sg+&`K 4 6Р~ViPA8ɡUcYN.@uRv©(*eJ]esZ*0`|o*91mL;xj U},YջR4tH=cVBbՠSGI[\JhGIU{˕-M:s ӱNvg~IE ɢ{5c$bQulD%Jpe&VPȭCL9VK7o0,Qqڔ*@D,Q"DUG ,BtDBc%v$RV0R&GДTZ'?+3% lD3C"!VVys@Dy]HkZƊ2k1} .z$C~?f7_C~4@dU Wg 8APHgڒ] K$+ľgm& զ3@g! 'O#Je"_\g_p:=4eM'vGL81ƿն{4@#$z.ȘG̈Lohdvu ;UdDdUPnPCFJ ?x,]mVB?]zbY9#?Y^Ve}[b]F#uuD r6OeԀ?´(fa@P6J@@8NOUa;ŜtL5:D? D)+0k C+x,<$zjPO7M0%< QT5uBLb2"*RbѠTh3Y- jAրG`u _9e)Ny 0JCYA9Ӗ+@KRi˒IQ$!W֭ܙ ,&"XU#Z] 7L)rWQ NJK+ɀ#ZnMVBK"мWJqC nl6ŮBڟD/>6,ZfL,O]?-̡\$TM#'O)::ZRt2@CՆ.efCCZJAX>vɴ=q>泘mXFޛ H|d_ K1|EGHnCHeV˜i@$ċjg(,(K [ShTLhdbJ/&lHB06]IB)j'ib` 6dԋ*.YHA*[4T9fF! &ݕn%h@ߖfX00|g<@16 J3#G%3 GX)CaQ#A(WijΔEh>K)YbC]Z+o"f{Q)yr "!~|WcYρOV 0>|۞s؅0m)G GϘD Ru\Z5':XU"L+ -vsVmRʭʭ %Nl6*Lme|Jؚr)5XNoDLhJ1,TPXxW&V$4)Z*ykDaHIHQ U*GB$:uV+3hD$̋D3(%PRbIN%QZ MJ VBM)VBGYP? h u>* UpGif@ .beFvYM?G?t&1'dd _+@}!J&_Rx[b15 ȕU7# BH"AaL8G(ZFP3IR/1y'uy13@5-SfEGh%:>)̴c;1+\a^{uܻHf$VF0̦@"@dRO'ئ5(ZOv%+ܠEmg6ch&Qԍ"(9Rp BdUF8U FJ)iDIʘ/RpVPNtRi؅M/zclT+Uq @~U#䩣 f \hK1)L"K 뻒_AbR%̥6a\ 6l-ߝƻA]M^߿z* n>b*lZ;z$#h[j:"+>;9&Q6Vi f 7<7<~XÕ& uo虀hI0y{#8xNeֲQ<71U d*7_a`7uᇎ MNfUR+STQVZ J 43aUzSHR+)IIʪ[3:ǒh)+eʌɧJb[Iv\Z1v p%tDwJu2%)dPBXk&JgG ,Gkn1ʬ0j.ie~ZFࢨJ OdIdUZ#P\;3Y%־pfվrs} jg;$s2tiΏꯧ 24U_-^3:ĪgCˁ+QZEKRUvu!H?$դR<,g,ْ[a%rm=*JP!DbXYQ-LJMdgORiL> P 5J"D:0VdҨq$"3ʈ^(IReQΛs%kQI@hY*beWD e*ʪG[\Z}uUB*1f17Hnl*+)Vn?)ʢhV*o*bFD QHC5i3cUaghF.%T'TdBl7Ek6h壔1R0 `ՇD莖v#D'鯁M,0Z@hv,`{ϲ5[;!3]@w#Vhw|41BYE LTYʬ(|4RjQ4ʘC|L5TDYL!0I$eU2}~ +`K' >"U=jnPi~-P@AVﺕ*GBɡVIGXZ1ͣIyeƊL@NߓD .7H"yGLYWzPI栵.U$&WV~ZT@ 9 VNll:Nȕ{ bf!5;iыAfm{1qڦyI`٧4%⺡2C}J]&V仕T gk>hĢЙ*(UnJ\URGr^E9 $lSWHFŊM))(N>Ib]L 7K1UܛmbD iLJר$:r.$Z%QH$aJdKU"&[NJ"?I[E&WJ(խ)QOW=J!1"MvbuB(UUzHQ4)T) MIhS/?gGVM>!QRWDZnuXPXePXn \WXҌD脔_5{ ȚnY-Y!@ &_,OW)\zG Հ3@7"K61_˭1-h IDAT}.5|\,G/қJ._0Yn]ת.!RH@Ḧ̤́*V`QrzwMVUl%9Uo&pPʽQ$J/yyLVu9v~uI|_5a ;Cui%K4eܨo/Z] ye*gp|8w'cjԘ =c躖֗^sO@(rgX&_(Z?tG9qp![ouWO<]uM/3fnG~aGd_;#e>cmȾ1m-Ə=f_=;aN<ǟ^le2t؈?sT]x3O8Û ?ovg}=rc8w?z-&muڷTfђ/rWڌmMi_Zrǝo1Yb~3oz4N8s@5^a}Qd4lav0h'9`$q3.lc;W%X勖۔֍3'V4KD\?3"6B:u!(Lǚ LkJS4B$ʦQ"GȤyRJQUHDGE^(꟠5-Y?*%Sd):oüRW5ȡc֏RroQXgMiSKLe`PR",V武-,HfI4XET:/;% Y!@gKDɷʘ[\ǣtT.I̩G)*;Z%mD(͗GIr%y#GbD*Y2n(:3cPy c2x_ϿZ:'pn{=z̗69O?~%6|j"#L9t\ǟxnj;y{PpOɁdrNj)6:X\*A)-'%mRW";YFU +yyo9T p֡AZV? Id&4/9)fVIy_k֨mnV25[ eC#5'q>{t.s[9ͭj2-Z:}s믾w!M߽ Xu^~?=xA{YI+D켋.D#t'쿿{[l5e+3uW>*l!1!_Dʚ#z>0]}?y0UO眣SoW_y9TO?xڷOchOмt|)Z;_&G;#vn`}iOYԽ@CSc囪:uD|Pci<7P {L}D.Y;:Vj[wƚ¤KZѴ REygOV"P(XrDAD:YY8̊Κ挶 qHtAVEn-qSEkæ(IdvVf)̄e6'|0Jl&6d@:+n,hřWrkEYP-J+u֑VIj$DDBSzNYym)\l25S3_f( Hh*[;hҤIm /555_@ TzcƏ?>-1cFM7bԨ! o9bIcf~G} rj *_l9o]>hAŒػSi*X7h7[;[n3n„v6z/{X{k~|;o{nPkq>yhfl;`хt_j@-CC={?/<)+_ē/]r9n?ZRQFb:Gy`(ZKOO%m'$5sY7ǟx;߽>zEgg Λ^]pEgg[ůo[t={ƸdWpO/yW.`08Ǎ_8󬓷fF~xmԫv]/^|9;~c:p['r#nTrcCFG~=>맟WUU K-v%?7콹N}9j靹&:iPŅ}c3=+D?@pͷ{;p/< 﫯ĠE  l/>)G[8bVq~]@8S9oy'rl 硅 >vI/#s!B=O>7H>?H8t{>ԉ->wPZ=dAƔJ+.,1xFM-on6wϜPؗM=bVݥ=j94Ʋi:1:ںVº)%b% +QE$Y[wZ&}5%J2;֌qZÝH4c͓ukIZ\9(W,~i_ yb!Q-)(g[SÎb9%IT<| $JWUk筺T$|erKhzhGYιbxVB-EZG՞UVK:$JxU T?~~+3:=y_5?v˜#ł5~ Ȏ*&261nm7cnJ$>z5'%qF /~OWs*=Uՙ73HwfC60zȰ4XqǮn7f,Af{3DbiUQ4:45esuMcǏA7wR3腛3GOrVqorMiƏ$V\cƏ}'uZLA}mvԨͰ9`@f#;@X<\QǬ<ӌ`DK}CS X?p#1{rr0:-&/Y] e>Q1+Jv*$ԼJhĄ_:!ꄎXf%IJu0%r23/\kUq:M`VTQndXU uzh+%n3MIX߰ D$䰓vPTtǪX'7ɀ3X8~Y M$:DX.8([MJB(9oXpsd1w(Y6o?c &nڐ?J 2Xf|~\ue˴<[GWf-_n@njn1iwyw|.^ d?$˯vϻ{ni/2e^zIVH4zٕߘ?归w4'2vwL9zhj4#Fk;:$\|8_>쓯;|{^ ֯]wYҙX{<`.s|9>tpu}/ܿbfG|P4|끓-]ʹ wu?Hyf*b"3au{ݾi/D C ]%V5żZg&_^˴i]ovh+3_w7VcMjjS˓Tꫳi*H C $$~&`>}^{hSf2Grp`ф~` PPxCAnۍ ^?Mr;%6| V;8s pgX6v:sm7 ^ӫ|"fԃ{a_<01}ǔYbu7f8c%JZb-%VJK8[ hE%DB[ CRZh>-E@P<'^n_ RS]KOrFC3+[lÆ͛d l+}+O$;&bGY1ua]}i,ϺB>Ÿr :?5"jIGVqݰ .w%|3O㖫p~mv{P2 p3/^U/Ox阣sW\_4[稣zt=ב0N{wPZRP>JC9 k׬t3!Ϥn桱b3aYgnڼv9#E~;6 Է/‰^s\?g^<#:W[XVZ:9>5K!y{rX _d #p>Etm b~l.;Z7 ء/s?qx'+f.8t|sʴ u'zK2gBoۄZ-_VH . E@7`޼y[nWWu.p#N+d4m[n4 ,7yYxD?د{8Tʵ5Ѩ mV\-^gTm 72f2l{:[ة`2=AqI%\X{AV邙 Ą <^=1iD#Ftq`:iHYos[$AY▟Cbzis2 h`]@AYiue3F.)LGk) =Cp|t U&(B#ɧv)Mk!j* =g>ڰn Esi_>G86ޝ>>VȂ{wͦ>\ۿk%%%=2.<195 2Wzxin*("|"ބ#᦭͟o|N‘7YvLzL:h۳@MWӠ4Y6oIDATNfeZMM7ևZMfi]XTT{oƻttҨ^x!O.Bg$ptXV|!n\7?,-)H6$܂fbMtr;4R^pPlcŸ~c|x/~XMEy{ x2RVƎ%|PD464iRVZ4tK8eqf:rfqlS3~B-q5x]N6X^?!"2[Pxړ<]& a LԆ8qfOPV.ads(sT/cXne,|*wؓXʄ gMq.Hq"_(YaMu,&Iat"KTWVD˅RyҶeURYSޘ'Ay7jBd//Kq P +'I ń0AB0gZF 5, K"FDcA4/Ȱ4]8"w0$C VleSiP' 5ȸ0ϛN&I̮ܱ~ naH8R dƗJ!0T%82ce*B EW_4*dueI'X4Q.JQcuH$(ekJ3t`-0"DqYuak).biuhG*-zfXl_;&(]ypaJ9Ud4*R턕+&]|^?,|ElaAi~+ *FHUBY!=E@*.T8Ga NcQKm<_FD MehH$崕m!MCvJ1 3N[2L  AHz ƒMp|򑐄  `)r1SNeZ##|RNKzXIeJΈa3)U OOJ!=594M|ZgΒ'LܓEi;hlp(->Ӈek|<)`:Tfk2Dx*7M7WT4 hIo7%'Q"(.qa(Lv,&5I-O 6gE;Uw|h,İ +;{D<ƪpƄ9~b.$L7BCaNx^±h[.)M]Ӱdh c8ta.ŚH5 y+s ۨؤcWJGd憞ք ~)J_VQj]' ïo&O ( }eY45 C?NtK 7c҂%Ҭo.J?fx _X"("(@[F@9k[MPE@PE@PΪρ"("(@[G@9k[!OPE@PE@9>"("(mm}T?E@PE@P ("("uRE@PE@P3("("PGHSE@PE@PΪπ"("(@[G@9k[!OPE@PE@9>"("(mm}T?E@PE@P ("("uRE@PE@P3("("uU?E@P1]>|xKj9E`F`sY[RE@h FjMθq jMVRRZQ؝;Y[ VTE@s/׬YS^^ ;vw}:v5SOƨh"P+r]+gCB+"Ih$qUI&:tps;uoՖf7mڴ{w4nݺ R)VVB>z})z rRP#aO?Ʒvu4SPE@xᇟ|s=7yӧOҥ駟>rHWe˖ :wK.a>X,{„ $=z vXX!`0_*...Z媪 E@h12(" pcόX1Ν4j3fO?,1c7pT -cѕ@7K/}駇 VTTckƆz[Xκ>qE@PKB;wi;xz)W8~xpBsoȚ4R{+V\9vXz"ݺu1b3l|[M~+ά"JaƍZꭷ:c z4uWGYPn>#'O[_x1d^qx㍏= vi0Q|L,yHcm."֎&fUVt|(ps@;*S+{YX hvBM;`љ7ogA]/7@s>n@7dd .]!n~<gw5]w|9ZdY+|`AXiLJ׈#eX샅iIE`7F`ɒ%w&ksgʬ^/Br5X]SE``e n-7\u L:o@K$T Ug־ՄL(?k,Bq S+Fp+Aci͝(gGCӊ"(-B`I)pG"c3Q-gBUq%.ݽ[YޭYvu>w}}QB E@Pm!Bb%2dU^۾1 hNe"^7>B6ɿCӊ"K 0%wnݴI4yn2Ϳe"C`jLDO )'E@(ϿtK>nr.sq\IENDB`opencolorio-1.1.0~dfsg0.orig/docs/userguide/images/ps_icc/psicc_open_current_profile.png0000644000175000017500000013165713223553423030046 0ustar mfvmfvPNG  IHDRx?Z@)$ AiCCPICC ProfilexwTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf&" pHYs   IDATxeE6I0,9 a *$HD0YQz񂊨 z$% "A9 𿧿afƆz^ַB]j3GJ@@@@@d`ɓ_:_qرalhhhhxVd`c=^yg,,=feeeee`20zM؟[e'?zCmZZZZZ;O/B -^w;{]wzK-Լ;yڿ{n:{{$co1GI&Mo~'?kf`ML/ -M6m6<̳=\ wfůNV[oJ+m-;0I}WmT^f-g~y=l97|,}{Юew>Sx_N~k^馛-ƌFy .]zE]4Cos=r~o6n6hh<ԑ#=jԚk|%!3f`x ɏM&ZakoA_G~ć?{=z^oQe__lm/50B{k EN;sߟi !n2)A:ܣFSiOfZ2oL:>3 loy[|ϗK|/r;'M4iӟtur0ӲOx9Oa,҃+v aN[BwV["k+MODݺ'~?Kc]}Շv{9s/~񋍮gkFt77Q~sW[ČIzg>nl\~Bb /5;3&s&z8n<.()hiO 7'f7 Rf}!{fn3L4Ѿ~M:7|;ӴGy^{yGxvun|%|p?_}5y}Ͼ7~uGyы^<`6[oc͡쬻nq]braxuRƴw~G}4=:u/|vz_ O=6le?-Ss9畯|Cu=dhpCWGSp#iN5Mw^;s?82020nh[Ü-2{}imV^ye/͌UWYuWꪫbO|k<µw7sm*Qo/~UW]U2,cv^k̕8m]x!Y;֮VY0u7?p K-C9 -#ƍZ˚lMoX>ܷ{v)/ ng3cvPl"xA#]`>O]qZƌ蟢m\HX`n\s}a"W\b-μ0#oTH.vog,{޹/yK(Qm_N5ڸ^,N r[nݰ \ dТZn8 WI~/q.Ey/x Oqq1P:sO~'G~>x饖u0wµ^#DruWc|廉9zuYc5,6as8<2˼}m.9ԹbD[>kw]{a?a >ͣpAd G?6n츾^5{it/ʊߛ ?O.&V\a7#","**W\yŴ[o94E~ #nYNM^,S M3YlMoy[gfѵc[w)oVe~WoEp{}s98Ƚa6ԁfcr㎷YV}үX%'FK6K[n/#M[aPd믷Т[‹.tj{ko1[ _~kҁxYg$ob]U8;Coy0u*PwңJieI\(()?>yol <#03Pcnj5SOM2yL z1|_zyiQ?<Šۮ}rf?omۘs9ŐS>U3kbqD|;z!3ه|hɥԴ WVC}-WٛmXv$o۽EGw{w#,jSr.gˋj)۾b[=e֤ɗE"`x$Remvlyk޵ǻ]a{ky<9q]N ,Vկ}cw`;j`-8kxmͳ9ۀG3Ń=g'v3Z^:_Ws@7w>>hK/ct6H2] z9Q}c~|7 _z{ 1þy>#ie8]Qҽmz5_jYckۛV^&*#,($bcj׿~O$ny.hlǍ]ɱY5"ҏr#UO+y %+b-rr年=Yg+?7v22 wYz`뀮k5LD$Ӏs9KݕI>:|J` RaZ~7;u042o3:'krWs=~_|&dOj;%xcE糟7b\pMb_,0j7818q_t`fwTFOYD%L^/S}w{ֻ2 Ef$L= T0IOӓN>Ƀ2í͈|nVrhI1cC"^.;CiWqНh5>D.60+ϻDsW=;=.%}YU:v.=. B2:/ K/Sv7m+E 4^I*u.oM)_Nn n3nzoY{9&<ӴZ33uC)kվU67opx+q? .0$E(-rbWXhDދ){}׿u*k֛[t76EzVMfZ0agS~qJ ;Not軭\M~e'X@?>q/~ _?kW^u{{Ӫ#'D7EцykZz{ȼ eU.C(;.xᇻڑx܀ud?򑏼=%b01SonWY᛼,nRr8я~Ե#"ti;w[𘛿|28CA mRDXh},wrV2=W?ש;~z}NG gZv <ַ3f.v~.V 2D׃z֖|ÉmE4)RqowSeR|BL8nzgĝ2uDwݘ/CQzi/8JH"ZMud%S5\Dh'0b52:ɳnUao)>uVD;2Qqgf K IZ2Jt#7ӡ5'G)A(OxO_pk9Q?|I=^ꖁўL@nLۉ:kfT=f;nc7wwhL* ܹuh@T ?-d9Vb5']Q*kitžy=a{t9A234Me`20e̘$fXP=,ױzLŠ}mq/8rM~=̻1ee9weoVyug$d`/U qZZZZZ}scS-----#!܇;/% BL0t@x@K QY(k0EHZ-NW)ڋy}5 Q8STn5c?o#BS`<Jc0*8e0taF?  mKlԉS~>jHIC0?5N2c}pm=Z|Ų$@B:!"-ƬDJF|3'iC@" :1ZTwTwc6ZD h>f8i^BdWTit^E_ꑖxD4t#Ōǚfr"!t[d 9馮;ؒn&iR&R-- #v}Ygq 30uuS'@i?&JY„0"*%BT4!]>|DXfOSd,;\W]w1[ 2q 0P l H6BfFW7"b`8 ;JWQJ6lˆYS~0jL]i?&s,^ϡ=hkE$5zT$&0R/& ?C'࣋UׄQnNWڵ+5XL~ZHK{_N+c SkP"ZR#?J8pR QF _"J_9&oۖd JU7]#w}u ǽD R!f$pX(,͘*f-BHQdžqT.C,bFJ?RrcDL7`~c_rZH5Z0Muw8i ,Bv ,VZ2)!9[4MDTRS"\%3٫P3M]0MFG!"}͗vڕ]xUW-J+lb˂ȝR;oӮE[i]m\{5B+`~?η^y_ uD)q`֧D]DjL`i0=[OZR,Q#(.d $&:j"T3*USIDoD%Rf,|jU?.lJ`˿ $ 5T5"fFfUDJ/d 9Q˞:R+U415#f`BKPG;y"pu8oZvo;\nu7ueR,ov̶7\Nޭ>s%Xnb_wtעkn-N]7xW}"?w-߱g2B&ir84ԘΨn2&wp:̲ftaŏ"@I#ݨFr5S: 6H[Cȿ_1}WT{>Zk}vW~w|{BN4_}4M8I#}NC7hyELDfQ?`.QJ#b!|Qu9/Sb@̧"ZɑqQFRV{n圣?-zo{q)|9}_p  >C|ox|>ŤO~x 5BͿu^˒K.Y0{%V~Ϥ(uTt)fӌ8LP\CctN_ZTwm}ҕb`?"5N)כ`Zb S%$DZ!-|'`*f8 &)S%<Cl^DԵN!K~gĉ'?I @>kX vai"~/2!h$8\ZDV4|VP}zAǩD<2Ͼr!~>.̅&_$69fHݴsgZϔ <-31Gew\uO;N[7PfgBOogz^uQȝӝmUV6W3ǵqc˪kg/tC&_MW& ^ٞ=e&h!{J}8_ ˑ|dޏ &4G+'bGB!bIdD>S OSiu:5~LR#G/3J BҒ7ߧ3T*X}%߷ZSַZ2mR9x5əWr/b9\ںko [l}7u IDATm]vŵoN* D68mˉt%WI 0s4MfL &ᣕd2yP'2x=ZCvEϟ{4/7c|==>i=Nu]eoy3=ѤL믿pҤ\d$!R7vlq&s̜]h)v9ӣ%%JcD?(:K+͒c(*UGE:Y(>ҭNTQWGFm^fSWptLT,~q"G $)Q,_e'n<˥f,i<L ꨨQr*"YsIЊeLG,! `L/eu'+~~~mfW^yk&UoC=&u~I-hwN^O}LǓt3E>+~q9dI~"MzXN≯X.0fIFF,&@tLT.Q)zY.I7"k8yzp;oz?w1MkGXIC?|uK.9F;o=㞸 GG1MPIT+a" Z1~PGTC)W'vb-pJS! v#hq1 ZhGPfYGWHB ~-"PW* $J5\so&azۿ^~#- Φ].,n&JZM -Q7hX㋋pt)XW !-dnƿQa\$VYcXL,>9 Z Q De@* uv) 4s6ngsyf{Qs5 I4vS 1s>:Sߓ!?l/8mƌsOL1ybw7\&Ym1O@M FLMC' Pe";1H):)&: R+'8?]TAZ.(|'4#-_b@I8Q/]DǗf\+] ACY\ * 6eNnG{キRRKov՗e_,~YG?osٮ+-ܮ!xIH>Pw]j"4_w|}CTrI@+IH6FU%pVz ng2BE8OxM7Q ?jG7孤Qw5j]N~be1!ּp-;׼cF6o/5۸1Mw=o=*ʻgN]VKMH M _V5x5;QQ3DžM3FfTbf#$u,bU+ߍ 2B [ֲd«y])|V @ףH[򣞡KX˿%vvs13V>?37).n'l5%|o?9Oe`s Se^tw\`̒KZhC{ԝ?>v~,VT h!=\hv/7vF N a\+'|NB`šYfZk1'Zl.*Ihμ؈XPHx TG0)Z砯}JSGP,QZ T5TԌͨkDDTGRMiStώf3aA%NU#n䚉}, ?6|]p]<:ir0G<{7|tKI=c=k(&=vշ>:~eV(Zb:q\g;+n%cD`0* JqB@ 4WcbDEq89?YCG(FpJ ]бS!jK K1SPQ!Ic' 42juxREPKSI`jL%Ze**-ƼT(>ϼ!|zs1Nl=%)nMM> :WW_}V3-M H:pgVxQ}jR,.~ L8-h|Lh?ٓ ITB˨9B /Ͷ7~ڙW^ы7joƫx|'l9R15\™kE_u7sο|eZd1on'LXfƺ5\c"|0wy*AMDۑ4)*3_HZDEHb6HӤ)H*B|`CSuJIF?Ne:})w&p/ +ۺO{ 'aQlJNq(X{yGb5kH%ZuUHId ЈĀ `$^`3zB߿QJi㿛dc?unZƓ1K/+&_b}cי) >:72(A}n8[.ka‚r?i";—CA}C]w;T0̜D"m0]8TJ$uJ'K`eJHG# CG/c(%.(SUv*1S1:) \="DrHbu$Hc, RO$uJjr V4 JwahD~DX3ЫB@3t8];Z]_V=gmNeW|< De3G欵Dn ӥԶ u]YY_8TV`f?F̿JTCܗ)SDu$$1Y#!LA?ݔXlމh6"`枭s̕ ]0 (6j΅!0 8t9͗/07SpJPzy"uUkGfTbCfB5 N/MLT Y!Ne8]lK 850Ya0jG6uFEqFE8tJ!ؤa:͢A"8e;~]'!om3Y_59ІBα`cU)JYc?F 5 4&Gw]W.h4CqxB &>xpo訫5!I_J5&}^CN|a *@+h ;(@+h5L O2T`ʿC#ÔcFBɆmsgf>KWf2sGˆLUGlR-pH0;3ZŀJ:~lD#X]Z%ܩxX@Mf!f8ANYLD-1 g爅4c(bhE j%xu NkON*!-2 O6柙G\]cmPslHi ->]|A/ŅZz|3d$%85_ JHSM-b:Š0OY:ӑA=5Fb3BHcP]qhQt>ݏBT*ubtc i`*a)rݖKړXJr$*)(PeАo_*hE~ɡDNKR-$$Wji深{GlhM}#2BY$4Brdی,{PN\Hb&xj|u0FGeHIl! t N˿$*{m;5ĩsd?5 2FK$3f 3rlFķL$&A+dD줩}r;hRҌ >"LF1꜍5F.PYH_Tgd&"v`1LD1.`Dk7N6əbHђ:'~J0mHQj(B~u ?me̝QL|VYЬ wt".dDt VtƲftPJ4TS~qBCPr@"Ic SE!oL!0tD ERiO6Z P 6sR&oK):~3VZdCfI{?V͌}=߅)a&8H҃nJVH;f܅|9Z9D,l_k|/c3uW=.?4~NJ%a&e!D~IK deJTSO>R|8_zr~{8j*EXOꞧ>_jp0Y$>6I,ABhM=}{Ξ[@ro-P$*,Y`v%BN$1^"[[$!C]3N1g`ZM_]Cؾ74XSOπ|/F*-I_}_Zo|#4/33A=\du,%貏PY 3d,O-! ]LxuҎTsǠf%7DHqB֭áã  J0|#M݅A&u"LxWW(1T<G(-IT $$#;k]3?mAj 49zC+C@/5f˙o#M9ÌZ PDB?ff욂֖X=/ dA Fw`qQud&'с Q!K(?Nߙ0N+dmLrV'lFG lu.TBTTe%.BiX$3iIiNç 2F+"ItN$OؚOb+;0$oZi ̮~EB18^Q*Fdzh(Ly5h7|L}ddߥq"E7{YхH:ݒvU-i%p(I5jp*Z2z?_e9*%-0eN 2誇O7V)JlNҍ)mUr6ݮM4NI CwKeHuhIk]1X,ݔ@&yvd >K>X֏X0R0XZ,GfK7t'= ?.LjK%pŦn/ Oji FBतhL^H]0ӗ"6hu,zDHoi@hk0wB ES0L([pR ~IZ40L|b0Qf伙^He 0K+6Y:LFiN$ S8F22N,g\~Ah,&"-֔*LD[D 4TTUb4f!5`iiKI+*Xc>ZMW 25~ТL  ΆHWW0i0I21U0oo76e\sMpl5k={

я"z ,8E'3)SaE+!򉗘^җzQ 3?OxΩveC=4[Z ; R!, f 3 ,L8ъT9I~ǂ:%c |S]É%Zk\"G0ÌGD;T?G`q ELT k4L%]_N3N1LvŞ˚6gwF׿621cxl!ewG^~F6fᎣg8̨8_׿o&U3W43cj\4fLm0F`jD( 4 |q}s^k檫ZmՄH$ kjLa*NHXE`wq~;Sj@d24S H&RfZ "3,&<wLCW Qf5ą4L Ma,uL%TR|ZL!OHIB0ckkvc[[38Lf5MVYG(> 2[= &E3N&L^=j4ƭ#8gzfN9認9+D`0_{qƚ%fՉ-M"j 35p]v:#=dNtaRQuN`(gq~_CXoVz }Gte6%K>O' A>'THt"'貣 TY".H `bLt);48uX5>B qDh/_]a&OK|oƳ1i^25wu8  5?}v>:$Ոu9LHM! әC%G'+PPIhDb;t  B`Tʠf' #D U3LDRIS=%I&<uES"&S xmUgꢧfƶq{~\rE]Ԩbnfr0o e7ݘ5&&IpA㤄gM=+wuצn:aKW&qZ1Z35 `+;o[5ҍSWIb G! Y@Εڷo}[|©+g=9o;0*.."6l݋[i* L[nj#aZ.ZX@թc`Rᣁc S18oA_+TH[  q4bB(j*}q eYWtH?"H"5>&E5k7u?Fz>tv븋)MSjr'3aoAdȘđ7Er*b`-ƙ 8MC IDAT)2.h`AjW6d'AB[a0tKfc K*b +xi8_VF2k"n-09^}ZS/2"|6 n_qbpU6C|$E6w`;ޱZ{yLfߏ܎֋QD_"y& Q4-%(RIzA$!RBKMDJOH8VЊA5xOHUL2Ij8Ff Q`u"'EP~8ZjMfK˿!Aaco;YSd{Wxu n!F+2J2hHh%G?ZX,B )v4Mt3"4I"N ڮтd;{H V36eń&3qia:сވݹ@F֍.ytmM7= /YY_~š^v9X=h=tJ;˺;8 N)Hl0'֨h  @K"8ᇠ%1hiq؇$R0"&bR 3FXBIT|%N3UcEP4"0Rc?iI$'9ro$#g2#9m&+,\s5+ꫯNs; ʡpfZ!5%1mdnBdм5z뭏=X\C"t၃Ԍb fW3#u]h׀yԁ+`̪S`&،D鯺V0DƺWM Rvt)B& 3t`f|w@z!xXM73i_얀XyfD*\( ؽϦfi4,:.p4BfN{|RF ;H.haJ&-"4`$h˜GI$XDX@W߹g*Nc:$D~7ƒC1H2L(gfM}#/x㍽1 Olmg4k3M8ވ5h"M%Zb {;1y1* IHy4Zb9mB{i_ &$P;I)T"3G&Vkqba2Y))OzrV٬ʶv3O?٢63X5waQ+yUĴ)R UAD Teg`UXn6 !iSe /^"اh-jYk-nؕz|rVRt$\R_!P'F$A0b(f%6|zV*\L@sf)ft/8 [CL  )>"5눢Rf4iI!~0D uaO\Nl.yMz[jN0Z|X(3xzs(#3Hjq̞af&tpk;>)Q?YcfH͸@#03UY~(F_ >VVd ](as/%Q]MW_PU9 Ӓɂ>#4 5iYքc*45%‡Wₔ#L61S#J< L- DT2u&—f8?]De'S b.w  Zd!v|x #Qe^gLG3 S,ƪU֛1^1"gN=|^qc|D"4L`|̂afR{-Y* J4& XPㄎ:.(វ['w!IbSlcA1Ԕ> +!1X):1،;tb!J<|x"”bY'veC->c=:MxMawȎ& wJ˿ 3Iɢh:Sp̜l eGEFX k7I!Z!R%^R[napKfJ,pljf э$ä c`#I$$)>L:~3Q@U dc$,~A 1~Q"*bP`)"`Z36Rt$iOZ3zeChi_/Kfr6:p-Pvb# waԜ8] Yt-{1Η@͎A"pjELibxLz,#s7aMTlh*,qdAxH/3}oo?m1>w첋-k-Y, "5|M ժrSK .~'M㝅8ҌQ'`EԌHESȚ& $`bICZg'DzGg%V4gޫ0#qF琵@|qf@ԁduq!' nz u&`*lF+MtAG6K1`b!*'`tHS .qG]'njqt9;0YQ&'ULE%5I¤$@˿!!dd33V !D>LD򉐮6@ GCck`r~hY?N PM0u()ft3#)j0~ 0&gE)&6rN77A[2d0QI;E'Z5X|);XZ#0*xLMulv{W6`0t nQN~Zh1S4FA/'J !D$ƒ䄞~$oeeeeee^?ym7-----|B;@[h3v@@@,C%eeee`83n22220g-h hhhh v8l h ,?ZZZZZ3m6----|B;@[h3v@@@,C%eeee`83n22220g-h hhhh v8l h ,?ZZZZZ3m6----|B;@[h3v@@@,C%eeee`83n22220g-h hhhh v8l 7g%e`2pmp r˃>8] #tg;61=zdO,ʋ_W^yd٢jx ;-x]vRK- +,ρln>qk ɓ],mĉGl-A2v$Zdk]b%YgLFlgǏ?|njc=n$\|m} Y#mՎxP2p7%/Hqxbɷ- \\uU#5-@[h"AM2 ۧ6Oモ5>eXeN4;|Zl6#-|By|e`W_z1zgEI~#Oϐ`X͢ /袋z{s=_>:Us9}{O˺h%oSؘ-#?mc"f<}s^qSW/| {t7wy7O/VL-2ram/-غ뮫7tTUl]R0>U 1w)3-#'m9ǢE23)Cr-?o~* 6W\qcMeF2TZk~K_j#܊iNU%kN0ІQo h H8 -gAs)cO<_;x]we/;cW\qEv{߮,z?<̳L ~o}7g\s|3^~;/fQ8qf-z`+~4|s_rS0 ^O8~55[F`Fk#0M-K]5CZ\/rXTJBK/ԧV?#6q<^hcZD_}3_*ڡh[>rWYKj0_]1zZe๗zTsu9ɟ{i=j AfSsZD%\yri`fjo=>X?[_z|+}C66?^XVMA#oKώrqgސrꪫk9-LvGuycJ?SOo͖gEfj]SngE[-CȀX~,??#eYFZf#[^~K_~2Σ:l} _oߍ/y/L*}k}ի^{ +!87~=w}U%JܷM4iL-_Ye]*udvE20pth,s[oO~x}{q`m(o~mG}#G-xۮʴl:*]nϒmU9~DYYڕֱ xmw9G+F !3EJs`J%V RG?OC-w6l3Ԓwy>j!үw{E/Z}ս6kmKӟxK.n^Vпv7=-J+t)SL?#kIg BkSٺ ]J~XMo?8ku+uj,l3~}t 6}#okO Fݏ|c-S6)D^>#7zT(:묳r!^= K/?Ӄ<Ȓ2Ț8hxe`~Ŭ7$sj=Bm O`S>~˞=T~ 7%43˗.dձm>eY'?ܑ5\ンg9HbAv\KoG"gSOS4f:e7{ IDAT@[hG1j3`gӻN;]IitkC;O3C6-D1Z$"KY*-$6!MdQHEڣQ"-Zo{}<ϩ}9_:r_WMKܑbp$W[dY}'|B&KFֿ%im3 u*:G!&qKyL(B CHfX)ؾbiů@*;]6 -HG&ҷȰb%)˯Ś.'0+ΐ!!Tw$9XuSiF=AU1OEVgppI+mA!yd-Go wC B@G %A0,! RC! @+B$hg B Hf\B@! A! D@6B@ Z !  WB@Ho@! @ b-B@VB@! 2mk! B@!A$h3X ! ߀B@ " AApZ! @J׽@B@! !#k ! ) Z'B@# A ! H ?3~J~o3 %-iG}M7|s!~Is>Vz? ~ep<ۗ_~_|qgI9|{۹sm#d0-sw-B@!`1<@<?cjնnݺqM6+dsf͚%JςY/ݩ5q+Vws9䓛4ib۷oF~;zꩈ)8}Wt{W|F0jԨn-X=B@!EW"Տ>+'|wN͛_y啗_~ ذgرJ:uYgիW/D<>Qoq&L*0;vn֮];bT<w>`V)8"q۪UtK{w!b-[k׎5bW^NB -^8>"/2dɒLw.kpb5]ѰaJ*gy]KI^p!WgΜUtJqnР 7P\9v EVu7v8avރhLMxTq/>#Y@|}(F 2r'p]&֭[WF 7ѣGZl;m/6mIӻv$Q\ET$+]%x k31M-ZI7A3^t)6mi~ 2a_Bs׈?3'B@p=x8> )"dXb͚5kʔ)h 䮢颒"vE`T@^p8M/_Qj b"ױhs6k p:u88,VE3;蠃-[1a_~%_! ~n3Ik@5]_]? }n uoI~diLHqh"bb. A6sLLVyvm}`ʓXB@!t'pR#_Ɠ'03yfm:kldM%-e=Ve+9@LIɖ$K.76i_!  )}L1*uB@! !3YbqWB@B@JcB@!'yB$! # A^پ~} Zm+ތt +⡠~! @$[!͙3ȪN;Etz 漓)sFT5s޻ロRŋo߾=˗/ꩧ.˻[b<9d a]ϛ7qƄu% Un)H_}U("]Gڶm`E, gO>djB0w\wh*U,B I0ku֛6mj׮216rș3gIMzk᭎Vj*^q_~>| c1M6mԨ•~NFw~ѣ.N矿;7o[oQ>z,Q*WDZr*4ЫW/7lVk@! !Ef~7믗(Quн{3fdb^[oU\rSN+W.e?x3k,ҶSH[ȂGK{ '3b@ ˌoUᅦZ)ׯt>}Pd_~cՠA ;L8!He믿~衇6lNi17kgAөSx7 .6<,F11`d %JH˖-)ݡC.a?L8e"T]bFɆ?XqUjb";)n.1f4SZb)S^hN:$]ݺu袋x%*={_B̹b@[^|ERt?,TO>$C&mé܎V47! i*/@y&^e{2ċw9\wuqGx9/\=sBS~,Y96K8AFfg"leʔvȋKEA)p1~xֆ"|+[#"Sx7ԂΝ;xT0;#jvt=/^|y]uUE9_,0#;ݵkn1#0wO>MD6_~W_qUB@$ȴE`U(AKt<7p#n5,vWw2TJ*!!kӦMʕ X4sv4hDQy#JIUD?]zN:X Q0"B@@t%KrCE ~omv5Ѣ.tһtc;9Ez\ n.ωS= j֬~'5ė_\xP5DBiv׎;:Q>%R['Fc\j ! CwQ{<96 / Ȳe:>7o3`^Ɛ{D~1 =jya"A7!IkFseD0<`7n܈N9Q]?pю67(%y`<ITIL I&ds9[l%ϗRhu_A|+X9-:1=ߐ8h-Nf_>}v;l00qLtwj ! B#@ x79G]50"PeKbHFA)ʪU*k Cf.d:F\JnQ|adcԫW!xp;M׀lk JU#F~4`9,f):v8mڴW)?: /054lxlپ};ɓ'c=q2ǫ_z`œdQ&8Eז2YJuL Eϳ>.Vb TLTal(_|68;amGotIW<O?gX0ku!3D`do+.3ޥL\8ܚ`˫ޙhP] IA1JmZ"5A^[pd!&L IYkv1җS M-8w?A`3=h!J4RG4HYBQv؟ĵc}JLBl}uj! Fȑ"kXOA=a$ \NC%go{#ܤlpmӸ~[]/sfb^98]򧎹6! `Os`N C1c\ M '  X"a\)xvqIǼ#u }@~䙹h߮Y ވD_d}lZ9%Dk,m̵FtDЃ #<;qi6ΓLB@ v;^VւZS(`8ʮEKxXp>A딀^_u;UC!`ucO DF%mVcśŴc 0f%Hd(b.(HpgcFZ]s%ᷟ~)bO&rB@%;K|8?cQc,Fdp7+APC!.$8}.PB"0P6dMB@xx{j2C2! @@6AB@E ԦcbIoy};$]""p6qS:䝠? dHV'rb""&nI>l)B@!8hIYEiw[Z"@NNRqM9b7oHk1:AKL#0$Y#$"Q'ٴJy>ً䋄究B@FKVk#YVοoz~OD J,щtA#Y?n?8Ly+S8NB@$@Hmۨ0n8_r?#Y%ߗ1cIml#B ZO6U XhѢ?SO=#ׯ)D; 1ީa@aZB@! G %A, (DA;K9hZ)h$?ֺugLPCQ:Z9x*B )C!L,t<$Ev&M$F奒<_Ҙݽ;v _ڐ^+9:B@8Rh7>?I&M0S”ZOQb,G #5n3x@B۷S?JBlSAԔ+QDFА Z׿Oѣil ,8~Ɂ2|p.]̜9 ޽;fpL'xebUB u,UoCIc"C@Ç#WAc_ۚ5kN:l[?#xNJ^al1RӱVd66C! @.TRj}f J$+nߎƊo={&SaX+}xKWB@$ݻl׌>2cǍԱM={8AE~m5k-R񔊇~X%-ӏ+}% ڂD[s ! Y$Fx[N(Wt~[3mؠG_kD"WW|ء}Wwlѥx9aZls-W0H́)A[kF! @>p91&/RIxR=70sΝ:Q h¯5iN2UV}Lx=Ǘ=޶qΘ9㭷*_|<ʈ~b}2\4n_uFIiZ6- B #{r% j{4f6R$t׽3h!nKs1PH=FMji۷kO]4 +1lOi |WW֨QRJ[ܲ_5GTRJU6gXM:u`4L[^tKYf t ^B@Dl&~1S/l\]VX8ygq *Us cƌ*v,g9r$♁nB@$ /QH/b7*Op ؐ׬]c H{6&RH=#I'SܴרZ^oJYgMx5[oHVۀl7%iS9s6{mH|mHnFT Fr]&߿?ڼ7z =oD2[-@̚= JDb3;ǫiҥ$+M6>ϘhU?mժUh.og`/ M.YHs~ܸqۉ^:{ų<ꨣƤ-P N쾚?>[իW_IfWa=z)WZ!C_66GשSn(}yǁ-楗^5jAtaf' Z6q_R,^4 IDAT8ޑWxؐ)ۂS\Y7-삼#,|ľD s :iܥ bMVe׮]B^24ؔ #B_aBwj!K 2~ixXB*hB.FLH nLLn`>l@b2LB@dEʷ8.u  ca늫P0j==z.vmѢܓO>ٶm[tP\E*!(7tf& ,YvKMIv_N<ͅB GCe6mO?4d 爄bo㣆A|ew=f`^eSLV{ eӢKZ#f?;*l*ٳg%B11nQ; 3fەK?YD5kBe8bY^^!q扜~W\I5 +pK;s _Kj!3'VApVܸ4 QH%܏obP30VvmGocwS줆{ JJ,+z!=a@ CtҮݘF"4>}6bD:럦,ia%&B@!OhR! 9m=PݎB@  p=F! r  {! zZB@9@u;B@!.$h Q>cx';wZM=RRJxk$%rKNEצ ShؒYngtVZE :$%pnCEf" P},unFjٮ[Ϊ ̤h<d)>sL; M>ETRr`QSD4m4&)4=4?6 @Gvz+^)BVau7LIMq#([5Sfj=%-4h0l0 7n\ₖ/|r{֣_! ,:=uK }G<&n*3JGKkL@m6 r-e"̪"nQȼwDmA_\t)Utʖ-;zh^zd! dl?5j%ڱ$UW] f`I! 00xn14`kwΈ6z{G' zɤ>9jEb}裏F[NXJ*ſxo,ЮG1⁐%>G<֩Sl-7&jcF~cƌO Xb{/f߾})Ep& xQS2$:=abQgٲe&LuFRoހ 53yg= ]G[^=zXؐ!C̔#<#(x˖-|XL8b<1q;ֈ[N:YTg\ERfǟe"qH{UN8dm|K$fPU@z[L^ YM]p Q6ϔo/6mc 5X+ÖǮV2i$}UVS~EQk -"!/+z!5c4h^ұcF/5{Mzڶm9|p Y€.l z1A`טt–.8ZwO<axl7N!((0]nn3'P{#`o9qmVXz5okk׮ovDtoHg;'Y?B*hyH(l|P[.!0C'/4u3H]}Fml@% k3Wqt湶^z[:12s _%Sdق]3L='f5W7|p\SrK#2ڝ:ubA E:Mt2yJٗ;Ƣ}XFf 4DFj|Bk(d?^/}ᇼU`U †y@o޼S*ILO.G&b^It~_ܒBCB3): v<dg ׬YG[Hn0痁 Sp 'јnH]G:H(~#|@/b/2FK? /"QƫQ$۹# a&rJ̄SٌK 2{ɒ%a_b,1EH}Z'1% 7֧ nGDs$Io1/&&/nBkZcl v~]8gF2jkKZuB={O#F 1cU~Fvp^vw"hYpb@^+49Sܦmp *枢 ⧳E7#o:CW;E O)j4 si ,KJn$WY(>^x'AC%Cc44 dDѪU+F1ZN)CuJթSg˖-@w}Tuɍ){ifqBLur|>(\?~ԁN;T%Jq#z؁յer׉O?}ƍFѦI! r ڜy! #a|*ZB@ 9(u#B@!F$hT&! RG>w %^ O*%rS)lGa֭[t.\slZyOA=:q)`>=TuTiڴ;ng}7Kޑ颋."S4zB@) Z2pdJdZl ڻ7dVܹK&R-?B3gRݤ)͛زe™T5VAK -ƒR+W&ӤI(\6 &B@!6Rz*УK Zjͺ w  66&EdщM"nTwV{"7Bc*ߡZyZX! @E ShR惎KM͛7%J,dR'vn۶[|) K_nB@ƒ@H-J'sb@9CzN-7nX<ԅ`s;v/>o_@޿B@xTв\1VVmŊ k!J6d\_w+Vx'R}ȑ6EK(@kBJ!aTw:zB@ RI&s%IqbŬ}S.Oviݻw'$8ڿY#jߏ)zw6mqR]@ ! Zвn܃>HׯowB9)).KwX|s=W"TP)#.T! @!5Ĵl2(K_d qŘ@ŪܡC3smhZTrpwiÆ $lIDAT7nYb-ڧOoL28tqJB@!Pxђ72][\'@eO:D\IBw߱w(]74D$9>%[% v0l¿5׬YsI'%V4B@ jo!VutoNFM'p™g ^xo!ُo)~ P%Pn #~kcʕd"UTa j*SۀJ$:%̌$]6\ݻ'")VU7,E֮]ԩC^{ 5jj! @z(81)wwÈQF9MΝ;ӟ֭[7h :a„'|BxW^y%H m>|8@رc[jGx,SNuȤ{/p~R1S(wĈ>o٩S'd](¬ΝW]u +W&2(f9#C}g(À +kSGs5;LB@d4L,('Z!Cy衇(w5אqTG;Jn9NJK7t3gٺK T@'*1cv~Q R8~xP,Ts I'tBu4f͚dDwp5@)UFcG|XڢE Afhv`ΥzjLM6Q: zrիD)Z7o矱o#)HIb DJj ! @#^1'`Q TBH-[; AU;ķޣQFxX}62ZgQX1‹"Qhg|ŋo$ڶ#n J1D%3Z~vRKyɘ1R஑>š0[ۭ[7 :}BFb ~ BW^:"G,ڰVZx@M7nG{#<XT4=H2LK.QGT4Ӻuk*hdoM6TߣMT 7;#?g%ުgϞM4V[!   ZD<=#gkDiݻ7[d֭['ÇF L}hNHVb\fa6 @75ܯc@o TgO7rusvu ! @A"^AfPL(i1Ó X(ؓ1$W fn~%jJHwXK§y5S3 (\~0|F[@(vѢE}JwXЉqEc-izB@!^pXw|qׯŋua1LyH.Ȯoc/C/bB0 2l0XSL߿?裏n۶-4lWEF}zJK@A,4 [L2[}=1b+СձcGB&\H)l`/=֭ +lƯB_\0gu#<#cHVhҍ !^{NPn9t[fnu=m+͓-zCvsD//GNA=B@!OvIB@pi*UJ퉛(ۖV1ѽ GWܗIENDB`opencolorio-1.1.0~dfsg0.orig/docs/userguide/images/ps_icc/psicc_select_profile.png0000644000175000017500000006711113223553423026613 0ustar mfvmfvPNG  IHDRpvB) AiCCPICC ProfilexwTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf&" pHYs   IDATx mEq?pH44&QA4".ȢDAEĨnȢl.""* EQ\@PAq$FQĸ ~9s;3w;y]]]N .7߼|re˖*xTvO[W< n fPNCUH+$@j!ڔ <E+ :y,̔BRM& *ȹR.D V?2RX"%)**8 )9?Jnu[iaPjczʌO p@Vp s!!vE@ \/MHO40E]10KU!BH̽E'=)O\"4 WG,dROER As/-39JY!)8AJ?яq薎3l"^t2dz$ i)mA\ey4)q`0!&rQ(dF.8f #Av)SZP  B'*e4CU0Sv3iʿ"2a4J!<&vu̔xᣓ9g+}.pJ ʣBA<RFC6ݥ 4)tr j{Y]+,B0A4lvP(w MhMQI8 x1d*{ 7AAc J!]yTfjSPܫWo)#O_JfCs2e@p1Y4we?MRii  rw=jRvQpܕZyW-}[q/&!&iTcZrZ5Or72O4$39,%=3'3-mS+)ERpO{^j $6q "&w髅 @ S&&&R ܕrXhŖB\")D;{GWu䂣 d?kQN S 65H Ұ<; (0Qf[0*)bQlIq.wnw;<3{3fWƖ7eڦt!tV!8dLJfqrЄ yJw * !4}B-4 M xl`[t{LX*V0qxh4qwBp BGD\a2El-KUPI I3 c"~?_j=w e\*k?ϭzwӝt\{R_W~_CF")"?𶷽+M= A}]}7u{Zwӟd< Xĭ6M6 ` As4WtWehr JYhXB~! jC!p/'UWpk螫TyL@\ࡣ 7܀ @" ŠU $seF>O~ri> -@R`9QFmUAg7}#ѻ9J̜0Rwgui^{G>R&!3izgygoo~?+~U?hV'5S2!*u2uT 0j\!  P-M YPԵ{(  drJs=*P 0뇣V\V_0]D9:ta . ABi=] %"38arGS"ގH)XDG 2Fp~\sͼYUW=_x)ze#eo{GIPn9vpSYƬ6@x44 )M V^$Rڦʪ;: j]xP]Pv*4өVa2͎VPqOpt^ d@J̉xBca8<8[*HE,] 1݋#L+w(kr0A Mjriʈ&U)ZGWDm?J֒erKsL믿!^9,W/^qqX''?I=AV/Ŵ~wE&Oݼ/)~tAhwE5#s u;կm:&@vI2>Qꪫp;4^0[o{#u>OyS.rp&'< }c XOyc DGgSU9˜K@2R*ACJ-:YހzD2K~ CोXS 架6WxSN_(C˸T xp!PNFW=hiB*h $@ZANC$ȥt# eDj)?dh!iҒ? $C..5\DC85 /t7-@gxK^D۝v)uAA*7;8KtH=ǼX[g3;/r@VB$zW(o>wVc ^CcVYh .e"{Dz Ěp. Q(h K#2=`/;=,(`Vha pRVK:SpR΀*MRܥM {E-_Cȭ ⎦&)( x*I 5I)\)ê);RpRS!$OQΥԦJMV/Y< o-{-/kq|y[zԣ8jA= P[+oVL0ͥ{W>LO|H91YB B!YWzLAY^Z[DCOXq@J c !/ќZ<2r} ^h]Bj p1G})7Cĥ*lxU=wjiQ0hy tRˣCG5)mB&傓r\RrY%wwUϟ;mz/P4 ٚN]x/9,v%CqxNxNh?*ͭySK,?=hEe/{&QpsSztp,rG<=]VD}C!GwPIE33 @Qw]TvC֏_ wQPrbД3`* @VrHTvI!+eM?^AF8Lpg j r !&V#S4ӗaq \Y+tRr)~ ? "UĒ@,3/~.a1E[jAMNWEZ;҅v~Ŗ*N L*b D!\e& se8);GMozS$ YGК?["uv{{|F(g?}O Wfo裙k_ַD\+ p,Ɵ+Wc 8UN SRVP:SI '.e4) BQ!  >4 ( KR(*gA( VzYxaW<͹ ýG {"QFJu(b%lJ?l *;4ksFxQW Ŕ=ՖXl5הBM.84Fn!y;WB=YϺꪫCפ9ҐF+RGwdXiނaJ(խ N1y3qB%E~67MH$0BG$a?Ac`J *h,K*"W4wrKDv8it6!=SP$^-r\x;WUԜDR%&f Io`Z^FCg?YMR P>$x; p|grIF-qYM29R[H:=z1vmc/~Mv,! եG \~ai:M8GZn/| )oCxG0򕯠Fjя:Q{s{wv*U#g'KmtJ.*6Q hu$L|TT@raLL':J(qLwQ"rKEkC RŻ;mDF$ӣB\I)՜)LW\qG(_"xsNw#8c|VA$ E]a{{mfm?=tmM) DaJ k/D8{73y}{iq&蠞p el(ei;@zAM_d+P 1~#TM ޼8!l}CD#jb$L"HN8Y,e#kQ IY&:Ҧ@e?xsF W$R03eG$fywj^R +̤-_/;#m2dU li^q % 8c8b8g 4kJB;TCe*K Ă`fpA=r(R/Lr,CCف݂2 DwIitG CC!rIEz#S- ˫ &r*0P2lFXCdJ9_ ?/D/p"XQ>8e Uf03ǣ;@35V),Qw_2/wa۟;5vۍWpʲ5Gټ/XgGa̖0PL^Sk0S6ʔ24i(SF՜RTLKPmzL0|1SjN%\=ŠКHv}kRS&BM0حyqt~gC;݉=YC:<ו%W.u 3M~j3sЬ aRN%/z(oVReƱ\?OsVOL/ef>RߔY;L_͇^FѳOzI$@B{ _H)X~>pugblp4PjBs/ۼ A&\9h#3B*ˮN1= \tGX?hnj׾$a4qĐՖ*r-؝Rf̔j ; O.J$m)"2GGko{JΌQREx5װhysWu[E}U(3['B~ ޤ\ser%0͑gY]~3WܮU]KBU(KzO`<M$PʬĶX ;2: CY B.սwL(3B72vdD+*ȥ*:**H*B3JJ`d edBsJJ`d ed1Mv IDATBsJJ`d edBsJJ`d ed&RH O׾v1| ÚE{U$y _J~0ϔ<3/–'Tn#oVVBIJ`Ia޾88gQ 'x&&?qwmc(lH+5g;%LM({u{ ,~X%0)XGIQJJ`H T2*Z@ ezU**!%PʐhUUK*eT1@U(C U T L/PQŨRc;!yh!z_撒@U(KuK|S^Cs %P jc_aYװhVe~: 0TBY/qCWs9hX`e&1wVF狼zlvuׁ;5X>se%S~ߖ[ni )wG:#'p\0V3BS5)Sb|C(Nw ^f-O}u?Ԧ (UW]%L >Ox6䞶^:SqV=xb";. #ruꫯ,Hpz l1h߯5yN6`Q /0gp#Kkgohu"8$xG낺Y|y6ke!Q׳Crb<|oW>'\zYȇͽo?/}鵯}evڌJn=VMdӶnۄL[Mޛ4VO?}ڶsGíN"u2+@<֛.|3qJ[Q,zDR`aFAkV(]_s5zЃvuWkvvpܐQ]k\H8cVܙN:)Zy;SX6/:)qᇋw "Ӏ~ޗ' 8@ $xBH`Js+#fiz׿^oJ,h/^EE+DbV )mh /|٣e][[3g֮fCz K{(3g76S/f!HVV];XNc&AeDXS>kt9@Y Rohg d*,YOx,mQk$r7"6pC[_n ?M)xG>?I]5jaPF ?;$8ꨣtϦ L | ѣ|gBSN9g=YG+ އ*T2=VMhsx9gZpOzۗXYlT/4j&0o}̸.w)`WLr7mVfy~U(L*S+_JSyE#tVCX977i_BƯ3nj?Z,!"]{PCnˉ0Bs7' (nɜ(շAVs:(xe2P,e6/eYq5Sp9sia)׋^"j)LLK3w"saHpK|ɼ6mO|"\:J`|ʪji^OSѧ;/0a};8)Ry#iQ9UlK6el6`颅/F>)V^lE¯$0ec``}>묳(W+b ~Ajկ~ 贂̈́k"t!;K+3+>Og!Ӏ~tL3_v@f1t С YlNvWペ f r>'&?N( @KϋEdo+}6h-ic b"q*aEkP+yx%}';i"k%ZHj0kQ%0oR:>ilS?3< rvSNYTAAc&e;?me8st[`g%k0قd!,lxKr"3,*Qcx/+F 2W3'(hlPyƙJjbrvt9^>97[o 5au٢K7_}tVpV H`,`|_aZL c=,* 'hL |xygXT!B &h& O-i[|u8r3 l6j[5N#|f+.NC:H,.[el&;ײl'ub'>jm2sCҒe*SQ;/vσWb}Eަ Z9z"z#T9Z?&Zq* =R1SDeC]q5 rO B\ hhvO7-棥b\5@ZgRе[d}LhT{xE-`B?R9pEP`+9u9vYmn<0Nٮ;P \w-mH+z?m 7^fdV_s۞zP p,|m୘ъ%P~+>vq oe>-iqYUYLs/}1YdI~-{U(F: JJ`~V_I@J*}w*@U(cJ*CU+P&UΫNU+ U LBwW9; T2vd ~S+_;UJc:Ƒ^yÍ7#q@U(6V/\p5\zϮCEE=*JH*"%Z8z6V qe%zW^?q>bӍBw5B@'.ckvUn&򲗿UW]&R$ꫯBǰ]-F_3`'?)ꨱ0rdxRr%$4SvS^I_{ %lφiݭF#*'V~Zy^(@$-(U < R${AS2p?bQ. 4MDILkpA QLQ]$FgTM)IS|Bo ;oᇿYvկ|~o&򰇯euGԗmGvSG 2;R%^t "bWnOLжZ=kJb$TpxB%͆Oq9КM$ !jV+3xgn4/+5X%.iJR!)$b_YM)o?NF>t|Ӎ*Z?ݼޏ|܎;c1{_߰joZ;0Z6i1!kmf7fs@z3e}-!rNqw*iҜQ%SRt9HWG[Ua!~.P#@Z읒Nꫯfq18.'7}P\6Ԗ1[,CC*rNW Z~t{wN6IH>J+8_}o56:4Ϭ|s_ZV6bAپ-`~]s] 08?O|aD p0& EM?Z 4Nni7Lٞ❶߹#T2wN6k_ڥ?ѽy=1묶ݻR%Д@=4wl)-#5O薈BF%aL(fx.2ĂV)Q3uO@#g&JFw=S DJnU?HG&QƆYt#gs3U8H& d]84RQ&"ud F/lhQ|DIڥAYsS7%wD&I<:Y?/[/^+ xvZ&o91g [2IQh"T։wR);&&Ltv8y$u^V'F:DYښ.{ 5\HC9I2<ǡTCp]q+`YvAT)D&\ T d0@ Ҳhy51N IDAT" AȿkSoy,Dy<nG [ arvE6m223P l"]#yRRN+4ڪFIgN4ciC$)ȋjK9M24)#$SW jICsyfsLߐ l3n jfJ?3e0ȳ3-жt g/&uB}U2p{^O.ς`(Qb-:ˢSg7(\pze|=)'>9=[2;OsK4W{ Ǹ8kϲKw;z51Ύjb2:lik٣,]G^(~hv*Bfg2¾dv$la_ %e;UE%i3/e)LYPd{;N5L`x.6cGü:鲇mZQj!֠ [;BV41DJ)˘Ɓ@A{ISw@x1X.VfVF4ES8[L,681 elbm^U& Ykwh!h-Vg^m8\JO%0҅8#-GOT(6/>]!-~Z lwܩY)KPDϛcxsY~EᄗG8/N3T2ƃ1y#G߱51p:BY/u!7;*V*Bd A|wCYB/~ކZʼvB) a93iPJ`$PjK*qC* @U(*U.P U&HUL˪V B7T T2A/Z%0?l74Ž`̉ҳ/qpPm+pI*Ma]Y'񫠉w }Lz$U˓(P&񭍒g DlM*)Z Eh{b:^:3JНqS7ض!ږz2{p<5d3ВϬ'DAz#*t 4@d0&+\Q"yL-o(>qDV$&Œ,'yK"G՗K>rEd+D΂W%aK@ʎub9vj(@}Q=T򖐤8]lȎ`̨yN$Nh@-!I̫AQ5x]Y!U )Ōf%z^ g Ze b vZ9/%& Uޒ}Js '`o˵H,Ts"˂ ޳-uc'nj+82ZM,~Η=Ҟl]a4/ +#cS=Y45hC&Rg 3UHCDQ#l3댵ez .t@x#j%y4Vʪ%3X>vaφ)f c*h=}Y ]{IPF$L|sYgمSDXTa}rzֳ$xtJV\zLL*߼9G]|z(M7ݴ+śqK{_Hw`."y ~L^P3QR"IEX )=>W~8`:&^5L=b#k8<.îq +VL:k-̮G};5MN& {;*~Rd|^AiF"}JW&K brfaAS5~+ 汬բJ*'a(LcZ1&{z.=_|C=ԏZO8sE?J_ _d`AZρ;:3ru*dx #]V'*IyS'}oϜ.$]6o^~+ϢuU 'PNֵ*E/P+X8 Tp=U ,z T_q`I*uJ`K*ENU,kOU^U,W\X%p ed]{X eѿ:*R(_v/jOUU)ǁb4qD\)xg!#ז[nN${1:s"D0h+3i&ň̝ "/g?m|pitjqʱP{K_*Yz׻ҴtDsjHG+q0&ĩ|p(FQ3񩧞j\v^6=bs1zsuY/xr+ʉ&Ȩv tweA$R d0" qaO `I Aq 98#bM>򑏈{:kn{r,;o2Z@*c.(ޑG!*&! /j^>]J~#EPwߝ.}w+\` 'ɓI͆b5$g*<[~o i/~!"RT=NHK,]N;Tb5wq5g@ @22 =(ԚZAp+j(bGH{K!aM1}__hђƫؤEH-LBX{b(1+5rf{E\'E$˜YN7e7j4Q:.O-Lf5f4i׳SZ;$颐7voL;DT^< E .j{TXfկfΤВ>&]{{Gb:%YIEFYbV=3] Դ4g:BWfP>س0ӱIM𒗼$nYpMTy hX[+iqh [ %y) N5fXQp MCӄ 9щ -avAs{M<(SfOY^vmov\jpQSGwY Rv*dka%0'QeihY@.U(>4kYVl+pZhv8B ?0{_Q%P%0/B)˟?rkj=rG/cH_}k y,-& ̗BgB&$*R(?WqYYyla5s5?w773ſ+{dKv @#{3B™g闬\f-R(.&ayLhB QWC ^_Zɬ-6D"KykwC!cHAFQ%X%0# ̗BO &F@ZN0v Gwtpڨ%M:DL@0LQKy_S/D6l͢|uiFhۯH'|?M&"^jo|uo)58|qKJ%Pm& t؟#-/?11N=T?m `4? I#__~nv. /-Z+ ̗B?P5q'v֯~mQfڿ߅p@PT;m+f"|yp~p&|@X@  .-t0/{{n6%qc?A$E~K:}mYvwNkKkmeQqҼ[DVyse5$ي›N; K?}ެMYkʮ_\.~T ]PPTuCK^=c]wm: xp P-9JHQT9Y$BF(lZQ.E^gq,% ')gvko<4ACqX*e>=y :|_"Zoi TZa\5 [kzp!x`+0W~w_y+J`$0 ڰ~\⌰,rYiZ[wA~_/mEpY 3 GYĠ ~"GFgvyS bNˎ`0WbMG,#.JKjWȚ㣥Vٌa IvSp4)r%0_>0*‹^" ʂׅ%9d#΢S$ 6N,T*C%+_&)ԲDn!4ysh)7$\Lck6Ju{&b W ̣"$kmڇ~ҏlSNX s a5B$IDATABJl ұ]-mݶ$X⤓N*@8c)0(vi'& |' fr)_%0; ̻Bwo1JLVBV~G_p-xavm :A(yaxpA٣usO0vMG-ܽ<>8=P^=i a=;gF8VU JP *tI5G™m!O3w\+o_d]vQ6 ˘ⶴO9)u8~&uӶj1~:W«F.zoY[wlPFAG>mhe#@#| ;-ÁNj܌U~YN/:y@z,Nf~W )ʐ)`:_@kƪn%k! ز}z*oO!WNl>δ\QE ™ZLY\PgNI$bu1_(\^**/t VU T ,2 ̗SvJJ` T2*N@P e(1U**a$P0R8UUCI*T@U(HT T %9}6NHUUK@W(ƏʗʏʇU T ,j Tʢ~upU +PV޵*E-P뭃XX TU ,j T_o\J*wJ`QK*EzVva_GJ`%0(HNW ,Poauު&[Շ2r_%0V e^GeJ`%ېa"IENDB`opencolorio-1.1.0~dfsg0.orig/docs/CompatibleSoftware.rst0000644000175000017500000002327213223553423021550 0ustar mfvmfv.. _compatiblesoftware: Compatible Software =================== The following sofware all supports OpenColorIO (to varying degrees). If you are interested in getting OCIO support for an application not listed here, please contact the ocio-dev mailing list. If you are a developer and would like assistance integration OCIO into your application, please contant ocio-dev as well. After Effects ************* `Compositor - Adobe `__ An OpenColorIO plugin is available for use in After Effects. See `src/aftereffects `__ if you are interested in building your own OCIO plugins. Pre-built binaries are also available for `download `__, courtesy of `fnordware `__. Blender ******* `Open Source 3D Application `__ In `version 2.64 `__, Blender has integrated OCIO as part it's redesigned `color management system `__. Krita ***** `2D Paint - Open Source `__ Krita now support OpenColorIO for image viewing, allowing for the accurate painting of float32/OpenEXR imagery. See `krita.org `__ for details. Silhouette ********** `Roto, Paint, Keying - SilhouetteFX `__ OCIO is natively integrated in `4.5+ `__ Full support is provide for both image import/export, as well as image display. Nuke **** `Compositor - The Foundry `__ Nuke 6.3v7+ ships with native support for OpenColorIO. The OCIO configuration is selectable in the user preferences. OCIO Nodes: OCIOCDLTransform, OCIOColorSpace, OCIODisplay, OCIOFileTransform, OCIOLookConvert, OCIOLogConvert The OCIODisplay node is suitable for use in the Viewer as an input process (IP), and a register function is provides to add viewer options for each display upon launch. The OCIO config "nuke-default" is provided, which matches the built-in Nuke color processing. This profile is useful for those who want to mirror the native nuke color processing in other applications. (The underlying equations are also provided as python code in the config as well). A `video demonstration `__ of the Nuke OCIO workflow. Mari **** `3D Paint - The Foundry `__ Mari 1.4v1+ ships with native support for OpenColorIO in their display toolbar. A `video demonstration `__ of the Mari OCIO workflow. Katana ****** `CG Pipeline / Lighting Tool - The Foundry `__ Color management in Katana (all versions) natively relies on OCIO. 2D Nodes: OCIODisplay, OCIOColorSpace, OCIOCDLTransform Monitor Panel: Full OCIO Support Hiero ***** `Conform & Review - The Foundry `__ Hiero 1.0 will ship with native support for OCIO in the display and the equivalent of Nuke's OCIOColorSpace in the Read nodes. It comes with "nuke-default" OCIO config by default, so the Hiero viewer matches when sending files to Nuke for rendering. Photoshop ********* OpenColorIO display luts can be exported as ICC profiles for use in photoshop. The core idea is to create an .icc profile, with a valid description, and then to save it to the proper OS icc directory. (On OSX, ``~/Library/ColorSync/Profiles/``). Upon a Photoshop relaunch, Edit->Assign Profile, and then select your new OCIO lut. See the the OCIO user guide `for details on baking ICC profiles for Photoshop `__ OpenImageIO *********** `Open Source Image Library / Renderer Texture Engine `__ Available in the current code trunk. Integration is with makecolortx (allowing for color space conversion during mipmap generation), and also through the public header `src/include/color.h `__ . Remaining integration tasks include `color conversion at runtime `__ . C++ *** The core OpenColorIO API is avaiable for use in C++. See the `export directory `__ for the C++ API headers. Minimal code examples are also available in the source code distribution. Of particular note are `src/apps/ocioconvert/ `__ and `src/apps/ociodisplay/ `__ Also see the :ref:`developer-guide` Python ****** The OpenColorIO API is available for use in python. See the "pyglue" directory in the codebase. See the devleoper guide for `usage examples `__ and API documentation on the PYthon bindings Vegas Pro ********* `Video editing - Sony `__ Vegas Pro 12 uses OpenColorIO, supporting workflows such as S-log footage via the ACES colorspace. Apps w/icc or luts ****************** flame (.3dl), lustre (.3dl), cinespace (.csp), houdini (.lut), iridas_itx (.itx) photoshop (.icc) Export capabilities through ociobakelut:: $ ociobakelut -- create a new LUT or icc profile from an OCIO config or lut file(s) $ $ usage: ociobakelut [options] $ $ example: ociobakelut --inputspace lg10 --outputspace srgb8 --format flame lg_to_srgb.3dl $ example: ociobakelut --lut filmlut.3dl --lut calibration.3dl --format flame display.3dl $ example: ociobakelut --lut look.3dl --offset 0.01 -0.02 0.03 --lut display.3dl --format flame display_with_look.3dl $ example: ociobakelut --inputspace lg10 --outputspace srgb8 --format icc ~/Library/ColorSync/Profiles/test.icc $ example: ociobakelut --lut filmlut.3dl --lut calibration.3dl --format icc ~/Library/ColorSync/Profiles/test.icc $ $ $ Using Existing OCIO Configurations $ --inputspace %s Input OCIO ColorSpace (or Role) $ --outputspace %s Output OCIO ColorSpace (or Role) $ --shaperspace %s the OCIO ColorSpace or Role, for the shaper $ --iconfig %s Input .ocio configuration file (default: $OCIO) $ $ Config-Free LUT Baking $ (all options can be specified multiple times, each is applied in order) $ --lut %s Specify a LUT (forward direction) $ --invlut %s Specify a LUT (inverse direction) $ --slope %f %f %f slope $ --offset %f %f %f offset (float) $ --offset10 %f %f %f offset (10-bit) $ --power %f %f %f power $ --sat %f saturation (ASC-CDL luma coefficients) $ $ Baking Options $ --format %s the lut format to bake: flame (.3dl), lustre (.3dl), $ cinespace (.csp), houdini (.lut), iridas_itx (.itx), icc (.icc) $ --shapersize %d size of the shaper (default: format specific) $ --cubesize %d size of the cube (default: format specific) $ --stdout Write to stdout (rather than file) $ --v Verbose $ --help Print help message $ $ ICC Options $ --whitepoint %d whitepoint for the profile (default: 6505) $ --displayicc %s an icc profile which matches the OCIO profiles target display $ --description %s a meaningful description, this will show up in UI like photoshop $ --copyright %s a copyright field See this `ocio-dev thread `__ for additional usage discussions. When exporting an ICC Profile, you will be asked to specify your monitor’s profile (it will be selected for you by default). This is because ICC Profile are not LUTs per se. An ICC Profile describes a color space and then needs a destination profile to calculate the transformation. So if you have an operation working and looking good on the monitor you’re using (and maybe its profile has been properly measured using a spectrophotometer), then choose your display. If the transform was approved on a different monitor, then maybe you should choose its profile instead. RV ********* `Playback Tool - Tweak Software `__ RV has native OCIO support in version 4 onwards. For more details, see the OpenColorIO section of the `RV User Manual `__. Java (Beta) *********** The OpenColorIO API is available for use in Java. See the `jniglue directory `__ in the codebase. This integration is currently considered a work in progress, and should not be relied upon for critical production work. Gaffer ****** `Open Source VFX Platform `__ Gaffer is a node based application for use in CG and VFX production, with a particular focus on lighting and look development. Natron ****** 'Open Source Compositing Softare ' CryEngine3 (Beta) ***************** `Game Engine - Crytek (Cinema Sandbox) `__ CryENGINE is a real-time game engine, targeting applications in the motion-picture market. While we don't know many details about the CryEngine OpenColorIO integration, we're looking forward to learning more as information becomes available. opencolorio-1.1.0~dfsg0.orig/docs/introduction.rst0000644000175000017500000001761313223553423020501 0ustar mfvmfv.. _introduction: Introduction ============ OpenColorIO (OCIO) is a complete color management solution geared towards motion picture production with an emphasis on visual effects and computer animation. As such, OCIO helps enforce a color management methodology that is required for the high fidelity color imaging in modern computer graphics. This section introduces those concepts and general workflow practices. Additional information can be found in Jeremy Selan's Cinematic Color `document `_. While OCIO is a color management library, it's only knowledge of color science comes from it's execution of the transforms defined in the OCIO configuration file. These transforms are either defined by the end user in a custom OCIO config or inherited from the publicly available configs. By specifying your desired ``config.ocio`` Config file in the local environment all OCIO compatible applications and software libraries will be able to see your defined color transform "universe", and direct the transformation of image data from one defined ``OCIO.ColorSpace`` to another, in addition to the other transforms documented elsewhere. Sony Pictures Imageworks Color Pipeline *************************************** This document describes a high-level overview on how to emulate the current color management practice at Sony Imageworks. It applies equally to all profiles used at Imageworks, including both the VFX and Animation profiles. It's by no means a requirement to follow this workflow at your own facility, this is merely a guideline on how we choose to work. General Pipeline Observations +++++++++++++++++++++++++++++ * All images, on disk, contain colorspace information as a substring within the filename. This is obeyed by all applications that load image, write images, or view images. File extensions and metadata are ignored with regards to color processing. Example:: colorimage_lnf.exr : lnf dataimage_ncf.exr : ncf plate_lg10.dpx : lg10 texture_dt8.tif : dt8 .. note:: File format extension does **NOT** imply a color space. Not all .dpx files are lg10. Not all .tif images are dt8. * The common file formats we use are exr, tif, dpx. * render outputs: exr * render inputs (mipmapped-textures): exr, tif (txtif) * photographic plates (scans): dpx * composite outputs: dpx, exr * on-set reference: (camera raw) NEF, CR2, etc. * painted textures: psd, tif * output proxies: jpg * All pipelines that need to be colorspace aware rely on ``Config.parseColorSpaceFromString``. * Color configurations are show specific. The ``$OCIO`` environment variable is set as part of a 'setshot' process, before other applications are launched. Artists are not allowed to work across different shows without using a fresh shell + setshot. * While the list of colorspaces can be show specific, care is taken to maintain similar naming to the greatest extent feasible. This reduces artist confusion. Even if two color spaces are not identical across shows, if they serve a similar purpose they are named the same. * Example: We label 10-bit scanned film negatives as lg10. Even if two different shows use different acquisition film stocks, and rely on different linearization curves, they are both labeled lg10. * There is no explicit guarantee that image assets copied across shows will be transferable in a color-correct manner. For example, in the above film scan example, one would not expect that the linearized versions of scans processed on different shows to match. In practice, this is not a problematic issue as the colorspaces which are convenient to copy (such as texture assets) happen to be similarly defined across show profiles. Rendering +++++++++ * Rendering and shading occurs in a scene-linear floating point space, typically named "ln". Half-float (16-bit) images are labeled lnh, full float images (32-bit) are labeled lnf. * All image inputs should be converted to ln prior to render-time. Typically, this is done when textures are published. (See below) * Renderer outputs are always floating-point. Color outputs are typically stored as lnh (16-bit half float). * Data outputs (normals, depth data, etc) are stored as ncf ("not color" data, 32-bit full float). Lossy compression is never utilized. * Render outputs are always viewed with an OCIO compatible image viewer. Thus, for typical color imagery the lnf display transform will be applied. In Nuke, this can be emulated using the `OCIODisplay` node. A standalone image viewer, ociodisplay, is also included with OpenColorIO src/example. .. _config-spipipeline-texture: Texture Painting / Matte Painting +++++++++++++++++++++++++++++++++ * Textures are painted either in a non-OCIO color-managed environment (Photoshop, etc), or a color managed one like Mari. * At texture publish time, before mipmaps are generated, all color processing is applied. Internally at SPI we use OpenImageIO's maketx that also links to OpenColorIO. This code is available on the public OIIO repository. Color processing (linearization) is applied before mipmap generation in order to assure energy preservation in the render. If the opposite processing order were used, (mipmap in the original space, color convert in the shader), the apparent intensity of texture values would change as the object approached or receded from the camera. * The original texture filenames contain the colorspace information as a substring, to signify processing intent. * Textures that contain data (bump maps, opacity maps, blend maps, etc) are labeled with the nc colorspaces according to their bitdepth. * Example: an 8-bit opacity map -> skin_opacity_nc8.tif * Painted textures that are intended to modulate diffuse color components are labelled dt (standing for "diffuse texture"). The dt8 colorspace is designed such that, when linearized, values will not extend above 1.0. At texture publishing time these are converted to lnh mipmapped tiffs/exr. Note that as linear textures have greater allocation requirements, a bit depth promotion is required in this case. I.e., even if the original texture as painted was only 8-bits, the mipmapped texture will be stored as a 16-bit float image. * Painted environment maps, which may be emissive as labeled vd (standing for 'video'). These values, when linearized, have the potential to generate specular information well above 1.0. Note that in the current vd linearization curves, the top code values may be very "sensitive". I.e., very small changes in the initial code value (such as 254->255) may actually result in very large differences in the estimated scene-linear intensity. All environment maps are store as lnh mipmapped tiffs/exr. The same bit-depth promotion as in the dt8 case is required here. Compositing +++++++++++ * The majority of compositing operations happen in scene-linear, lnf, colorspace. * All image inputs are linearized to lnf as they are loaded. Customized input nodes make this processing convenient. Rendered elements, which are stored in linear already, do not require processing. Photographic plates will typically be linearized according to their source type, (lg10 for film scans, gn10 for genesis sources, etc). * All output images are de-linearized from lnf when they are written. A customized output node makes this convenient. * On occasion log data is required for certain processing operations. (Plate resizing, pulling keys, degrain, etc). For each show, a colorspace is specified as appropriate for this operation. The artist does not have to keep track of which colorspace is appropriate to use; the OCIOLogConvert node is always intended for this purpose. (Within the OCIO profile, this is specified using the 'compositing_log' role). Further Information ******************* Specific information with regard to the public OCIO configs can be found in the :ref:`configurations` section. opencolorio-1.1.0~dfsg0.orig/docs/ChangeLog.rst0000755000175000017500000000010113223553423017572 0ustar mfvmfv.. _changelog-main: ChangeLog ========= .. include:: ChangeLog opencolorio-1.1.0~dfsg0.orig/docs/downloads.rst0000644000175000017500000000706013223553423017745 0ustar mfvmfv.. _downloads: Downloads ========= * Sample OCIO Configurations -- `.zip `__ `.tar.gz `__ * Reference Images v1.0v4 -- `.tgz `__ * Core Library v1.0.9 -- `.zip `__ `.tar.gz `__ * Core Library latest -- `.zip `__ `.tar.gz `__ Per-version updates: :ref:`changelog-main`. Build instructions: :ref:`building-from-source`. .. _contributor-license-agreements: Contributor License Agreements ****************************** Please see the `Imageworks Open Source website `__ Deprecated Downloads ******************** * Reference Images v1.0v2 `tgz `__ * Reference Images v1.0v1 `tgz `__ * Core Library v1.0.8 -- `.zip `__ `.tar.gz `__ * Core Library v1.0.7 -- `.zip `__ `.tar.gz `__ * Core Library v1.0.6 -- `.zip `__ `.tar.gz `__ * Core Library v1.0.5 -- `.zip `__ `.tar.gz `__ * Core Library v1.0.4 -- `.zip `__ `.tar.gz `__ * Core Library v1.0.3 -- `.zip `__ `.tar.gz `__ * Core Library v1.0.2 -- `.zip `__ `.tar.gz `__ * Core Library v1.0.1 -- `.zip `__ `.tar.gz `__ * Core Library v1.0.0 -- `.zip `__ `.tar.gz `__ * Color Config v0.7v4 `tgz `__ (OCIO v0.7.6+) * Core Library v0.8.7 -- `.zip `__ `.tar.gz `__ * Core Library v0.7.9 -- `.zip `__ `.tar.gz `__ * Core Library v0.6.1 -- `.zip `__ `.tar.gz `__ * Core Library v0.5.16 -- `.zip `__ `.tar.gz `__ * Core Library v0.5.8 -- `.zip `__ `.tar.gz `__ opencolorio-1.1.0~dfsg0.orig/docs/index.rst0000644000175000017500000000625313223553423017065 0ustar mfvmfvHome ==== OpenColorIO (OCIO) is a complete color management solution geared towards motion picture production with an emphasis on visual effects and computer animation. OCIO provides a straightforward and consistent user experience across all supporting applications while allowing for sophisticated back-end configuration options suitable for high-end production usage. OCIO is compatible with the Academy Color Encoding Specification (ACES) and is LUT-format agnostic, supporting many popular formats. OpenColorIO is released as version 1.0 and has been in development since 2003. OCIO represents the culmination of years of production experience earned on such films as SpiderMan 2 (2004), Surf's Up (2007), Cloudy with a Chance of Meatballs (2009), Alice in Wonderland (2010), and many more. OpenColorIO is natively supported in commercial applications like Katana, Mari, Nuke, Silhouette FX, and others. .. _mailing_lists: Mailing Lists ************* There are two mailing lists associated with OpenColorIO: `ocio-users `__\ ``@googlegroups.com`` For end users (artists, often) interested in OCIO profile design, facility color management, and workflow. `ocio-dev `__\ ``@googlegroups.com`` For developers interested OCIO APIs, code integration, compilation, etc. Quick Start *********** Most users will likely want to use the OpenColorIO that comes precompiled with their applications. See the :ref:`compatiblesoftware` for further details on each application. Note that OCIO configurations are required to do any 'real' work, and are available separately on the :ref:`downloads` section of this site. Example images are also available. For assistance customizing .ocio configurations, contact `ocio-users `__\. - Step 1: set the OCIO environment-variable to /path/to/your/profile.ocio - Step 2: Launch supported application. If you are on a platform that is not envvar friendly, most applications also provide a menu option to select a different OCIO configuration after launch. Please be sure to select a profile that matches your color workflow (VFX work typically requires a different profile than animated features). If you need assistance picking a profile, email `ocio-users `__\. Downloading and Building the Code ********************************* Source code is available on Github at http://github.com/imageworks/OpenColorIO Download a `.zip `_ or `.tar.gz `_ of the current state of the repository. Please see the :ref:`developer-guide` for more info, and contact `ocio-dev `__\ with any questions. .. toctree:: :hidden: :maxdepth: 2 self introduction configurations/index installation userguide/index developers/index CompatibleSoftware FAQ downloads ChangeLog License -------------------------------------------------------------------------------- :ref:`search` :ref:`genindex` opencolorio-1.1.0~dfsg0.orig/docs/developers/0000755000175000017500000000000013223553423017366 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/docs/developers/getting_started.rst0000644000175000017500000000776013223553423023321 0ustar mfvmfv.. _getting-started: Getting started =============== Checking Out The Codebase ************************* The master code repository is available on Github: http://github.com/imageworks/OpenColorIO For those unfamiliar with git, the wonderful part about it is that even though only a limited number people have write access to the master repository, anyone is free to create, and even check in, changes to their own local git repository. Your local changes will not automatically be pushed back to the master repository, so everyone feel free to informally play around with the codebase. Also - unlike svn - when you download the git repository you have a full copy of the project's history (including revision history, logs, etc), so the majority of code changes you will make, including commits, do not require network server access. The first step is to install git on your system. For those new to the world of git, GitHub has an excellent tutorial stepping you through the process, available at: http://help.github.com/ To check out a read-only version of the repository (no GitHub signup required):: git clone git://github.com/imageworks/OpenColorIO.git ocio For write-access, you must first register for a GitHub account (free). Then, you must create a local fork of the OpenColorIO repository by visiting http://github.com/imageworks/OpenColorIO and clicking the "Fork" icon. If you get hung up on this, further instructions on this process are available at http://help.github.com/forking/ To check out a read-write version of the repository (GitHub acct required):: git clone git@github.com:$USER/OpenColorIO.git ocio Initialized empty Git repository in /mcp/ocio/.git/ remote: Counting objects: 2220, done. remote: Compressing objects: 100% (952/952), done. remote: Total 2220 (delta 1434), reused 1851 (delta 1168) Receiving objects: 100% (2220/2220), 2.89 MiB | 2.29 MiB/s, done. Resolving deltas: 100% (1434/1434), done. Both read + read/write users should then add the Imageworks (SPI) master branch as a remote. This will allow you to more easily fetch updates as they become available:: cd ocio git remote add upstream git://github.com/imageworks/OpenColorIO.git Optionally, you may then add any additional users who have individual working forks (just as you've done). This will allow you to track, view, and potentially merge intermediate changes before they're been pushed into the main trunk. (For really bleeding edge folks). For example, to add Jeremy Selan's working fork:: git remote add js git://github.com/jeremyselan/OpenColorIO.git You should then do a git fetch, and git merge (detailed below) to download the remote branches you've just added. Reference Build Environment *************************** To aid new developers to the project and provide a baseline standard, OCIO provides a reference build environment through Docker. Docker essentially is a container that consits of both a Linux distro and the dependencies needed to run a client application. This is typically used for deploying apps and services to servers, but we are using it to provide an isolated development environment to build and test OCIO with. With this environment you are guaranteed to be able to compile OCIO and run its non-GUI command line applications. For more information on Docker, start here: https://docs.docker.com/engine/docker-overview/ In order to run the Docker environment you will have to build it from the Dockerfile provided in the repo directory:: OpenColorIO/shared/docker Run this command in order to build the Docker image (aprox. 20min):: docker build . -t ocio:centos7_gcc48 -f dockerfile_centos7_gcc48 You can then mount the current OCIO directory and compile using the Docker image with:: docker run --volume $PWD/../../:/src/ociosrc -t ocio:centos7_gcc48 bash -c 'mkdir /build && cd /build && cmake /src/ociosrc && make -j2` Merging changes *************** More detailed guide coming soon, for now, see http://help.github.com/remotes/ .. TODO: Write this opencolorio-1.1.0~dfsg0.orig/docs/developers/bindings/0000755000175000017500000000000013223553423021163 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/docs/developers/bindings/PythonAPI.rst0000644000175000017500000001006713223553423023534 0ustar mfvmfvPython API ========== Description *********** A color configuration (:py:class:`PyOpenColorIO.Config`) defines all the color spaces to be available at runtime. (:py:class:`PyOpenColorIO.Config`) is the main object for interacting with this library. It encapsulates all the information necessary to use customized :py:class:`PyOpenColorIO.ColorSpaceTransform` and :py:class:`PyOpenColorIO.DisplayTransform` operations. See the :ref:`user-guide` for more information on selecting, creating, and working with custom color configurations. For applications interested in using only one color configuration at a time (this is the vast majority of apps), their API would traditionally get the global configuration and use that, as opposed to creating a new one. This simplifies the use case for plugins and bindings, as it alleviates the need to pass around configuration handles. An example of an application where this would not be sufficient would be a multi-threaded image proxy server (daemon) that wants to handle multiple show configurations concurrently in a single process. This app would need to keep multiple configurations alive, and manage them appropriately. Roughly speaking, a novice user should select a default configuration that most closely approximates the use case (animation, visual effects, etc.), and set the :envvar:`OCIO` environment variable to point at the root of that configuration. .. note:: Initialization using environment variables is typically preferable in a multi-app ecosystem, as it allows all applications to be consistently configured. .. note:: Paths to LUTs can be relative. The search paths are defined in :py:class:`PyOpenColorIO.Config`. See :ref:`developers-usageexamples` Examples of Use +++++++++++++++ .. code-block:: python import PyOpenColorIO as OCIO # Load an existing configuration from the environment. # The resulting configuration is read-only. If $OCIO is set, it will use that. # Otherwise it will use an internal default. config = OCIO.GetCurrentConfig() # What color spaces exist? colorSpaceNames = [ cs.getName() for cs in config.getColorSpaces() ] # Given a string, can we parse a color space name from it? inputString = 'myname_linear.exr' colorSpaceName = config.parseColorSpaceFromString(inputString) if colorSpaceName: print 'Found color space', colorSpaceName else: print 'Could not get color space from string', inputString # What is the name of scene-linear in the configuration? colorSpace = config.getColorSpace(OCIO.Constants.ROLE_SCENE_LINEAR) if colorSpace: print colorSpace.getName() else: print 'The role of scene-linear is not defined in the configuration' # For examples of how to actually perform the color transform math, # see 'Python: Processor' docs. # Create a new, empty, editable configuration config = OCIO.Config() # Create a new color space, and add it cs = OCIO.ColorSpace(...) # (See ColorSpace for details) config.addColorSpace(cs) # For additional examples of config manipulation, see # https://github.com/imageworks/OpenColorIO-Configs/blob/master/nuke-default/make.py Exceptions ********** .. autoclass:: PyOpenColorIO.Exception :members: :undoc-members: .. autoclass:: PyOpenColorIO.ExceptionMissingFile :members: :undoc-members: Global ****** .. autofunction:: PyOpenColorIO.ClearAllCaches .. autofunction:: PyOpenColorIO.GetCurrentConfig .. autofunction:: PyOpenColorIO.GetLoggingLevel .. autofunction:: PyOpenColorIO.SetCurrentConfig .. autofunction:: PyOpenColorIO.SetLoggingLevel Config ****** .. autoclass:: PyOpenColorIO.Config :members: :undoc-members: ColorSpace ********** .. autoclass:: PyOpenColorIO.ColorSpace :members: :undoc-members: Look **** .. autoclass:: PyOpenColorIO.Look :members: :undoc-members: Processor ********* .. autoclass:: PyOpenColorIO.Processor :members: :undoc-members: Context ******* .. autoclass:: PyOpenColorIO.Context :members: :undoc-members: opencolorio-1.1.0~dfsg0.orig/docs/developers/bindings/PythonTypes.rst0000644000175000017500000000017213223553423024223 0ustar mfvmfvPython Types ============ Constants ********* .. automodule:: PyOpenColorIO.Constants :members: :undoc-members: opencolorio-1.1.0~dfsg0.orig/docs/developers/bindings/PythonTransforms.rst0000644000175000017500000000517013223553423025260 0ustar mfvmfv.. _python-transforms: Python Transforms ================= Transform ********* .. autoclass:: PyOpenColorIO.Transform :members: :undoc-members: AllocationTransform ******************* .. code-block:: python import PyOpenColorIO as OCIO transform = OCIO.AllocationTransform() transform.setAllocation(OCIO.Constants.ALLOCATION_LG2) .. autoclass:: PyOpenColorIO.AllocationTransform :members: :undoc-members: :inherited-members: CDLTransform ************ .. code-block:: python import PyOpenColorIO as OCIO cdl = OCIO.CDLTransform() # Set the slope, offset, power, and saturation for each channel. cdl.setSOP([, , , , , , , , ]) cdl.setSat([, , ]) cdl.getSatLumaCoefs() .. autoclass:: PyOpenColorIO.CDLTransform :members: :undoc-members: :inherited-members: ColorSpaceTransform ******************* This class is meant so that ColorSpace conversions can be reused, referencing ColorSpaces that already exist. .. note:: Careless use of this may create infinite loops, so avoid referencing the colorspace you're in. .. code-block:: python import PyOpenColorIO as OCIO transform = OCIO.ColorSpaceTransform() .. autoclass:: PyOpenColorIO.ColorSpaceTransform :members: :undoc-members: :inherited-members: DisplayTransform **************** .. code-block:: python import PyOpenColorIO as OCIO transform = OCIO.DisplayTransform() .. autoclass:: PyOpenColorIO.DisplayTransform :members: :undoc-members: :inherited-members: ExponentTransform ***************** .. code-block:: python import PyOpenColorIO as OCIO transform = OCIO.ExponentTransform() .. autoclass:: PyOpenColorIO.ExponentTransform :members: :undoc-members: :inherited-members: FileTransform ************* .. autoclass:: PyOpenColorIO.FileTransform :members: :undoc-members: :inherited-members: GroupTransform ************** .. autoclass:: PyOpenColorIO.GroupTransform :members: :undoc-members: :inherited-members: LogTransform ************ .. code-block:: python import PyOpenColorIO as OCIO :py:class:`PyOpenColorIO.LogTransform` is used to define a log transform. The direction of the transform and its numerical base can be specified. .. autoclass:: PyOpenColorIO.LogTransform :members: :undoc-members: :inherited-members: LookTransform ************* .. autoclass:: PyOpenColorIO.LookTransform :members: :undoc-members: :inherited-members: MatrixTransform *************** .. autoclass:: PyOpenColorIO.MatrixTransform :members: :undoc-members: :inherited-members: opencolorio-1.1.0~dfsg0.orig/docs/developers/documentation_guidelines.rst0000644000175000017500000000506213223553423025204 0ustar mfvmfvDocumentation guidelines ======================== OpenColorIO is documentated using reStructuredText, processed by `Sphinx `__. The documentation primarily lives in the ``docs/`` folder, within the main OpenColorIO repoistory. The rST source for the C++ API documentation is extracted from comments in the public header files in ``export/`` The Python API documentation is extracted from dummy .py files within the ``src/pyglue/DocStrings/`` folder Building the docs ***************** Just like a :ref:`regular build from source `, but specify the ``-D OCIO_BUILD_DOCS=yes`` argument to CMake. Then run the ``make doc`` target. The default HTML output will be created in ``build_dir/docs/build-html/`` Note that CMake must be run before each invokation of ``make`` to copy the edited rST files. Initial run: $ mkdir build && cd build Then after each change you wish to preview: $ cmake -D OCIO_BUILD_DOCS=yes .. && make doc Basics ****** * Try to keep the writing style consistent with surrounding docs. * Fix all warnings output by the Sphinx build process. An example of such an warning is:: checking consistency... [...]/build/docs/userguide/writing_configs.rst:: WARNING: document isn't included in any toctree * Use the following hierarchy of header decorations:: Level 1 heading =============== Level 2 heading *************** Level 3 heading +++++++++++++++ Level 4 heading --------------- * To add a new page, create a new ``.rst`` file in the appropriate location. In that directory's ``index.rst``, add the new file to the ``toctree`` directive. The new file should contain a top-level heading (decorated with `=====` underline), and an approriate label for referencing from other pages. For example, a new file ``docs/userguide/baking_luts.rst`` might start like this:: .. _userguide-bakingluts: Baking LUT's ============ In order to bake a LUT, ... Emacs rST mode ************** Emacs' includes a mode for editing rST files. It is documented on `the docutils site `__ One of the features it includes is readjusting the hierarchy of heading decorations (the underlines for different heading levels). To configure this to use OCIO's convention, put the following in your ``.emacs.d/init.el``: .. code-block:: common-lisp (setq rst-preferred-decorations '((?= simple 0) (?* simple 0) (?+ simple 0) (?- simple 0))) opencolorio-1.1.0~dfsg0.orig/docs/developers/index.rst0000644000175000017500000000114413223553423021227 0ustar mfvmfv.. _developer-guide: Developer Guide =============== Some information on contributing to OCIO: .. toctree:: :maxdepth: 1 getting_started coding_guidelines documentation_guidelines submitting_changes issues Instructions on using OCIO: .. toctree:: :maxdepth: 1 usage_examples C++ API documentation: .. toctree:: :maxdepth: 1 api/index Python API documentation: .. toctree:: :maxdepth: 1 bindings/PythonAPI bindings/PythonTransforms bindings/PythonTypes Internal Architecture: .. toctree:: :maxdepth: 1 internal_architecture opencolorio-1.1.0~dfsg0.orig/docs/developers/issues.rst0000644000175000017500000000020413223553423021427 0ustar mfvmfvIssues ====== Please visit http://github.com/imageworks/OpenColorIO/issues for an up to date listing of bugs, feature requests etc opencolorio-1.1.0~dfsg0.orig/docs/developers/submitting_changes.rst0000644000175000017500000000420213223553423023773 0ustar mfvmfv.. _submitting-changes: Submitting Changes ================== Code Review *********** Ask early, and ask often! All new contributors are highly encouraged to post development ideas, questions, or any other thoughts to the :ref:`mailing_lists` before starting to code. This greatly improves the process and quality of the resulting library. Code reviews (particularly for non-trivial changes) are typically far simpler if the reviewers are aware of a development task beforehand. (And, who knows? Maybe they will have implementation suggestions as well!) GitHub Basics ************* This will outline the general mechanics of working with git and GitHub to successfully contribute to the project. If any of the terms used are unfamiliar to you please do a quick search and then ask any of the contributors for assistance. * Fork the Imageworks OpenColorIO repository * Activate Travis-CI and Appveyor for your fork * Clone your fork to your local workspace:: git clone https://github.com/$USER/OpenColorIO.git * cd into the cloned directory * Connect your cloned repo to the original upstream repository as a remote:: git remote add upstream https://github.com/imageworks/OpenColorIO.git * You should now have two remotes:: git remote -v origin https://github.com/$USER/OpenColorIO (fetch) origin https://github.com/$USER/OpenColorIO (fetch) upstream https://github.com/imageworks/OpenColorIO (fetch) upstream https://github.com/imageworks/OpenColorIO (push) * Pull the latest changes from upstream:: git checkout master git pull upstream master * Create a branch for your contribution:: git checkout -b myFeature * Check if it successfully compiles and passes all unit tests * Commit your changes:: git add . git commit -m 'Implement my feature' * Push your changes back to origin (your fork):: git push origin myFeature * Ensure that all CI tests complete on Travis-CI and Appveyor * Visit your fork in a web browser on github.com * When ready click the "New pull request" button, make sure it can merge, and add appropriate comments and notes * Wait for code review and comments from the community opencolorio-1.1.0~dfsg0.orig/docs/developers/coding_guidelines.rst0000644000175000017500000000744213223553423023602 0ustar mfvmfvCoding guidelines ================= There are only two important rules: 1. When making changes, conform to the style and conventions of the surrounding code. 2. Strive for clarity, even if that means occasionally breaking the guidelines. Use your head and ask for advice if your common sense seems to disagree with the conventions. File Conventions **************** C++ implementation should be named ``*.cpp``. Headers should be named ``*.h``. All source files should begin with the copyright and license, which can be cut and pasted from other source files). For NEW source files, please do change the copyright year to the present. However DO NOT edit existing files just to update the copyright year, it just creates pointless deltas and offers no increased protection Line Length *********** Each line of text in your code should be at most 80 characters long. Generally the only exceptions are for comments with example commands or URLs - to make cut and paste easier. The other exception is for those rare cases where letting a line be longer (and wrapping on an 80-character window) is actually a better and clearer alternative than trying to split it into two lines. Sometimes this happens, but it's rare. DO NOT alter somebody else's code to re-wrap lines (or change whitespace) just because you found something that violates the rules. Let the group/author/leader know, and resist the temptation to change it yourself. Formatting ********** * Indent 4 spaces at a time, and use actual spaces, not tabs. This is particularly critical on python code. The only exception currently allowed in within Makefiles, where tab characters are sometimes required. * Opening brace on the line following the condition or loop. * The contents of namespaces are not indented. * Function names should be on the same line as their return values. * Function calls should NOT have a space between the function name and the opening parenthesis. A single space should be added after each required comma. Here is a short code fragement that shows these concepts in action: .. code-block:: c++ namespace { int MungeMyNumbers(int a, int b) { int x = a + b; if (a == 0 || b==0) { x += 1; x += 2; } else { for (int i=0; i<16; ++i) { x += a * i; } } return x; } } // namespace Misc. Rules *********** * Avoid macros when possible. * Anonymous namespaces are preferred when sensible. * Variable names should be camelCase, as well as longAndExplicit. * Avoid long function implementations. Break up work into small, manageable chunks. * Use "TODO:" comments for code that is temporary, a short-term solution, or good-enough but not perfect. This is vastly preferred to leaving subtle corner cases undocumented. * Always initialize variables on construction. * Do not leave dead code paths around. (This is what revision history is for) * Includes should always be ordered as follows: C library, C++ library, other libraries' .h, OCIO public headers, OCIO private headers. Includes within a category should be alphabetized. * The C++ "using" directive is not allowed. * Static / global variables should be avoided at all costs. * Use const whenever it makes sense to do so. * The use of Boost is not allowed, except for unit_test_framework and shared_ptr. * Default function arguments are not allowed. Bottom Line *********** When in doubt, look elsewhere in the code base for examples of similar structures and try to format your code in the same manner. Portions of this document have been blatantly lifted from `OpenImageIO `__, and `Google `__. opencolorio-1.1.0~dfsg0.orig/docs/developers/usage_examples.rst0000644000175000017500000003221413223553423023124 0ustar mfvmfv.. _developers-usageexamples: Usage Examples ============== Some examples of using the OCIO API, via both C++ and the Python bindings. For further examples, see the ``src/apps/`` directory in the git repository .. _usage_applybasic: Applying a basic ColorSpace transform, using the CPU **************************************************** This describes what code is used to convert from a specified source :cpp:class:`ColorSpace` to a specified destination :cpp:class:`ColorSpace`. If you are using the OCIO Nuke plugins, the OCIOColorSpace node performs these steps internally. #. **Get the Config.** This represents the entirety of the current color "universe". It can either be initialized by your app at startup or created explicitly. In common usage, you can just query :cpp:func:`GetCurrentConfig`, which will auto initialize on first use using the :envvar:`OCIO` environment variable. #. **Get Processor from the Config.** A processor corresponds to a 'baked' color transformation. You specify two arguments when querying a processor: the :ref:`colorspace_section` you are coming from, and the :ref:`colorspace_section` you are going to. :ref:`cfgcolorspaces_section` ColorSpaces can be either explicitly named strings (defined by the current configuration) or can be :ref:`cfgroles_section` (essentially :ref:`colorspace_section` aliases) which are consistent across configurations. Constructing a :cpp:class:`Processor` object is likely a blocking operation (thread-wise) so care should be taken to do this as infrequently as is sensible. Once per render 'setup' would be appropriate, once per scanline would be inappropriate. #. **Convert your image, using the Processor.** Once you have the processor, you can apply the color transformation using the "apply" function. In :ref:`usage_applybasic_cpp`, you apply the processing in-place, by first wrapping your image in an :cpp:class:`ImageDesc` class. This approach is intended to be used in high performance applications, and can be used on multiple threads (per scanline, per tile, etc). In :ref:`usage_applybasic_python` you call "applyRGB" / "applyRGBA" on your sequence of pixels. Note that in both languages, it is far more efficient to call "apply" on batches of pixels at a time. .. _usage_applybasic_cpp: C++ +++ .. code-block:: cpp #include namespace OCIO = OCIO_NAMESPACE; try { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); ConstProcessorRcPtr processor = config->getProcessor(OCIO::ROLE_COMPOSITING_LOG, OCIO::ROLE_SCENE_LINEAR); OCIO::PackedImageDesc img(imageData, w, h, 4); processor->apply(img); } catch(OCIO::Exception & exception) { std::cerr << "OpenColorIO Error: " << exception.what() << std::endl; } .. _usage_applybasic_python: Python ++++++ .. code-block:: py import PyOpenColorIO as OCIO try: config = OCIO.GetCurrentConfig() processor = config.getProcessor(OCIO.Constants.ROLE_COMPOSITING_LOG, OCIO.Constants.ROLE_SCENE_LINEAR) # Apply the color transform to the existing RGBA pixel data img = processor.applyRGBA(img) except Exception, e: print "OpenColorIO Error",e .. _usage_displayimage: Displaying an image, using the CPU (simple ColorSpace conversion) ***************************************************************** Converting an image for display is similar to a normal color space conversion. The only difference is that one has to first determine the name of the display (destination) ColorSpace by querying the config with the device name and transform name. #. **Get the Config.** See :ref:`usage_applybasic` for details. #. **Lookup the display ColorSpace.** The display :cpp:class:`ColorSpace` is queried from the configuration using :cpp:func:`Config::getDisplayColorSpaceName`. If the user has specified value for the ``device`` or the ``displayTransformName``, use them. If these values are unknown default values can be queried (as shown below). #. **Get the processor from the Config.** See :ref:`usage_applybasic` for details. #. **Convert your image, using the processor.** See :ref:`usage_applybasic` for details. C++ +++ .. code-block:: cpp #include namespace OCIO = OCIO_NAMESPACE; OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); // If the user hasn't picked a display, use the defaults... const char * device = config->getDefaultDisplayDeviceName(); const char * transformName = config->getDefaultDisplayTransformName(device); const char * displayColorSpace = config->getDisplayColorSpaceName(device, transformName); ConstProcessorRcPtr processor = config->getProcessor(OCIO::ROLE_SCENE_LINEAR, displayColorSpace); OCIO::PackedImageDesc img(imageData, w, h, 4); processor->apply(img); Python ++++++ .. code-block:: python import PyOpenColorIO as OCIO config = OCIO.GetCurrentConfig() device = config.getDefaultDisplayDeviceName() transformName = config.getDefaultDisplayTransformName(device) displayColorSpace = config.getDisplayColorSpaceName(device, transformName) processor = config.getProcessor(OCIO.Constants.ROLE_SCENE_LINEAR, displayColorSpace) processor.applyRGB(imageData) Displaying an image, using the CPU (Full Display Pipeline) ********************************************************** This alternative version allows for a more complex displayTransform, allowing for all of the controls typically added to real-world viewer interfaces. For example, options are allowed to control which channels (red, green, blue, alpha, luma) are visible, as well as allowing for optional color corrections (such as an exposure offset in scene linear). If you are using the OCIO Nuke plugins, the OCIODisplay node performs these steps internally. #. **Get the Config.** See :ref:`usage_applybasic` for details. #. **Lookup the display ColorSpace.** See :ref:`usage_displayimage` for details #. **Create a new DisplayTransform.** This transform will embody the full 'display' pipeline you wish to control. The user is required to call :cpp:func:`DisplayTransform::setInputColorSpaceName` to set the input ColorSpace, as well as :cpp:func:`DisplayTransform::setDisplayColorSpaceName` (with the results of :cpp:func:`Config::getDisplayColorSpaceName`). #. **Set any additional DisplayTransform options.** If the user wants to specify a channel swizzle, a scene-linear exposure offset, an artistic look, this is the place to add it. See below for an example. Note that although we provide recommendations for display, any transforms are allowed to be added into any of the slots. So if for your app you want to add 3 transforms into a particular slot (chained together), you are free to wrap them in a :cpp:class:`GroupTransform` and set it accordingly! #. **Get the processor from the Config.** The processor is then queried from the config passing the new :cpp:class:`DisplayTransform` as the argument. Once the processor has been returned, the original :cpp:class:`DisplayTransform` is no longer necessary to hold onto. (Though if you'd like to for re-use, there is no problem doing so). #. **Convert your image, using the processor.** See :ref:`usage_applybasic` for details. C++ +++ .. code-block:: cpp // Step 1: Get the config OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); // Step 2: Lookup the display ColorSpace const char * device = config->getDefaultDisplayDeviceName(); const char * transformName = config->getDefaultDisplayTransformName(device); const char * displayColorSpace = config->getDisplayColorSpaceName(device, transformName); // Step 3: Create a DisplayTransform, and set the input and display ColorSpaces // (This example assumes the input is scene linear. Adapt as needed.) OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create(); transform->setInputColorSpaceName( OCIO::ROLE_SCENE_LINEAR ); transform->setDisplayColorSpaceName( displayColorSpace ); // Step 4: Add custom transforms for a 'canonical' Display Pipeline // Add an fstop exposure control (in SCENE_LINEAR) float gain = powf(2.0f, exposure_in_stops); const float slope3f[] = { gain, gain, gain }; OCIO::CDLTransformRcPtr cc = OCIO::CDLTransform::Create(); cc->setSlope(slope3f); transform->setLinearCC(cc); // Add a Channel view 'swizzle' // 'channelHot' controls which channels are viewed. int channelHot[4] = { 1, 1, 1, 1 }; // show rgb //int channelHot[4] = { 1, 0, 0, 0 }; // show red //int channelHot[4] = { 0, 0, 0, 1 }; // show alpha //int channelHot[4] = { 1, 1, 1, 0 }; // show luma float lumacoef[3]; config.getDefaultLumaCoefs(lumacoef); float m44[16]; float offset[4]; OCIO::MatrixTransform::View(m44, offset, channelHot, lumacoef); OCIO::MatrixTransformRcPtr swizzle = OCIO::MatrixTransform::Create(); swizzle->setValue(m44, offset); transform->setChannelView(swizzle); // And then process the image normally. OCIO::ConstProcessorRcPtr processor = config->getProcessor(transform); OCIO::PackedImageDesc img(imageData, w, h, 4); processor->apply(img); Python ++++++ .. code-block:: python import PyOpenColorIO as OCIO # Step 1: Get the config config = OCIO.GetCurrentConfig() # Step 2: Lookup the display ColorSpace device = config.getDefaultDisplayDeviceName() transformName = config.getDefaultDisplayTransformName(device) displayColorSpace = config.getDisplayColorSpaceName(device, transformName) # Step 3: Create a DisplayTransform, and set the input and display ColorSpaces # (This example assumes the input is scene linear. Adapt as needed.) transform = OCIO.DisplayTransform() transform.setInputColorSpaceName(OCIO.Constants.ROLE_SCENE_LINEAR) transform.setDisplayColorSpaceName(displayColorSpace) # Step 4: Add custom transforms for a 'canonical' Display Pipeline # Add an fstop exposure control (in SCENE_LINEAR) gain = 2**exposure slope3f = (gain, gain, gain) cc = OCIO.CDLTransform() cc.setSlope(slope3f) transform.setLinearCC(cc) # Add a Channel view 'swizzle' channelHot = (1, 1, 1, 1) # show rgb # channelHot = (1, 0, 0, 0) # show red # channelHot = (0, 0, 0, 1) # show alpha # channelHot = (1, 1, 1, 0) # show luma lumacoef = config.getDefaultLumaCoefs() m44, offset = OCIO.MatrixTransform.View(channelHot, lumacoef) swizzle = OCIO.MatrixTransform() swizzle.setValue(m44, offset) transform.setChannelView(swizzle) # And then process the image normally. processor = config.getProcessor(transform) print processor.applyRGB(imageData) Displaying an image, using the GPU ********************************** Applying OpenColorIO's color processing using GPU processing is straightforward, provided you have the capability to upload custom shader code and a custom 3D Lookup Table (3DLUT). #. **Get the Processor.** This portion of the pipeline is identical to the CPU approach. Just get the processor as you normally would have, see above for details. #. **Create a GpuShaderDesc.** #. **Query the GPU Shader Text + 3D LUT.** #. **Configure the GPU State.** #. **Draw your image.** C++ +++ This example is available as a working app in the OCIO source: src/apps/ociodisplay. .. code-block:: cpp // Step 0: Get the processor using any of the pipelines mentioned above. OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char * device = config->getDefaultDisplayDeviceName(); const char * transformName = config->getDefaultDisplayTransformName(device); const char * displayColorSpace = config->getDisplayColorSpaceName(device, transformName); ConstProcessorRcPtr processor = config->getProcessor(OCIO::ROLE_SCENE_LINEAR, displayColorSpace); // Step 1: Create a GPU Shader Description GpuShaderDesc shaderDesc; shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0); shaderDesc.setFunctionName("OCIODisplay"); const int LUT3D_EDGE_SIZE = 32; shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE); // Step 2: Compute and the 3D LUT // Optional Optimization: // Only do this the 3D LUT's contents // are different from the last drawn frame. // Use getGpuLut3DCacheID to compute the cacheID. // cheaply. // // std::string lut3dCacheID = processor->getGpuLut3DCacheID(shaderDesc); int num3Dentries = 3*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE; std::vector g_lut3d; g_lut3d.resize(num3Dentries); processor->getGpuLut3D(&g_lut3d[0], shaderDesc); // Load the data into an OpenGL 3D Texture glGenTextures(1, &g_lut3d_textureID); glBindTexture(GL_TEXTURE_3D, g_lut3d_textureID); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, 0, GL_RGB,GL_FLOAT, &g_lut3d[0]); // Step 3: Query opencolorio-1.1.0~dfsg0.orig/docs/developers/api/0000755000175000017500000000000013223553423020137 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/docs/developers/api/index.rst0000644000175000017500000000013613223553423022000 0ustar mfvmfv.. toctree:: :maxdepth: 1 OpenColorIO OpenColorTransforms OpenColorTypes opencolorio-1.1.0~dfsg0.orig/docs/developers/internal_architecture.rst0000644000175000017500000002262313223553423024503 0ustar mfvmfvInternal Architecture Overview ============================== External API ************ Configs +++++++ At the highest level, we have OCIO::Configs. This represents the entirety of the current color "universe". Configs are serialized as .ocio files, read at runtime, and are often used in a 'read-only' context. Config are loaded at runtime to allow for customized color handling in a show- dependent manner. Example Configs: * ACES (Academy's standard color workflow) * spi-vfx (Used on some Imageworks VFX shows such as spiderman, etc). * and others ColorSpaces +++++++++++ The meat of an OCIO::Config is a list of named ColorSpaces. ColorSpace often correspond to input image states, output image states, or image states used for internal processing. Example ColorSpaces (from ACES configuration): * aces (HDR, scene-linear) * adx10 (log-like density encoding space) * slogf35 (sony F35 slog camera encoding) * rrt_srgb (baked in display transform, suitable for srgb display) * rrt_p3dci (baked in display transform, suitable for dcip3 display) Transforms ++++++++++ ColorSpaces contain an ordered list of transforms, which define the conversion to and from the Config's "reference" space. Transforms are the atomic units available to the designer in order to specify a color conversion. Examples of OCIO::Transforms are: * File-based transforms (1d lut, 3d lut, mtx... anything, really.) * Math functions (gamma, log, mtx) * The 'meta' GroupTransform, which contains itself an ordered lists of transforms * The 'meta' LookTransform, which contains an ordered lists of transforms For example, the adx10 ColorSpace (in one particular ACES configuration) -Transform FROM adx, to our reference ColorSpace: #. Apply FileTransform adx_adx10_to_cdd.spimtx #. Apply FileTransform adx_cdd_to_cid.spimtx #. Apply FileTransform adx_cid_to_rle.spi1d #. Apply LogTransform base 10 (inverse) #. Apply FileTransform adx_exp_to_aces.spimtx If we have an image in the reference ColorSpace (unnamed), we can convert TO adx by applying each in the inverse direction: #. Apply FileTransform adx_exp_to_aces.spimtx (inverse) #. Apply LogTransform base 10 (forward) #. Apply FileTransform adx_cid_to_rle.spi1d (inverse) #. Apply FileTransform adx_cdd_to_cid.spimtx (inverse) #. Apply FileTransform adx_adx10_to_cdd.spimtx (inverse) Note that this isn't possible in all cases (what if a lut or matrix is not invertible?), but conceptually it's a simple way to think about the design. Summary +++++++ Configs and ColorSpaces are just a bookkeeping device used to get and ordered lists of Transforms corresponding to image color transformation. Transforms are visible to the person AUTHORING the OCIO config, but are NOT visible to the client applications. Client apps need only concern themselves with Configs and Processors. OCIO::Processors ++++++++++++++++ A processor corresponds to a 'baked' color transformation. You specify two arguments when querying a processor: the :ref:`colorspace_section` you are coming from, and the :ref:`colorspace_section` you are going to. Once you have the processor, you can apply the color transformation using the "apply" function. For the CPU veseion, first wrap your image in an ImageDesc class, and then call apply to process in place. Example: .. code-block:: cpp #include namespace OCIO = OCIO_NAMESPACE; try { // Get the global OpenColorIO config // This will auto-initialize (using $OCIO) on first use OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); // Get the processor corresponding to this transform. // These strings, in this example, are specific to the above // example. ColorSpace names should NEVER be hard-coded into client // software, but should be dynamically queried at runtime from the library OCIO::ConstProcessorRcPtr processor = config->getProcessor("adx10", "aces"); // Wrap the image in a light-weight ImageDescription OCIO::PackedImageDesc img(imageData, w, h, 4); // Apply the color transformation (in place) processor->apply(img); } catch(OCIO::Exception & exception) { std::cerr << "OpenColorIO Error: " << exception.what() << std::endl; } The GPU code path is similar. You get the processor from the config, and then query the shaderText and the lut3d. The client loads these to the GPU themselves, and then makes the appropriate calls to the newly defined function. See `src/apps/ociodisplay` for an example. Internal API ************ The Op Abstraction ++++++++++++++++++ It is a useful abstraction, both for code-reuse and optimization, to not relying on the transforms to do pixel processing themselves. Consider that the FileTransform represents a wide-range of image processing operations (basically all of em), many of which are really complex. For example, the houdini lut format in a single file may contain a log convert, a 1d lut, and then a 3d lut; all of which need to be applied in a row! If we don't want the FileTransform to know how to process all possible pixel operations, it's much simpler to make light-weight processing operations, which the transforms can create to do the dirty work as needed. All image processing operations (ops) are a class that present the same interface, and it's rather simple: .. code-block:: cpp virtual void apply(float* rgbaBuffer, long numPixels) Basically, given a packed float array with the specified number of pixels, process em. Examples of ops include Lut1DOp, Lut3DOp, MtxOffsetOp, LogOp, etc. Thus, the job of a transform becomes much simpler and they're only responsible for converting themselves to a list of ops. A simple FileTransform that only has a single 1D lut internally may just generate a single Lut1DOp, but a FileTransform that references a more complex format (such as the houdini lut case referenced above) may generate a few ops: .. code-block:: cpp void FileFormatHDL::BuildFileOps(OpRcPtrVec & ops, const Config& /*config*/, const ConstContextRcPtr & /*context*/, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { // Code omitted which loads the lut file into the file cache... CreateLut1DOp(ops, cachedFile->lut1D, fileTransform.getInterpolation(), dir); CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), dir); See (``src/core/*Ops.h``) for the available ops. Note that while compositors often have complex, branching trees of image processing operations, we just have a linear list of ops, lending itself very well to optimization. Before the ops are run, they are optimized. (Collapsed with appropriate neighbors, etc). An Example ++++++++++ Let us consider the internal steps when getProcessor() is called to convert from ColorSpace 'adx10' to ColorSpace 'aces': * The first step is to turn this ColorSpace conversion into an ordered list of transforms. We do this by creating a single of the conversions from 'adx10' to reference, and then adding the transforms required to go from reference to 'aces'. * The Transform list is then converted into a list of ops. It is during this stage luts, are loaded, etc. CPU CODE PATH +++++++++++++ The master list of ops is then optimized, and stored internally in the processor. .. code-block:: cpp FinalizeOpVec(m_cpuOps); During Processor::apply(...), a subunit of pixels in the image are formatted into a sequential rgba block. (Block size is optimized for computational (SSE) simplicity and performance, and is typically similar in size to an image scanline) .. code-block:: cpp float * rgbaBuffer = 0; long numPixels = 0; while(true) { scanlineHelper.prepRGBAScanline(&rgbaBuffer, &numPixels); ... Then for each op, op->apply is called in-place. .. code-block:: cpp for(OpRcPtrVec::size_type i=0, size = m_cpuOps.size(); iapply(rgbaBuffer, numPixels); } After all ops have been applied, the results are copied back to the source .. code-block:: cpp scanlineHelper.finishRGBAScanline(); GPU CODE PATH +++++++++++++ #. The master list of ops is partitioned into 3 ordered lists: - As many ops as possible from the BEGINNING of the op-list that can be done analytically in shader text. (called gpu-preops) - As many ops as possible from the END of the op-list that can be done analytically in shader text. (called gpu-postops) - The left-over ops in the middle that cannot support shader text, and thus will be baked into a 3dlut. (called gpu-lattice) #. Between the first an the second lists (gpu-preops, and gpu-latticeops), we analyze the op-stream metadata and determine the appropriate allocation to use. (to minimize clamping, quantization, etc). This is accounted for here by interserting a forward allocation to the end of the pre-ops, and the inverse allocation to the start of the lattice ops. See https://github.com/imageworks/OpenColorIO/blob/master/src/core/NoOps.cpp#L183 #. The 3 lists of ops are then optimized individually, and stored on the processor. The Lut3d is computed by applying the gpu-lattice ops, on the CPU, to a lut3d image. The shader text is computed by calculating the shader for the gpu-preops, adding a sampling function of the 3d lut, and then calculating the shader for the gpu post ops. opencolorio-1.1.0~dfsg0.orig/docs/installation.rst0000644000175000017500000002647613223553423020470 0ustar mfvmfv.. _installation: Installation ============ The easy way ************ While prebuilt binaries are not yet available for all platforms, OCIO is available via several platform's package managers. Fedora and RHEL +++++++++++++++ In Fedora Core 15 and above, the following command will install OpenColorIO:: yum install OpenColorIO Providing you are using the `Fedora EPEL repository `__ (see the `FAQ for instructions `__), this same command will work for RedHat Enterprise Linux 6 and higher (including RHEL derivatives such as CentOS 6 and Scientific Linux 6) OS X using Homebrew +++++++++++++++++++ You can use the Homebrew package manager to install OpenColorIO on OS X. First install Homebrew as per the instructions on the `Homebrew homepage `__ (or see the `Homebrew wiki `__ for more detailed instructions) Then simply run the following command to install:: brew install opencolorio To build with the Python library use this command:: brew install opencolorio --with-python .. _building-from-source: Building from source ******************** .. _osx-and-linux OS X and Linux ++++++++++++++ While there is a huge range of possible setups, the following steps should work on OS X and most Linux distros. The basic requirements are: - cmake >= 2.8 - (optional) Python 2.x (for the Python bindings) - (optional) Nuke 6.x or newer (for the Nuke nodes) - (optional) OpenImageIO (for apps including ocioconvert) - (optional) Truelight SDK (for TruelightTransform) To keep things simple, this guide will use the following example paths - these will almost definitely be different for you: - source code: ``/source/ocio`` - the temporary build location: ``/tmp/ociobuild`` - the final install directory: ``/software/ocio`` First make the build directory and cd to it:: $ mkdir /tmp/ociobuild $ cd /tmp/ociobuild Next step is to run cmake, which looks for things such as the compiler's required arguments, optional requirements like Python, Nuke, OpenImageIO etc As we want to install OCIO to a custom location (instead of the default ``/usr/local``), we will run cmake with ``CMAKE_INSTALL_PREFIX`` Still in ``/tmp/ociobuild``, run:: $ cmake -D CMAKE_INSTALL_PREFIX=/software/ocio /source/ocio The last argument is the location of the OCIO source code (containing the main CMakeLists.txt file). You should see something along the lines of:: -- Configuring done -- Generating done -- Build files have been written to: /tmp/ociobuild Next, build everything (with the ``-j`` flag to build using 8 threads):: $ make -j8 This should complete in a few minutes. Finally, install the files into the specified location:: $ make install If nothing went wrong, ``/software/ocio`` should look something like this:: $ cd /software/ocio $ ls bin/ include/ lib/ $ ls bin/ ocio2icc ociobakelut ociocheck $ ls include/ OpenColorIO/ PyOpenColorIO/ pkgconfig/ $ ls lib/ libOpenColorIO.a libOpenColorIO.dylib .. _windows-build Windows Build +++++++++++++ While build environments may vary between user, here is an example batch file for compiling on Windows as provided by `@hodoulp `__:: @echo off REM Grab the repo name, default is ocio_rw set repo_name=ocio_rw if not %1.==. set repo_name=%1 set CYGWIN=nodosfilewarning set CMAKE_PATH=D:\OpenSource\cmake-3.9.3 set PYTHON_PATH=C:\Python27 set BOOST_ROOT=D:\SolidAngle\boost_1_55_0 set PATH=D:\Tools\cygwin64\bin;%CMAKE_PATH%\bin;%PYTHON_PATH%;%PATH% call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64 set OCIO_PATH=D:\OpenSource\%repo_name% @doskey ne="D:\Tools\Notepad++\notepad++.exe" -nosession -multiInst $* @doskey sub="D:\Tools\Sublime Text 3\subl.exe" --project %OCIO_PATH%_project.sublime-project REM Decompose the directory change to avoid problems... D: IF NOT EXIST %OCIO_PATH% ( echo %OCIO_PATH% does not exist exit /b ) cd %OCIO_PATH% set CMAKE_BUILD_TYPE=Release echo ******* echo ********************************************* echo ******* Building %OCIO_PATH% echo ** echo ** set are_you_sure = Y set /P are_you_sure=Build in %CMAKE_BUILD_TYPE% ([Y]/N)? if not %are_you_sure%==Y set CMAKE_BUILD_TYPE=Debug set BUILD_PATH=_build_rls if not %CMAKE_BUILD_TYPE%==Release set BUILD_PATH=_build_dbg IF NOT EXIST %BUILD_PATH% ( mkdir %BUILD_PATH% ) cd %BUILD_PATH% echo ** echo ** cmake -G "NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE% ^ -DCMAKE_INSTALL_PREFIX=%OCIO_PATH%\_install ^ -DOCIO_BUILD_TESTS=ON ^ %OCIO_PATH% set PATH=%OCIO_PATH%\%BUILD_PATH%\src\core;%PATH% REM Find the current branch set GITBRANCH= for /f %%I in ('git.exe rev-parse --abbrev-ref HEAD 2^> NUL') do set GITBRANCH=%%I if not "%GITBRANCH%" == "" prompt $C%GITBRANCH%$F $P$G echo ******* echo ********************************************* echo boost = %BOOST_ROOT% echo cmake = %CMAKE_PATH% echo ******* if not "%GITBRANCH%" == "" echo branch = %GITBRANCH% echo ******* echo Mode = %CMAKE_BUILD_TYPE% echo path = %OCIO_PATH%\%BUILD_PATH% echo compile = nmake all echo test = nmake test echo ********************************************* echo ******* Also look to the Appveyor config script at the root of repository for an example build sequence. .. _enabling-optional-components: Enabling optional components ++++++++++++++++++++++++++++ The OpenColorIO library is probably not all you want - the Python libraries bindings, the Nuke nodes and several applications are only built if their dependencies are found. In the case of the Python bindings, the dependencies are the Python headers for the version you wish to use. These may be picked up by default - if so, when you run cmake you would see:: -- Python 2.6 okay, will build the Python bindings against .../include/python2.6 If not, you can point cmake to correct Python executable using the ``-D PYTHON=...`` cmake flag:: $ cmake -D PYTHON=/my/custom/python2.6 /source/ocio Same process with Nuke (although it less likely to be picked up automatically). Point cmake to your Nuke install directory by adding ``-D NUKE_INSTALL_PATH``:: $ cmake -D PYTHON=/my/custom/python2.6 -D NUKE_INSTALL_PATH=/Applications/Nuke6.2v1/Nuke6.2v1.app/Contents/MacOS/ /source/ocio The ``NUKE_INSTALL_PATH`` directory should contain the Nuke executable (e.g Nuke6.2v1), and a ``include/`` directory containing ``DDImage/`` and others. If set correctly, you will see something similar to:: -- Found Nuke: /Applications/Nuke6.2v1/Nuke6.2v1.app/Contents/MacOS/include -- Nuke_API_VERSION: --6.2-- The Nuke plugins are installed into ``lib/nuke$MAJOR.$MINOR/``, e.g ``lib/nuke6.2/OCIODisdplay.so`` .. note:: If you are using the Nuke plugins, you should compile the Python bindings for the same version of Python that Nuke uses internally. For Nuke 6.0 and 6.1 this is Python 2.5, and for 6.2 it is Python 2.6 The applications included with OCIO have various dependencies - to determine these, look at the CMake output when first run:: -- Not building ocioconvert. Requirement(s) found: OIIO:FALSE .. _quick-env-config: Quick environment configuration ******************************* The quickest way to set the required :ref:`environment-setup` is to source the ``share/ocio/setup_ocio.sh`` script installed with OCIO. For a simple single-user setup, add the following to ``~/.bashrc`` (assuming you are using bash, and the example install directory of ``/software/ocio``):: source /software/ocio/share/ocio/setup_ocio.sh The only environment variable you must configure manually is :envvar:`OCIO`, which points to the configuration file you wish to use. For prebuilt config files, see the :ref:`downloads` section To do this, you would add a line to ``~/.bashrc`` (or a per-project configuration script etc), for example:: export OCIO="/path/to/my/config.ocio" .. _nuke-configuration: Nuke Configuration ****************** If you specified the ``NUKE_INSTALL_PATH`` option when running cmake, you should have a ``/software/ocio/lib/nuke6.2`` directory containing various files. If you have followed :ref:`quick-env-config`, the plugins should be functional. However, one common additional configuration step is to register an OCIODisplay node for each display device/view specified in the config. To do this, in a menu.py on :envvar:`NUKE_PATH` (e.g ``~/.nuke/menu.py`` for a single user setup), add the following: .. code-block:: python import ocionuke.viewer ocionuke.viewer.populate_viewer(also_remove = "default") The ``also_remove`` argument can be set to either "default" to remove the default sRGB/rec709 options, "all" to remove everything, or "none" to leave existing viewer processes untouched. Alternatively, if your workflow has different requirements, you can copy the function and modify it as required, or use it as reference to write your own, better viewer setup function! .. literalinclude:: viewer.py :language: python .. _environment-setup: Environment variables ********************* .. envvar:: OCIO This variable needs to point to the global OCIO config file, e.g ``config.ocio`` .. envvar:: OCIO_LOGGING_LEVEL Configures OCIO's internal logging level. Valid values are ``none``, ``warning``, ``info``, or ``debug`` (or their respective numeric values ``0``, ``1``, ``2``, or ``3`` can be used) Logging output is sent to STDERR output. .. envvar:: OCIO_ACTIVE_DISPLAYS Overrides the :ref:`active_displays` configuration value. Colon-separated list of displays, e.g ``sRGB:P3`` .. envvar:: OCIO_ACTIVE_VIEWS Overrides the :ref:`active_views` configuration item. Colon-separated list of view names, e.g ``internal:client:DI`` .. envvar:: DYLD_LIBRARY_PATH The ``lib/`` folder (containing ``libOpenColorIO.dylib``) must be on the ``DYLD_LIBRARY_PATH`` search path, or you will get an error similar to:: dlopen(.../OCIOColorSpace.so, 2): Library not loaded: libOpenColorIO.dylib Referenced from: .../OCIOColorSpace.so Reason: image not found This applies to anything that links against OCIO, including the Nuke nodes, and the ``PyOpenColorIO`` Python bindings. .. envvar:: LD_LIBRARY_PATH Equivalent to the ``DYLD_LIBRARY_PATH`` on Linux .. envvar:: PYTHONPATH Python's module search path. If you are using the PyOpenColorIO module, you must add ``lib/python2.x`` to this search path (e.g ``python/2.5``), or importing the module will fail:: >>> import PyOpenColorIO Traceback (most recent call last): File "", line 1, in ImportError: No module named PyOpenColorIO Note that :envvar:`DYLD_LIBRARY_PATH` or :envvar:`LD_LIBRARY_PATH` must be set correctly for the module to work. .. envvar:: NUKE_PATH Nuke's customization search path, where it will look for plugins, gizmos, init.py and menu.py scripts and other customizations. This should point to both ``lib/nuke6.2/`` (or whatever version the plugins are built against), and ``share/nuke/`` opencolorio-1.1.0~dfsg0.orig/docs/conf.py.in0000644000175000017500000000651513223553423017131 0ustar mfvmfv# -*- coding: utf-8 -*- # See: # http://sphinx.pocoo.org/config.html import sys, os # -- Add PyOpenColorIO to sys.path sys.path.insert(0, "@CMAKE_BINARY_DIR@/src/pyglue") # -- General configuration ----------------------------------------------------- extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.ifconfig'] templates_path = ['templates'] source_suffix = '.rst' master_doc = 'index' project = u'OpenColorIO' copyright = u'2010, Sony Pictures Imageworks' # The short X.Y version. version = '@OCIO_VERSION_MAJOR@.@OCIO_VERSION_MINOR@' # The full version, including alpha/beta/rc tags. release = '@OCIO_VERSION@' exclude_patterns = ['build', '*-prefix'] #add_function_parentheses = True #add_module_names = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' #modindex_common_prefix = [] rst_prolog = """ .. |OCIO| replace:: *OCIO* .. |OpenColorIO| replace:: **OpenColorIO** .. _Sony Imageworks: http://www.imageworks.com/ .. |Sony Imageworks| replace:: `Sony Imageworks`_ .. _Jeremy Selan: mailto:jeremy.selan@gmail.com .. |Jeremy Selan| replace:: `Jeremy Selan`_ .. _ocio-users: http://groups.google.com/group/ocio-users .. _ocio-dev: http://groups.google.com/group/ocio-dev """ # -- Options for HTML output --------------------------------------------------- html_theme_path = ['.'] html_theme = 'ociotheme' #html_theme_options = {} #html_title = None #html_short_title = None #html_logo = None #html_favicon = None html_static_path = [] #html_last_updated_fmt = '%b %d, %Y' #html_use_smartypants = True #html_sidebars = {} #html_additional_pages = {} html_domain_indices = ['cpp-modindex', 'py-modindex'] #html_use_index = True #html_split_index = False #html_show_sourcelink = True #html_show_sphinx = True #html_show_copyright = True #html_use_opensearch = '' #html_file_suffix = None htmlhelp_basename = 'OpenColorIOdoc' # -- Options for LaTeX output -------------------------------------------------- #latex_paper_size = 'letter' #latex_font_size = '10pt' latex_documents = [ ('index', 'OpenColorIO.tex', u'OpenColorIO Documentation', u'Sony Pictures Imageworks', 'manual', False), ] latex_elements = { 'preamble': '\setcounter{tocdepth}{2}', 'footer': 'test...123' } #latex_logo = None #latex_use_parts = False #latex_show_pagerefs = False #latex_show_urls = False #latex_preamble = '\setcounter{tocdepth}{2}' #latex_appendices = [] latex_domain_indices = ['cpp-modindex', 'py-modindex'] # -- Options for manual page output -------------------------------------------- man_pages = [ ('index', 'opencolorio', u'OpenColorIO Documentation', [u'Sony Pictures Imageworks'], 1) ] # -- Options for Texinfo output ------------------------------------------------ texinfo_documents = [ ('index', 'OpenColorIO', u'OpenColorIO Documentation', u'Sony Pictures Imageworks', 'OpenColorIO', 'One line description of project.', 'Miscellaneous'), ] texinfo_appendices = [] # -- Options for Epub output --------------------------------------------------- epub_title = u'OpenColorIO' epub_author = u'Sony Pictures Imageworks' epub_publisher = u'Sony Pictures Imageworks' epub_copyright = u'2010, Sony Pictures Imageworks' #epub_language = '' #epub_scheme = '' #epub_identifier = '' #epub_uid = '' #epub_cover = () #epub_pre_files = [] #epub_post_files = [] #epub_exclude_files = [] #epub_tocdepth = 3 #epub_tocdup = True opencolorio-1.1.0~dfsg0.orig/src/0000755000175000017500000000000013223553423015055 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/0000755000175000017500000000000013223553423017516 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/OpenColorIO_AE.h0000755000175000017500000001265413223553423022377 0ustar mfvmfv/* Copyright (c) 2003-2012 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. */ #pragma once #ifndef _OPENCOLORIO_AE_H_ #define _OPENCOLORIO_AE_H_ //#define PF_DEEP_COLOR_AWARE 1 // do we really still need this? #include "AEConfig.h" #include "entry.h" #include "SPTypes.h" #include "PrSDKAESupport.h" #include "AE_Macros.h" #include "Param_Utils.h" #include "AE_Effect.h" #include "AE_EffectUI.h" #include "AE_EffectCB.h" #ifdef MSWindows #include #else #ifndef __MACH__ #include "string.h" #endif #endif // Versioning information #define MAJOR_VERSION 1 #define MINOR_VERSION 0 #define BUG_VERSION 0 #define STAGE_VERSION PF_Stage_RELEASE #define BUILD_VERSION 0 // Paramater constants enum { OCIO_INPUT = 0, OCIO_DATA, OCIO_GPU, OCIO_NUM_PARAMS }; enum { OCIO_DATA_ID = 1, OCIO_GPU_ID }; // Our Arbitrary Data struct #define CURRENT_ARB_VERSION 1 #define ARB_PATH_LEN 255 #define ARB_SPACE_LEN 63 enum { OCIO_ACTION_NONE = 0, OCIO_ACTION_LUT, OCIO_ACTION_CONVERT, OCIO_ACTION_DISPLAY }; typedef A_u_char OCIO_Action; enum { OCIO_STORAGE_NONE = 0, OCIO_STORAGE_ZIP_FILE }; typedef A_u_char OCIO_Storage; enum { OCIO_SOURCE_NONE = 0, OCIO_SOURCE_ENVIRONMENT, OCIO_SOURCE_STANDARD, OCIO_SOURCE_CUSTOM }; typedef A_u_char OCIO_Source; enum { OCIO_INTERP_UNKNOWN = 0, OCIO_INTERP_NEAREST = 1, OCIO_INTERP_LINEAR = 2, OCIO_INTERP_TETRAHEDRAL = 3, OCIO_INTERP_BEST = 255 }; typedef A_u_char OCIO_Interp; typedef struct { A_u_char version; // version of this data structure OCIO_Action action; A_Boolean invert; // only used for LUTs OCIO_Storage storage; // storage not used...yet A_u_long storage_size; OCIO_Source source; OCIO_Interp interpolation; A_u_char reserved[54]; // 64 pre-path bytes char path[ARB_PATH_LEN+1]; char relative_path[ARB_PATH_LEN+1]; char input[ARB_SPACE_LEN+1]; char output[ARB_SPACE_LEN+1]; char transform[ARB_SPACE_LEN+1]; char device[ARB_SPACE_LEN+1]; char look[ARB_SPACE_LEN+1]; // not used currently A_u_char storage_buf[1]; } ArbitraryData; #ifdef __cplusplus class OpenColorIO_AE_Context; enum { STATUS_UNKNOWN = 0, STATUS_OK, STATUS_NO_FILE, STATUS_USING_ABSOLUTE, STATUS_USING_RELATIVE, STATUS_FILE_MISSING, STATUS_OCIO_ERROR }; typedef A_u_char FileStatus; enum { GPU_ERR_NONE = 0, GPU_ERR_INSUFFICIENT, GPU_ERR_RENDER_ERR }; typedef A_u_char GPUErr; enum { PREMIERE_UNKNOWN = 0, PREMIERE_LINEAR, PREMIERE_NON_LINEAR }; typedef A_u_char PremiereStatus; typedef struct { FileStatus status; GPUErr gpu_err; PremiereStatus prem_status; OCIO_Source source; OpenColorIO_AE_Context *context; char path[ARB_PATH_LEN+1]; char relative_path[ARB_PATH_LEN+1]; } SequenceData; #endif #define UI_CONTROL_HEIGHT 200 #define UI_CONTROL_WIDTH 500 #ifdef __cplusplus extern "C" { #endif // Prototypes DllExport PF_Err PluginMain( PF_Cmd cmd, PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, void *extra) ; PF_Err HandleEvent( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, PF_EventExtra *extra ); PF_Err ArbNewDefault( // needed by ParamSetup() PF_InData *in_data, PF_OutData *out_data, void *refconPV, PF_ArbitraryH *arbPH); PF_Err HandleArbitrary( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, PF_ArbParamsExtra *extra); #ifdef __cplusplus } #endif #endif // _OPENCOLORIO_AE_H_opencolorio-1.1.0~dfsg0.orig/src/aftereffects/win/0000755000175000017500000000000013223553423020313 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/win/resource.h0000644000175000017500000000076313223553423022321 0ustar mfvmfv//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by OpenColorIO.rc // #define IDB_BITMAP1 102 #define BANNER1 102 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 103 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1002 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif opencolorio-1.1.0~dfsg0.orig/src/aftereffects/win/OpenColorIO_AE_GL_Win.cpp0000644000175000017500000001304313223553423024714 0ustar mfvmfv/* Copyright (c) 2003-2012 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 "OpenColorIO_AE_GL.h" #include #include #include static HWND g_win = NULL; static HDC g_hdc = NULL; static HGLRC g_context = NULL; static GLuint g_framebuffer = GL_INVALID_VALUE; static bool HaveRequiredExtensions() { const GLubyte *strVersion = glGetString(GL_VERSION); const GLubyte *strExt = glGetString(GL_EXTENSIONS); if(strVersion == NULL) return false; #define CheckExtension(N) glewIsExtensionSupported(N) return (GLEW_VERSION_2_0 && CheckExtension("GL_ARB_color_buffer_float") && CheckExtension("GL_ARB_texture_float") && CheckExtension("GL_ARB_vertex_program") && CheckExtension("GL_ARB_vertex_shader") && CheckExtension("GL_ARB_texture_cube_map") && CheckExtension("GL_ARB_fragment_shader") && CheckExtension("GL_ARB_draw_buffers") && CheckExtension("GL_ARB_framebuffer_object") ); } void GlobalSetup_GL() { GLenum init = glewInit(); if(init != GLEW_OK) return; WNDCLASSEX winClass; MSG uMsg; memset(&uMsg,0,sizeof(uMsg)); winClass.lpszClassName = "OpenColorIO_AE_Win_Class"; winClass.cbSize = sizeof(WNDCLASSEX); winClass.style = CS_HREDRAW | CS_VREDRAW; winClass.lpfnWndProc = DefWindowProc; winClass.hInstance = NULL; winClass.hIcon = NULL; winClass.hIconSm = NULL; winClass.hCursor = LoadCursor(NULL, IDC_ARROW); winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winClass.lpszMenuName = NULL; winClass.cbClsExtra = 0; winClass.cbWndExtra = 0; if( !( RegisterClassEx(&winClass) ) ) return; g_win = CreateWindowEx( NULL, "OpenColorIO_AE_Win_Class", "OpenGL-using FBOs in AE", 0, 0, 0, 50, 50, NULL, NULL, NULL, NULL ); if(g_win == NULL) return; g_hdc = GetDC(g_win); int pixelFormat; PIXELFORMATDESCRIPTOR pfd; ZeroMemory( &pfd, sizeof( pfd ) ); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 128; pfd.cDepthBits = 32; pfd.cStencilBits = 32; pfd.iLayerType = PFD_MAIN_PLANE; pixelFormat = ChoosePixelFormat(g_hdc, &pfd); BOOL set_format = SetPixelFormat(g_hdc, pixelFormat, &pfd); if(!set_format) { GlobalSetdown_GL(); return; } g_context = wglCreateContext(g_hdc); glFlush(); if(g_context == NULL) { GlobalSetdown_GL(); return; } SetPluginContext(); GLint units; glGetIntegerv(GL_MAX_TEXTURE_UNITS, &units); if( !HaveRequiredExtensions() || units < 2) { GlobalSetdown_GL(); SetAEContext(); return; } glGenFramebuffersEXT(1, &g_framebuffer); SetAEContext(); } bool HaveOpenGL() { return (g_context != NULL && g_win != NULL); } static HDC g_ae_hdc; static HGLRC g_ae_context; void SetPluginContext() { g_ae_hdc = wglGetCurrentDC(); g_ae_context = wglGetCurrentContext(); wglMakeCurrent(g_hdc, g_context); } void SetAEContext() { wglMakeCurrent(g_ae_hdc, g_ae_context); } GLuint GetFrameBuffer() { return g_framebuffer; } void GlobalSetdown_GL() { if(g_framebuffer != GL_INVALID_VALUE) { glDeleteFramebuffersEXT(1, &g_framebuffer); g_framebuffer = GL_INVALID_VALUE; } if(g_context) { wglDeleteContext(g_context); g_context = NULL; } if(g_win) { ReleaseDC(g_win, g_hdc); g_win = NULL; g_hdc = NULL; UnregisterClass("OpenColorIO_AE_Win_Class", NULL); } } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/win/OpenColorIO.rc0000644000175000017500000000442113223553423022772 0ustar mfvmfv// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog // PROFILEDIALOG DIALOGEX 0, 0, 233, 78 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "OpenColorIO" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "OK",IDOK,176,57,50,14 PUSHBUTTON "Cancel",IDCANCEL,117,57,50,14 COMBOBOX 3,74,20,133,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Monitor Profile:",IDC_STATIC,15,20,55,12,SS_CENTERIMAGE,WS_EX_RIGHT END ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN "PROFILEDIALOG", DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 226 TOPMARGIN, 7 BOTTOMMARGIN, 71 END END #endif // APSTUDIO_INVOKED #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED opencolorio-1.1.0~dfsg0.orig/src/aftereffects/win/OpenColorIO_AE_Dialogs_Win.cpp0000644000175000017500000005305113223553423025777 0ustar mfvmfv/* Copyright (c) 2003-2012 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 "OpenColorIO_AE_Dialogs.h" #include #include #include #include #include "lcms2.h" static HINSTANCE hDllInstance = NULL; static void AppendString(char *text, int &length, const char *str, int len = -1) { if(len < 0) len = strlen(str); const char *in = str; char *out = &text[length]; for(int i=0; i < len; i++) { *out++ = *in++; length++; } } static void AppendNull(char *text, int &length) { AppendString(text, length, "\0\0", 1); } static void MakeFilterText(char *filter_text, const ExtensionMap &extensions, bool do_combined) { // Construct the Windows file dialog filter string, which looks like this: // // "All OCIO files\0" // "*.ocio;*.cube;*.vf;*.mga\0" // "OpenColorIO (*.ocio)\0" // "*.ocio\0" // "Iridas (*.cube)\0" // "*.cube\0" // "Nuke Vectorfield (*.vf)\0" // "*.vf\0" // "Apple Color (*.mga)\0" // "*.mga\0" // "\0"; // // Note the inline nulls and final double-null, which foil regular string functions. char combined_entry[512]; int combined_length = 0; char seperate_entries[512]; int seperate_length = 0; AppendString(combined_entry, combined_length, "All OCIO files"); AppendNull(combined_entry, combined_length); for(ExtensionMap::const_iterator i = extensions.begin(); i != extensions.end(); i++) { std::string extension = i->first; std::string format = i->second; std::string format_part = format + " (*." + extension + ")"; std::string extension_part = "*." + extension; std::string combined_part = extension_part + ";"; AppendString(seperate_entries, seperate_length, format_part.c_str(), format_part.size()); AppendNull(seperate_entries, seperate_length); AppendString(seperate_entries, seperate_length, extension_part.c_str(), extension_part.size()); AppendNull(seperate_entries, seperate_length); AppendString(combined_entry, combined_length, combined_part.c_str(), combined_part.size()); } AppendNull(seperate_entries, seperate_length); AppendNull(combined_entry, combined_length); char *in = combined_entry; char *out = filter_text; if(do_combined) { for(int i=0; i < combined_length; i++) *out++ = *in++; } in = seperate_entries; for(int i=0; i < seperate_length; i++) *out++ = *in++; } bool OpenFile(char *path, int buf_len, const ExtensionMap &extensions, const void *hwnd) { const char *my_lpstrTitle = "Import OCIO"; const char *my_lpstrDefExt = "ocio"; char my_lpstrFilter[1024]; MakeFilterText(my_lpstrFilter, extensions, true); OPENFILENAME lpofn; lpofn.lStructSize = sizeof(lpofn); lpofn.hwndOwner = (HWND)hwnd; lpofn.hInstance = hDllInstance; lpofn.lpstrFilter = my_lpstrFilter; lpofn.lpstrCustomFilter = NULL; lpofn.nMaxCustFilter = 0; lpofn.nFilterIndex = 0; lpofn.lpstrFile = path; lpofn.nMaxFile = buf_len; lpofn.lpstrFileTitle = path; lpofn.nMaxFileTitle = buf_len; lpofn.lpstrInitialDir = NULL; lpofn.lpstrTitle = my_lpstrTitle; lpofn.Flags = OFN_LONGNAMES | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT; lpofn.nFileOffset = 0; lpofn.nFileExtension = 0; lpofn.lpstrDefExt = my_lpstrDefExt; lpofn.lCustData = 0; lpofn.lpfnHook = NULL; lpofn.lpTemplateName = NULL; lpofn.lStructSize = sizeof(lpofn); return GetOpenFileName(&lpofn); } bool SaveFile(char *path, int buf_len, const ExtensionMap &extensions, const void *hwnd) { const char *my_lpstrTitle = "Export OCIO"; const char *my_lpstrDefExt = "icc"; char my_lpstrFilter[512]; MakeFilterText(my_lpstrFilter, extensions, false); OPENFILENAME lpofn; lpofn.lStructSize = sizeof(lpofn); lpofn.hwndOwner = (HWND)hwnd; lpofn.hInstance = hDllInstance; lpofn.lpstrFilter = my_lpstrFilter; lpofn.lpstrCustomFilter = NULL; lpofn.nMaxCustFilter = 0; lpofn.nFilterIndex = 0; lpofn.lpstrFile = path; lpofn.nMaxFile = buf_len; lpofn.lpstrFileTitle = path; lpofn.nMaxFileTitle = buf_len; lpofn.lpstrInitialDir = NULL; lpofn.lpstrTitle = my_lpstrTitle; lpofn.Flags = OFN_LONGNAMES | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT; lpofn.nFileOffset = 0; lpofn.nFileExtension = 0; lpofn.lpstrDefExt = my_lpstrDefExt; lpofn.lCustData = 0; lpofn.lpfnHook = NULL; lpofn.lpTemplateName = NULL; lpofn.lStructSize = sizeof(lpofn); return GetSaveFileName(&lpofn); } // dialog item IDs enum { DLOG_noUI = -1, DLOG_OK = IDOK, // was 1 DLOG_Cancel = IDCANCEL, // was 2 DLOG_Profile_Menu = 3 }; static std::vector *g_profile_vec = NULL; static int g_selected_item = DLOG_noUI; static WORD g_item_clicked = 0; static BOOL CALLBACK DialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { BOOL fError; switch (message) { case WM_INITDIALOG: do{ // add profile list to combo boxe HWND menu = GetDlgItem(hwndDlg, DLOG_Profile_Menu); for(int i=0; i < g_profile_vec->size(); i++) { SendMessage(menu, (UINT)CB_ADDSTRING, (WPARAM)wParam, (LPARAM)(LPCTSTR)g_profile_vec->at(i).c_str() ); SendMessage(menu,(UINT)CB_SETITEMDATA, (WPARAM)i, (LPARAM)(DWORD)i); // channel index number if( g_selected_item == i ) SendMessage(menu, CB_SETCURSEL, (WPARAM)i, (LPARAM)0); } }while(0); return FALSE; case WM_COMMAND: g_item_clicked = LOWORD(wParam); switch(LOWORD(wParam)) { case DLOG_OK: case DLOG_Cancel: // do the same thing, but g_item_clicked differ do{ HWND menu = GetDlgItem(hwndDlg, DLOG_Profile_Menu); LRESULT cur_sel = SendMessage(menu, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0); g_selected_item = SendMessage(menu, (UINT)CB_GETITEMDATA, (WPARAM)cur_sel, (LPARAM)0); }while(0); EndDialog(hwndDlg, 0); return TRUE; } } return FALSE; } bool GetMonitorProfile(char *path, int buf_len, const void *hwnd) { std::list profile_descriptions; std::map profile_paths; // path to the monitor's profile char monitor_profile_path[256] = { '\0' }; DWORD path_size = 256; BOOL get_icm_result = GetICMProfile(GetDC((HWND)hwnd), &path_size, monitor_profile_path); // directory where Windows stores its profiles char profile_directory[256] = { '\0' }; DWORD dir_name_size = 256; BOOL get_color_dir_result = GetColorDirectory(NULL, profile_directory, &dir_name_size); // Get the profile file names from Windows ENUMTYPE enum_type; enum_type.dwSize = sizeof(ENUMTYPE); enum_type.dwVersion = ENUM_TYPE_VERSION; enum_type.dwFields = ET_DEVICECLASS; // alternately could use ET_CLASS enum_type.dwDeviceClass = CLASS_MONITOR; BYTE *buf = NULL; DWORD buf_size = 0; DWORD num_profiles = 0; BOOL other_enum_result = EnumColorProfiles(NULL, &enum_type, buf, &buf_size, &num_profiles); if(buf_size > 0 && num_profiles > 0) { buf = (BYTE *)malloc(buf_size); other_enum_result = EnumColorProfiles(NULL, &enum_type, buf, &buf_size, &num_profiles); if(other_enum_result) { // build a list of the profile descriptions // and a map to return the paths char *prof_name = (char *)buf; for(int i=0; i < num_profiles; i++) { std::string prof = prof_name; std::string prof_path = std::string(profile_directory) + "\\" + prof_name; cmsHPROFILE hProfile = cmsOpenProfileFromFile(prof_path.c_str(), "r"); // Note: Windows will give us profiles that aren't ICC (.cdmp for example). // Don't worry, LittleCMS will just return NULL for those. if(hProfile) { char profile_description[256]; cmsUInt32Number got_desc = cmsGetProfileInfoASCII(hProfile, cmsInfoDescription, "en", "US", profile_description, 256); if(got_desc) { profile_descriptions.push_back(profile_description); profile_paths[ profile_description ] = prof_path; } cmsCloseProfile(hProfile); } prof_name += strlen(prof_name) + 1; } } free(buf); } if(profile_descriptions.size() > 0) { // set a vector and selected index for building the profile menu profile_descriptions.sort(); profile_descriptions.unique(); std::vector profile_vec; int selected = 0; for(std::list::const_iterator i = profile_descriptions.begin(); i != profile_descriptions.end(); i++) { profile_vec.push_back( *i ); if( profile_paths[ *i ] == monitor_profile_path) { selected = profile_vec.size() - 1; } } // run the dialog g_profile_vec = &profile_vec; g_selected_item = selected; int status = DialogBox(hDllInstance, (LPSTR)"PROFILEDIALOG", (HWND)hwnd, (DLGPROC)DialogProc); if(status == -1) { // dialog didn't open, my bad return true; } else if(g_item_clicked == DLOG_Cancel) { return false; } else { strncpy(path, profile_paths[ profile_vec[ g_selected_item ] ].c_str(), buf_len); return true; } } else return true; } int PopUpMenu(const MenuVec &menu_items, int selected_index, const void *hwnd) { HMENU menu = CreatePopupMenu(); if(menu) { for(int i=0; i < menu_items.size(); i++) { std::string label = menu_items[i]; UINT flags = (i == selected_index ? (MF_STRING | MF_CHECKED) : MF_STRING); if(label == "(-") { flags |= MF_SEPARATOR; } else if(label == "$OCIO") { char *file = std::getenv("OCIO"); if(file == NULL) flags |= MF_GRAYED; } else if(label == "(nada)") { flags |= MF_GRAYED; char appdata_path[MAX_PATH]; HRESULT result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdata_path); if(result == S_OK) { label = "No configs in " + std::string(appdata_path) + "\\OpenColorIO\\"; } } AppendMenu(menu, flags, i + 1, label.c_str()); } POINT pos; GetCursorPos(&pos); int result = TrackPopupMenuEx(menu, (TPM_NONOTIFY | TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD), pos.x, pos.y, (HWND)hwnd, NULL); DestroyMenu(menu); if(result == 0) { // means the user clicked off the menu return selected_index; } else return result - 1; } else return selected_index; } static void tokenize(std::vector &tokens, const std::string& str, std::string delimiters) { std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); std::string::size_type pos = str.find_first_of(delimiters, lastPos); while (pos != std::string::npos || lastPos != std::string::npos) { tokens.push_back(str.substr(lastPos, pos - lastPos)); lastPos = str.find_first_not_of(delimiters, pos); pos = str.find_first_of(delimiters, lastPos); } } bool ColorSpacePopUpMenu(OCIO::ConstConfigRcPtr config, std::string &colorSpace, bool selectRoles, const void *hwnd) { HMENU menu = CreatePopupMenu(); for(int i=0; i < config->getNumColorSpaces(); ++i) { const char *colorSpaceName = config->getColorSpaceNameByIndex(i); OCIO::ConstColorSpaceRcPtr colorSpacePtr = config->getColorSpace(colorSpaceName); const char *family = colorSpacePtr->getFamily(); std::string colorSpacePath; if(family == NULL) { colorSpacePath = colorSpaceName; } else { colorSpacePath = std::string(family) + "/" + colorSpaceName; } std::vector pathComponents; tokenize(pathComponents, colorSpacePath, "/"); HMENU currentMenu = menu; for(int j=0; j < pathComponents.size(); j++) { const std::string &componentName = pathComponents[j]; if(j == (pathComponents.size() - 1)) { UINT flags = MF_STRING; if(componentName == colorSpace) flags |= MF_CHECKED; const BOOL inserted = AppendMenu(currentMenu, flags, i + 1, componentName.c_str()); assert(inserted); } else { int componentMenuPos = -1; for(int k=0; k < GetMenuItemCount(currentMenu) && componentMenuPos < 0; k++) { CHAR buf[256]; const int strLen = GetMenuString(currentMenu, k, buf, 255, MF_BYPOSITION); assert(strLen > 0); if(componentName == buf) componentMenuPos = k; } if(componentMenuPos < 0) { HMENU subMenu = CreateMenu(); const BOOL inserted = AppendMenu(currentMenu, MF_STRING | MF_POPUP, (UINT_PTR)subMenu, componentName.c_str()); assert(inserted); componentMenuPos = (GetMenuItemCount(currentMenu) - 1); } currentMenu = GetSubMenu(currentMenu, componentMenuPos); } } } if(config->getNumRoles() > 0) { HMENU rolesMenu = CreatePopupMenu(); const BOOL rolesInserted = InsertMenu(menu, 0, MF_STRING | MF_BYPOSITION | MF_POPUP, (UINT_PTR)rolesMenu, "Roles"); assert(rolesInserted); for(int i=0; i < config->getNumRoles(); i++) { const std::string roleName = config->getRoleName(i); OCIO::ConstColorSpaceRcPtr colorSpacePtr = config->getColorSpace(roleName.c_str()); const std::string colorSpaceName = colorSpacePtr->getName(); int colorSpaceIndex = -1; for(int k=0; k < config->getNumColorSpaces() && colorSpaceIndex < 0; k++) { const std::string colorSpaceName2 = config->getColorSpaceNameByIndex(k); if(colorSpaceName2 == colorSpaceName) colorSpaceIndex = k; } HMENU roleSubmenu = CreatePopupMenu(); UINT roleFlags = MF_STRING | MF_POPUP; if(selectRoles && roleName == colorSpace) roleFlags |= MF_CHECKED; const BOOL roleInserted = AppendMenu(rolesMenu, roleFlags, (UINT_PTR)roleSubmenu, roleName.c_str()); assert(roleInserted); UINT colorSpaceFlags = MF_STRING; if(colorSpaceName == colorSpace) colorSpaceFlags |= MF_CHECKED; const BOOL colorSpaceInsterted = AppendMenu(roleSubmenu, colorSpaceFlags, colorSpaceIndex + 1, colorSpaceName.c_str()); assert(colorSpaceInsterted); } const BOOL dividerInserted = InsertMenu(menu, 1, MF_STRING | MF_BYPOSITION | MF_SEPARATOR, 0, "Sep"); assert(dividerInserted); } POINT pos; GetCursorPos(&pos); int result = TrackPopupMenuEx(menu, (TPM_NONOTIFY | TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD), pos.x, pos.y, (HWND)hwnd, NULL); DestroyMenu(menu); if(result > 0) { colorSpace = config->getColorSpaceNameByIndex(result - 1); return true; } else return false; } void GetStdConfigs(ConfigVec &configs) { char appdata_path[MAX_PATH]; HRESULT result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdata_path); if(result == S_OK) { std::string dir_path = std::string(appdata_path) + "\\OpenColorIO\\"; std::string search_path = dir_path + "*"; WIN32_FIND_DATA find_data; HANDLE searchH = FindFirstFile(search_path.c_str(), &find_data); if(searchH != INVALID_HANDLE_VALUE) { if(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { std::string config_path = dir_path + find_data.cFileName + "\\config.ocio"; WIN32_FIND_DATA find_data_temp; HANDLE fileH = FindFirstFile(config_path.c_str(), &find_data_temp); if(fileH != INVALID_HANDLE_VALUE) { configs.push_back(find_data.cFileName); FindClose(fileH); } } while( FindNextFile(searchH, &find_data) ) { if(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { std::string config_path = dir_path + find_data.cFileName + "\\config.ocio"; WIN32_FIND_DATA find_data_temp; HANDLE fileH = FindFirstFile(config_path.c_str(), &find_data_temp); if(fileH != INVALID_HANDLE_VALUE) { configs.push_back(find_data.cFileName); FindClose(fileH); } } } FindClose(searchH); } } } std::string GetStdConfigPath(const std::string &name) { char appdata_path[MAX_PATH]; HRESULT result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdata_path); if(result == S_OK) { std::string config_path = std::string(appdata_path) + "\\OpenColorIO\\" + name + "\\config.ocio"; WIN32_FIND_DATA find_data; HANDLE searchH = FindFirstFile(config_path.c_str(), &find_data); if(searchH != INVALID_HANDLE_VALUE) { FindClose(searchH); return config_path; } } return ""; } void ErrorMessage(const char *message , const void *hwnd) { MessageBox((HWND)hwnd, message, "OpenColorIO", MB_OK); } #ifdef SUPPLY_HINSTANCE void SetHInstance(void *hInstance) { hDllInstance = (HINSTANCE)hInstance; } #else BOOL WINAPI DllMain(HANDLE hInstance, DWORD fdwReason, LPVOID lpReserved) { if (fdwReason == DLL_PROCESS_ATTACH) hDllInstance = (HINSTANCE)hInstance; return TRUE; } #endifopencolorio-1.1.0~dfsg0.orig/src/aftereffects/OpenColorIO_AE.cpp0000755000175000017500000011031513223553423022723 0ustar mfvmfv/* Copyright (c) 2003-2012 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 "OpenColorIO_AE.h" #include "OpenColorIO_AE_Context.h" #include "OpenColorIO_AE_Dialogs.h" #include "AEGP_SuiteHandler.h" // this lives in OpenColorIO_AE_UI.cpp std::string GetProjectDir(PF_InData *in_data); static PF_Err About( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output ) { PF_SPRINTF( out_data->return_msg, "OpenColorIO\r\r" "opencolorio.org\r" "version %s", OCIO::GetVersion() ); return PF_Err_NONE; } static PF_Err GlobalSetup( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output ) { out_data->my_version = PF_VERSION( MAJOR_VERSION, MINOR_VERSION, BUG_VERSION, STAGE_VERSION, BUILD_VERSION); out_data->out_flags = PF_OutFlag_DEEP_COLOR_AWARE | PF_OutFlag_PIX_INDEPENDENT | PF_OutFlag_CUSTOM_UI | PF_OutFlag_USE_OUTPUT_EXTENT | PF_OutFlag_I_HAVE_EXTERNAL_DEPENDENCIES; out_data->out_flags2 = PF_OutFlag2_PARAM_GROUP_START_COLLAPSED_FLAG | PF_OutFlag2_SUPPORTS_SMART_RENDER | PF_OutFlag2_FLOAT_COLOR_AWARE | PF_OutFlag2_PPRO_DO_NOT_CLONE_SEQUENCE_DATA_FOR_RENDER; GlobalSetup_GL(); if(in_data->appl_id == 'PrMr') { PF_PixelFormatSuite1 *pfS = NULL; in_data->pica_basicP->AcquireSuite(kPFPixelFormatSuite, kPFPixelFormatSuiteVersion1, (const void **)&pfS); if(pfS) { pfS->ClearSupportedPixelFormats(in_data->effect_ref); pfS->AddSupportedPixelFormat(in_data->effect_ref, PrPixelFormat_BGRA_4444_32f); in_data->pica_basicP->ReleaseSuite(kPFPixelFormatSuite, kPFPixelFormatSuiteVersion1); } } return PF_Err_NONE; } static PF_Err GlobalSetdown( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output ) { GlobalSetdown_GL(); return PF_Err_NONE; } static PF_Err ParamsSetup( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output) { PF_Err err = PF_Err_NONE; PF_ParamDef def; // readout AEFX_CLR_STRUCT(def); // we can time_vary once we're willing to print and scan ArbData text def.flags = PF_ParamFlag_CANNOT_TIME_VARY; ArbNewDefault(in_data, out_data, NULL, &def.u.arb_d.dephault); PF_ADD_ARBITRARY("OCIO", UI_CONTROL_WIDTH, UI_CONTROL_HEIGHT, PF_PUI_CONTROL, def.u.arb_d.dephault, OCIO_DATA, NULL); AEFX_CLR_STRUCT(def); PF_ADD_CHECKBOX("", "Use GPU", FALSE, 0, OCIO_GPU_ID); out_data->num_params = OCIO_NUM_PARAMS; // register custom UI if (!err) { PF_CustomUIInfo ci; AEFX_CLR_STRUCT(ci); ci.events = PF_CustomEFlag_EFFECT; ci.comp_ui_width = ci.comp_ui_height = 0; ci.comp_ui_alignment = PF_UIAlignment_NONE; ci.layer_ui_width = 0; ci.layer_ui_height = 0; ci.layer_ui_alignment = PF_UIAlignment_NONE; ci.preview_ui_width = 0; ci.preview_ui_height = 0; ci.layer_ui_alignment = PF_UIAlignment_NONE; err = (*(in_data->inter.register_ui))(in_data->effect_ref, &ci); } return err; } static PF_Err SequenceSetup( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output ) { PF_Err err = PF_Err_NONE; SequenceData *seq_data = NULL; // set up sequence data if( (in_data->sequence_data == NULL) ) { out_data->sequence_data = PF_NEW_HANDLE( sizeof(SequenceData) ); seq_data = (SequenceData *)PF_LOCK_HANDLE(out_data->sequence_data); seq_data->path[0] = '\0'; seq_data->relative_path[0] = '\0'; } else // reset pre-existing sequence data { if( PF_GET_HANDLE_SIZE(in_data->sequence_data) != sizeof(SequenceData) ) { PF_RESIZE_HANDLE(sizeof(SequenceData), &in_data->sequence_data); } seq_data = (SequenceData *)PF_LOCK_HANDLE(in_data->sequence_data); } seq_data->status = STATUS_UNKNOWN; seq_data->gpu_err = GPU_ERR_NONE; seq_data->prem_status = PREMIERE_UNKNOWN; seq_data->context = NULL; PF_UNLOCK_HANDLE(in_data->sequence_data); return err; } static PF_Err SequenceSetdown( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output ) { PF_Err err = PF_Err_NONE; if(in_data->sequence_data) { SequenceData *seq_data = (SequenceData *)PF_LOCK_HANDLE(out_data->sequence_data); if(seq_data->context) { delete seq_data->context; seq_data->status = STATUS_UNKNOWN; seq_data->gpu_err = GPU_ERR_NONE; seq_data->prem_status = PREMIERE_UNKNOWN; seq_data->context = NULL; } PF_DISPOSE_HANDLE(in_data->sequence_data); } return err; } static PF_Err SequenceFlatten( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output ) { PF_Err err = PF_Err_NONE; if(in_data->sequence_data) { SequenceData *seq_data = (SequenceData *)PF_LOCK_HANDLE(in_data->sequence_data); if(seq_data->context) { delete seq_data->context; seq_data->status = STATUS_UNKNOWN; seq_data->gpu_err = GPU_ERR_NONE; seq_data->prem_status = PREMIERE_UNKNOWN; seq_data->context = NULL; } PF_UNLOCK_HANDLE(in_data->sequence_data); } return err; } static PF_Boolean IsEmptyRect(const PF_LRect *r){ return (r->left >= r->right) || (r->top >= r->bottom); } #ifndef mmin #define mmin(a,b) ((a) < (b) ? (a) : (b)) #define mmax(a,b) ((a) > (b) ? (a) : (b)) #endif static void UnionLRect(const PF_LRect *src, PF_LRect *dst) { if (IsEmptyRect(dst)) { *dst = *src; } else if (!IsEmptyRect(src)) { dst->left = mmin(dst->left, src->left); dst->top = mmin(dst->top, src->top); dst->right = mmax(dst->right, src->right); dst->bottom = mmax(dst->bottom, src->bottom); } } static PF_Err PreRender( PF_InData *in_data, PF_OutData *out_data, PF_PreRenderExtra *extra) { PF_Err err = PF_Err_NONE; PF_RenderRequest req = extra->input->output_request; PF_CheckoutResult in_result; req.preserve_rgb_of_zero_alpha = TRUE; ERR(extra->cb->checkout_layer( in_data->effect_ref, OCIO_INPUT, OCIO_INPUT, &req, in_data->current_time, in_data->time_step, in_data->time_scale, &in_result)); UnionLRect(&in_result.result_rect, &extra->output->result_rect); UnionLRect(&in_result.max_result_rect, &extra->output->max_result_rect); return err; } #pragma mark- template static inline OutFormat Convert(InFormat in); template <> static inline float Convert(A_u_char in) { return (float)in / (float)PF_MAX_CHAN8; } template <> static inline float Convert(A_u_short in) { return (float)in / (float)PF_MAX_CHAN16; } template <> static inline float Convert(float in) { return in; } static inline float Clamp(float in) { return (in > 1.f ? 1.f : in < 0.f ? 0.f : in); } template <> static inline A_u_char Convert(float in) { return ( Clamp(in) * (float)PF_MAX_CHAN8 ) + 0.5f; } template <> static inline A_u_short Convert(float in) { return ( Clamp(in) * (float)PF_MAX_CHAN16 ) + 0.5f; } typedef struct { PF_InData *in_data; void *in_buffer; A_long in_rowbytes; void *out_buffer; A_long out_rowbytes; int width; } IterateData; template static PF_Err CopyWorld_Iterate( void *refconPV, A_long thread_indexL, A_long i, A_long iterationsL) { PF_Err err = PF_Err_NONE; IterateData *i_data = (IterateData *)refconPV; PF_InData *in_data = i_data->in_data; InFormat *in_pix = (InFormat *)((char *)i_data->in_buffer + (i * i_data->in_rowbytes)); OutFormat *out_pix = (OutFormat *)((char *)i_data->out_buffer + (i * i_data->out_rowbytes)); #ifdef NDEBUG if(thread_indexL == 0) err = PF_ABORT(in_data); #endif for(int x=0; x < i_data->width; x++) { *out_pix++ = Convert( *in_pix++ ); } return err; } typedef struct { PF_InData *in_data; void *in_buffer; A_long in_rowbytes; int width; } SwapData; static PF_Err Swap_Iterate( void *refconPV, A_long thread_indexL, A_long i, A_long iterationsL) { PF_Err err = PF_Err_NONE; SwapData *i_data = (SwapData *)refconPV; PF_InData *in_data = i_data->in_data; PF_PixelFloat *pix = (PF_PixelFloat *)((char *)i_data->in_buffer + (i * i_data->in_rowbytes)); #ifdef NDEBUG if(thread_indexL == 0) err = PF_ABORT(in_data); #endif for(int x=0; x < i_data->width; x++) { float temp; // BGRA -> ARGB temp = pix->alpha; // BGRA temp B pix->alpha = pix->blue; // AGRA temp B pix->blue = temp; // AGRB temp B temp = pix->red; // AGRB temp G pix->red = pix->green; // ARRB temp G pix->green = temp; // ARGB temp G pix++; } return err; } typedef struct { PF_InData *in_data; void *buffer; A_long rowbytes; int width; OpenColorIO_AE_Context *context; } ProcessData; static PF_Err Process_Iterate( void *refconPV, A_long thread_indexL, A_long i, A_long iterationsL) { PF_Err err = PF_Err_NONE; ProcessData *i_data = (ProcessData *)refconPV; PF_InData *in_data = i_data->in_data; PF_PixelFloat *pix = (PF_PixelFloat *)((char *)i_data->buffer + (i * i_data->rowbytes)); #ifdef NDEBUG if(thread_indexL == 0) err = PF_ABORT(in_data); #endif try { float *rOut = &pix->red; OCIO::PackedImageDesc img(rOut, i_data->width, 1, 4); i_data->context->processor()->apply(img); } catch(...) { err = PF_Err_INTERNAL_STRUCT_DAMAGED; } return err; } // two functions below to get Premiere to run my functions multi-threaded // because they couldn't bother to give me PF_Iterate8Suite1->iterate_generic typedef PF_Err (*GenericIterator)(void *refconPV, A_long thread_indexL, A_long i, A_long iterationsL); typedef struct { PF_InData *in_data; GenericIterator fn_func; void *refconPV; A_long height; } FakeData; static PF_Err MyFakeIterator( void *refcon, A_long x, A_long y, PF_Pixel *in, PF_Pixel *out) { PF_Err err = PF_Err_NONE; FakeData *i_data = (FakeData *)refcon; PF_InData *in_data = i_data->in_data; err = i_data->fn_func(i_data->refconPV, 1, y, i_data->height); return err; } typedef PF_Err (*GenericIterateFunc)( A_long iterationsL, void *refconPV, GenericIterator fn_func); static PF_Err MyGenericIterateFunc( A_long iterationsL, void *refconPV, GenericIterator fn_func) { PF_Err err = PF_Err_NONE; PF_InData **in_dataH = (PF_InData **)refconPV; // always put PF_InData first PF_InData *in_data = *in_dataH; PF_Iterate8Suite1 *i8sP = NULL; in_data->pica_basicP->AcquireSuite(kPFIterate8Suite, kPFIterate8SuiteVersion1, (const void **)&i8sP); if(i8sP && i8sP->iterate) { PF_EffectWorld fake_world; PF_NEW_WORLD(1, iterationsL, PF_NewWorldFlag_NONE, &fake_world); FakeData i_data = { in_data, fn_func, refconPV, iterationsL }; err = i8sP->iterate(in_data, 0, iterationsL, &fake_world, NULL, (void *)&i_data, MyFakeIterator, &fake_world); PF_DISPOSE_WORLD(&fake_world); in_data->pica_basicP->ReleaseSuite(kPFIterate8Suite, kPFIterate8SuiteVersion1); } else { for(int i=0; i < iterationsL && !err; i++) { err = fn_func(refconPV, 0, i, iterationsL); } } return err; } static PF_Err DoRender( PF_InData *in_data, PF_EffectWorld *input, PF_ParamDef *OCIO_data, PF_ParamDef *OCIO_gpu, PF_OutData *out_data, PF_EffectWorld *output) { PF_Err err = PF_Err_NONE; AEGP_SuiteHandler suites(in_data->pica_basicP); PF_PixelFormatSuite1 *pfS = NULL; PF_WorldSuite2 *wsP = NULL; err = in_data->pica_basicP->AcquireSuite(kPFPixelFormatSuite, kPFPixelFormatSuiteVersion1, (const void **)&pfS); err = in_data->pica_basicP->AcquireSuite(kPFWorldSuite, kPFWorldSuiteVersion2, (const void **)&wsP); if(!err) { ArbitraryData *arb_data = (ArbitraryData *)PF_LOCK_HANDLE(OCIO_data->u.arb_d.value); SequenceData *seq_data = (SequenceData *)PF_LOCK_HANDLE(in_data->sequence_data); try { seq_data->status = STATUS_OK; std::string dir = GetProjectDir(in_data); // must always verify that our context lines up with the parameters // things like undo can change them without notice if(seq_data->context != NULL) { bool verified = seq_data->context->Verify(arb_data, dir); if(!verified) { delete seq_data->context; seq_data->status = STATUS_UNKNOWN; seq_data->context = NULL; } } if(arb_data->action == OCIO_ACTION_NONE) { seq_data->status = STATUS_NO_FILE; } else if(seq_data->context == NULL) { seq_data->source = arb_data->source; if(arb_data->source == OCIO_SOURCE_ENVIRONMENT) { char *file = std::getenv("OCIO"); if(file == NULL) seq_data->status = STATUS_FILE_MISSING; } else if(arb_data->source == OCIO_SOURCE_STANDARD) { std::string path = GetStdConfigPath(arb_data->path); if( path.empty() ) { seq_data->status = STATUS_FILE_MISSING; } else { strncpy(seq_data->path, arb_data->path, ARB_PATH_LEN); strncpy(seq_data->relative_path, arb_data->relative_path, ARB_PATH_LEN); } } else if(arb_data->source == OCIO_SOURCE_CUSTOM) { Path absolute_path(arb_data->path, dir); Path relative_path(arb_data->relative_path, dir); Path seq_absolute_path(seq_data->path, dir); Path seq_relative_path(seq_data->relative_path, dir); if( absolute_path.exists() ) { seq_data->status = STATUS_USING_ABSOLUTE; strncpy(seq_data->path, absolute_path.full_path().c_str(), ARB_PATH_LEN); strncpy(seq_data->relative_path, absolute_path.relative_path(false).c_str(), ARB_PATH_LEN); } else if( relative_path.exists() ) { seq_data->status = STATUS_USING_RELATIVE; strncpy(seq_data->path, relative_path.full_path().c_str(), ARB_PATH_LEN); strncpy(seq_data->relative_path, relative_path.relative_path(false).c_str(), ARB_PATH_LEN); } else if( seq_absolute_path.exists() ) { // In some cases, we may have a good path in sequence options but not in // the arbitrary parameter. An alert will not be provided because it is the // sequence options that get checked. Therefore, we have to use the sequence // options as a last resort. We copy the path back to arb data, but the change // should not stick. seq_data->status = STATUS_USING_ABSOLUTE; strncpy(arb_data->path, seq_absolute_path.full_path().c_str(), ARB_PATH_LEN); strncpy(arb_data->relative_path, seq_absolute_path.relative_path(false).c_str(), ARB_PATH_LEN); } else if( seq_relative_path.exists() ) { seq_data->status = STATUS_USING_RELATIVE; strncpy(arb_data->path, seq_relative_path.full_path().c_str(), ARB_PATH_LEN); strncpy(arb_data->relative_path, seq_relative_path.relative_path(false).c_str(), ARB_PATH_LEN); } else seq_data->status = STATUS_FILE_MISSING; } if(seq_data->status != STATUS_FILE_MISSING) { seq_data->context = new OpenColorIO_AE_Context(arb_data, dir); } } } catch(...) { seq_data->status = STATUS_OCIO_ERROR; } if(seq_data->status == STATUS_FILE_MISSING || seq_data->status == STATUS_OCIO_ERROR) { err = PF_Err_INTERNAL_STRUCT_DAMAGED; } if(!err) { if(seq_data->context == NULL || seq_data->context->processor()->isNoOp()) { err = PF_COPY(input, output, NULL, NULL); } else { GenericIterateFunc iterate_generic = suites.Iterate8Suite1()->iterate_generic; if(iterate_generic == NULL) iterate_generic = MyGenericIterateFunc; // thanks a lot, Premiere // OpenColorIO only does float worlds // might have to create one PF_EffectWorld *float_world = NULL; PF_EffectWorld temp_world_data; PF_EffectWorld *temp_world = NULL; PF_Handle temp_worldH = NULL; PF_PixelFormat format; wsP->PF_GetPixelFormat(output, &format); if(in_data->appl_id == 'PrMr' && pfS) { // the regular world suite function will give a bogus value for Premiere pfS->GetPixelFormat(output, (PrPixelFormat *)&format); seq_data->prem_status = (format == PrPixelFormat_BGRA_4444_32f_Linear ? PREMIERE_LINEAR : PREMIERE_NON_LINEAR); } A_Boolean use_gpu = OCIO_gpu->u.bd.value; seq_data->gpu_err = GPU_ERR_NONE; A_long non_padded_rowbytes = sizeof(PF_PixelFloat) * output->width; if(format == PF_PixelFormat_ARGB128 && (!use_gpu || output->rowbytes == non_padded_rowbytes)) // GPU doesn't do padding { err = PF_COPY(input, output, NULL, NULL); float_world = output; } else { temp_worldH = PF_NEW_HANDLE(non_padded_rowbytes * (output->height + 1)); // little extra because we go over by a channel if(temp_worldH) { temp_world_data.data = (PF_PixelPtr)PF_LOCK_HANDLE(temp_worldH); temp_world_data.width = output->width; temp_world_data.height = output->height; temp_world_data.rowbytes = non_padded_rowbytes; float_world = temp_world = &temp_world_data; // convert to new temp float world IterateData i_data = { in_data, input->data, input->rowbytes, float_world->data, float_world->rowbytes, float_world->width * 4 }; if(format == PF_PixelFormat_ARGB32 || format == PrPixelFormat_BGRA_4444_8u) { err = iterate_generic(float_world->height, &i_data, CopyWorld_Iterate); } else if(format == PF_PixelFormat_ARGB64) { err = iterate_generic(float_world->height, &i_data, CopyWorld_Iterate); } else if(format == PF_PixelFormat_ARGB128 || format == PrPixelFormat_BGRA_4444_32f || format == PrPixelFormat_BGRA_4444_32f_Linear) { err = iterate_generic(float_world->height, &i_data, CopyWorld_Iterate); } // switch BGRA to ARGB for premiere if(!err && (format == PrPixelFormat_BGRA_4444_8u || format == PrPixelFormat_BGRA_4444_32f_Linear || format == PrPixelFormat_BGRA_4444_32f)) { SwapData s_data = { in_data, float_world->data, float_world->rowbytes, float_world->width }; err = iterate_generic(float_world->height, &s_data, Swap_Iterate); } } else err = PF_Err_OUT_OF_MEMORY; } if(!err) { bool gpu_rendered = false; // OpenColorIO processing if(use_gpu) { if( HaveOpenGL() ) { gpu_rendered = seq_data->context->ProcessWorldGL(float_world); if(!gpu_rendered) seq_data->gpu_err = GPU_ERR_RENDER_ERR; } else seq_data->gpu_err = GPU_ERR_INSUFFICIENT; } if(!gpu_rendered) { ProcessData p_data = { in_data, float_world->data, float_world->rowbytes, float_world->width, seq_data->context }; err = iterate_generic(float_world->height, &p_data, Process_Iterate); } } // copy back to non-float world and dispose if(temp_world) { if(!err && (format == PrPixelFormat_BGRA_4444_8u || format == PrPixelFormat_BGRA_4444_32f_Linear || format == PrPixelFormat_BGRA_4444_32f)) { SwapData s_data = { in_data, float_world->data, float_world->rowbytes, float_world->width }; err = iterate_generic(float_world->height, &s_data, Swap_Iterate); } if(!err) { IterateData i_data = { in_data, float_world->data, float_world->rowbytes, output->data, output->rowbytes, output->width * 4 }; if(format == PF_PixelFormat_ARGB32 || format == PrPixelFormat_BGRA_4444_8u) { err = iterate_generic(output->height, &i_data, CopyWorld_Iterate); } else if(format == PF_PixelFormat_ARGB64) { err = iterate_generic(output->height, &i_data, CopyWorld_Iterate); } else if(format == PF_PixelFormat_ARGB128 || format == PrPixelFormat_BGRA_4444_32f || format == PrPixelFormat_BGRA_4444_32f_Linear) { err = iterate_generic(output->height, &i_data, CopyWorld_Iterate); } } PF_DISPOSE_HANDLE(temp_worldH); } PF_UNLOCK_HANDLE(OCIO_data->u.arb_d.value); PF_UNLOCK_HANDLE(in_data->sequence_data); if(seq_data->gpu_err == GPU_ERR_INSUFFICIENT) { suites.AdvAppSuite2()->PF_AppendInfoText("OpenColorIO: GPU Insufficient"); } else if(seq_data->gpu_err == GPU_ERR_RENDER_ERR) { suites.AdvAppSuite2()->PF_AppendInfoText("OpenColorIO: GPU Render Error"); } } } } if(pfS) in_data->pica_basicP->ReleaseSuite(kPFPixelFormatSuite, kPFPixelFormatSuiteVersion1); if(wsP) in_data->pica_basicP->ReleaseSuite(kPFWorldSuite, kPFWorldSuiteVersion2); return err; } static PF_Err SmartRender( PF_InData *in_data, PF_OutData *out_data, PF_SmartRenderExtra *extra) { PF_Err err = PF_Err_NONE, err2 = PF_Err_NONE; PF_EffectWorld *input, *output; PF_ParamDef OCIO_data, OCIO_gpu; // zero-out parameters AEFX_CLR_STRUCT(OCIO_data); AEFX_CLR_STRUCT(OCIO_gpu); // checkout input & output buffers. ERR( extra->cb->checkout_layer_pixels( in_data->effect_ref, OCIO_INPUT, &input) ); ERR( extra->cb->checkout_output( in_data->effect_ref, &output) ); // bail before param checkout if(err) return err; #define PF_CHECKOUT_PARAM_NOW( PARAM, DEST ) \ PF_CHECKOUT_PARAM( in_data, (PARAM), in_data->current_time,\ in_data->time_step, in_data->time_scale, DEST ) // checkout the required params ERR( PF_CHECKOUT_PARAM_NOW( OCIO_DATA, &OCIO_data ) ); ERR( PF_CHECKOUT_PARAM_NOW( OCIO_GPU, &OCIO_gpu ) ); ERR(DoRender( in_data, input, &OCIO_data, &OCIO_gpu, out_data, output)); // Always check in, no matter what the error condition! ERR2( PF_CHECKIN_PARAM(in_data, &OCIO_data ) ); ERR2( PF_CHECKIN_PARAM(in_data, &OCIO_gpu ) ); return err; } static PF_Err Render( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output ) { return DoRender(in_data, ¶ms[OCIO_INPUT]->u.ld, params[OCIO_DATA], params[OCIO_GPU], out_data, output); } static PF_Err GetExternalDependencies( PF_InData *in_data, PF_OutData *out_data, PF_ExtDependenciesExtra *extra) { PF_Err err = PF_Err_NONE; SequenceData *seq_data = (SequenceData *)PF_LOCK_HANDLE(in_data->sequence_data); if(seq_data == NULL) return PF_Err_BAD_CALLBACK_PARAM; std::string dependency; if(seq_data->source == OCIO_SOURCE_ENVIRONMENT) { if(extra->check_type == PF_DepCheckType_ALL_DEPENDENCIES) { dependency = "$OCIO environment variable"; } else if(extra->check_type == PF_DepCheckType_MISSING_DEPENDENCIES) { char *file = std::getenv("OCIO"); if(!file) dependency = "$OCIO environment variable"; } } else if(seq_data->source == OCIO_SOURCE_STANDARD) { if(extra->check_type == PF_DepCheckType_ALL_DEPENDENCIES) { dependency = "OCIO configuration " + std::string(seq_data->path); } else if(extra->check_type == PF_DepCheckType_MISSING_DEPENDENCIES) { std::string path = GetStdConfigPath(seq_data->path); if( path.empty() ) dependency = "OCIO configuration " + std::string(seq_data->path); } } else if(seq_data->source == OCIO_SOURCE_CUSTOM && seq_data->path[0] != '\0') { std::string dir = GetProjectDir(in_data); Path absolute_path(seq_data->path, ""); Path relative_path(seq_data->relative_path, dir); if(extra->check_type == PF_DepCheckType_ALL_DEPENDENCIES) { if( !absolute_path.exists() && relative_path.exists() ) { dependency = relative_path.full_path(); } else dependency = absolute_path.full_path(); } else if(extra->check_type == PF_DepCheckType_MISSING_DEPENDENCIES && !absolute_path.exists() && !relative_path.exists() ) { dependency = absolute_path.full_path(); } } if( !dependency.empty() ) { extra->dependencies_strH = PF_NEW_HANDLE(sizeof(char) * (dependency.size() + 1)); char *p = (char *)PF_LOCK_HANDLE(extra->dependencies_strH); strcpy(p, dependency.c_str()); } PF_UNLOCK_HANDLE(in_data->sequence_data); return err; } DllExport PF_Err PluginMain( PF_Cmd cmd, PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, void *extra) { PF_Err err = PF_Err_NONE; try { switch(cmd) { case PF_Cmd_ABOUT: err = About(in_data,out_data,params,output); break; case PF_Cmd_GLOBAL_SETUP: err = GlobalSetup(in_data,out_data,params,output); break; case PF_Cmd_GLOBAL_SETDOWN: err = GlobalSetdown(in_data,out_data,params,output); break; case PF_Cmd_PARAMS_SETUP: err = ParamsSetup(in_data,out_data,params,output); break; case PF_Cmd_SEQUENCE_SETUP: case PF_Cmd_SEQUENCE_RESETUP: err = SequenceSetup(in_data, out_data, params, output); break; case PF_Cmd_SEQUENCE_FLATTEN: err = SequenceFlatten(in_data, out_data, params, output); break; case PF_Cmd_SEQUENCE_SETDOWN: err = SequenceSetdown(in_data, out_data, params, output); break; case PF_Cmd_SMART_PRE_RENDER: err = PreRender(in_data, out_data, (PF_PreRenderExtra*)extra); break; case PF_Cmd_SMART_RENDER: err = SmartRender(in_data, out_data, (PF_SmartRenderExtra*)extra); break; case PF_Cmd_RENDER: err = Render(in_data, out_data, params, output); break; case PF_Cmd_EVENT: err = HandleEvent(in_data, out_data, params, output, (PF_EventExtra *)extra); break; case PF_Cmd_ARBITRARY_CALLBACK: err = HandleArbitrary(in_data, out_data, params, output, (PF_ArbParamsExtra *)extra); break; case PF_Cmd_GET_EXTERNAL_DEPENDENCIES: err = GetExternalDependencies(in_data, out_data, (PF_ExtDependenciesExtra *)extra); break; } } catch(PF_Err &thrown_err) { err = thrown_err; } catch(...) { err = PF_Err_INTERNAL_STRUCT_DAMAGED; } return err; } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/DrawbotBot.h0000644000175000017500000000677413223553423021754 0ustar mfvmfv/* Copyright (c) 2003-2012 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 _DRAWBOTBOT_H_ #define _DRAWBOTBOT_H_ #include "AEGP_SuiteHandler.h" class DrawbotBot { public: DrawbotBot(struct SPBasicSuite *pica_basicP, PF_ContextH contextH, A_long appl_id); ~DrawbotBot(); void MoveTo(DRAWBOT_PointF32 pos) { _brush_pos = pos; } void MoveTo(float x, float y) { _brush_pos.x = x; _brush_pos.y = y; } void Move(float x = 0, float y = 0) { _brush_pos.x += x; _brush_pos.y += y; } void SetColor(PF_App_ColorType color, float a = 1.f); void SetColor(DRAWBOT_ColorRGBA color) { _brush_color = color; } void SetColor(float r, float g, float b, float a = 1.f) { _brush_color.red = r; _brush_color.green = g; _brush_color.blue = b; _brush_color.alpha = a; } DRAWBOT_PointF32 Pos() const { return _brush_pos; } float FontSize() const { return _font_size; } void DrawLineTo(float x, float y, float brush_size = 0.5f); void DrawRect(float w, float h, float brush_size = 0.5f) const; void PaintRect(float w, float h) const; void PaintTriangle(float w, float h) const; void DrawString(const DRAWBOT_UTF16Char *str, DRAWBOT_TextAlignment align = kDRAWBOT_TextAlignment_Default, DRAWBOT_TextTruncation truncate = kDRAWBOT_TextTruncation_None, float truncation_width = 0.f) const; void DrawString(const char *str, DRAWBOT_TextAlignment align = kDRAWBOT_TextAlignment_Default, DRAWBOT_TextTruncation truncate = kDRAWBOT_TextTruncation_None, float truncation_width = 0.f) const; private: AEGP_SuiteHandler suites; A_long _appl_id; DRAWBOT_SupplierSuiteCurrent *_suiteP; DRAWBOT_DrawRef _drawbot_ref; DRAWBOT_SupplierRef _supplier_ref; DRAWBOT_SurfaceRef _surface_ref; DRAWBOT_PointF32 _brush_pos; DRAWBOT_ColorRGBA _brush_color; float _font_size; }; #endif // _DRAWBOTBOT_H_opencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/0000755000175000017500000000000013223553423020620 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/OpenColorABI.h0000644000175000017500000000751413223553423023214 0ustar mfvmfv/* 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_OCIO_OPENCOLORABI_H #define INCLUDED_OCIO_OPENCOLORABI_H // Makefile configuration options #define OCIO_NAMESPACE OpenColorIO #define OCIO_USE_BOOST_PTR 0 #define OCIO_VERSION "1.0.9" #define OCIO_VERSION_NS v1 /* Version as a single 4-byte hex number, e.g. 0x01050200 == 1.5.2 Use this for numeric comparisons, e.g. #if OCIO_VERSION_HEX >= ... Note: in the case where SOVERSION is overridden at compile-time, this will reflect the original API version number. */ #define OCIO_VERSION_HEX ((1 << 24) | \ (0 << 16) | \ (9 << 8)) // Namespace / version mojo #define OCIO_NAMESPACE_ENTER namespace OCIO_NAMESPACE { namespace OCIO_VERSION_NS #define OCIO_NAMESPACE_EXIT using namespace OCIO_VERSION_NS; } #define OCIO_NAMESPACE_USING using namespace OCIO_NAMESPACE; // shared_ptr / dynamic_pointer_cast #if OCIO_USE_BOOST_PTR #include #define OCIO_SHARED_PTR boost::shared_ptr #define OCIO_DYNAMIC_POINTER_CAST boost::dynamic_pointer_cast #elif __GNUC__ >= 4 #include #define OCIO_SHARED_PTR std::tr1::shared_ptr #define OCIO_DYNAMIC_POINTER_CAST std::tr1::dynamic_pointer_cast #else #error OCIO needs gcc 4 or later to get access to (or specify USE_BOOST_PTR instead) #endif #ifdef OpenColorIO_SHARED // If supported, define OCIOEXPORT, OCIOHIDDEN // (used to choose which symbols to export from OpenColorIO) #if defined __linux__ || __APPLE__ #if __GNUC__ >= 4 #define OCIOEXPORT __attribute__ ((visibility("default"))) #define OCIOHIDDEN __attribute__ ((visibility("hidden"))) #else #define OCIOEXPORT #define OCIOHIDDEN #endif #elif defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) || defined(_MSC_VER) // Windows requires you to export from the main library and then import in any others #if defined OpenColorIO_EXPORTS #define OCIOEXPORT __declspec(dllexport) #else #define OCIOEXPORT __declspec(dllimport) #endif #define OCIOHIDDEN #else // Others platforms not supported atm #define OCIOEXPORT #define OCIOHIDDEN #endif #else #define OCIOEXPORT #define OCIOHIDDEN #endif // Windows defines these troublesome macros that collide with std::limits #if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) || defined(_MSC_VER) #undef min #undef max #endif #endif // INCLUDED_OCIO_OPENCOLORABI_H opencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/aftereffects/0000755000175000017500000000000013223553423023261 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/aftereffects/OpenColorIO_AE.xcodeproj/0000755000175000017500000000000013223553423027752 5ustar mfvmfv././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootrootopencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/aftereffects/OpenColorIO_AE.xcodeproj/project.pbxprojopencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/aftereffects/OpenColorIO_AE.xcodeproj/project.pb0000755000175000017500000006500013223553423031747 0ustar mfvmfv// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 44; objects = { /* Begin PBXBuildFile section */ 2A180A6914801EB90000D11A /* OpenColorIO_AE_MonitorProfileChooser.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A180A6814801EB90000D11A /* OpenColorIO_AE_MonitorProfileChooser.xib */; }; 2A180A6D14801FFA0000D11A /* OpenColorIO_AE_MonitorProfileChooser_Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A180A6B14801FFA0000D11A /* OpenColorIO_AE_MonitorProfileChooser_Controller.m */; }; 2A3BAA7110C0F40600AD32F2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A3BAA7010C0F40600AD32F2 /* Cocoa.framework */; }; 2A4A0AF61554679400D5AEB7 /* ocioicc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A4A0AF41554679400D5AEB7 /* ocioicc.cpp */; }; 2A60CADB1491A51C009D6DBF /* OpenColorIO_AE_GL_Cocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2A60CADA1491A51C009D6DBF /* OpenColorIO_AE_GL_Cocoa.mm */; }; 2A60CB091491A9FF009D6DBF /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A60CB081491A9FF009D6DBF /* AGL.framework */; }; 2A60CB0B1491A9FF009D6DBF /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A60CB0A1491A9FF009D6DBF /* OpenGL.framework */; }; 2AF56B96147A431100F9968C /* OpenColorIO_AE_ArbData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AF56B8F147A431100F9968C /* OpenColorIO_AE_ArbData.cpp */; }; 2AF56B99147A431100F9968C /* OpenColorIO_AE_PiPL.r in Rez */ = {isa = PBXBuildFile; fileRef = 2AF56B92147A431100F9968C /* OpenColorIO_AE_PiPL.r */; }; 2AF56B9A147A431100F9968C /* OpenColorIO_AE_UI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AF56B93147A431100F9968C /* OpenColorIO_AE_UI.cpp */; }; 2AF56B9B147A431100F9968C /* OpenColorIO_AE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AF56B94147A431100F9968C /* OpenColorIO_AE.cpp */; }; 2AF56BA0147A458800F9968C /* AEGP_SuiteHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AF56B9D147A458800F9968C /* AEGP_SuiteHandler.cpp */; }; 2AF56BA1147A458800F9968C /* MissingSuiteError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AF56B9F147A458800F9968C /* MissingSuiteError.cpp */; }; 2AF56C24147A54A300F9968C /* OpenColorIO_AE_Dialogs_Cocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2AF56B90147A431100F9968C /* OpenColorIO_AE_Dialogs_Cocoa.mm */; }; 2AF56D06147AB5C900F9968C /* DrawbotBot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AF56D04147AB5C900F9968C /* DrawbotBot.cpp */; }; 2AF56EE8147AD11200F9968C /* libOpenColorIO.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AF56EE7147AD10E00F9968C /* libOpenColorIO.a */; }; 2AF57004147AE17200F9968C /* libtinyxml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AF56FFB147AE16A00F9968C /* libtinyxml.a */; }; 2AF57005147AE17400F9968C /* libyaml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AF57001147AE16A00F9968C /* libyaml.a */; }; 2AF57B93147C6FE000F9968C /* OpenColorIO_AE_Menu.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AF57B92147C6FE000F9968C /* OpenColorIO_AE_Menu.m */; }; 2AF57D20147C994100F9968C /* OpenColorIO_AE_Context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AF57D1F147C994100F9968C /* OpenColorIO_AE_Context.cpp */; }; 2AF999CB147E1DD200FEB83B /* liblcms.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AF999C8147E1DCA00FEB83B /* liblcms.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 2AF56EE6147AD10E00F9968C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2AF56EE2147AD10E00F9968C /* OpenColorIO.xcodeproj */; proxyType = 2; remoteGlobalIDString = 2ACF567114776A0A00991ED5; remoteInfo = OpenColorIO; }; 2AF56FFA147AE16A00F9968C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2AF56FF0147AE16A00F9968C /* tinyxml.xcodeproj */; proxyType = 2; remoteGlobalIDString = 2ACF55441477682B00991ED5; remoteInfo = tinyxml; }; 2AF57000147AE16A00F9968C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2AF56FF3147AE16A00F9968C /* yaml.xcodeproj */; proxyType = 2; remoteGlobalIDString = 2ACF559C1477692300991ED5; remoteInfo = yaml; }; 2AF57012147AE18600F9968C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2AF56FF0147AE16A00F9968C /* tinyxml.xcodeproj */; proxyType = 1; remoteGlobalIDString = 2ACF55431477682B00991ED5; remoteInfo = tinyxml; }; 2AF57014147AE18600F9968C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2AF56FF3147AE16A00F9968C /* yaml.xcodeproj */; proxyType = 1; remoteGlobalIDString = 2ACF559B1477692300991ED5; remoteInfo = yaml; }; 2AF57016147AE18600F9968C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2AF56EE2147AD10E00F9968C /* OpenColorIO.xcodeproj */; proxyType = 1; remoteGlobalIDString = 2ACF567014776A0A00991ED5; remoteInfo = OpenColorIO; }; 2AF999C7147E1DCA00FEB83B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2AF999C0147E1DCA00FEB83B /* lcms.xcodeproj */; proxyType = 2; remoteGlobalIDString = 2ACF9E56147824F500991ED5; remoteInfo = lcms; }; 2AF999CC147E1DDB00FEB83B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2AF999C0147E1DCA00FEB83B /* lcms.xcodeproj */; proxyType = 1; remoteGlobalIDString = 2ACF9E55147824F500991ED5; remoteInfo = lcms; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 2A180A6814801EB90000D11A /* OpenColorIO_AE_MonitorProfileChooser.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = OpenColorIO_AE_MonitorProfileChooser.xib; path = ../../mac/OpenColorIO_AE_MonitorProfileChooser.xib; sourceTree = ""; }; 2A180A6B14801FFA0000D11A /* OpenColorIO_AE_MonitorProfileChooser_Controller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OpenColorIO_AE_MonitorProfileChooser_Controller.m; path = ../../mac/OpenColorIO_AE_MonitorProfileChooser_Controller.m; sourceTree = ""; usesTabs = 0; }; 2A180A6C14801FFA0000D11A /* OpenColorIO_AE_MonitorProfileChooser_Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_AE_MonitorProfileChooser_Controller.h; path = ../../mac/OpenColorIO_AE_MonitorProfileChooser_Controller.h; sourceTree = ""; usesTabs = 0; }; 2A3BAA7010C0F40600AD32F2 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 2A4A0AF41554679400D5AEB7 /* ocioicc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ocioicc.cpp; path = ../../../apps/ociobakelut/ocioicc.cpp; sourceTree = SOURCE_ROOT; }; 2A4A0AF51554679400D5AEB7 /* ocioicc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ocioicc.h; path = ../../../apps/ociobakelut/ocioicc.h; sourceTree = SOURCE_ROOT; }; 2A60CAD91491A506009D6DBF /* OpenColorIO_AE_GL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_AE_GL.h; path = ../../OpenColorIO_AE_GL.h; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2A60CADA1491A51C009D6DBF /* OpenColorIO_AE_GL_Cocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = OpenColorIO_AE_GL_Cocoa.mm; path = ../../mac/OpenColorIO_AE_GL_Cocoa.mm; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2A60CB081491A9FF009D6DBF /* AGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AGL.framework; path = System/Library/Frameworks/AGL.framework; sourceTree = SDKROOT; }; 2A60CB0A1491A9FF009D6DBF /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; 2AF56B8F147A431100F9968C /* OpenColorIO_AE_ArbData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenColorIO_AE_ArbData.cpp; path = ../../OpenColorIO_AE_ArbData.cpp; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF56B90147A431100F9968C /* OpenColorIO_AE_Dialogs_Cocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = OpenColorIO_AE_Dialogs_Cocoa.mm; path = ../../mac/OpenColorIO_AE_Dialogs_Cocoa.mm; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF56B92147A431100F9968C /* OpenColorIO_AE_PiPL.r */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.rez; name = OpenColorIO_AE_PiPL.r; path = ../../OpenColorIO_AE_PiPL.r; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF56B93147A431100F9968C /* OpenColorIO_AE_UI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenColorIO_AE_UI.cpp; path = ../../OpenColorIO_AE_UI.cpp; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF56B94147A431100F9968C /* OpenColorIO_AE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenColorIO_AE.cpp; path = ../../OpenColorIO_AE.cpp; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF56B95147A431100F9968C /* OpenColorIO_AE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_AE.h; path = ../../OpenColorIO_AE.h; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF56B9D147A458800F9968C /* AEGP_SuiteHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AEGP_SuiteHandler.cpp; path = "../../../../ext/Adobe After Effects CS5 SDK/Examples/Util/AEGP_SuiteHandler.cpp"; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF56B9E147A458800F9968C /* AEGP_SuiteHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AEGP_SuiteHandler.h; path = "../../../../ext/Adobe After Effects CS5 SDK/Examples/Util/AEGP_SuiteHandler.h"; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF56B9F147A458800F9968C /* MissingSuiteError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MissingSuiteError.cpp; path = "../../../../ext/Adobe After Effects CS5 SDK/Examples/Util/MissingSuiteError.cpp"; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF56D04147AB5C900F9968C /* DrawbotBot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DrawbotBot.cpp; path = ../../DrawbotBot.cpp; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF56D05147AB5C900F9968C /* DrawbotBot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DrawbotBot.h; path = ../../DrawbotBot.h; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF56EE2147AD10E00F9968C /* OpenColorIO.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OpenColorIO.xcodeproj; path = ../OpenColorIO.xcodeproj; sourceTree = SOURCE_ROOT; }; 2AF56FF0147AE16A00F9968C /* tinyxml.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = tinyxml.xcodeproj; path = ../ext/tinyxml.xcodeproj; sourceTree = SOURCE_ROOT; }; 2AF56FF3147AE16A00F9968C /* yaml.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = yaml.xcodeproj; path = ../ext/yaml.xcodeproj; sourceTree = SOURCE_ROOT; }; 2AF57171147B36F300F9968C /* OpenColorIO_AE_Dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_AE_Dialogs.h; path = ../../OpenColorIO_AE_Dialogs.h; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF57B91147C6FE000F9968C /* OpenColorIO_AE_Menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_AE_Menu.h; path = ../../mac/OpenColorIO_AE_Menu.h; sourceTree = ""; usesTabs = 0; }; 2AF57B92147C6FE000F9968C /* OpenColorIO_AE_Menu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OpenColorIO_AE_Menu.m; path = ../../mac/OpenColorIO_AE_Menu.m; sourceTree = ""; usesTabs = 0; }; 2AF57D1E147C994100F9968C /* OpenColorIO_AE_Context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_AE_Context.h; path = ../../OpenColorIO_AE_Context.h; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF57D1F147C994100F9968C /* OpenColorIO_AE_Context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenColorIO_AE_Context.cpp; path = ../../OpenColorIO_AE_Context.cpp; sourceTree = SOURCE_ROOT; usesTabs = 0; }; 2AF999C0147E1DCA00FEB83B /* lcms.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = lcms.xcodeproj; path = ../ext/lcms.xcodeproj; sourceTree = SOURCE_ROOT; }; C4E618CC095A3CE80012CA3F /* OpenColorIO.plugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OpenColorIO.plugin; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ C4E618CA095A3CE80012CA3F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 2A3BAA7110C0F40600AD32F2 /* Cocoa.framework in Frameworks */, 2AF56EE8147AD11200F9968C /* libOpenColorIO.a in Frameworks */, 2AF57004147AE17200F9968C /* libtinyxml.a in Frameworks */, 2AF57005147AE17400F9968C /* libyaml.a in Frameworks */, 2AF999CB147E1DD200FEB83B /* liblcms.a in Frameworks */, 2A60CB091491A9FF009D6DBF /* AGL.framework in Frameworks */, 2A60CB0B1491A9FF009D6DBF /* OpenGL.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 2AF56EE3147AD10E00F9968C /* Products */ = { isa = PBXGroup; children = ( 2AF56EE7147AD10E00F9968C /* libOpenColorIO.a */, ); name = Products; sourceTree = ""; }; 2AF56FF1147AE16A00F9968C /* Products */ = { isa = PBXGroup; children = ( 2AF56FFB147AE16A00F9968C /* libtinyxml.a */, ); name = Products; sourceTree = ""; }; 2AF56FF4147AE16A00F9968C /* Products */ = { isa = PBXGroup; children = ( 2AF57001147AE16A00F9968C /* libyaml.a */, ); name = Products; sourceTree = ""; }; 2AF999C1147E1DCA00FEB83B /* Products */ = { isa = PBXGroup; children = ( 2AF999C8147E1DCA00FEB83B /* liblcms.a */, ); name = Products; sourceTree = ""; }; C4E6187C095A3C800012CA3F = { isa = PBXGroup; children = ( 2AF56B95147A431100F9968C /* OpenColorIO_AE.h */, 2AF56B94147A431100F9968C /* OpenColorIO_AE.cpp */, 2AF57D1E147C994100F9968C /* OpenColorIO_AE_Context.h */, 2AF57D1F147C994100F9968C /* OpenColorIO_AE_Context.cpp */, 2AF56B8F147A431100F9968C /* OpenColorIO_AE_ArbData.cpp */, 2AF56B93147A431100F9968C /* OpenColorIO_AE_UI.cpp */, 2A60CAD91491A506009D6DBF /* OpenColorIO_AE_GL.h */, 2A60CADA1491A51C009D6DBF /* OpenColorIO_AE_GL_Cocoa.mm */, 2AF57171147B36F300F9968C /* OpenColorIO_AE_Dialogs.h */, 2AF56B90147A431100F9968C /* OpenColorIO_AE_Dialogs_Cocoa.mm */, 2AF57B91147C6FE000F9968C /* OpenColorIO_AE_Menu.h */, 2AF57B92147C6FE000F9968C /* OpenColorIO_AE_Menu.m */, 2AF56B92147A431100F9968C /* OpenColorIO_AE_PiPL.r */, 2AF56B9E147A458800F9968C /* AEGP_SuiteHandler.h */, 2AF56B9D147A458800F9968C /* AEGP_SuiteHandler.cpp */, 2AF56B9F147A458800F9968C /* MissingSuiteError.cpp */, 2AF56D05147AB5C900F9968C /* DrawbotBot.h */, 2AF56D04147AB5C900F9968C /* DrawbotBot.cpp */, 2A4A0AF51554679400D5AEB7 /* ocioicc.h */, 2A4A0AF41554679400D5AEB7 /* ocioicc.cpp */, 2A180A6814801EB90000D11A /* OpenColorIO_AE_MonitorProfileChooser.xib */, 2A180A6C14801FFA0000D11A /* OpenColorIO_AE_MonitorProfileChooser_Controller.h */, 2A180A6B14801FFA0000D11A /* OpenColorIO_AE_MonitorProfileChooser_Controller.m */, 2AF56EE2147AD10E00F9968C /* OpenColorIO.xcodeproj */, 2AF56FF0147AE16A00F9968C /* tinyxml.xcodeproj */, 2AF56FF3147AE16A00F9968C /* yaml.xcodeproj */, 2AF999C0147E1DCA00FEB83B /* lcms.xcodeproj */, C4E6188C095A3C800012CA3F /* Products */, 2A3BAA7010C0F40600AD32F2 /* Cocoa.framework */, 2A60CB081491A9FF009D6DBF /* AGL.framework */, 2A60CB0A1491A9FF009D6DBF /* OpenGL.framework */, ); comments = "SDK Backwards is some pretty rudimentary audio processing, but the flags and params are handled in an appropriate manner."; sourceTree = ""; }; C4E6188C095A3C800012CA3F /* Products */ = { isa = PBXGroup; children = ( C4E618CC095A3CE80012CA3F /* OpenColorIO.plugin */, ); name = Products; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ C4E618CB095A3CE80012CA3F /* OpenColorIO */ = { isa = PBXNativeTarget; buildConfigurationList = C4E618CE095A3CE90012CA3F /* Build configuration list for PBXNativeTarget "OpenColorIO" */; buildPhases = ( C4E618C8095A3CE80012CA3F /* Resources */, C4E618C9095A3CE80012CA3F /* Sources */, C4E618CA095A3CE80012CA3F /* Frameworks */, C4E618EA095A3E040012CA3F /* Rez */, ); buildRules = ( ); dependencies = ( 2AF57013147AE18600F9968C /* PBXTargetDependency */, 2AF57015147AE18600F9968C /* PBXTargetDependency */, 2AF57017147AE18600F9968C /* PBXTargetDependency */, 2AF999CD147E1DDB00FEB83B /* PBXTargetDependency */, ); name = OpenColorIO; productName = SDK_Backwards.plugin; productReference = C4E618CC095A3CE80012CA3F /* OpenColorIO.plugin */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ C4E6187E095A3C800012CA3F /* Project object */ = { isa = PBXProject; buildConfigurationList = C4E6187F095A3C800012CA3F /* Build configuration list for PBXProject "OpenColorIO_AE" */; compatibilityVersion = "Xcode 3.0"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( English, Japanese, French, German, ); mainGroup = C4E6187C095A3C800012CA3F; productRefGroup = C4E6188C095A3C800012CA3F /* Products */; projectDirPath = ""; projectReferences = ( { ProductGroup = 2AF999C1147E1DCA00FEB83B /* Products */; ProjectRef = 2AF999C0147E1DCA00FEB83B /* lcms.xcodeproj */; }, { ProductGroup = 2AF56EE3147AD10E00F9968C /* Products */; ProjectRef = 2AF56EE2147AD10E00F9968C /* OpenColorIO.xcodeproj */; }, { ProductGroup = 2AF56FF1147AE16A00F9968C /* Products */; ProjectRef = 2AF56FF0147AE16A00F9968C /* tinyxml.xcodeproj */; }, { ProductGroup = 2AF56FF4147AE16A00F9968C /* Products */; ProjectRef = 2AF56FF3147AE16A00F9968C /* yaml.xcodeproj */; }, ); projectRoot = ""; targets = ( C4E618CB095A3CE80012CA3F /* OpenColorIO */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ 2AF56EE7147AD10E00F9968C /* libOpenColorIO.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libOpenColorIO.a; remoteRef = 2AF56EE6147AD10E00F9968C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; 2AF56FFB147AE16A00F9968C /* libtinyxml.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libtinyxml.a; remoteRef = 2AF56FFA147AE16A00F9968C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; 2AF57001147AE16A00F9968C /* libyaml.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libyaml.a; remoteRef = 2AF57000147AE16A00F9968C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; 2AF999C8147E1DCA00FEB83B /* liblcms.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = liblcms.a; remoteRef = 2AF999C7147E1DCA00FEB83B /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ C4E618C8095A3CE80012CA3F /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 2A180A6914801EB90000D11A /* OpenColorIO_AE_MonitorProfileChooser.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ C4E618EA095A3E040012CA3F /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( 2AF56B99147A431100F9968C /* OpenColorIO_AE_PiPL.r in Rez */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXRezBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ C4E618C9095A3CE80012CA3F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 2AF56B96147A431100F9968C /* OpenColorIO_AE_ArbData.cpp in Sources */, 2AF56B9A147A431100F9968C /* OpenColorIO_AE_UI.cpp in Sources */, 2AF56B9B147A431100F9968C /* OpenColorIO_AE.cpp in Sources */, 2AF56BA0147A458800F9968C /* AEGP_SuiteHandler.cpp in Sources */, 2AF56BA1147A458800F9968C /* MissingSuiteError.cpp in Sources */, 2AF56C24147A54A300F9968C /* OpenColorIO_AE_Dialogs_Cocoa.mm in Sources */, 2AF56D06147AB5C900F9968C /* DrawbotBot.cpp in Sources */, 2AF57B93147C6FE000F9968C /* OpenColorIO_AE_Menu.m in Sources */, 2AF57D20147C994100F9968C /* OpenColorIO_AE_Context.cpp in Sources */, 2A180A6D14801FFA0000D11A /* OpenColorIO_AE_MonitorProfileChooser_Controller.m in Sources */, 2A60CADB1491A51C009D6DBF /* OpenColorIO_AE_GL_Cocoa.mm in Sources */, 2A4A0AF61554679400D5AEB7 /* ocioicc.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 2AF57013147AE18600F9968C /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = tinyxml; targetProxy = 2AF57012147AE18600F9968C /* PBXContainerItemProxy */; }; 2AF57015147AE18600F9968C /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = yaml; targetProxy = 2AF57014147AE18600F9968C /* PBXContainerItemProxy */; }; 2AF57017147AE18600F9968C /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = OpenColorIO; targetProxy = 2AF57016147AE18600F9968C /* PBXContainerItemProxy */; }; 2AF999CD147E1DDB00FEB83B /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = lcms; targetProxy = 2AF999CC147E1DDB00FEB83B /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 2A1BAC2310C3C82A00244D12 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { AE_SDK = "\"../../../../ext/Adobe After Effects CS5 SDK\""; "AE_SDK[arch=i386]" = "\"../../../../ext/Adobe After Effects CS3 SDK\""; "AE_SDK[arch=ppc]" = "\"../../../../ext/Adobe After Effects CS3 SDK\""; ARCHS = x86_64; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = ""; GCC_OPTIMIZATION_LEVEL = 3; GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; HEADER_SEARCH_PATHS = ( ../, "$(AE_SDK)/Examples/Headers", "$(AE_SDK)/Examples/Util", "$(AE_SDK)/Examples/Headers/SP", "$(AE_SDK)/Examples/Resources", ../../../../export, ../../../../src/core, ../../../../ext/tinyxml, "../../../../ext/yaml-cpp/include", "../../../../ext/lcms2-2.1/include", ); REZ_PREPROCESSOR_DEFINITIONS = __MACH__; REZ_SEARCH_PATHS = "$(SDK_PATH)/Developer/Headers/FlatCarbon"; SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk"; }; name = Release; }; 2A1BAC2410C3C82A00244D12 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SDKROOT)/System/Library/Frameworks/Carbon.framework/Headers/Carbon.h"; GENERATE_PKGINFO_FILE = YES; INFOPLIST_FILE = "../../mac/OpenColorIO_AE.plugin-Info.plist"; INSTALL_PATH = "$(HOME)/Library/Bundles"; LINK_WITH_STANDARD_LIBRARIES = YES; PREBINDING = NO; PRODUCT_NAME = OpenColorIO; WRAPPER_EXTENSION = plugin; ZERO_LINK = NO; }; name = Release; }; C4E61880095A3C800012CA3F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { AE_SDK = "\"../../../../ext/Adobe After Effects CS5 SDK\""; "AE_SDK[arch=i386]" = "\"../../../../ext/Adobe After Effects CS3 SDK\""; "AE_SDK[arch=ppc]" = "\"../../../../ext/Adobe After Effects CS3 SDK\""; ARCHS = x86_64; COPY_PHASE_STRIP = NO; GCC_MODEL_TUNING = ""; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; HEADER_SEARCH_PATHS = ( ../, "$(AE_SDK)/Examples/Headers", "$(AE_SDK)/Examples/Util", "$(AE_SDK)/Examples/Headers/SP", "$(AE_SDK)/Examples/Resources", ../../../../export, ../../../../src/core, ../../../../ext/tinyxml, "../../../../ext/yaml-cpp/include", "../../../../ext/lcms2-2.1/include", ); REZ_PREPROCESSOR_DEFINITIONS = __MACH__; REZ_SEARCH_PATHS = "$(SDK_PATH)/Developer/Headers/FlatCarbon"; SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk"; STRIP_INSTALLED_PRODUCT = NO; }; name = Debug; }; C4E618CF095A3CE90012CA3F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SDKROOT)/System/Library/Frameworks/Carbon.framework/Headers/Carbon.h"; GENERATE_PKGINFO_FILE = YES; INFOPLIST_FILE = "../../mac/OpenColorIO_AE.plugin-Info.plist"; INSTALL_PATH = "$(HOME)/Library/Bundles"; LINK_WITH_STANDARD_LIBRARIES = YES; PREBINDING = NO; PRODUCT_NAME = OpenColorIO; WRAPPER_EXTENSION = plugin; ZERO_LINK = NO; }; name = Debug; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ C4E6187F095A3C800012CA3F /* Build configuration list for PBXProject "OpenColorIO_AE" */ = { isa = XCConfigurationList; buildConfigurations = ( C4E61880095A3C800012CA3F /* Debug */, 2A1BAC2310C3C82A00244D12 /* Release */, ); defaultConfigurationIsVisible = 1; defaultConfigurationName = Debug; }; C4E618CE095A3CE90012CA3F /* Build configuration list for PBXNativeTarget "OpenColorIO" */ = { isa = XCConfigurationList; buildConfigurations = ( C4E618CF095A3CE90012CA3F /* Debug */, 2A1BAC2410C3C82A00244D12 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ }; rootObject = C4E6187E095A3C800012CA3F /* Project object */; } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/ext/0000755000175000017500000000000013223553423021420 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/ext/tinyxml.xcodeproj/0000755000175000017500000000000013223553423025120 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/ext/tinyxml.xcodeproj/project.pbxproj0000644000175000017500000002134013223553423030174 0ustar mfvmfv// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 45; objects = { /* Begin PBXBuildFile section */ 2ACF55501477685000991ED5 /* tinystr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF554A1477685000991ED5 /* tinystr.cpp */; }; 2ACF55511477685000991ED5 /* tinystr.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF554B1477685000991ED5 /* tinystr.h */; }; 2ACF55521477685000991ED5 /* tinyxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF554C1477685000991ED5 /* tinyxml.cpp */; }; 2ACF55531477685000991ED5 /* tinyxml.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF554D1477685000991ED5 /* tinyxml.h */; }; 2ACF55541477685000991ED5 /* tinyxmlerror.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF554E1477685000991ED5 /* tinyxmlerror.cpp */; }; 2ACF55551477685000991ED5 /* tinyxmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF554F1477685000991ED5 /* tinyxmlparser.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 2ACF55441477682B00991ED5 /* libtinyxml.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtinyxml.a; sourceTree = BUILT_PRODUCTS_DIR; }; 2ACF554A1477685000991ED5 /* tinystr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinystr.cpp; sourceTree = ""; }; 2ACF554B1477685000991ED5 /* tinystr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinystr.h; sourceTree = ""; }; 2ACF554C1477685000991ED5 /* tinyxml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxml.cpp; sourceTree = ""; }; 2ACF554D1477685000991ED5 /* tinyxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyxml.h; sourceTree = ""; }; 2ACF554E1477685000991ED5 /* tinyxmlerror.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxmlerror.cpp; sourceTree = ""; }; 2ACF554F1477685000991ED5 /* tinyxmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxmlparser.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 2ACF55421477682B00991ED5 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 034768DDFF38A45A11DB9C8B /* Products */ = { isa = PBXGroup; children = ( 2ACF55441477682B00991ED5 /* libtinyxml.a */, ); name = Products; sourceTree = ""; }; 0867D691FE84028FC02AAC07 /* tinyxml */ = { isa = PBXGroup; children = ( 2ACF55481477685000991ED5 /* tinyxml */, 034768DDFF38A45A11DB9C8B /* Products */, ); name = tinyxml; sourceTree = ""; }; 2ACF55481477685000991ED5 /* tinyxml */ = { isa = PBXGroup; children = ( 2ACF554A1477685000991ED5 /* tinystr.cpp */, 2ACF554B1477685000991ED5 /* tinystr.h */, 2ACF554C1477685000991ED5 /* tinyxml.cpp */, 2ACF554D1477685000991ED5 /* tinyxml.h */, 2ACF554E1477685000991ED5 /* tinyxmlerror.cpp */, 2ACF554F1477685000991ED5 /* tinyxmlparser.cpp */, ); name = tinyxml; path = ../../../../ext/tinyxml; sourceTree = SOURCE_ROOT; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 2ACF55401477682B00991ED5 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 2ACF55511477685000991ED5 /* tinystr.h in Headers */, 2ACF55531477685000991ED5 /* tinyxml.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 2ACF55431477682B00991ED5 /* tinyxml */ = { isa = PBXNativeTarget; buildConfigurationList = 2ACF55471477683C00991ED5 /* Build configuration list for PBXNativeTarget "tinyxml" */; buildPhases = ( 2AF569961479999900F9968C /* Unpack tinyxml */, 2ACF55401477682B00991ED5 /* Headers */, 2ACF55411477682B00991ED5 /* Sources */, 2ACF55421477682B00991ED5 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = tinyxml; productName = tinyxml; productReference = 2ACF55441477682B00991ED5 /* libtinyxml.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB916408733D950010E9CD /* Build configuration list for PBXProject "tinyxml" */; compatibilityVersion = "Xcode 3.1"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 0867D691FE84028FC02AAC07 /* tinyxml */; productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 2ACF55431477682B00991ED5 /* tinyxml */, ); }; /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ 2AF569961479999900F9968C /* Unpack tinyxml */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(SRCROOT)/../../../../ext/tinyxml_2_6_1.tar.gz", "$(SRCROOT)/../../../../ext/tinyxml_2_6_1.patch", ); name = "Unpack tinyxml"; outputPaths = ( "$(SRCROOT)/../../../../ext/tinyxml", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "cd $SRCROOT/../../../../ext\n\nif [ ! -d tinyxml ]\nthen\n\ttar -xzf tinyxml_2_6_1.tar.gz\n\tpatch -p0 < tinyxml_2_6_1.patch\nfi\n"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 2ACF55411477682B00991ED5 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 2ACF55501477685000991ED5 /* tinystr.cpp in Sources */, 2ACF55521477685000991ED5 /* tinyxml.cpp in Sources */, 2ACF55541477685000991ED5 /* tinyxmlerror.cpp in Sources */, 2ACF55551477685000991ED5 /* tinyxmlparser.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 1DEB916508733D950010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = TIXML_USE_STL; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; SDKROOT = macosx10.5; }; name = Debug; }; 1DEB916608733D950010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PREPROCESSOR_DEFINITIONS = ( NDEBUG, TIXML_USE_STL, ); GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; SDKROOT = macosx10.5; }; name = Release; }; 2ACF55451477682B00991ED5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; INSTALL_PATH = /usr/local/lib; PREBINDING = NO; PRODUCT_NAME = tinyxml; }; name = Debug; }; 2ACF55461477682B00991ED5 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; INSTALL_PATH = /usr/local/lib; PREBINDING = NO; PRODUCT_NAME = tinyxml; ZERO_LINK = NO; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1DEB916408733D950010E9CD /* Build configuration list for PBXProject "tinyxml" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB916508733D950010E9CD /* Debug */, 1DEB916608733D950010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 2ACF55471477683C00991ED5 /* Build configuration list for PBXNativeTarget "tinyxml" */ = { isa = XCConfigurationList; buildConfigurations = ( 2ACF55451477682B00991ED5 /* Debug */, 2ACF55461477682B00991ED5 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 0867D690FE84028FC02AAC07 /* Project object */; } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/ext/lcms.xcodeproj/0000755000175000017500000000000013223553423024352 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/ext/lcms.xcodeproj/project.pbxproj0000644000175000017500000004207613223553423027437 0ustar mfvmfv// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 45; objects = { /* Begin PBXBuildFile section */ 2ACF9F2C1478251500991ED5 /* lcms2.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF9E6D1478251500991ED5 /* lcms2.h */; }; 2ACF9F2D1478251500991ED5 /* lcms2_plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF9E6E1478251500991ED5 /* lcms2_plugin.h */; }; 2ACF9F311478251500991ED5 /* cmscam02.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ECE1478251500991ED5 /* cmscam02.c */; }; 2ACF9F321478251500991ED5 /* cmscgats.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ECF1478251500991ED5 /* cmscgats.c */; }; 2ACF9F331478251500991ED5 /* cmscnvrt.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ED01478251500991ED5 /* cmscnvrt.c */; }; 2ACF9F341478251500991ED5 /* cmserr.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ED11478251500991ED5 /* cmserr.c */; }; 2ACF9F351478251500991ED5 /* cmsgamma.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ED21478251500991ED5 /* cmsgamma.c */; }; 2ACF9F361478251500991ED5 /* cmsgmt.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ED31478251500991ED5 /* cmsgmt.c */; }; 2ACF9F371478251500991ED5 /* cmsintrp.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ED41478251500991ED5 /* cmsintrp.c */; }; 2ACF9F381478251500991ED5 /* cmsio0.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ED51478251500991ED5 /* cmsio0.c */; }; 2ACF9F391478251500991ED5 /* cmsio1.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ED61478251500991ED5 /* cmsio1.c */; }; 2ACF9F3A1478251500991ED5 /* cmslut.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ED71478251500991ED5 /* cmslut.c */; }; 2ACF9F3B1478251500991ED5 /* cmsmd5.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ED81478251500991ED5 /* cmsmd5.c */; }; 2ACF9F3C1478251500991ED5 /* cmsmtrx.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9ED91478251500991ED5 /* cmsmtrx.c */; }; 2ACF9F3D1478251500991ED5 /* cmsnamed.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EDA1478251500991ED5 /* cmsnamed.c */; }; 2ACF9F3E1478251500991ED5 /* cmsopt.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EDB1478251500991ED5 /* cmsopt.c */; }; 2ACF9F3F1478251500991ED5 /* cmspack.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EDC1478251500991ED5 /* cmspack.c */; }; 2ACF9F401478251500991ED5 /* cmspcs.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EDD1478251500991ED5 /* cmspcs.c */; }; 2ACF9F411478251500991ED5 /* cmsplugin.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EDE1478251500991ED5 /* cmsplugin.c */; }; 2ACF9F421478251500991ED5 /* cmsps2.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EDF1478251500991ED5 /* cmsps2.c */; }; 2ACF9F431478251500991ED5 /* cmssamp.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EE01478251500991ED5 /* cmssamp.c */; }; 2ACF9F441478251500991ED5 /* cmssm.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EE11478251500991ED5 /* cmssm.c */; }; 2ACF9F451478251500991ED5 /* cmstypes.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EE21478251500991ED5 /* cmstypes.c */; }; 2ACF9F461478251500991ED5 /* cmsvirt.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EE31478251500991ED5 /* cmsvirt.c */; }; 2ACF9F471478251500991ED5 /* cmswtpnt.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EE41478251500991ED5 /* cmswtpnt.c */; }; 2ACF9F481478251500991ED5 /* cmsxform.c in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF9EE51478251500991ED5 /* cmsxform.c */; }; 2ACF9F491478251500991ED5 /* lcms2_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF9EE71478251500991ED5 /* lcms2_internal.h */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 2ACF9E56147824F500991ED5 /* liblcms.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liblcms.a; sourceTree = BUILT_PRODUCTS_DIR; }; 2ACF9E6D1478251500991ED5 /* lcms2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcms2.h; sourceTree = ""; }; 2ACF9E6E1478251500991ED5 /* lcms2_plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcms2_plugin.h; sourceTree = ""; }; 2ACF9ECE1478251500991ED5 /* cmscam02.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmscam02.c; sourceTree = ""; }; 2ACF9ECF1478251500991ED5 /* cmscgats.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmscgats.c; sourceTree = ""; }; 2ACF9ED01478251500991ED5 /* cmscnvrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmscnvrt.c; sourceTree = ""; }; 2ACF9ED11478251500991ED5 /* cmserr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmserr.c; sourceTree = ""; }; 2ACF9ED21478251500991ED5 /* cmsgamma.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsgamma.c; sourceTree = ""; }; 2ACF9ED31478251500991ED5 /* cmsgmt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsgmt.c; sourceTree = ""; }; 2ACF9ED41478251500991ED5 /* cmsintrp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsintrp.c; sourceTree = ""; }; 2ACF9ED51478251500991ED5 /* cmsio0.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsio0.c; sourceTree = ""; }; 2ACF9ED61478251500991ED5 /* cmsio1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsio1.c; sourceTree = ""; }; 2ACF9ED71478251500991ED5 /* cmslut.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmslut.c; sourceTree = ""; }; 2ACF9ED81478251500991ED5 /* cmsmd5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsmd5.c; sourceTree = ""; }; 2ACF9ED91478251500991ED5 /* cmsmtrx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsmtrx.c; sourceTree = ""; }; 2ACF9EDA1478251500991ED5 /* cmsnamed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsnamed.c; sourceTree = ""; }; 2ACF9EDB1478251500991ED5 /* cmsopt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsopt.c; sourceTree = ""; }; 2ACF9EDC1478251500991ED5 /* cmspack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmspack.c; sourceTree = ""; }; 2ACF9EDD1478251500991ED5 /* cmspcs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmspcs.c; sourceTree = ""; }; 2ACF9EDE1478251500991ED5 /* cmsplugin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsplugin.c; sourceTree = ""; }; 2ACF9EDF1478251500991ED5 /* cmsps2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsps2.c; sourceTree = ""; }; 2ACF9EE01478251500991ED5 /* cmssamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmssamp.c; sourceTree = ""; }; 2ACF9EE11478251500991ED5 /* cmssm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmssm.c; sourceTree = ""; }; 2ACF9EE21478251500991ED5 /* cmstypes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmstypes.c; sourceTree = ""; }; 2ACF9EE31478251500991ED5 /* cmsvirt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsvirt.c; sourceTree = ""; }; 2ACF9EE41478251500991ED5 /* cmswtpnt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmswtpnt.c; sourceTree = ""; }; 2ACF9EE51478251500991ED5 /* cmsxform.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmsxform.c; sourceTree = ""; }; 2ACF9EE71478251500991ED5 /* lcms2_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcms2_internal.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 2ACF9E54147824F500991ED5 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 034768DDFF38A45A11DB9C8B /* Products */ = { isa = PBXGroup; children = ( 2ACF9E56147824F500991ED5 /* liblcms.a */, ); name = Products; sourceTree = ""; }; 0867D691FE84028FC02AAC07 /* lcms */ = { isa = PBXGroup; children = ( 2ACF9E5A1478251500991ED5 /* lcms2-2.1 */, 034768DDFF38A45A11DB9C8B /* Products */, ); name = lcms; sourceTree = ""; }; 2ACF9E5A1478251500991ED5 /* lcms2-2.1 */ = { isa = PBXGroup; children = ( 2ACF9E6C1478251500991ED5 /* include */, 2ACF9ECD1478251500991ED5 /* src */, ); name = "lcms2-2.1"; path = "../../../../ext/lcms2-2.1"; sourceTree = SOURCE_ROOT; }; 2ACF9E6C1478251500991ED5 /* include */ = { isa = PBXGroup; children = ( 2ACF9E6D1478251500991ED5 /* lcms2.h */, 2ACF9E6E1478251500991ED5 /* lcms2_plugin.h */, ); path = include; sourceTree = ""; }; 2ACF9ECD1478251500991ED5 /* src */ = { isa = PBXGroup; children = ( 2ACF9ECE1478251500991ED5 /* cmscam02.c */, 2ACF9ECF1478251500991ED5 /* cmscgats.c */, 2ACF9ED01478251500991ED5 /* cmscnvrt.c */, 2ACF9ED11478251500991ED5 /* cmserr.c */, 2ACF9ED21478251500991ED5 /* cmsgamma.c */, 2ACF9ED31478251500991ED5 /* cmsgmt.c */, 2ACF9ED41478251500991ED5 /* cmsintrp.c */, 2ACF9ED51478251500991ED5 /* cmsio0.c */, 2ACF9ED61478251500991ED5 /* cmsio1.c */, 2ACF9ED71478251500991ED5 /* cmslut.c */, 2ACF9ED81478251500991ED5 /* cmsmd5.c */, 2ACF9ED91478251500991ED5 /* cmsmtrx.c */, 2ACF9EDA1478251500991ED5 /* cmsnamed.c */, 2ACF9EDB1478251500991ED5 /* cmsopt.c */, 2ACF9EDC1478251500991ED5 /* cmspack.c */, 2ACF9EDD1478251500991ED5 /* cmspcs.c */, 2ACF9EDE1478251500991ED5 /* cmsplugin.c */, 2ACF9EDF1478251500991ED5 /* cmsps2.c */, 2ACF9EE01478251500991ED5 /* cmssamp.c */, 2ACF9EE11478251500991ED5 /* cmssm.c */, 2ACF9EE21478251500991ED5 /* cmstypes.c */, 2ACF9EE31478251500991ED5 /* cmsvirt.c */, 2ACF9EE41478251500991ED5 /* cmswtpnt.c */, 2ACF9EE51478251500991ED5 /* cmsxform.c */, 2ACF9EE71478251500991ED5 /* lcms2_internal.h */, ); path = src; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 2ACF9E52147824F500991ED5 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 2ACF9F2C1478251500991ED5 /* lcms2.h in Headers */, 2ACF9F2D1478251500991ED5 /* lcms2_plugin.h in Headers */, 2ACF9F491478251500991ED5 /* lcms2_internal.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 2ACF9E55147824F500991ED5 /* lcms */ = { isa = PBXNativeTarget; buildConfigurationList = 2ACF9E59147824FB00991ED5 /* Build configuration list for PBXNativeTarget "lcms" */; buildPhases = ( 2AF569A814799AF900F9968C /* Unpack lcms2 */, 2ACF9E52147824F500991ED5 /* Headers */, 2ACF9E53147824F500991ED5 /* Sources */, 2ACF9E54147824F500991ED5 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = lcms; productName = lcms; productReference = 2ACF9E56147824F500991ED5 /* liblcms.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB916408733D950010E9CD /* Build configuration list for PBXProject "lcms" */; compatibilityVersion = "Xcode 3.1"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 0867D691FE84028FC02AAC07 /* lcms */; productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 2ACF9E55147824F500991ED5 /* lcms */, ); }; /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ 2AF569A814799AF900F9968C /* Unpack lcms2 */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(SRCROOT)/../../../../ext/lcms2-2.1.tar.gz", ); name = "Unpack lcms2"; outputPaths = ( "$(SRCROOT)/../../../../ext/lcms2-2.1", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "cd $SRCROOT/../../../../ext\n\nif [ ! -d lcms2-2.1 ]\nthen\n\ttar -xzf lcms2-2.1.tar.gz\nfi\n"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 2ACF9E53147824F500991ED5 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 2ACF9F311478251500991ED5 /* cmscam02.c in Sources */, 2ACF9F321478251500991ED5 /* cmscgats.c in Sources */, 2ACF9F331478251500991ED5 /* cmscnvrt.c in Sources */, 2ACF9F341478251500991ED5 /* cmserr.c in Sources */, 2ACF9F351478251500991ED5 /* cmsgamma.c in Sources */, 2ACF9F361478251500991ED5 /* cmsgmt.c in Sources */, 2ACF9F371478251500991ED5 /* cmsintrp.c in Sources */, 2ACF9F381478251500991ED5 /* cmsio0.c in Sources */, 2ACF9F391478251500991ED5 /* cmsio1.c in Sources */, 2ACF9F3A1478251500991ED5 /* cmslut.c in Sources */, 2ACF9F3B1478251500991ED5 /* cmsmd5.c in Sources */, 2ACF9F3C1478251500991ED5 /* cmsmtrx.c in Sources */, 2ACF9F3D1478251500991ED5 /* cmsnamed.c in Sources */, 2ACF9F3E1478251500991ED5 /* cmsopt.c in Sources */, 2ACF9F3F1478251500991ED5 /* cmspack.c in Sources */, 2ACF9F401478251500991ED5 /* cmspcs.c in Sources */, 2ACF9F411478251500991ED5 /* cmsplugin.c in Sources */, 2ACF9F421478251500991ED5 /* cmsps2.c in Sources */, 2ACF9F431478251500991ED5 /* cmssamp.c in Sources */, 2ACF9F441478251500991ED5 /* cmssm.c in Sources */, 2ACF9F451478251500991ED5 /* cmstypes.c in Sources */, 2ACF9F461478251500991ED5 /* cmsvirt.c in Sources */, 2ACF9F471478251500991ED5 /* cmswtpnt.c in Sources */, 2ACF9F481478251500991ED5 /* cmsxform.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 1DEB916508733D950010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; SDKROOT = macosx10.5; }; name = Debug; }; 1DEB916608733D950010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; SDKROOT = macosx10.5; }; name = Release; }; 2ACF9E57147824F600991ED5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; INSTALL_PATH = /usr/local/lib; PREBINDING = NO; PRODUCT_NAME = lcms; }; name = Debug; }; 2ACF9E58147824F600991ED5 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; INSTALL_PATH = /usr/local/lib; PREBINDING = NO; PRODUCT_NAME = lcms; ZERO_LINK = NO; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1DEB916408733D950010E9CD /* Build configuration list for PBXProject "lcms" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB916508733D950010E9CD /* Debug */, 1DEB916608733D950010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 2ACF9E59147824FB00991ED5 /* Build configuration list for PBXNativeTarget "lcms" */ = { isa = XCConfigurationList; buildConfigurations = ( 2ACF9E57147824F600991ED5 /* Debug */, 2ACF9E58147824F600991ED5 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 0867D690FE84028FC02AAC07 /* Project object */; } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/ext/yaml.xcodeproj/0000755000175000017500000000000013223553423024356 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/ext/yaml.xcodeproj/project.pbxproj0000644000175000017500000011546313223553423027444 0ustar mfvmfv// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 45; objects = { /* Begin PBXBuildFile section */ 2AB6B01315538484007C3547 /* binary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AB6B01215538484007C3547 /* binary.cpp */; }; 2ACF55F21477693B00991ED5 /* aliasmanager.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55A31477693B00991ED5 /* aliasmanager.h */; }; 2ACF55F31477693B00991ED5 /* anchor.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55A41477693B00991ED5 /* anchor.h */; }; 2ACF55F41477693B00991ED5 /* anchordict.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55A61477693B00991ED5 /* anchordict.h */; }; 2ACF55F51477693B00991ED5 /* graphbuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55A71477693B00991ED5 /* graphbuilder.h */; }; 2ACF55F61477693B00991ED5 /* conversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55A81477693B00991ED5 /* conversion.h */; }; 2ACF55F71477693B00991ED5 /* dll.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55A91477693B00991ED5 /* dll.h */; }; 2ACF55F81477693B00991ED5 /* emitfromevents.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55AA1477693B00991ED5 /* emitfromevents.h */; }; 2ACF55F91477693B00991ED5 /* emitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55AB1477693B00991ED5 /* emitter.h */; }; 2ACF55FA1477693B00991ED5 /* emittermanip.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55AC1477693B00991ED5 /* emittermanip.h */; }; 2ACF55FB1477693B00991ED5 /* eventhandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55AD1477693B00991ED5 /* eventhandler.h */; }; 2ACF55FC1477693B00991ED5 /* exceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55AE1477693B00991ED5 /* exceptions.h */; }; 2ACF55FD1477693B00991ED5 /* iterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55AF1477693B00991ED5 /* iterator.h */; }; 2ACF55FE1477693B00991ED5 /* ltnode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55B01477693B00991ED5 /* ltnode.h */; }; 2ACF55FF1477693B00991ED5 /* mark.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55B11477693B00991ED5 /* mark.h */; }; 2ACF56001477693B00991ED5 /* node.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55B21477693B00991ED5 /* node.h */; }; 2ACF56011477693B00991ED5 /* nodeimpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55B31477693B00991ED5 /* nodeimpl.h */; }; 2ACF56021477693B00991ED5 /* nodereadimpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55B41477693B00991ED5 /* nodereadimpl.h */; }; 2ACF56031477693B00991ED5 /* nodeutil.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55B51477693B00991ED5 /* nodeutil.h */; }; 2ACF56041477693B00991ED5 /* noncopyable.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55B61477693B00991ED5 /* noncopyable.h */; }; 2ACF56051477693B00991ED5 /* null.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55B71477693B00991ED5 /* null.h */; }; 2ACF56061477693B00991ED5 /* ostream.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55B81477693B00991ED5 /* ostream.h */; }; 2ACF56071477693B00991ED5 /* parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55B91477693B00991ED5 /* parser.h */; }; 2ACF56081477693B00991ED5 /* stlemitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55BA1477693B00991ED5 /* stlemitter.h */; }; 2ACF56091477693B00991ED5 /* stlnode.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55BB1477693B00991ED5 /* stlnode.h */; }; 2ACF560A1477693B00991ED5 /* traits.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55BC1477693B00991ED5 /* traits.h */; }; 2ACF560B1477693B00991ED5 /* yaml.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55BD1477693B00991ED5 /* yaml.h */; }; 2ACF560C1477693B00991ED5 /* aliasmanager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55BF1477693B00991ED5 /* aliasmanager.cpp */; }; 2ACF560D1477693B00991ED5 /* collectionstack.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55C01477693B00991ED5 /* collectionstack.h */; }; 2ACF560E1477693B00991ED5 /* graphbuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55C21477693B00991ED5 /* graphbuilder.cpp */; }; 2ACF560F1477693B00991ED5 /* graphbuilderadapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55C31477693B00991ED5 /* graphbuilderadapter.cpp */; }; 2ACF56101477693B00991ED5 /* graphbuilderadapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55C41477693B00991ED5 /* graphbuilderadapter.h */; }; 2ACF56111477693B00991ED5 /* conversion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55C51477693B00991ED5 /* conversion.cpp */; }; 2ACF56121477693B00991ED5 /* directives.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55C61477693B00991ED5 /* directives.cpp */; }; 2ACF56131477693B00991ED5 /* directives.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55C71477693B00991ED5 /* directives.h */; }; 2ACF56141477693B00991ED5 /* emitfromevents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55C81477693B00991ED5 /* emitfromevents.cpp */; }; 2ACF56151477693B00991ED5 /* emitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55C91477693B00991ED5 /* emitter.cpp */; }; 2ACF56161477693B00991ED5 /* emitterstate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55CA1477693B00991ED5 /* emitterstate.cpp */; }; 2ACF56171477693B00991ED5 /* emitterstate.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55CB1477693B00991ED5 /* emitterstate.h */; }; 2ACF56181477693B00991ED5 /* emitterutils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55CC1477693B00991ED5 /* emitterutils.cpp */; }; 2ACF56191477693B00991ED5 /* emitterutils.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55CD1477693B00991ED5 /* emitterutils.h */; }; 2ACF561A1477693B00991ED5 /* exp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55CE1477693B00991ED5 /* exp.cpp */; }; 2ACF561B1477693B00991ED5 /* exp.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55CF1477693B00991ED5 /* exp.h */; }; 2ACF561C1477693B00991ED5 /* indentation.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55D01477693B00991ED5 /* indentation.h */; }; 2ACF561D1477693B00991ED5 /* iterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55D11477693B00991ED5 /* iterator.cpp */; }; 2ACF561E1477693B00991ED5 /* iterpriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55D21477693B00991ED5 /* iterpriv.h */; }; 2ACF561F1477693B00991ED5 /* node.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55D31477693B00991ED5 /* node.cpp */; }; 2ACF56201477693B00991ED5 /* nodebuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55D41477693B00991ED5 /* nodebuilder.cpp */; }; 2ACF56211477693B00991ED5 /* nodebuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55D51477693B00991ED5 /* nodebuilder.h */; }; 2ACF56221477693B00991ED5 /* nodeownership.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55D61477693B00991ED5 /* nodeownership.cpp */; }; 2ACF56231477693B00991ED5 /* nodeownership.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55D71477693B00991ED5 /* nodeownership.h */; }; 2ACF56241477693B00991ED5 /* null.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55D81477693B00991ED5 /* null.cpp */; }; 2ACF56251477693B00991ED5 /* ostream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55D91477693B00991ED5 /* ostream.cpp */; }; 2ACF56261477693B00991ED5 /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55DA1477693B00991ED5 /* parser.cpp */; }; 2ACF56271477693B00991ED5 /* ptr_stack.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55DB1477693B00991ED5 /* ptr_stack.h */; }; 2ACF56281477693B00991ED5 /* ptr_vector.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55DC1477693B00991ED5 /* ptr_vector.h */; }; 2ACF56291477693B00991ED5 /* regex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55DD1477693B00991ED5 /* regex.cpp */; }; 2ACF562A1477693B00991ED5 /* regex.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55DE1477693B00991ED5 /* regex.h */; }; 2ACF562B1477693B00991ED5 /* regeximpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55DF1477693B00991ED5 /* regeximpl.h */; }; 2ACF562C1477693B00991ED5 /* scanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55E01477693B00991ED5 /* scanner.cpp */; }; 2ACF562D1477693B00991ED5 /* scanner.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55E11477693B00991ED5 /* scanner.h */; }; 2ACF562E1477693B00991ED5 /* scanscalar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55E21477693B00991ED5 /* scanscalar.cpp */; }; 2ACF562F1477693B00991ED5 /* scanscalar.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55E31477693B00991ED5 /* scanscalar.h */; }; 2ACF56301477693B00991ED5 /* scantag.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55E41477693B00991ED5 /* scantag.cpp */; }; 2ACF56311477693B00991ED5 /* scantag.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55E51477693B00991ED5 /* scantag.h */; }; 2ACF56321477693B00991ED5 /* scantoken.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55E61477693B00991ED5 /* scantoken.cpp */; }; 2ACF56331477693B00991ED5 /* setting.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55E71477693B00991ED5 /* setting.h */; }; 2ACF56341477693B00991ED5 /* simplekey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55E81477693B00991ED5 /* simplekey.cpp */; }; 2ACF56351477693B00991ED5 /* singledocparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55E91477693B00991ED5 /* singledocparser.cpp */; }; 2ACF56361477693B00991ED5 /* singledocparser.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55EA1477693B00991ED5 /* singledocparser.h */; }; 2ACF56371477693B00991ED5 /* stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55EB1477693B00991ED5 /* stream.cpp */; }; 2ACF56381477693B00991ED5 /* stream.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55EC1477693B00991ED5 /* stream.h */; }; 2ACF56391477693B00991ED5 /* streamcharsource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55ED1477693B00991ED5 /* streamcharsource.h */; }; 2ACF563A1477693B00991ED5 /* stringsource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55EE1477693B00991ED5 /* stringsource.h */; }; 2ACF563B1477693B00991ED5 /* tag.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF55EF1477693B00991ED5 /* tag.cpp */; }; 2ACF563C1477693B00991ED5 /* tag.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55F01477693B00991ED5 /* tag.h */; }; 2ACF563D1477693B00991ED5 /* token.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF55F11477693B00991ED5 /* token.h */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 2AB6B01215538484007C3547 /* binary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = binary.cpp; sourceTree = ""; }; 2ACF559C1477692300991ED5 /* libyaml.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libyaml.a; sourceTree = BUILT_PRODUCTS_DIR; }; 2ACF55A31477693B00991ED5 /* aliasmanager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aliasmanager.h; sourceTree = ""; }; 2ACF55A41477693B00991ED5 /* anchor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = anchor.h; sourceTree = ""; }; 2ACF55A61477693B00991ED5 /* anchordict.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = anchordict.h; sourceTree = ""; }; 2ACF55A71477693B00991ED5 /* graphbuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphbuilder.h; sourceTree = ""; }; 2ACF55A81477693B00991ED5 /* conversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = conversion.h; sourceTree = ""; }; 2ACF55A91477693B00991ED5 /* dll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dll.h; sourceTree = ""; }; 2ACF55AA1477693B00991ED5 /* emitfromevents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = emitfromevents.h; sourceTree = ""; }; 2ACF55AB1477693B00991ED5 /* emitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = emitter.h; sourceTree = ""; }; 2ACF55AC1477693B00991ED5 /* emittermanip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = emittermanip.h; sourceTree = ""; }; 2ACF55AD1477693B00991ED5 /* eventhandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = eventhandler.h; sourceTree = ""; }; 2ACF55AE1477693B00991ED5 /* exceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exceptions.h; sourceTree = ""; }; 2ACF55AF1477693B00991ED5 /* iterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iterator.h; sourceTree = ""; }; 2ACF55B01477693B00991ED5 /* ltnode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ltnode.h; sourceTree = ""; }; 2ACF55B11477693B00991ED5 /* mark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mark.h; sourceTree = ""; }; 2ACF55B21477693B00991ED5 /* node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = node.h; sourceTree = ""; }; 2ACF55B31477693B00991ED5 /* nodeimpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nodeimpl.h; sourceTree = ""; }; 2ACF55B41477693B00991ED5 /* nodereadimpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nodereadimpl.h; sourceTree = ""; }; 2ACF55B51477693B00991ED5 /* nodeutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nodeutil.h; sourceTree = ""; }; 2ACF55B61477693B00991ED5 /* noncopyable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = noncopyable.h; sourceTree = ""; }; 2ACF55B71477693B00991ED5 /* null.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = null.h; sourceTree = ""; }; 2ACF55B81477693B00991ED5 /* ostream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ostream.h; sourceTree = ""; }; 2ACF55B91477693B00991ED5 /* parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parser.h; sourceTree = ""; }; 2ACF55BA1477693B00991ED5 /* stlemitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stlemitter.h; sourceTree = ""; }; 2ACF55BB1477693B00991ED5 /* stlnode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stlnode.h; sourceTree = ""; }; 2ACF55BC1477693B00991ED5 /* traits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = traits.h; sourceTree = ""; }; 2ACF55BD1477693B00991ED5 /* yaml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yaml.h; sourceTree = ""; }; 2ACF55BF1477693B00991ED5 /* aliasmanager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = aliasmanager.cpp; sourceTree = ""; }; 2ACF55C01477693B00991ED5 /* collectionstack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = collectionstack.h; sourceTree = ""; }; 2ACF55C21477693B00991ED5 /* graphbuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphbuilder.cpp; sourceTree = ""; }; 2ACF55C31477693B00991ED5 /* graphbuilderadapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = graphbuilderadapter.cpp; sourceTree = ""; }; 2ACF55C41477693B00991ED5 /* graphbuilderadapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = graphbuilderadapter.h; sourceTree = ""; }; 2ACF55C51477693B00991ED5 /* conversion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = conversion.cpp; sourceTree = ""; }; 2ACF55C61477693B00991ED5 /* directives.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = directives.cpp; sourceTree = ""; }; 2ACF55C71477693B00991ED5 /* directives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = directives.h; sourceTree = ""; }; 2ACF55C81477693B00991ED5 /* emitfromevents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = emitfromevents.cpp; sourceTree = ""; }; 2ACF55C91477693B00991ED5 /* emitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = emitter.cpp; sourceTree = ""; }; 2ACF55CA1477693B00991ED5 /* emitterstate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = emitterstate.cpp; sourceTree = ""; }; 2ACF55CB1477693B00991ED5 /* emitterstate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = emitterstate.h; sourceTree = ""; }; 2ACF55CC1477693B00991ED5 /* emitterutils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = emitterutils.cpp; sourceTree = ""; }; 2ACF55CD1477693B00991ED5 /* emitterutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = emitterutils.h; sourceTree = ""; }; 2ACF55CE1477693B00991ED5 /* exp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = exp.cpp; sourceTree = ""; }; 2ACF55CF1477693B00991ED5 /* exp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = exp.h; sourceTree = ""; }; 2ACF55D01477693B00991ED5 /* indentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = indentation.h; sourceTree = ""; }; 2ACF55D11477693B00991ED5 /* iterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iterator.cpp; sourceTree = ""; }; 2ACF55D21477693B00991ED5 /* iterpriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iterpriv.h; sourceTree = ""; }; 2ACF55D31477693B00991ED5 /* node.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = node.cpp; sourceTree = ""; }; 2ACF55D41477693B00991ED5 /* nodebuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nodebuilder.cpp; sourceTree = ""; }; 2ACF55D51477693B00991ED5 /* nodebuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nodebuilder.h; sourceTree = ""; }; 2ACF55D61477693B00991ED5 /* nodeownership.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nodeownership.cpp; sourceTree = ""; }; 2ACF55D71477693B00991ED5 /* nodeownership.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nodeownership.h; sourceTree = ""; }; 2ACF55D81477693B00991ED5 /* null.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = null.cpp; sourceTree = ""; }; 2ACF55D91477693B00991ED5 /* ostream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ostream.cpp; sourceTree = ""; }; 2ACF55DA1477693B00991ED5 /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser.cpp; sourceTree = ""; }; 2ACF55DB1477693B00991ED5 /* ptr_stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ptr_stack.h; sourceTree = ""; }; 2ACF55DC1477693B00991ED5 /* ptr_vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ptr_vector.h; sourceTree = ""; }; 2ACF55DD1477693B00991ED5 /* regex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = regex.cpp; sourceTree = ""; }; 2ACF55DE1477693B00991ED5 /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = ""; }; 2ACF55DF1477693B00991ED5 /* regeximpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regeximpl.h; sourceTree = ""; }; 2ACF55E01477693B00991ED5 /* scanner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scanner.cpp; sourceTree = ""; }; 2ACF55E11477693B00991ED5 /* scanner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scanner.h; sourceTree = ""; }; 2ACF55E21477693B00991ED5 /* scanscalar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scanscalar.cpp; sourceTree = ""; }; 2ACF55E31477693B00991ED5 /* scanscalar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scanscalar.h; sourceTree = ""; }; 2ACF55E41477693B00991ED5 /* scantag.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scantag.cpp; sourceTree = ""; }; 2ACF55E51477693B00991ED5 /* scantag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scantag.h; sourceTree = ""; }; 2ACF55E61477693B00991ED5 /* scantoken.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scantoken.cpp; sourceTree = ""; }; 2ACF55E71477693B00991ED5 /* setting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = setting.h; sourceTree = ""; }; 2ACF55E81477693B00991ED5 /* simplekey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = simplekey.cpp; sourceTree = ""; }; 2ACF55E91477693B00991ED5 /* singledocparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = singledocparser.cpp; sourceTree = ""; }; 2ACF55EA1477693B00991ED5 /* singledocparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = singledocparser.h; sourceTree = ""; }; 2ACF55EB1477693B00991ED5 /* stream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stream.cpp; sourceTree = ""; }; 2ACF55EC1477693B00991ED5 /* stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stream.h; sourceTree = ""; }; 2ACF55ED1477693B00991ED5 /* streamcharsource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = streamcharsource.h; sourceTree = ""; }; 2ACF55EE1477693B00991ED5 /* stringsource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stringsource.h; sourceTree = ""; }; 2ACF55EF1477693B00991ED5 /* tag.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tag.cpp; sourceTree = ""; }; 2ACF55F01477693B00991ED5 /* tag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tag.h; sourceTree = ""; }; 2ACF55F11477693B00991ED5 /* token.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = token.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 2ACF559A1477692300991ED5 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 034768DDFF38A45A11DB9C8B /* Products */ = { isa = PBXGroup; children = ( 2ACF559C1477692300991ED5 /* libyaml.a */, ); name = Products; sourceTree = ""; }; 0867D691FE84028FC02AAC07 /* yaml */ = { isa = PBXGroup; children = ( 2ACF55A01477693B00991ED5 /* yaml-cpp */, 034768DDFF38A45A11DB9C8B /* Products */, ); name = yaml; sourceTree = ""; }; 2ACF55A01477693B00991ED5 /* yaml-cpp */ = { isa = PBXGroup; children = ( 2ACF55A11477693B00991ED5 /* include */, 2ACF55BE1477693B00991ED5 /* src */, ); name = "yaml-cpp"; path = "../../../../ext/yaml-cpp"; sourceTree = SOURCE_ROOT; }; 2ACF55A11477693B00991ED5 /* include */ = { isa = PBXGroup; children = ( 2ACF55A21477693B00991ED5 /* yaml-cpp */, ); path = include; sourceTree = ""; }; 2ACF55A21477693B00991ED5 /* yaml-cpp */ = { isa = PBXGroup; children = ( 2ACF55A31477693B00991ED5 /* aliasmanager.h */, 2ACF55A41477693B00991ED5 /* anchor.h */, 2ACF55A51477693B00991ED5 /* contrib */, 2ACF55A81477693B00991ED5 /* conversion.h */, 2ACF55A91477693B00991ED5 /* dll.h */, 2ACF55AA1477693B00991ED5 /* emitfromevents.h */, 2ACF55AB1477693B00991ED5 /* emitter.h */, 2ACF55AC1477693B00991ED5 /* emittermanip.h */, 2ACF55AD1477693B00991ED5 /* eventhandler.h */, 2ACF55AE1477693B00991ED5 /* exceptions.h */, 2ACF55AF1477693B00991ED5 /* iterator.h */, 2ACF55B01477693B00991ED5 /* ltnode.h */, 2ACF55B11477693B00991ED5 /* mark.h */, 2ACF55B21477693B00991ED5 /* node.h */, 2ACF55B31477693B00991ED5 /* nodeimpl.h */, 2ACF55B41477693B00991ED5 /* nodereadimpl.h */, 2ACF55B51477693B00991ED5 /* nodeutil.h */, 2ACF55B61477693B00991ED5 /* noncopyable.h */, 2ACF55B71477693B00991ED5 /* null.h */, 2ACF55B81477693B00991ED5 /* ostream.h */, 2ACF55B91477693B00991ED5 /* parser.h */, 2ACF55BA1477693B00991ED5 /* stlemitter.h */, 2ACF55BB1477693B00991ED5 /* stlnode.h */, 2ACF55BC1477693B00991ED5 /* traits.h */, 2ACF55BD1477693B00991ED5 /* yaml.h */, ); path = "yaml-cpp"; sourceTree = ""; }; 2ACF55A51477693B00991ED5 /* contrib */ = { isa = PBXGroup; children = ( 2ACF55A61477693B00991ED5 /* anchordict.h */, 2ACF55A71477693B00991ED5 /* graphbuilder.h */, ); path = contrib; sourceTree = ""; }; 2ACF55BE1477693B00991ED5 /* src */ = { isa = PBXGroup; children = ( 2ACF55BF1477693B00991ED5 /* aliasmanager.cpp */, 2AB6B01215538484007C3547 /* binary.cpp */, 2ACF55C01477693B00991ED5 /* collectionstack.h */, 2ACF55C11477693B00991ED5 /* contrib */, 2ACF55C51477693B00991ED5 /* conversion.cpp */, 2ACF55C61477693B00991ED5 /* directives.cpp */, 2ACF55C71477693B00991ED5 /* directives.h */, 2ACF55C81477693B00991ED5 /* emitfromevents.cpp */, 2ACF55C91477693B00991ED5 /* emitter.cpp */, 2ACF55CA1477693B00991ED5 /* emitterstate.cpp */, 2ACF55CB1477693B00991ED5 /* emitterstate.h */, 2ACF55CC1477693B00991ED5 /* emitterutils.cpp */, 2ACF55CD1477693B00991ED5 /* emitterutils.h */, 2ACF55CE1477693B00991ED5 /* exp.cpp */, 2ACF55CF1477693B00991ED5 /* exp.h */, 2ACF55D01477693B00991ED5 /* indentation.h */, 2ACF55D11477693B00991ED5 /* iterator.cpp */, 2ACF55D21477693B00991ED5 /* iterpriv.h */, 2ACF55D31477693B00991ED5 /* node.cpp */, 2ACF55D41477693B00991ED5 /* nodebuilder.cpp */, 2ACF55D51477693B00991ED5 /* nodebuilder.h */, 2ACF55D61477693B00991ED5 /* nodeownership.cpp */, 2ACF55D71477693B00991ED5 /* nodeownership.h */, 2ACF55D81477693B00991ED5 /* null.cpp */, 2ACF55D91477693B00991ED5 /* ostream.cpp */, 2ACF55DA1477693B00991ED5 /* parser.cpp */, 2ACF55DB1477693B00991ED5 /* ptr_stack.h */, 2ACF55DC1477693B00991ED5 /* ptr_vector.h */, 2ACF55DD1477693B00991ED5 /* regex.cpp */, 2ACF55DE1477693B00991ED5 /* regex.h */, 2ACF55DF1477693B00991ED5 /* regeximpl.h */, 2ACF55E01477693B00991ED5 /* scanner.cpp */, 2ACF55E11477693B00991ED5 /* scanner.h */, 2ACF55E21477693B00991ED5 /* scanscalar.cpp */, 2ACF55E31477693B00991ED5 /* scanscalar.h */, 2ACF55E41477693B00991ED5 /* scantag.cpp */, 2ACF55E51477693B00991ED5 /* scantag.h */, 2ACF55E61477693B00991ED5 /* scantoken.cpp */, 2ACF55E71477693B00991ED5 /* setting.h */, 2ACF55E81477693B00991ED5 /* simplekey.cpp */, 2ACF55E91477693B00991ED5 /* singledocparser.cpp */, 2ACF55EA1477693B00991ED5 /* singledocparser.h */, 2ACF55EB1477693B00991ED5 /* stream.cpp */, 2ACF55EC1477693B00991ED5 /* stream.h */, 2ACF55ED1477693B00991ED5 /* streamcharsource.h */, 2ACF55EE1477693B00991ED5 /* stringsource.h */, 2ACF55EF1477693B00991ED5 /* tag.cpp */, 2ACF55F01477693B00991ED5 /* tag.h */, 2ACF55F11477693B00991ED5 /* token.h */, ); path = src; sourceTree = ""; }; 2ACF55C11477693B00991ED5 /* contrib */ = { isa = PBXGroup; children = ( 2ACF55C21477693B00991ED5 /* graphbuilder.cpp */, 2ACF55C31477693B00991ED5 /* graphbuilderadapter.cpp */, 2ACF55C41477693B00991ED5 /* graphbuilderadapter.h */, ); path = contrib; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 2ACF55981477692300991ED5 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 2ACF55F21477693B00991ED5 /* aliasmanager.h in Headers */, 2ACF55F31477693B00991ED5 /* anchor.h in Headers */, 2ACF55F41477693B00991ED5 /* anchordict.h in Headers */, 2ACF55F51477693B00991ED5 /* graphbuilder.h in Headers */, 2ACF55F61477693B00991ED5 /* conversion.h in Headers */, 2ACF55F71477693B00991ED5 /* dll.h in Headers */, 2ACF55F81477693B00991ED5 /* emitfromevents.h in Headers */, 2ACF55F91477693B00991ED5 /* emitter.h in Headers */, 2ACF55FA1477693B00991ED5 /* emittermanip.h in Headers */, 2ACF55FB1477693B00991ED5 /* eventhandler.h in Headers */, 2ACF55FC1477693B00991ED5 /* exceptions.h in Headers */, 2ACF55FD1477693B00991ED5 /* iterator.h in Headers */, 2ACF55FE1477693B00991ED5 /* ltnode.h in Headers */, 2ACF55FF1477693B00991ED5 /* mark.h in Headers */, 2ACF56001477693B00991ED5 /* node.h in Headers */, 2ACF56011477693B00991ED5 /* nodeimpl.h in Headers */, 2ACF56021477693B00991ED5 /* nodereadimpl.h in Headers */, 2ACF56031477693B00991ED5 /* nodeutil.h in Headers */, 2ACF56041477693B00991ED5 /* noncopyable.h in Headers */, 2ACF56051477693B00991ED5 /* null.h in Headers */, 2ACF56061477693B00991ED5 /* ostream.h in Headers */, 2ACF56071477693B00991ED5 /* parser.h in Headers */, 2ACF56081477693B00991ED5 /* stlemitter.h in Headers */, 2ACF56091477693B00991ED5 /* stlnode.h in Headers */, 2ACF560A1477693B00991ED5 /* traits.h in Headers */, 2ACF560B1477693B00991ED5 /* yaml.h in Headers */, 2ACF560D1477693B00991ED5 /* collectionstack.h in Headers */, 2ACF56101477693B00991ED5 /* graphbuilderadapter.h in Headers */, 2ACF56131477693B00991ED5 /* directives.h in Headers */, 2ACF56171477693B00991ED5 /* emitterstate.h in Headers */, 2ACF56191477693B00991ED5 /* emitterutils.h in Headers */, 2ACF561B1477693B00991ED5 /* exp.h in Headers */, 2ACF561C1477693B00991ED5 /* indentation.h in Headers */, 2ACF561E1477693B00991ED5 /* iterpriv.h in Headers */, 2ACF56211477693B00991ED5 /* nodebuilder.h in Headers */, 2ACF56231477693B00991ED5 /* nodeownership.h in Headers */, 2ACF56271477693B00991ED5 /* ptr_stack.h in Headers */, 2ACF56281477693B00991ED5 /* ptr_vector.h in Headers */, 2ACF562A1477693B00991ED5 /* regex.h in Headers */, 2ACF562B1477693B00991ED5 /* regeximpl.h in Headers */, 2ACF562D1477693B00991ED5 /* scanner.h in Headers */, 2ACF562F1477693B00991ED5 /* scanscalar.h in Headers */, 2ACF56311477693B00991ED5 /* scantag.h in Headers */, 2ACF56331477693B00991ED5 /* setting.h in Headers */, 2ACF56361477693B00991ED5 /* singledocparser.h in Headers */, 2ACF56381477693B00991ED5 /* stream.h in Headers */, 2ACF56391477693B00991ED5 /* streamcharsource.h in Headers */, 2ACF563A1477693B00991ED5 /* stringsource.h in Headers */, 2ACF563C1477693B00991ED5 /* tag.h in Headers */, 2ACF563D1477693B00991ED5 /* token.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 2ACF559B1477692300991ED5 /* yaml */ = { isa = PBXNativeTarget; buildConfigurationList = 2ACF559F1477692B00991ED5 /* Build configuration list for PBXNativeTarget "yaml" */; buildPhases = ( 2AF56976147991F700F9968C /* Unpack yaml */, 2ACF55981477692300991ED5 /* Headers */, 2ACF55991477692300991ED5 /* Sources */, 2ACF559A1477692300991ED5 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = yaml; productName = yaml; productReference = 2ACF559C1477692300991ED5 /* libyaml.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB916408733D950010E9CD /* Build configuration list for PBXProject "yaml" */; compatibilityVersion = "Xcode 3.1"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 0867D691FE84028FC02AAC07 /* yaml */; productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 2ACF559B1477692300991ED5 /* yaml */, ); }; /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ 2AF56976147991F700F9968C /* Unpack yaml */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(SRCROOT)/../../../../ext/yaml-cpp-0.3.0.tar.gz", "$(SRCROOT)/../../../../ext/yaml-cpp-0.3.0.patch", ); name = "Unpack yaml"; outputPaths = ( "$(SRCROOT)/../../../../ext/yaml-cpp", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "cd $SRCROOT/../../../../ext\n\nif [ ! -d yaml-cpp ]\nthen\n\ttar -xzf yaml-cpp-0.3.0.tar.gz\n\tpatch -p0 < yaml-cpp-0.3.0.patch\nfi\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 2ACF55991477692300991ED5 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 2ACF560C1477693B00991ED5 /* aliasmanager.cpp in Sources */, 2ACF560E1477693B00991ED5 /* graphbuilder.cpp in Sources */, 2ACF560F1477693B00991ED5 /* graphbuilderadapter.cpp in Sources */, 2ACF56111477693B00991ED5 /* conversion.cpp in Sources */, 2ACF56121477693B00991ED5 /* directives.cpp in Sources */, 2ACF56141477693B00991ED5 /* emitfromevents.cpp in Sources */, 2ACF56151477693B00991ED5 /* emitter.cpp in Sources */, 2ACF56161477693B00991ED5 /* emitterstate.cpp in Sources */, 2ACF56181477693B00991ED5 /* emitterutils.cpp in Sources */, 2ACF561A1477693B00991ED5 /* exp.cpp in Sources */, 2ACF561D1477693B00991ED5 /* iterator.cpp in Sources */, 2ACF561F1477693B00991ED5 /* node.cpp in Sources */, 2ACF56201477693B00991ED5 /* nodebuilder.cpp in Sources */, 2ACF56221477693B00991ED5 /* nodeownership.cpp in Sources */, 2ACF56241477693B00991ED5 /* null.cpp in Sources */, 2ACF56251477693B00991ED5 /* ostream.cpp in Sources */, 2ACF56261477693B00991ED5 /* parser.cpp in Sources */, 2ACF56291477693B00991ED5 /* regex.cpp in Sources */, 2ACF562C1477693B00991ED5 /* scanner.cpp in Sources */, 2ACF562E1477693B00991ED5 /* scanscalar.cpp in Sources */, 2ACF56301477693B00991ED5 /* scantag.cpp in Sources */, 2ACF56321477693B00991ED5 /* scantoken.cpp in Sources */, 2ACF56341477693B00991ED5 /* simplekey.cpp in Sources */, 2ACF56351477693B00991ED5 /* singledocparser.cpp in Sources */, 2ACF56371477693B00991ED5 /* stream.cpp in Sources */, 2ACF563B1477693B00991ED5 /* tag.cpp in Sources */, 2AB6B01315538484007C3547 /* binary.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 1DEB916508733D950010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = "../../../../ext/yaml-cpp/include"; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; SDKROOT = macosx10.5; }; name = Debug; }; 1DEB916608733D950010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = "../../../../ext/yaml-cpp/include"; PREBINDING = NO; SDKROOT = macosx10.5; }; name = Release; }; 2ACF559D1477692300991ED5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; INSTALL_PATH = /usr/local/lib; PREBINDING = NO; PRODUCT_NAME = yaml; }; name = Debug; }; 2ACF559E1477692300991ED5 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; INSTALL_PATH = /usr/local/lib; PREBINDING = NO; PRODUCT_NAME = yaml; ZERO_LINK = NO; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1DEB916408733D950010E9CD /* Build configuration list for PBXProject "yaml" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB916508733D950010E9CD /* Debug */, 1DEB916608733D950010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 2ACF559F1477692B00991ED5 /* Build configuration list for PBXNativeTarget "yaml" */ = { isa = XCConfigurationList; buildConfigurations = ( 2ACF559D1477692300991ED5 /* Debug */, 2ACF559E1477692300991ED5 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 0867D690FE84028FC02AAC07 /* Project object */; } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/OpenColorIO.xcodeproj/0000755000175000017500000000000013223553423024744 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/xcode/OpenColorIO.xcodeproj/project.pbxproj0000644000175000017500000013335313223553423030030 0ustar mfvmfv// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 45; objects = { /* Begin PBXBuildFile section */ 2A7CACBB15536CD700F52C98 /* FileFormatIridasLook.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A7CACB515536CD700F52C98 /* FileFormatIridasLook.cpp */; }; 2A7CACBC15536CD700F52C98 /* LookParse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A7CACB615536CD700F52C98 /* LookParse.cpp */; }; 2A7CACBD15536CD700F52C98 /* LookParse.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A7CACB715536CD700F52C98 /* LookParse.h */; }; 2A7CACBE15536CD700F52C98 /* NoOps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A7CACB815536CD700F52C98 /* NoOps.cpp */; }; 2A7CACBF15536CD700F52C98 /* NoOps.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A7CACB915536CD700F52C98 /* NoOps.h */; }; 2A7CACC015536CD700F52C98 /* OpOptimizers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A7CACBA15536CD700F52C98 /* OpOptimizers.cpp */; }; 2A7F20D31E2F17D2003428D7 /* FileFormatCDL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A7F20D21E2F17D2003428D7 /* FileFormatCDL.cpp */; }; 2ACB3D001CC074A200134356 /* Display.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACB3CFE1CC074A200134356 /* Display.cpp */; }; 2ACB3D011CC074A200134356 /* Display.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACB3CFF1CC074A200134356 /* Display.h */; }; 2ACF56CC14776A1E00991ED5 /* AllocationOp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF567614776A1E00991ED5 /* AllocationOp.cpp */; }; 2ACF56CD14776A1E00991ED5 /* AllocationOp.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF567714776A1E00991ED5 /* AllocationOp.h */; }; 2ACF56CE14776A1E00991ED5 /* AllocationTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF567814776A1E00991ED5 /* AllocationTransform.cpp */; }; 2ACF56CF14776A1E00991ED5 /* Baker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF567914776A1E00991ED5 /* Baker.cpp */; }; 2ACF56D014776A1E00991ED5 /* Caching.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF567A14776A1E00991ED5 /* Caching.cpp */; }; 2ACF56D114776A1E00991ED5 /* CDLTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF567B14776A1E00991ED5 /* CDLTransform.cpp */; }; 2ACF56D214776A1E00991ED5 /* CDLTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF567C14776A1E00991ED5 /* CDLTransform.h */; }; 2ACF56D314776A1E00991ED5 /* ColorSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF567D14776A1E00991ED5 /* ColorSpace.cpp */; }; 2ACF56D414776A1E00991ED5 /* ColorSpaceTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF567E14776A1E00991ED5 /* ColorSpaceTransform.cpp */; }; 2ACF56D514776A1E00991ED5 /* Config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF567F14776A1E00991ED5 /* Config.cpp */; }; 2ACF56D614776A1E00991ED5 /* Context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568014776A1E00991ED5 /* Context.cpp */; }; 2ACF56D714776A1E00991ED5 /* DisplayTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568114776A1E00991ED5 /* DisplayTransform.cpp */; }; 2ACF56D814776A1E00991ED5 /* Exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568214776A1E00991ED5 /* Exception.cpp */; }; 2ACF56D914776A1E00991ED5 /* ExponentOps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568314776A1E00991ED5 /* ExponentOps.cpp */; }; 2ACF56DA14776A1E00991ED5 /* ExponentOps.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF568414776A1E00991ED5 /* ExponentOps.h */; }; 2ACF56DB14776A1E00991ED5 /* ExponentTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568514776A1E00991ED5 /* ExponentTransform.cpp */; }; 2ACF56DC14776A1E00991ED5 /* FileFormat3DL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568614776A1E00991ED5 /* FileFormat3DL.cpp */; }; 2ACF56DD14776A1E00991ED5 /* FileFormatCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568714776A1E00991ED5 /* FileFormatCC.cpp */; }; 2ACF56DE14776A1E00991ED5 /* FileFormatCCC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568814776A1E00991ED5 /* FileFormatCCC.cpp */; }; 2ACF56DF14776A1E00991ED5 /* FileFormatCSP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568914776A1E00991ED5 /* FileFormatCSP.cpp */; }; 2ACF56E014776A1E00991ED5 /* FileFormatHDL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568A14776A1E00991ED5 /* FileFormatHDL.cpp */; }; 2ACF56E114776A1E00991ED5 /* FileFormatIridasCube.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568B14776A1E00991ED5 /* FileFormatIridasCube.cpp */; }; 2ACF56E214776A1E00991ED5 /* FileFormatIridasItx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568C14776A1E00991ED5 /* FileFormatIridasItx.cpp */; }; 2ACF56E314776A1E00991ED5 /* FileFormatPandora.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568D14776A1E00991ED5 /* FileFormatPandora.cpp */; }; 2ACF56E414776A1E00991ED5 /* FileFormatSpi1D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568E14776A1E00991ED5 /* FileFormatSpi1D.cpp */; }; 2ACF56E514776A1E00991ED5 /* FileFormatSpi3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF568F14776A1E00991ED5 /* FileFormatSpi3D.cpp */; }; 2ACF56E614776A1E00991ED5 /* FileFormatSpiMtx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF569014776A1E00991ED5 /* FileFormatSpiMtx.cpp */; }; 2ACF56E714776A1E00991ED5 /* FileFormatTruelight.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF569114776A1E00991ED5 /* FileFormatTruelight.cpp */; }; 2ACF56E814776A1E00991ED5 /* FileFormatVF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF569214776A1E00991ED5 /* FileFormatVF.cpp */; }; 2ACF56E914776A1E00991ED5 /* FileTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF569314776A1E00991ED5 /* FileTransform.cpp */; }; 2ACF56EA14776A1E00991ED5 /* FileTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF569414776A1E00991ED5 /* FileTransform.h */; }; 2ACF56EC14776A1E00991ED5 /* GpuShaderDesc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF569614776A1E00991ED5 /* GpuShaderDesc.cpp */; }; 2ACF56ED14776A1E00991ED5 /* GpuShaderUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF569714776A1E00991ED5 /* GpuShaderUtils.cpp */; }; 2ACF56EE14776A1E00991ED5 /* GpuShaderUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF569814776A1E00991ED5 /* GpuShaderUtils.h */; }; 2ACF56EF14776A1E00991ED5 /* GroupTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF569914776A1E00991ED5 /* GroupTransform.cpp */; }; 2ACF56F014776A1E00991ED5 /* HashUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF569A14776A1E00991ED5 /* HashUtils.cpp */; }; 2ACF56F114776A1E00991ED5 /* HashUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF569B14776A1E00991ED5 /* HashUtils.h */; }; 2ACF56F214776A1E00991ED5 /* ImageDesc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF569C14776A1E00991ED5 /* ImageDesc.cpp */; }; 2ACF56F314776A1E00991ED5 /* ImagePacking.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF569D14776A1E00991ED5 /* ImagePacking.cpp */; }; 2ACF56F414776A1E00991ED5 /* ImagePacking.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF569E14776A1E00991ED5 /* ImagePacking.h */; }; 2ACF56F514776A1E00991ED5 /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF569F14776A1E00991ED5 /* Logging.cpp */; }; 2ACF56F614776A1E00991ED5 /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56A014776A1E00991ED5 /* Logging.h */; }; 2ACF56F714776A1E00991ED5 /* LogOps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56A114776A1E00991ED5 /* LogOps.cpp */; }; 2ACF56F814776A1E00991ED5 /* LogOps.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56A214776A1E00991ED5 /* LogOps.h */; }; 2ACF56F914776A1E00991ED5 /* LogTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56A314776A1E00991ED5 /* LogTransform.cpp */; }; 2ACF56FA14776A1E00991ED5 /* Look.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56A414776A1E00991ED5 /* Look.cpp */; }; 2ACF56FB14776A1E00991ED5 /* LookTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56A514776A1E00991ED5 /* LookTransform.cpp */; }; 2ACF56FC14776A1E00991ED5 /* Lut1DOp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56A614776A1E00991ED5 /* Lut1DOp.cpp */; }; 2ACF56FD14776A1E00991ED5 /* Lut1DOp.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56A714776A1E00991ED5 /* Lut1DOp.h */; }; 2ACF56FE14776A1E00991ED5 /* Lut3DOp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56A814776A1E00991ED5 /* Lut3DOp.cpp */; }; 2ACF56FF14776A1E00991ED5 /* Lut3DOp.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56A914776A1E00991ED5 /* Lut3DOp.h */; }; 2ACF570014776A1E00991ED5 /* MathUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56AA14776A1E00991ED5 /* MathUtils.cpp */; }; 2ACF570114776A1E00991ED5 /* MathUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56AB14776A1E00991ED5 /* MathUtils.h */; }; 2ACF570214776A1E00991ED5 /* MatrixOps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56AC14776A1E00991ED5 /* MatrixOps.cpp */; }; 2ACF570314776A1E00991ED5 /* MatrixOps.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56AD14776A1E00991ED5 /* MatrixOps.h */; }; 2ACF570414776A1E00991ED5 /* MatrixTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56AE14776A1E00991ED5 /* MatrixTransform.cpp */; }; 2ACF570514776A1E00991ED5 /* md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56B014776A1E00991ED5 /* md5.cpp */; }; 2ACF570614776A1E00991ED5 /* md5.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56B114776A1E00991ED5 /* md5.h */; }; 2ACF570714776A1E00991ED5 /* Mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56B214776A1E00991ED5 /* Mutex.h */; }; 2ACF570814776A1E00991ED5 /* OCIOYaml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56B314776A1E00991ED5 /* OCIOYaml.cpp */; }; 2ACF570914776A1E00991ED5 /* OCIOYaml.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56B414776A1E00991ED5 /* OCIOYaml.h */; }; 2ACF570A14776A1E00991ED5 /* Op.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56B514776A1E00991ED5 /* Op.cpp */; }; 2ACF570B14776A1E00991ED5 /* Op.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56B614776A1E00991ED5 /* Op.h */; }; 2ACF570C14776A1E00991ED5 /* OpBuilders.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56B714776A1E00991ED5 /* OpBuilders.h */; }; 2ACF570D14776A1E00991ED5 /* ParseUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56B814776A1E00991ED5 /* ParseUtils.cpp */; }; 2ACF570E14776A1E00991ED5 /* ParseUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56B914776A1E00991ED5 /* ParseUtils.h */; }; 2ACF570F14776A1E00991ED5 /* PathUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56BA14776A1E00991ED5 /* PathUtils.cpp */; }; 2ACF571014776A1E00991ED5 /* PathUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56BB14776A1E00991ED5 /* PathUtils.h */; }; 2ACF571114776A1E00991ED5 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56BC14776A1E00991ED5 /* Platform.h */; }; 2ACF571214776A1E00991ED5 /* PrivateTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56BD14776A1E00991ED5 /* PrivateTypes.h */; }; 2ACF571314776A1E00991ED5 /* Processor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56BE14776A1E00991ED5 /* Processor.cpp */; }; 2ACF571414776A1E00991ED5 /* Processor.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56BF14776A1E00991ED5 /* Processor.h */; }; 2ACF571514776A1E00991ED5 /* pystring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56C114776A1E00991ED5 /* pystring.cpp */; }; 2ACF571614776A1E00991ED5 /* pystring.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56C214776A1E00991ED5 /* pystring.h */; }; 2ACF571714776A1E00991ED5 /* ScanlineHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56C314776A1E00991ED5 /* ScanlineHelper.cpp */; }; 2ACF571814776A1E00991ED5 /* ScanlineHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56C414776A1E00991ED5 /* ScanlineHelper.h */; }; 2ACF571914776A1E00991ED5 /* SSE.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56C514776A1E00991ED5 /* SSE.h */; }; 2ACF571A14776A1E00991ED5 /* Transform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56C614776A1E00991ED5 /* Transform.cpp */; }; 2ACF571B14776A1E00991ED5 /* TruelightOp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56C714776A1E00991ED5 /* TruelightOp.cpp */; }; 2ACF571C14776A1E00991ED5 /* TruelightOp.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56C814776A1E00991ED5 /* TruelightOp.h */; }; 2ACF571D14776A1E00991ED5 /* TruelightTransform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56C914776A1E00991ED5 /* TruelightTransform.cpp */; }; 2ACF571E14776A1E00991ED5 /* UnitTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ACF56CA14776A1E00991ED5 /* UnitTest.cpp */; }; 2ACF571F14776A1E00991ED5 /* UnitTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF56CB14776A1E00991ED5 /* UnitTest.h */; }; 2ACF573F14776B7000991ED5 /* OpenColorABI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2ACF573E14776B7000991ED5 /* OpenColorABI.h */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 2A7CACB515536CD700F52C98 /* FileFormatIridasLook.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatIridasLook.cpp; sourceTree = ""; }; 2A7CACB615536CD700F52C98 /* LookParse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LookParse.cpp; sourceTree = ""; }; 2A7CACB715536CD700F52C98 /* LookParse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LookParse.h; sourceTree = ""; }; 2A7CACB815536CD700F52C98 /* NoOps.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NoOps.cpp; sourceTree = ""; }; 2A7CACB915536CD700F52C98 /* NoOps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NoOps.h; sourceTree = ""; }; 2A7CACBA15536CD700F52C98 /* OpOptimizers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpOptimizers.cpp; sourceTree = ""; }; 2A7F20D21E2F17D2003428D7 /* FileFormatCDL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatCDL.cpp; sourceTree = ""; }; 2ACB3CFE1CC074A200134356 /* Display.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Display.cpp; sourceTree = ""; }; 2ACB3CFF1CC074A200134356 /* Display.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Display.h; sourceTree = ""; }; 2ACF567114776A0A00991ED5 /* libOpenColorIO.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libOpenColorIO.a; sourceTree = BUILT_PRODUCTS_DIR; }; 2ACF567614776A1E00991ED5 /* AllocationOp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AllocationOp.cpp; sourceTree = ""; }; 2ACF567714776A1E00991ED5 /* AllocationOp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllocationOp.h; sourceTree = ""; }; 2ACF567814776A1E00991ED5 /* AllocationTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AllocationTransform.cpp; sourceTree = ""; }; 2ACF567914776A1E00991ED5 /* Baker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Baker.cpp; sourceTree = ""; }; 2ACF567A14776A1E00991ED5 /* Caching.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Caching.cpp; sourceTree = ""; }; 2ACF567B14776A1E00991ED5 /* CDLTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CDLTransform.cpp; sourceTree = ""; }; 2ACF567C14776A1E00991ED5 /* CDLTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDLTransform.h; sourceTree = ""; }; 2ACF567D14776A1E00991ED5 /* ColorSpace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ColorSpace.cpp; sourceTree = ""; }; 2ACF567E14776A1E00991ED5 /* ColorSpaceTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ColorSpaceTransform.cpp; sourceTree = ""; }; 2ACF567F14776A1E00991ED5 /* Config.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Config.cpp; sourceTree = ""; }; 2ACF568014776A1E00991ED5 /* Context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Context.cpp; sourceTree = ""; }; 2ACF568114776A1E00991ED5 /* DisplayTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayTransform.cpp; sourceTree = ""; }; 2ACF568214776A1E00991ED5 /* Exception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Exception.cpp; sourceTree = ""; }; 2ACF568314776A1E00991ED5 /* ExponentOps.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExponentOps.cpp; sourceTree = ""; }; 2ACF568414776A1E00991ED5 /* ExponentOps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExponentOps.h; sourceTree = ""; }; 2ACF568514776A1E00991ED5 /* ExponentTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExponentTransform.cpp; sourceTree = ""; }; 2ACF568614776A1E00991ED5 /* FileFormat3DL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormat3DL.cpp; sourceTree = ""; }; 2ACF568714776A1E00991ED5 /* FileFormatCC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatCC.cpp; sourceTree = ""; }; 2ACF568814776A1E00991ED5 /* FileFormatCCC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatCCC.cpp; sourceTree = ""; }; 2ACF568914776A1E00991ED5 /* FileFormatCSP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatCSP.cpp; sourceTree = ""; }; 2ACF568A14776A1E00991ED5 /* FileFormatHDL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatHDL.cpp; sourceTree = ""; }; 2ACF568B14776A1E00991ED5 /* FileFormatIridasCube.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatIridasCube.cpp; sourceTree = ""; }; 2ACF568C14776A1E00991ED5 /* FileFormatIridasItx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatIridasItx.cpp; sourceTree = ""; }; 2ACF568D14776A1E00991ED5 /* FileFormatPandora.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatPandora.cpp; sourceTree = ""; }; 2ACF568E14776A1E00991ED5 /* FileFormatSpi1D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatSpi1D.cpp; sourceTree = ""; }; 2ACF568F14776A1E00991ED5 /* FileFormatSpi3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatSpi3D.cpp; sourceTree = ""; }; 2ACF569014776A1E00991ED5 /* FileFormatSpiMtx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatSpiMtx.cpp; sourceTree = ""; }; 2ACF569114776A1E00991ED5 /* FileFormatTruelight.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatTruelight.cpp; sourceTree = ""; }; 2ACF569214776A1E00991ED5 /* FileFormatVF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileFormatVF.cpp; sourceTree = ""; }; 2ACF569314776A1E00991ED5 /* FileTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileTransform.cpp; sourceTree = ""; }; 2ACF569414776A1E00991ED5 /* FileTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileTransform.h; sourceTree = ""; }; 2ACF569614776A1E00991ED5 /* GpuShaderDesc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GpuShaderDesc.cpp; sourceTree = ""; }; 2ACF569714776A1E00991ED5 /* GpuShaderUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GpuShaderUtils.cpp; sourceTree = ""; }; 2ACF569814776A1E00991ED5 /* GpuShaderUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GpuShaderUtils.h; sourceTree = ""; }; 2ACF569914776A1E00991ED5 /* GroupTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GroupTransform.cpp; sourceTree = ""; }; 2ACF569A14776A1E00991ED5 /* HashUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HashUtils.cpp; sourceTree = ""; }; 2ACF569B14776A1E00991ED5 /* HashUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashUtils.h; sourceTree = ""; }; 2ACF569C14776A1E00991ED5 /* ImageDesc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDesc.cpp; sourceTree = ""; }; 2ACF569D14776A1E00991ED5 /* ImagePacking.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImagePacking.cpp; sourceTree = ""; }; 2ACF569E14776A1E00991ED5 /* ImagePacking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImagePacking.h; sourceTree = ""; }; 2ACF569F14776A1E00991ED5 /* Logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Logging.cpp; sourceTree = ""; }; 2ACF56A014776A1E00991ED5 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = ""; }; 2ACF56A114776A1E00991ED5 /* LogOps.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogOps.cpp; sourceTree = ""; }; 2ACF56A214776A1E00991ED5 /* LogOps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogOps.h; sourceTree = ""; }; 2ACF56A314776A1E00991ED5 /* LogTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LogTransform.cpp; sourceTree = ""; }; 2ACF56A414776A1E00991ED5 /* Look.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Look.cpp; sourceTree = ""; }; 2ACF56A514776A1E00991ED5 /* LookTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LookTransform.cpp; sourceTree = ""; }; 2ACF56A614776A1E00991ED5 /* Lut1DOp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lut1DOp.cpp; sourceTree = ""; }; 2ACF56A714776A1E00991ED5 /* Lut1DOp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lut1DOp.h; sourceTree = ""; }; 2ACF56A814776A1E00991ED5 /* Lut3DOp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lut3DOp.cpp; sourceTree = ""; }; 2ACF56A914776A1E00991ED5 /* Lut3DOp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lut3DOp.h; sourceTree = ""; }; 2ACF56AA14776A1E00991ED5 /* MathUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathUtils.cpp; sourceTree = ""; }; 2ACF56AB14776A1E00991ED5 /* MathUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathUtils.h; sourceTree = ""; }; 2ACF56AC14776A1E00991ED5 /* MatrixOps.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MatrixOps.cpp; sourceTree = ""; }; 2ACF56AD14776A1E00991ED5 /* MatrixOps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatrixOps.h; sourceTree = ""; }; 2ACF56AE14776A1E00991ED5 /* MatrixTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MatrixTransform.cpp; sourceTree = ""; }; 2ACF56B014776A1E00991ED5 /* md5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = md5.cpp; sourceTree = ""; }; 2ACF56B114776A1E00991ED5 /* md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = md5.h; sourceTree = ""; }; 2ACF56B214776A1E00991ED5 /* Mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mutex.h; sourceTree = ""; }; 2ACF56B314776A1E00991ED5 /* OCIOYaml.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OCIOYaml.cpp; sourceTree = ""; }; 2ACF56B414776A1E00991ED5 /* OCIOYaml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCIOYaml.h; sourceTree = ""; }; 2ACF56B514776A1E00991ED5 /* Op.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Op.cpp; sourceTree = ""; }; 2ACF56B614776A1E00991ED5 /* Op.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Op.h; sourceTree = ""; }; 2ACF56B714776A1E00991ED5 /* OpBuilders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpBuilders.h; sourceTree = ""; }; 2ACF56B814776A1E00991ED5 /* ParseUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParseUtils.cpp; sourceTree = ""; }; 2ACF56B914776A1E00991ED5 /* ParseUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseUtils.h; sourceTree = ""; }; 2ACF56BA14776A1E00991ED5 /* PathUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathUtils.cpp; sourceTree = ""; }; 2ACF56BB14776A1E00991ED5 /* PathUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathUtils.h; sourceTree = ""; }; 2ACF56BC14776A1E00991ED5 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Platform.h; sourceTree = ""; }; 2ACF56BD14776A1E00991ED5 /* PrivateTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateTypes.h; sourceTree = ""; }; 2ACF56BE14776A1E00991ED5 /* Processor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Processor.cpp; sourceTree = ""; }; 2ACF56BF14776A1E00991ED5 /* Processor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Processor.h; sourceTree = ""; }; 2ACF56C114776A1E00991ED5 /* pystring.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pystring.cpp; sourceTree = ""; }; 2ACF56C214776A1E00991ED5 /* pystring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pystring.h; sourceTree = ""; }; 2ACF56C314776A1E00991ED5 /* ScanlineHelper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScanlineHelper.cpp; sourceTree = ""; }; 2ACF56C414776A1E00991ED5 /* ScanlineHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScanlineHelper.h; sourceTree = ""; }; 2ACF56C514776A1E00991ED5 /* SSE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSE.h; sourceTree = ""; }; 2ACF56C614776A1E00991ED5 /* Transform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Transform.cpp; sourceTree = ""; }; 2ACF56C714776A1E00991ED5 /* TruelightOp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TruelightOp.cpp; sourceTree = ""; }; 2ACF56C814776A1E00991ED5 /* TruelightOp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TruelightOp.h; sourceTree = ""; }; 2ACF56C914776A1E00991ED5 /* TruelightTransform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TruelightTransform.cpp; sourceTree = ""; }; 2ACF56CA14776A1E00991ED5 /* UnitTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnitTest.cpp; sourceTree = ""; }; 2ACF56CB14776A1E00991ED5 /* UnitTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnitTest.h; sourceTree = ""; }; 2ACF573E14776B7000991ED5 /* OpenColorABI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenColorABI.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 2ACF566F14776A0A00991ED5 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 034768DDFF38A45A11DB9C8B /* Products */ = { isa = PBXGroup; children = ( 2ACF567114776A0A00991ED5 /* libOpenColorIO.a */, ); name = Products; sourceTree = ""; }; 0867D691FE84028FC02AAC07 /* OpenColorIO */ = { isa = PBXGroup; children = ( 2ACF573E14776B7000991ED5 /* OpenColorABI.h */, 2ACF567514776A1E00991ED5 /* core */, 034768DDFF38A45A11DB9C8B /* Products */, ); name = OpenColorIO; sourceTree = ""; }; 2ACF567514776A1E00991ED5 /* core */ = { isa = PBXGroup; children = ( 2ACB3CFE1CC074A200134356 /* Display.cpp */, 2ACB3CFF1CC074A200134356 /* Display.h */, 2ACF567614776A1E00991ED5 /* AllocationOp.cpp */, 2ACF567714776A1E00991ED5 /* AllocationOp.h */, 2ACF567814776A1E00991ED5 /* AllocationTransform.cpp */, 2ACF567914776A1E00991ED5 /* Baker.cpp */, 2ACF567A14776A1E00991ED5 /* Caching.cpp */, 2ACF567B14776A1E00991ED5 /* CDLTransform.cpp */, 2ACF567C14776A1E00991ED5 /* CDLTransform.h */, 2ACF567D14776A1E00991ED5 /* ColorSpace.cpp */, 2ACF567E14776A1E00991ED5 /* ColorSpaceTransform.cpp */, 2ACF567F14776A1E00991ED5 /* Config.cpp */, 2ACF568014776A1E00991ED5 /* Context.cpp */, 2ACF568114776A1E00991ED5 /* DisplayTransform.cpp */, 2ACF568214776A1E00991ED5 /* Exception.cpp */, 2ACF568314776A1E00991ED5 /* ExponentOps.cpp */, 2ACF568414776A1E00991ED5 /* ExponentOps.h */, 2ACF568514776A1E00991ED5 /* ExponentTransform.cpp */, 2ACF568614776A1E00991ED5 /* FileFormat3DL.cpp */, 2ACF568714776A1E00991ED5 /* FileFormatCC.cpp */, 2ACF568814776A1E00991ED5 /* FileFormatCCC.cpp */, 2A7F20D21E2F17D2003428D7 /* FileFormatCDL.cpp */, 2ACF568914776A1E00991ED5 /* FileFormatCSP.cpp */, 2ACF568A14776A1E00991ED5 /* FileFormatHDL.cpp */, 2ACF568B14776A1E00991ED5 /* FileFormatIridasCube.cpp */, 2ACF568C14776A1E00991ED5 /* FileFormatIridasItx.cpp */, 2A7CACB515536CD700F52C98 /* FileFormatIridasLook.cpp */, 2ACF568D14776A1E00991ED5 /* FileFormatPandora.cpp */, 2ACF568E14776A1E00991ED5 /* FileFormatSpi1D.cpp */, 2ACF568F14776A1E00991ED5 /* FileFormatSpi3D.cpp */, 2ACF569014776A1E00991ED5 /* FileFormatSpiMtx.cpp */, 2ACF569114776A1E00991ED5 /* FileFormatTruelight.cpp */, 2ACF569214776A1E00991ED5 /* FileFormatVF.cpp */, 2ACF569314776A1E00991ED5 /* FileTransform.cpp */, 2ACF569414776A1E00991ED5 /* FileTransform.h */, 2ACF569614776A1E00991ED5 /* GpuShaderDesc.cpp */, 2ACF569714776A1E00991ED5 /* GpuShaderUtils.cpp */, 2ACF569814776A1E00991ED5 /* GpuShaderUtils.h */, 2ACF569914776A1E00991ED5 /* GroupTransform.cpp */, 2ACF569A14776A1E00991ED5 /* HashUtils.cpp */, 2ACF569B14776A1E00991ED5 /* HashUtils.h */, 2ACF569C14776A1E00991ED5 /* ImageDesc.cpp */, 2ACF569D14776A1E00991ED5 /* ImagePacking.cpp */, 2ACF569E14776A1E00991ED5 /* ImagePacking.h */, 2ACF569F14776A1E00991ED5 /* Logging.cpp */, 2ACF56A014776A1E00991ED5 /* Logging.h */, 2ACF56A114776A1E00991ED5 /* LogOps.cpp */, 2ACF56A214776A1E00991ED5 /* LogOps.h */, 2A7CACB615536CD700F52C98 /* LookParse.cpp */, 2A7CACB715536CD700F52C98 /* LookParse.h */, 2ACF56A314776A1E00991ED5 /* LogTransform.cpp */, 2ACF56A414776A1E00991ED5 /* Look.cpp */, 2ACF56A514776A1E00991ED5 /* LookTransform.cpp */, 2ACF56A614776A1E00991ED5 /* Lut1DOp.cpp */, 2ACF56A714776A1E00991ED5 /* Lut1DOp.h */, 2ACF56A814776A1E00991ED5 /* Lut3DOp.cpp */, 2ACF56A914776A1E00991ED5 /* Lut3DOp.h */, 2ACF56AA14776A1E00991ED5 /* MathUtils.cpp */, 2ACF56AB14776A1E00991ED5 /* MathUtils.h */, 2ACF56AC14776A1E00991ED5 /* MatrixOps.cpp */, 2ACF56AD14776A1E00991ED5 /* MatrixOps.h */, 2ACF56AE14776A1E00991ED5 /* MatrixTransform.cpp */, 2ACF56AF14776A1E00991ED5 /* md5 */, 2ACF56B214776A1E00991ED5 /* Mutex.h */, 2A7CACB815536CD700F52C98 /* NoOps.cpp */, 2A7CACB915536CD700F52C98 /* NoOps.h */, 2ACF56B314776A1E00991ED5 /* OCIOYaml.cpp */, 2ACF56B414776A1E00991ED5 /* OCIOYaml.h */, 2ACF56B514776A1E00991ED5 /* Op.cpp */, 2ACF56B614776A1E00991ED5 /* Op.h */, 2ACF56B714776A1E00991ED5 /* OpBuilders.h */, 2A7CACBA15536CD700F52C98 /* OpOptimizers.cpp */, 2ACF56B814776A1E00991ED5 /* ParseUtils.cpp */, 2ACF56B914776A1E00991ED5 /* ParseUtils.h */, 2ACF56BA14776A1E00991ED5 /* PathUtils.cpp */, 2ACF56BB14776A1E00991ED5 /* PathUtils.h */, 2ACF56BC14776A1E00991ED5 /* Platform.h */, 2ACF56BD14776A1E00991ED5 /* PrivateTypes.h */, 2ACF56BE14776A1E00991ED5 /* Processor.cpp */, 2ACF56BF14776A1E00991ED5 /* Processor.h */, 2ACF56C014776A1E00991ED5 /* pystring */, 2ACF56C314776A1E00991ED5 /* ScanlineHelper.cpp */, 2ACF56C414776A1E00991ED5 /* ScanlineHelper.h */, 2ACF56C514776A1E00991ED5 /* SSE.h */, 2ACF56C614776A1E00991ED5 /* Transform.cpp */, 2ACF56C714776A1E00991ED5 /* TruelightOp.cpp */, 2ACF56C814776A1E00991ED5 /* TruelightOp.h */, 2ACF56C914776A1E00991ED5 /* TruelightTransform.cpp */, 2ACF56CA14776A1E00991ED5 /* UnitTest.cpp */, 2ACF56CB14776A1E00991ED5 /* UnitTest.h */, ); name = core; path = ../../core; sourceTree = SOURCE_ROOT; }; 2ACF56AF14776A1E00991ED5 /* md5 */ = { isa = PBXGroup; children = ( 2ACF56B014776A1E00991ED5 /* md5.cpp */, 2ACF56B114776A1E00991ED5 /* md5.h */, ); path = md5; sourceTree = ""; }; 2ACF56C014776A1E00991ED5 /* pystring */ = { isa = PBXGroup; children = ( 2ACF56C114776A1E00991ED5 /* pystring.cpp */, 2ACF56C214776A1E00991ED5 /* pystring.h */, ); path = pystring; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 2ACF566D14776A0A00991ED5 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 2ACF56CD14776A1E00991ED5 /* AllocationOp.h in Headers */, 2ACF56D214776A1E00991ED5 /* CDLTransform.h in Headers */, 2ACF56DA14776A1E00991ED5 /* ExponentOps.h in Headers */, 2ACF56EA14776A1E00991ED5 /* FileTransform.h in Headers */, 2ACF56EE14776A1E00991ED5 /* GpuShaderUtils.h in Headers */, 2ACF56F114776A1E00991ED5 /* HashUtils.h in Headers */, 2ACF56F414776A1E00991ED5 /* ImagePacking.h in Headers */, 2ACF56F614776A1E00991ED5 /* Logging.h in Headers */, 2ACF56F814776A1E00991ED5 /* LogOps.h in Headers */, 2ACF56FD14776A1E00991ED5 /* Lut1DOp.h in Headers */, 2ACF56FF14776A1E00991ED5 /* Lut3DOp.h in Headers */, 2ACF570114776A1E00991ED5 /* MathUtils.h in Headers */, 2ACF570314776A1E00991ED5 /* MatrixOps.h in Headers */, 2ACF570614776A1E00991ED5 /* md5.h in Headers */, 2ACF570714776A1E00991ED5 /* Mutex.h in Headers */, 2ACF570914776A1E00991ED5 /* OCIOYaml.h in Headers */, 2ACF570B14776A1E00991ED5 /* Op.h in Headers */, 2ACF570C14776A1E00991ED5 /* OpBuilders.h in Headers */, 2ACF570E14776A1E00991ED5 /* ParseUtils.h in Headers */, 2ACF571014776A1E00991ED5 /* PathUtils.h in Headers */, 2ACF571114776A1E00991ED5 /* Platform.h in Headers */, 2ACF571214776A1E00991ED5 /* PrivateTypes.h in Headers */, 2ACF571414776A1E00991ED5 /* Processor.h in Headers */, 2ACF571614776A1E00991ED5 /* pystring.h in Headers */, 2ACF571814776A1E00991ED5 /* ScanlineHelper.h in Headers */, 2ACF571914776A1E00991ED5 /* SSE.h in Headers */, 2ACF571C14776A1E00991ED5 /* TruelightOp.h in Headers */, 2ACF571F14776A1E00991ED5 /* UnitTest.h in Headers */, 2ACF573F14776B7000991ED5 /* OpenColorABI.h in Headers */, 2A7CACBD15536CD700F52C98 /* LookParse.h in Headers */, 2A7CACBF15536CD700F52C98 /* NoOps.h in Headers */, 2ACB3D011CC074A200134356 /* Display.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 2ACF567014776A0A00991ED5 /* OpenColorIO */ = { isa = PBXNativeTarget; buildConfigurationList = 2ACF567414776A1300991ED5 /* Build configuration list for PBXNativeTarget "OpenColorIO" */; buildPhases = ( 2ACF566D14776A0A00991ED5 /* Headers */, 2ACF566E14776A0A00991ED5 /* Sources */, 2ACF566F14776A0A00991ED5 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = OpenColorIO; productName = OpenColorIO; productReference = 2ACF567114776A0A00991ED5 /* libOpenColorIO.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB916408733D950010E9CD /* Build configuration list for PBXProject "OpenColorIO" */; compatibilityVersion = "Xcode 3.1"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 0867D691FE84028FC02AAC07 /* OpenColorIO */; productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 2ACF567014776A0A00991ED5 /* OpenColorIO */, ); }; /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ 2ACF566E14776A0A00991ED5 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 2ACF56CC14776A1E00991ED5 /* AllocationOp.cpp in Sources */, 2ACF56CE14776A1E00991ED5 /* AllocationTransform.cpp in Sources */, 2ACF56CF14776A1E00991ED5 /* Baker.cpp in Sources */, 2ACF56D014776A1E00991ED5 /* Caching.cpp in Sources */, 2ACF56D114776A1E00991ED5 /* CDLTransform.cpp in Sources */, 2ACF56D314776A1E00991ED5 /* ColorSpace.cpp in Sources */, 2ACF56D414776A1E00991ED5 /* ColorSpaceTransform.cpp in Sources */, 2ACF56D514776A1E00991ED5 /* Config.cpp in Sources */, 2ACF56D614776A1E00991ED5 /* Context.cpp in Sources */, 2ACF56D714776A1E00991ED5 /* DisplayTransform.cpp in Sources */, 2ACF56D814776A1E00991ED5 /* Exception.cpp in Sources */, 2ACF56D914776A1E00991ED5 /* ExponentOps.cpp in Sources */, 2ACF56DB14776A1E00991ED5 /* ExponentTransform.cpp in Sources */, 2ACF56DC14776A1E00991ED5 /* FileFormat3DL.cpp in Sources */, 2ACF56DD14776A1E00991ED5 /* FileFormatCC.cpp in Sources */, 2ACF56DE14776A1E00991ED5 /* FileFormatCCC.cpp in Sources */, 2ACF56DF14776A1E00991ED5 /* FileFormatCSP.cpp in Sources */, 2ACF56E014776A1E00991ED5 /* FileFormatHDL.cpp in Sources */, 2ACF56E114776A1E00991ED5 /* FileFormatIridasCube.cpp in Sources */, 2ACF56E214776A1E00991ED5 /* FileFormatIridasItx.cpp in Sources */, 2ACF56E314776A1E00991ED5 /* FileFormatPandora.cpp in Sources */, 2ACF56E414776A1E00991ED5 /* FileFormatSpi1D.cpp in Sources */, 2ACF56E514776A1E00991ED5 /* FileFormatSpi3D.cpp in Sources */, 2ACF56E614776A1E00991ED5 /* FileFormatSpiMtx.cpp in Sources */, 2ACF56E714776A1E00991ED5 /* FileFormatTruelight.cpp in Sources */, 2ACF56E814776A1E00991ED5 /* FileFormatVF.cpp in Sources */, 2ACF56E914776A1E00991ED5 /* FileTransform.cpp in Sources */, 2ACF56EC14776A1E00991ED5 /* GpuShaderDesc.cpp in Sources */, 2ACF56ED14776A1E00991ED5 /* GpuShaderUtils.cpp in Sources */, 2ACF56EF14776A1E00991ED5 /* GroupTransform.cpp in Sources */, 2ACF56F014776A1E00991ED5 /* HashUtils.cpp in Sources */, 2ACF56F214776A1E00991ED5 /* ImageDesc.cpp in Sources */, 2ACF56F314776A1E00991ED5 /* ImagePacking.cpp in Sources */, 2ACF56F514776A1E00991ED5 /* Logging.cpp in Sources */, 2ACF56F714776A1E00991ED5 /* LogOps.cpp in Sources */, 2ACF56F914776A1E00991ED5 /* LogTransform.cpp in Sources */, 2ACF56FA14776A1E00991ED5 /* Look.cpp in Sources */, 2ACF56FB14776A1E00991ED5 /* LookTransform.cpp in Sources */, 2ACF56FC14776A1E00991ED5 /* Lut1DOp.cpp in Sources */, 2ACF56FE14776A1E00991ED5 /* Lut3DOp.cpp in Sources */, 2ACF570014776A1E00991ED5 /* MathUtils.cpp in Sources */, 2ACF570214776A1E00991ED5 /* MatrixOps.cpp in Sources */, 2ACF570414776A1E00991ED5 /* MatrixTransform.cpp in Sources */, 2ACF570514776A1E00991ED5 /* md5.cpp in Sources */, 2ACF570814776A1E00991ED5 /* OCIOYaml.cpp in Sources */, 2ACF570A14776A1E00991ED5 /* Op.cpp in Sources */, 2ACF570D14776A1E00991ED5 /* ParseUtils.cpp in Sources */, 2ACF570F14776A1E00991ED5 /* PathUtils.cpp in Sources */, 2ACF571314776A1E00991ED5 /* Processor.cpp in Sources */, 2ACF571514776A1E00991ED5 /* pystring.cpp in Sources */, 2ACF571714776A1E00991ED5 /* ScanlineHelper.cpp in Sources */, 2ACF571A14776A1E00991ED5 /* Transform.cpp in Sources */, 2ACF571B14776A1E00991ED5 /* TruelightOp.cpp in Sources */, 2ACF571D14776A1E00991ED5 /* TruelightTransform.cpp in Sources */, 2ACF571E14776A1E00991ED5 /* UnitTest.cpp in Sources */, 2A7CACBB15536CD700F52C98 /* FileFormatIridasLook.cpp in Sources */, 2A7CACBC15536CD700F52C98 /* LookParse.cpp in Sources */, 2A7CACBE15536CD700F52C98 /* NoOps.cpp in Sources */, 2A7CACC015536CD700F52C98 /* OpOptimizers.cpp in Sources */, 2ACB3D001CC074A200134356 /* Display.cpp in Sources */, 2A7F20D31E2F17D2003428D7 /* FileFormatCDL.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 1DEB916508733D950010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( TIXML_USE_STL, OLDYAML, ); GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( ../../../export, ../../../ext/tinyxml, "../../../ext/yaml-cpp/include", ); ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; SDKROOT = macosx10.5; }; name = Debug; }; 1DEB916608733D950010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PREPROCESSOR_DEFINITIONS = ( NDEBUG, TIXML_USE_STL, OLDYAML, ); GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( ../../../export, ../../../ext/tinyxml, "../../../ext/yaml-cpp/include", ); PREBINDING = NO; SDKROOT = macosx10.5; }; name = Release; }; 2ACF567214776A0A00991ED5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; INSTALL_PATH = /usr/local/lib; PREBINDING = NO; PRODUCT_NAME = OpenColorIO; }; name = Debug; }; 2ACF567314776A0A00991ED5 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; INSTALL_PATH = /usr/local/lib; PREBINDING = NO; PRODUCT_NAME = OpenColorIO; ZERO_LINK = NO; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1DEB916408733D950010E9CD /* Build configuration list for PBXProject "OpenColorIO" */ = { isa = XCConfigurationList; buildConfigurations = ( 1DEB916508733D950010E9CD /* Debug */, 1DEB916608733D950010E9CD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 2ACF567414776A1300991ED5 /* Build configuration list for PBXNativeTarget "OpenColorIO" */ = { isa = XCConfigurationList; buildConfigurations = ( 2ACF567214776A0A00991ED5 /* Debug */, 2ACF567314776A0A00991ED5 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 0867D690FE84028FC02AAC07 /* Project object */; } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/OpenColorIO_AE_UI.cpp0000644000175000017500000013052613223553423023323 0ustar mfvmfv/* Copyright (c) 2003-2012 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 "OpenColorIO_AE.h" #include "OpenColorIO_AE_Context.h" #include "OpenColorIO_AE_Dialogs.h" #include "DrawbotBot.h" // UI drawing constants #define LEFT_MARGIN 5 #define TOP_MARGIN 5 #define RIGHT_MARGIN 50 #define FILE_LABEL_WIDTH 35 #define FIELD_HEIGHT 22 #define FIELD_TEXT_INDENT_H 10 #define FIELD_TEXT_INDENT_V 4 #define BUTTONS_INDENT_H (LEFT_MARGIN + 70) #define BUTTONS_GAP_V 20 #define BUTTONS_GAP_H 30 #define BUTTON_HEIGHT 20 #define BUTTON_WIDTH 80 #define BUTTON_TEXT_INDENT_V 2 #define MENUS_INDENT_H 0 #define MENUS_GAP_V 20 #define MENU_LABEL_WIDTH 100 #define MENU_LABEL_SPACE 5 #define MENU_WIDTH 150 #define MENU_HEIGHT 20 #define MENU_TEXT_INDENT_H 10 #define MENU_TEXT_INDENT_V 2 #define MENU_ARROW_WIDTH 14 #define MENU_ARROW_HEIGHT 7 #define MENU_ARROW_SPACE_H 8 #define MENU_ARROW_SPACE_V 7 #define MENU_SHADOW_OFFSET 3 #define MENU_SPACE_V 20 #define TEXT_COLOR PF_App_Color_TEXT_DISABLED typedef enum { REGION_NONE=0, REGION_CONFIG_MENU, REGION_PATH, REGION_CONVERT_BUTTON, REGION_DISPLAY_BUTTON, REGION_EXPORT_BUTTON, REGION_MENU1, REGION_MENU2, REGION_MENU3 } UIRegion; static UIRegion WhichRegion(PF_Point ui_point, bool menus, bool third_menu) { int field_top = TOP_MARGIN; int field_bottom = field_top + FIELD_HEIGHT; if(ui_point.v >= field_top && ui_point.v <= field_bottom) { int menu_left = LEFT_MARGIN + MENUS_INDENT_H + MENU_LABEL_WIDTH; int menu_right = menu_left + MENU_WIDTH; if(ui_point.h >= menu_left && ui_point.h <= menu_right) { return REGION_CONFIG_MENU; } else { int field_left = MENUS_INDENT_H + MENU_LABEL_WIDTH + MENU_LABEL_SPACE + MENU_WIDTH + FIELD_TEXT_INDENT_H; if(ui_point.h >= field_left) return REGION_PATH; } } else { int buttons_top = field_bottom + BUTTONS_GAP_V; int buttons_bottom = buttons_top + BUTTON_HEIGHT; if(ui_point.v >= buttons_top && ui_point.v <= buttons_bottom) { int convert_left = BUTTONS_INDENT_H; int convert_right = convert_left + BUTTON_WIDTH; int display_left = convert_right + BUTTONS_GAP_H; int display_right = display_left + BUTTON_WIDTH; int export_left = display_right + BUTTONS_GAP_H; int export_right = export_left + BUTTON_WIDTH; if(ui_point.h >= convert_left && ui_point.h <= convert_right) return REGION_CONVERT_BUTTON; else if(ui_point.h >= display_left && ui_point.h <= display_right) return REGION_DISPLAY_BUTTON; else if(ui_point.h >= export_left && ui_point.h <= export_right) return REGION_EXPORT_BUTTON; } else if(menus) { int menu_left = LEFT_MARGIN + MENUS_INDENT_H + MENU_LABEL_WIDTH; int menu_right = menu_left + MENU_WIDTH; if(ui_point.h >= menu_left && ui_point.h <= menu_right) { int menu1_top = buttons_bottom + MENUS_GAP_V; int menu1_bottom = menu1_top + MENU_HEIGHT; int menu2_top = menu1_bottom + MENU_SPACE_V; int menu2_bottom = menu2_top + MENU_HEIGHT; int menu3_top = menu2_bottom + MENU_SPACE_V; int menu3_bottom = menu3_top + MENU_HEIGHT; if(ui_point.v >= menu1_top && ui_point.v <= menu1_bottom) return REGION_MENU1; else if(ui_point.v >= menu2_top && ui_point.v <= menu2_bottom) return REGION_MENU2; else if(third_menu && ui_point.v >= menu3_top && ui_point.v <= menu3_bottom) return REGION_MENU3; } } } return REGION_NONE; } static void DrawMenu(DrawbotBot &bot, const char *label, const char *item) { DRAWBOT_PointF32 original = bot.Pos(); float text_height = bot.FontSize(); bot.Move(MENU_LABEL_WIDTH, MENU_TEXT_INDENT_V + text_height); bot.SetColor(TEXT_COLOR); bot.DrawString(label, kDRAWBOT_TextAlignment_Right); bot.Move(MENU_LABEL_SPACE, -(MENU_TEXT_INDENT_V + text_height)); DRAWBOT_PointF32 menu_corner = bot.Pos(); bot.Move(MENU_SHADOW_OFFSET, MENU_SHADOW_OFFSET); bot.SetColor(PF_App_Color_BLACK, 0.3f); bot.PaintRect(MENU_WIDTH, MENU_HEIGHT); bot.MoveTo(menu_corner); bot.SetColor(PF_App_Color_SHADOW); bot.PaintRect(MENU_WIDTH, MENU_HEIGHT); bot.SetColor(PF_App_Color_HILITE); bot.DrawRect(MENU_WIDTH, MENU_HEIGHT); bot.Move(MENU_TEXT_INDENT_H, MENU_TEXT_INDENT_V + text_height); bot.SetColor(TEXT_COLOR); bot.DrawString(item, kDRAWBOT_TextAlignment_Left, kDRAWBOT_TextTruncation_EndEllipsis, MENU_WIDTH - MENU_TEXT_INDENT_H - MENU_TEXT_INDENT_H - MENU_ARROW_WIDTH - MENU_ARROW_SPACE_H - MENU_ARROW_SPACE_H); bot.MoveTo(menu_corner.x + MENU_WIDTH - MENU_ARROW_SPACE_H - MENU_ARROW_WIDTH, menu_corner.y + MENU_ARROW_SPACE_V); bot.SetColor(PF_App_Color_LIGHT_TINGE); bot.PaintTriangle(MENU_ARROW_WIDTH, MENU_ARROW_HEIGHT); bot.MoveTo(original); } static void DrawButton(DrawbotBot &bot, const char *label, int width, bool pressed) { DRAWBOT_PointF32 original = bot.Pos(); float text_height = bot.FontSize(); PF_App_ColorType button_color = (pressed ? PF_App_Color_BUTTON_PRESSED_FILL : PF_App_Color_BUTTON_FILL); PF_App_ColorType button_hilite = (pressed ? PF_App_Color_BLACK : PF_App_Color_HILITE); PF_App_ColorType button_lowlite = (pressed ? PF_App_Color_HILITE : PF_App_Color_BLACK); bot.SetColor(button_color); bot.PaintRect(width, BUTTON_HEIGHT); float brush_size = (pressed ? 1.f : 0.5f); bot.SetColor(button_hilite); bot.MoveTo(original.x + 1, original.y + BUTTON_HEIGHT - 1); bot.DrawLineTo(original.x + 1, original.y + 1, brush_size); bot.DrawLineTo(original.x + width - 1, original.y + 1, brush_size); bot.MoveTo(original); // annoying corner pixel bot.SetColor(button_hilite, 0.3f); bot.PaintRect(1, 1); brush_size = (pressed ? 0.5f : 1.f); bot.SetColor(button_lowlite); bot.MoveTo(original.x + 1, original.y + BUTTON_HEIGHT - 1); bot.DrawLineTo(original.x + width - 1, original.y + BUTTON_HEIGHT - 1, brush_size); bot.DrawLineTo(original.x + width - 1, original.y + 2, brush_size); bot.MoveTo(original.x + width - 1, original.y + BUTTON_HEIGHT - 1); // corner bot.SetColor(button_lowlite, 0.3f); bot.PaintRect(1, 1); bot.MoveTo(original.x + (width / 2), original.y + text_height + BUTTON_TEXT_INDENT_V); if(pressed) bot.Move(2, 2); bot.SetColor(TEXT_COLOR); bot.DrawString(label, kDRAWBOT_TextAlignment_Center); bot.MoveTo(original); } static PF_Err DrawEvent( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, PF_EventExtra *event_extra) { PF_Err err = PF_Err_NONE; if(!(event_extra->evt_in_flags & PF_EI_DONT_DRAW) && params[OCIO_DATA]->u.arb_d.value != NULL) { if(event_extra->effect_win.area == PF_EA_CONTROL) { ArbitraryData *arb_data = (ArbitraryData *)PF_LOCK_HANDLE(params[OCIO_DATA]->u.arb_d.value); SequenceData *seq_data = (SequenceData *)PF_LOCK_HANDLE(in_data->sequence_data); DrawbotBot bot(in_data->pica_basicP, event_extra->contextH, in_data->appl_id); int panel_left = event_extra->effect_win.current_frame.left; int panel_top = event_extra->effect_win.current_frame.top; int panel_width = event_extra->effect_win.current_frame.right; int panel_height = event_extra->effect_win.current_frame.bottom; float text_height = bot.FontSize(); if(in_data->appl_id != 'FXTC') { // for Premiere we need to paint the background first bot.SetColor(PF_App_Color_PANEL_BACKGROUND); bot.MoveTo(panel_left, panel_top); bot.PaintRect(panel_width, panel_height); } // configuration menu bot.MoveTo(panel_left + MENUS_INDENT_H, panel_top + TOP_MARGIN); std::string config_menu_text = arb_data->path; if(arb_data->source == OCIO_SOURCE_NONE) { config_menu_text = "(none)"; } if(arb_data->source == OCIO_SOURCE_ENVIRONMENT) { config_menu_text = "$OCIO"; } else if(arb_data->source == OCIO_SOURCE_CUSTOM) { config_menu_text = (arb_data->action == OCIO_ACTION_LUT ? "LUT" : "Custom"); } DrawMenu(bot, "Configuration:", config_menu_text.c_str()); if(arb_data->source == OCIO_SOURCE_CUSTOM || arb_data->source == OCIO_SOURCE_ENVIRONMENT) { // path text field int field_left = panel_left + MENUS_INDENT_H + MENU_LABEL_WIDTH + MENU_LABEL_SPACE + MENU_WIDTH + FIELD_TEXT_INDENT_H; bot.MoveTo(field_left, panel_top + TOP_MARGIN); int field_width = MAX(panel_width - field_left + panel_left - RIGHT_MARGIN, 60); bot.SetColor(PF_App_Color_SHADOW); bot.PaintRect(field_width, FIELD_HEIGHT); bot.SetColor(PF_App_Color_BLACK); bot.DrawRect(field_width, FIELD_HEIGHT); bot.Move(FIELD_TEXT_INDENT_H, FIELD_TEXT_INDENT_V + text_height); bot.SetColor(TEXT_COLOR); std::string file_string = "(none)"; if(arb_data->source == OCIO_SOURCE_ENVIRONMENT) { char *file = std::getenv("OCIO"); if(file) file_string = file; } else { file_string = (seq_data->status == STATUS_USING_RELATIVE ? arb_data->relative_path : arb_data->path); } bot.DrawString(file_string.c_str(), kDRAWBOT_TextAlignment_Default, kDRAWBOT_TextTruncation_PathEllipsis, field_width - (2 * FIELD_TEXT_INDENT_H)); } if(seq_data->status == STATUS_FILE_MISSING) { bot.MoveTo(panel_left + MENU_LABEL_WIDTH + MENU_LABEL_SPACE, panel_top + MENU_HEIGHT + BUTTONS_GAP_V + BUTTON_HEIGHT + BUTTONS_GAP_V); bot.SetColor(PF_App_Color_RED); bot.PaintRect(200, 50); bot.Move(100, 25 + (bot.FontSize() / 2)); bot.SetColor(PF_App_Color_WHITE); if(arb_data->source == OCIO_SOURCE_ENVIRONMENT) bot.DrawString("$OCIO NOT SET", kDRAWBOT_TextAlignment_Center); else bot.DrawString("FILE MISSING", kDRAWBOT_TextAlignment_Center); } else { // buttons int field_bottom = panel_top + TOP_MARGIN + FIELD_HEIGHT; int buttons_top = field_bottom + BUTTONS_GAP_V; // GPU alert if(seq_data->gpu_err != GPU_ERR_NONE) { bot.MoveTo(panel_left + MENU_LABEL_WIDTH + MENU_LABEL_SPACE, field_bottom + bot.FontSize() + BUTTON_TEXT_INDENT_V); if(seq_data->gpu_err == GPU_ERR_INSUFFICIENT) { bot.DrawString("GPU Insufficient"); } else if(seq_data->gpu_err == GPU_ERR_RENDER_ERR) { bot.DrawString("GPU Render Error"); } } #ifndef NDEBUG // Premiere color space (only for debugging purposes) if(in_data->appl_id == 'PrMr' && seq_data->prem_status != PREMIERE_UNKNOWN) { bot.MoveTo(panel_left + MENU_LABEL_WIDTH + MENU_LABEL_SPACE + 200, field_bottom + bot.FontSize() + BUTTON_TEXT_INDENT_V); bot.SetColor(PF_App_Color_WHITE); if(seq_data->prem_status == PREMIERE_LINEAR) { bot.DrawString("Linear Float"); } else if(seq_data->prem_status == PREMIERE_NON_LINEAR) { bot.DrawString("Non-Linear Float"); } } #endif // Export button if(arb_data->action != OCIO_ACTION_NONE) { bot.MoveTo(panel_left + BUTTONS_INDENT_H + (2 * (BUTTON_WIDTH + BUTTONS_GAP_H)), buttons_top); DrawButton(bot, "Export...", BUTTON_WIDTH, false); } if(arb_data->action == OCIO_ACTION_LUT) { // Invert button bot.MoveTo(panel_left + BUTTONS_INDENT_H, buttons_top); DrawButton(bot, "Invert", BUTTON_WIDTH, arb_data->invert); // interpolation menu int buttons_bottom = buttons_top + BUTTON_HEIGHT; bot.MoveTo(panel_left + MENUS_INDENT_H, buttons_bottom + MENUS_GAP_V); const char *txt = arb_data->interpolation == OCIO_INTERP_NEAREST ? "Nearest Neighbor" : arb_data->interpolation == OCIO_INTERP_LINEAR ? "Linear" : arb_data->interpolation == OCIO_INTERP_TETRAHEDRAL ? "Tetrahedral" : arb_data->interpolation == OCIO_INTERP_BEST ? "Best" : "Unknown"; DrawMenu(bot, "Interpolation:", txt); } else if(arb_data->action == OCIO_ACTION_CONVERT || arb_data->action == OCIO_ACTION_DISPLAY) { // Convert/Display buttons bot.MoveTo(panel_left + BUTTONS_INDENT_H, buttons_top); DrawButton(bot, "Convert", BUTTON_WIDTH, arb_data->action == OCIO_ACTION_CONVERT); bot.Move(BUTTON_WIDTH + BUTTONS_GAP_H); DrawButton(bot, "Display", BUTTON_WIDTH, arb_data->action == OCIO_ACTION_DISPLAY); // menus int buttons_bottom = buttons_top + BUTTON_HEIGHT; bot.MoveTo(panel_left + MENUS_INDENT_H, buttons_bottom + MENUS_GAP_V); if(arb_data->action == OCIO_ACTION_CONVERT) { DrawMenu(bot, "Input Space:", arb_data->input); bot.Move(0, MENU_HEIGHT + MENU_SPACE_V); DrawMenu(bot, "Output Space:", arb_data->output); } else if(arb_data->action == OCIO_ACTION_DISPLAY) { // color space transformations DrawMenu(bot, "Input Space:", arb_data->input); bot.Move(0, MENU_HEIGHT + MENU_SPACE_V); DrawMenu(bot, "Device:", arb_data->device); bot.Move(0, MENU_HEIGHT + MENU_SPACE_V); DrawMenu(bot, "Transform:", arb_data->transform); } } } event_extra->evt_out_flags = PF_EO_HANDLED_EVENT; PF_UNLOCK_HANDLE(params[OCIO_DATA]->u.arb_d.value); PF_UNLOCK_HANDLE(in_data->sequence_data); } } return err; } std::string GetProjectDir(PF_InData *in_data) { if(in_data->appl_id == 'PrMr') return std::string(""); AEGP_SuiteHandler suites(in_data->pica_basicP); AEGP_ProjectH projH = NULL; suites.ProjSuite5()->AEGP_GetProjectByIndex(0, &projH); AEGP_MemHandle pathH = NULL; suites.ProjSuite5()->AEGP_GetProjectPath(projH, &pathH); if(pathH) { std::string proj_dir; A_UTF16Char *path = NULL; suites.MemorySuite1()->AEGP_LockMemHandle(pathH, (void **)&path); if(path) { // poor-man's unicode copy char c_path[AEGP_MAX_PATH_SIZE]; char *c = c_path; A_UTF16Char *s = path; do{ *c++ = *s; }while(*s++ != '\0'); #ifdef WIN_ENV #define PATH_DELIMITER '\\' #else #define PATH_DELIMITER '/' #endif std::string proj_path(c_path); if(proj_path.find_last_of(PATH_DELIMITER) != std::string::npos) { proj_dir = proj_path.substr(0, proj_path.find_last_of(PATH_DELIMITER)); } } suites.MemorySuite1()->AEGP_FreeMemHandle(pathH); return proj_dir; } return std::string(""); } static int FindInVec(const std::vector &vec, const std::string val) { for(int i=0; i < vec.size(); i++) { if(vec[i] == val) return i; } return -1; } static void DoClickPath( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, PF_EventExtra *event_extra, ArbitraryData *arb_data, SequenceData *seq_data) { ExtensionMap extensions; for(int i=0; i < OCIO::FileTransform::getNumFormats(); i++) { const char *extension = OCIO::FileTransform::getFormatExtensionByIndex(i); const char *format = OCIO::FileTransform::getFormatNameByIndex(i); if(extension != std::string("ccc")) // .ccc files require an ID parameter extensions[ extension ] = format; } extensions[ "ocio" ] = "OCIO Format"; void *hwndOwner = NULL; #ifdef WIN_ENV PF_GET_PLATFORM_DATA(PF_PlatData_MAIN_WND, &hwndOwner); #endif char c_path[ARB_PATH_LEN + 1] = { '\0' }; bool result = OpenFile(c_path, ARB_PATH_LEN, extensions, hwndOwner); if(result) { Path path(c_path, GetProjectDir(in_data)); OpenColorIO_AE_Context *new_context = new OpenColorIO_AE_Context(path.full_path(), OCIO_SOURCE_CUSTOM); if(new_context == NULL) throw OCIO::Exception("WTF?"); if(seq_data->context) { delete seq_data->context; } seq_data->context = new_context; arb_data->source = seq_data->source = OCIO_SOURCE_CUSTOM; strncpy(arb_data->path, path.full_path().c_str(), ARB_PATH_LEN); strncpy(arb_data->relative_path, path.relative_path(false).c_str(), ARB_PATH_LEN); strncpy(seq_data->path, arb_data->path, ARB_PATH_LEN); strncpy(seq_data->relative_path, arb_data->relative_path, ARB_PATH_LEN); // try to retain settings if it looks like the same situation, // possibly fixing a moved path if(OCIO_ACTION_NONE == arb_data->action || (OCIO_ACTION_LUT == new_context->getAction() && OCIO_ACTION_LUT != arb_data->action) || (OCIO_ACTION_LUT != new_context->getAction() && OCIO_ACTION_LUT == arb_data->action) || (OCIO_ACTION_LUT != new_context->getAction() && (-1 == FindInVec(new_context->getInputs(), arb_data->input) || -1 == FindInVec(new_context->getInputs(), arb_data->output) || -1 == FindInVec(new_context->getTransforms(), arb_data->transform) || -1 == FindInVec(new_context->getDevices(), arb_data->device) ) ) ) { // Configuration is different, so initialize defaults arb_data->action = seq_data->context->getAction(); if(arb_data->action == OCIO_ACTION_LUT) { arb_data->invert = FALSE; arb_data->interpolation = OCIO_INTERP_LINEAR; } else { strncpy(arb_data->input, seq_data->context->getInput().c_str(), ARB_SPACE_LEN); strncpy(arb_data->output, seq_data->context->getOutput().c_str(), ARB_SPACE_LEN); strncpy(arb_data->transform, seq_data->context->getTransform().c_str(), ARB_SPACE_LEN); strncpy(arb_data->device, seq_data->context->getDevice().c_str(), ARB_SPACE_LEN); } } else { // Configuration is the same, retain current settings if(arb_data->action == OCIO_ACTION_LUT) { seq_data->context->setupLUT(arb_data->invert, arb_data->interpolation); } else if(arb_data->action == OCIO_ACTION_CONVERT) { seq_data->context->setupConvert(arb_data->input, arb_data->output); } else if(arb_data->action == OCIO_ACTION_DISPLAY) { seq_data->context->setupDisplay(arb_data->input, arb_data->device, arb_data->transform); // transform may have changed strncpy(arb_data->transform, seq_data->context->getTransform().c_str(), ARB_SPACE_LEN); } } params[OCIO_DATA]->uu.change_flags = PF_ChangeFlag_CHANGED_VALUE; seq_data->status = STATUS_USING_ABSOLUTE; } } static void DoClickConfig( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, PF_EventExtra *event_extra, ArbitraryData *arb_data, SequenceData *seq_data) { void *hwndOwner = NULL; #ifdef WIN_ENV PF_GET_PLATFORM_DATA(PF_PlatData_MAIN_WND, &hwndOwner); #endif ConfigVec configs; GetStdConfigs(configs); if(configs.size() == 0) configs.push_back("(nada)"); // menu makes a gray entry that says "No configs in $PATH" MenuVec menu_items; int selected = 0; menu_items.push_back("$OCIO"); // menu will gray this out if $OCIO is not defined menu_items.push_back("(-"); // this tells the menu to make a seperator for(ConfigVec::const_iterator i = configs.begin(); i != configs.end(); ++i) { menu_items.push_back( *i ); if(arb_data->source == OCIO_SOURCE_STANDARD && arb_data->path == *i) { selected = menu_items.size() - 1; } } menu_items.push_back("(-"); menu_items.push_back("Custom..."); int custom_choice = menu_items.size() - 1; if(arb_data->source == OCIO_SOURCE_CUSTOM) { selected = -1; } int choice = PopUpMenu(menu_items, selected, hwndOwner); if(choice == custom_choice) { // custom is the same as clicking the path DoClickPath(in_data, out_data, params, output, event_extra, arb_data, seq_data); } else if(choice != selected) { OpenColorIO_AE_Context *new_context = NULL; if(choice == 0) { // $OCIO char *file = std::getenv("OCIO"); if(file) { Path path(file, GetProjectDir(in_data)); new_context = new OpenColorIO_AE_Context(path.full_path(), OCIO_SOURCE_ENVIRONMENT); arb_data->source = seq_data->source = OCIO_SOURCE_ENVIRONMENT; strncpy(arb_data->path, path.full_path().c_str(), ARB_PATH_LEN); strncpy(arb_data->relative_path, path.relative_path(false).c_str(), ARB_PATH_LEN); } else throw OCIO::Exception("No $OCIO environment variable defined."); } else { // standard configs std::string config = configs[choice - 2]; std::string path = GetStdConfigPath(config); if( !path.empty() ) { new_context = new OpenColorIO_AE_Context(config, OCIO_SOURCE_STANDARD); arb_data->source = seq_data->source = OCIO_SOURCE_STANDARD; strncpy(arb_data->path, config.c_str(), ARB_PATH_LEN); strncpy(arb_data->relative_path, path.c_str(), ARB_PATH_LEN); } else throw OCIO::Exception("Problem loading OCIO configuration."); } if(new_context) { if(seq_data->context) { delete seq_data->context; } seq_data->context = new_context; strncpy(seq_data->path, arb_data->path, ARB_PATH_LEN); strncpy(seq_data->relative_path, arb_data->relative_path, ARB_PATH_LEN); // try to retain settings if it looks like the same situation, // possibly fixing a moved path if(OCIO_ACTION_NONE == arb_data->action || (OCIO_ACTION_LUT == new_context->getAction() && OCIO_ACTION_LUT != arb_data->action) || (OCIO_ACTION_LUT != new_context->getAction() && OCIO_ACTION_LUT == arb_data->action) || (OCIO_ACTION_LUT != new_context->getAction() && (-1 == FindInVec(new_context->getInputs(), arb_data->input) || -1 == FindInVec(new_context->getInputs(), arb_data->output) || -1 == FindInVec(new_context->getTransforms(), arb_data->transform) || -1 == FindInVec(new_context->getDevices(), arb_data->device) ) ) ) { // Configuration is different, so initialize defaults arb_data->action = seq_data->context->getAction(); if(arb_data->action == OCIO_ACTION_LUT) { arb_data->invert = FALSE; arb_data->interpolation = OCIO_INTERP_LINEAR; } else { strncpy(arb_data->input, seq_data->context->getInput().c_str(), ARB_SPACE_LEN); strncpy(arb_data->output, seq_data->context->getOutput().c_str(), ARB_SPACE_LEN); strncpy(arb_data->transform, seq_data->context->getTransform().c_str(), ARB_SPACE_LEN); strncpy(arb_data->device, seq_data->context->getDevice().c_str(), ARB_SPACE_LEN); } } else { // Configuration is the same, retain current settings if(arb_data->action == OCIO_ACTION_LUT) { seq_data->context->setupLUT(arb_data->invert, arb_data->interpolation); } else if(arb_data->action == OCIO_ACTION_CONVERT) { seq_data->context->setupConvert(arb_data->input, arb_data->output); } else if(arb_data->action == OCIO_ACTION_DISPLAY) { seq_data->context->setupDisplay(arb_data->input, arb_data->device, arb_data->transform); // transform may have changed strncpy(arb_data->transform, seq_data->context->getTransform().c_str(), ARB_SPACE_LEN); } } params[OCIO_DATA]->uu.change_flags = PF_ChangeFlag_CHANGED_VALUE; seq_data->status = STATUS_OK; } } } static void DoClickConvertDisplay( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, PF_EventExtra *event_extra, ArbitraryData *arb_data, SequenceData *seq_data, UIRegion reg ) { if(arb_data->action == OCIO_ACTION_LUT) { if(reg == REGION_CONVERT_BUTTON) // i.e. Invert { // doing it this way so that any exceptions thrown by setupLUT // because the LUT can't be inverted are thrown before // I actually chenge the ArbData setting seq_data->context->setupLUT(!arb_data->invert, arb_data->interpolation); arb_data->invert = !arb_data->invert; params[OCIO_DATA]->uu.change_flags = PF_ChangeFlag_CHANGED_VALUE; } } else if(arb_data->action == OCIO_ACTION_CONVERT || arb_data->action == OCIO_ACTION_DISPLAY) { if(reg == REGION_CONVERT_BUTTON && arb_data->action != OCIO_ACTION_CONVERT) { arb_data->action = OCIO_ACTION_CONVERT; seq_data->context->setupConvert(arb_data->input, arb_data->output); params[OCIO_DATA]->uu.change_flags = PF_ChangeFlag_CHANGED_VALUE; } else if(reg == REGION_DISPLAY_BUTTON && arb_data->action != OCIO_ACTION_DISPLAY) { arb_data->action = OCIO_ACTION_DISPLAY; seq_data->context->setupDisplay(arb_data->input, arb_data->device, arb_data->transform); // transform may have changed strncpy(arb_data->transform, seq_data->context->getTransform().c_str(), ARB_SPACE_LEN); params[OCIO_DATA]->uu.change_flags = PF_ChangeFlag_CHANGED_VALUE; } } } static void DoClickExport( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, PF_EventExtra *event_extra, ArbitraryData *arb_data, SequenceData *seq_data, UIRegion reg ) { ExtensionMap extensions; for(int i=0; i < OCIO::Baker::getNumFormats(); ++i) { const char *extension = OCIO::Baker::getFormatExtensionByIndex(i); const char *format = OCIO::Baker::getFormatNameByIndex(i); extensions[ extension ] = format; } extensions[ "icc" ] = "ICC Profile"; void *hwndOwner = NULL; #ifdef WIN_ENV PF_GET_PLATFORM_DATA(PF_PlatData_MAIN_WND, &hwndOwner); #endif char path[256] = { '\0' }; bool result = SaveFile(path, 255, extensions, hwndOwner); if(result) { std::string the_path(path); std::string the_extension = the_path.substr( the_path.find_last_of('.') + 1 ); bool do_export = true; std::string monitor_icc_path; if(the_extension == "icc") { char monitor_path[256] = {'\0'}; do_export = GetMonitorProfile(monitor_path, 255, hwndOwner); if(monitor_path[0] != '\0') monitor_icc_path = monitor_path; } if(do_export) seq_data->context->ExportLUT(the_path, monitor_icc_path); } } static void DoClickMenus( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, PF_EventExtra *event_extra, ArbitraryData *arb_data, SequenceData *seq_data, UIRegion reg ) { if(seq_data->context != NULL && arb_data->action == seq_data->context->getAction()) { if(arb_data->action == OCIO_ACTION_CONVERT || (arb_data->action == OCIO_ACTION_DISPLAY && (reg == REGION_MENU1))) { // colorSpace menus std::string selected_item; if(reg == REGION_MENU1) { selected_item = arb_data->input; } else { selected_item = arb_data->output; } void *hwndOwner = NULL; #ifdef WIN_ENV PF_GET_PLATFORM_DATA(PF_PlatData_MAIN_WND, &hwndOwner); #endif const bool changed = ColorSpacePopUpMenu(seq_data->context->config(), selected_item, true, hwndOwner); if(changed) { if(reg == REGION_MENU1) { strncpy(arb_data->input, selected_item.c_str(), ARB_SPACE_LEN); } else { strncpy(arb_data->output, selected_item.c_str(), ARB_SPACE_LEN); } params[OCIO_DATA]->uu.change_flags = PF_ChangeFlag_CHANGED_VALUE; } } else { // standard menus MenuVec menu_items; int selected_item; if(arb_data->action == OCIO_ACTION_LUT) { if(reg == REGION_MENU1) { menu_items.push_back("Nearest Neighbor"); menu_items.push_back("Linear"); menu_items.push_back("Tetrahedral"); menu_items.push_back("(-"); menu_items.push_back("Best"); selected_item = arb_data->interpolation == OCIO_INTERP_NEAREST ? 0 : arb_data->interpolation == OCIO_INTERP_LINEAR ? 1 : arb_data->interpolation == OCIO_INTERP_TETRAHEDRAL ? 2 : arb_data->interpolation == OCIO_INTERP_BEST ? 4 : -1; } } else if(arb_data->action == OCIO_ACTION_CONVERT) { menu_items = seq_data->context->getInputs(); if(reg == REGION_MENU1) { selected_item = FindInVec(menu_items, arb_data->input); } else { selected_item = FindInVec(menu_items, arb_data->output); } } else if(arb_data->action == OCIO_ACTION_DISPLAY) { if(reg == REGION_MENU1) { menu_items = seq_data->context->getInputs(); selected_item = FindInVec(menu_items, arb_data->input); } else if(reg == REGION_MENU2) { menu_items = seq_data->context->getDevices(); selected_item = FindInVec(menu_items, arb_data->device); } else if(reg == REGION_MENU3) { menu_items = seq_data->context->getTransforms(); selected_item = FindInVec(menu_items, arb_data->transform); } } void *hwndOwner = NULL; #ifdef WIN_ENV PF_GET_PLATFORM_DATA(PF_PlatData_MAIN_WND, &hwndOwner); #endif int result = PopUpMenu(menu_items, selected_item, hwndOwner); if(result != selected_item) { std::string color_space = menu_items[ result ]; if(arb_data->action == OCIO_ACTION_LUT) { if(reg == REGION_MENU1) { arb_data->interpolation = result == 0 ? OCIO_INTERP_NEAREST : result == 2 ? OCIO_INTERP_TETRAHEDRAL : result == 4 ? OCIO_INTERP_BEST : OCIO_INTERP_LINEAR; seq_data->context->setupLUT(arb_data->invert, arb_data->interpolation); } } else if(arb_data->action == OCIO_ACTION_CONVERT) { if(reg == REGION_MENU1) { strncpy(arb_data->input, color_space.c_str(), ARB_SPACE_LEN); } else if(reg == REGION_MENU2) { strncpy(arb_data->output, color_space.c_str(), ARB_SPACE_LEN); } seq_data->context->setupConvert(arb_data->input, arb_data->output); } else if(arb_data->action == OCIO_ACTION_DISPLAY) { if(reg == REGION_MENU1) { strncpy(arb_data->input, color_space.c_str(), ARB_SPACE_LEN); } else if(reg == REGION_MENU2) { strncpy(arb_data->device, color_space.c_str(), ARB_SPACE_LEN); } else if(reg == REGION_MENU3) { strncpy(arb_data->transform, color_space.c_str(), ARB_SPACE_LEN); } seq_data->context->setupDisplay(arb_data->input, arb_data->device, arb_data->transform); // transform may have changed strncpy(arb_data->transform, seq_data->context->getTransform().c_str(), ARB_SPACE_LEN); } params[OCIO_DATA]->uu.change_flags = PF_ChangeFlag_CHANGED_VALUE; } } } } static PF_Err DoClick( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, PF_EventExtra *event_extra ) { PF_Err err = PF_Err_NONE; ArbitraryData *arb_data = (ArbitraryData *)PF_LOCK_HANDLE(params[OCIO_DATA]->u.arb_d.value); SequenceData *seq_data = (SequenceData *)PF_LOCK_HANDLE(in_data->sequence_data); if(event_extra->effect_win.area == PF_EA_CONTROL) { bool menus_visible = (arb_data->action != OCIO_ACTION_NONE); bool third_menu = (arb_data->action == OCIO_ACTION_DISPLAY); PF_Point local_point; local_point.h = event_extra->u.do_click.screen_point.h - event_extra->effect_win.current_frame.left; local_point.v = event_extra->u.do_click.screen_point.v - event_extra->effect_win.current_frame.top; UIRegion reg = WhichRegion(local_point, menus_visible, third_menu); if(reg != REGION_NONE) { try { if(reg == REGION_CONFIG_MENU) { DoClickConfig(in_data, out_data, params, output, event_extra, arb_data, seq_data); } else if(reg == REGION_PATH) { if(arb_data->source == OCIO_SOURCE_CUSTOM) { DoClickPath(in_data, out_data, params, output, event_extra, arb_data, seq_data); } } else if(arb_data->action != OCIO_ACTION_NONE && seq_data->status != STATUS_FILE_MISSING) { if(seq_data->context == NULL) { seq_data->context = new OpenColorIO_AE_Context(arb_data, GetProjectDir(in_data) ); } if(reg == REGION_CONVERT_BUTTON || reg == REGION_DISPLAY_BUTTON) { DoClickConvertDisplay(in_data, out_data, params, output, event_extra, arb_data, seq_data, reg); } else if(reg == REGION_EXPORT_BUTTON) { DoClickExport(in_data, out_data, params, output, event_extra, arb_data, seq_data, reg); } else // must be a menu then { DoClickMenus(in_data, out_data, params, output, event_extra, arb_data, seq_data, reg); } } } catch(std::exception &e) { if(in_data->appl_id == 'FXTC') { PF_SPRINTF(out_data->return_msg, e.what()); out_data->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; } else { void *hwndOwner = NULL; #ifdef WIN_ENV PF_GET_PLATFORM_DATA(PF_PlatData_MAIN_WND, &hwndOwner); #endif ErrorMessage(e.what(), hwndOwner); } } catch(...) { PF_SPRINTF(out_data->return_msg, "Unknown error"); out_data->out_flags |= PF_OutFlag_DISPLAY_ERROR_MESSAGE; } } } PF_UNLOCK_HANDLE(params[OCIO_DATA]->u.arb_d.value); PF_UNLOCK_HANDLE(in_data->sequence_data); event_extra->evt_out_flags = PF_EO_HANDLED_EVENT; return err; } PF_Err HandleEvent ( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, PF_EventExtra *extra ) { PF_Err err = PF_Err_NONE; extra->evt_out_flags = 0; if(!err) { switch(extra->e_type) { case PF_Event_DRAW: err = DrawEvent(in_data, out_data, params, output, extra); break; case PF_Event_DO_CLICK: err = DoClick(in_data, out_data, params, output, extra); break; } } return err; } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/DrawbotBot.cpp0000644000175000017500000001723013223553423022274 0ustar mfvmfv/* Copyright (c) 2003-2012 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 "DrawbotBot.h" DrawbotBot::DrawbotBot(struct SPBasicSuite *pica_basicP, PF_ContextH contextH, A_long appl_id) : suites(pica_basicP), _appl_id(appl_id), _suiteP(NULL), _drawbot_ref(NULL), _supplier_ref(NULL), _surface_ref(NULL) { suites.EffectCustomUISuite1()->PF_GetDrawingReference(contextH, &_drawbot_ref); _suiteP = suites.SupplierSuiteCurrent(); suites.DrawbotSuiteCurrent()->GetSupplier(_drawbot_ref, &_supplier_ref); suites.DrawbotSuiteCurrent()->GetSurface(_drawbot_ref, &_surface_ref); _brush_pos.x = 0.f; _brush_pos.y = 0.f; SetColor(PF_App_Color_TEXT); _suiteP->GetDefaultFontSize(_supplier_ref, &_font_size); } DrawbotBot::~DrawbotBot() { } void DrawbotBot::SetColor(PF_App_ColorType color, float a) { if(_appl_id == 'FXTC') { PF_App_Color app_color; suites.AppSuite4()->PF_AppGetColor(color, &app_color); _brush_color.red = (float)app_color.red / (float)PF_MAX_CHAN16; _brush_color.green = (float)app_color.green / (float)PF_MAX_CHAN16; _brush_color.blue = (float)app_color.blue / (float)PF_MAX_CHAN16; } else { // Premiere isn't doing this properly, so I'll have to. // Only supporting the colors I'm actually using at the moment. switch(color) { case PF_App_Color_BLACK: _brush_color.red = _brush_color.green = _brush_color.blue = 0.f; break; case PF_App_Color_WHITE: _brush_color.red = _brush_color.green = _brush_color.blue = 1.f; break; case PF_App_Color_RED: _brush_color.red = 1.f; _brush_color.green = _brush_color.blue = 0.f; break; case PF_App_Color_TEXT_DISABLED: _brush_color.red = _brush_color.green = _brush_color.blue = 0.6f; break; case PF_App_Color_SHADOW: _brush_color.red = _brush_color.green = _brush_color.blue = 0.3f; break; case PF_App_Color_HILITE: _brush_color.red = _brush_color.green = _brush_color.blue = 0.8f; break; case PF_App_Color_LIGHT_TINGE: _brush_color.red = _brush_color.green = _brush_color.blue = 0.7f; break; case PF_App_Color_BUTTON_FILL: _brush_color.red = _brush_color.green = _brush_color.blue = 0.5f; break; case PF_App_Color_BUTTON_PRESSED_FILL: _brush_color.red = _brush_color.green = _brush_color.blue = 0.3f; break; case PF_App_Color_PANEL_BACKGROUND: { PF_App_Color app_color; suites.AppSuite4()->PF_AppGetBgColor(&app_color); _brush_color.red = (float)app_color.red / (float)65535; _brush_color.green = (float)app_color.green / (float)65535; _brush_color.blue = (float)app_color.blue / (float)65535; } break; default: _brush_color.red = _brush_color.green = _brush_color.blue = 0.9f; break; } } _brush_color.alpha = a; } void DrawbotBot::DrawLineTo(float x, float y, float brush_size) { DRAWBOT_PathP pathP(_suiteP, _supplier_ref); DRAWBOT_PenP penP(_suiteP, _supplier_ref, &_brush_color, brush_size); suites.PathSuiteCurrent()->MoveTo(pathP.Get(), _brush_pos.x, _brush_pos.y); suites.PathSuiteCurrent()->LineTo(pathP.Get(), x, y); suites.SurfaceSuiteCurrent()->StrokePath(_surface_ref, penP.Get(), pathP.Get()); MoveTo(x, y); } void DrawbotBot::DrawRect(float w, float h, float brush_size) const { DRAWBOT_PathP pathP(_suiteP, _supplier_ref); DRAWBOT_PenP penP(_suiteP, _supplier_ref, &_brush_color, brush_size); DRAWBOT_RectF32 rect; rect.left = _brush_pos.x - 0.5f; rect.top = _brush_pos.y - 0.5f; rect.width = w; rect.height = h; suites.PathSuiteCurrent()->AddRect(pathP.Get(), &rect); suites.SurfaceSuiteCurrent()->StrokePath(_surface_ref, penP.Get(), pathP.Get()); } void DrawbotBot::PaintRect(float w, float h) const { DRAWBOT_RectF32 rect; rect.left = _brush_pos.x; rect.top = _brush_pos.y; rect.width = w; rect.height = h; suites.SurfaceSuiteCurrent()->PaintRect(_surface_ref, &_brush_color, &rect); } void DrawbotBot::PaintTriangle(float w, float h) const { DRAWBOT_PathP pathP(_suiteP, _supplier_ref); DRAWBOT_BrushP brushP(_suiteP, _supplier_ref, &_brush_color); suites.PathSuiteCurrent()->MoveTo(pathP.Get(), _brush_pos.x, _brush_pos.y); suites.PathSuiteCurrent()->LineTo(pathP.Get(), _brush_pos.x + w, _brush_pos.y); suites.PathSuiteCurrent()->LineTo(pathP.Get(), _brush_pos.x + (w / 2.f), _brush_pos.y + h); suites.PathSuiteCurrent()->Close(pathP.Get()); suites.SurfaceSuiteCurrent()->FillPath(_surface_ref, brushP.Get(), pathP.Get(), kDRAWBOT_FillType_Default); } void DrawbotBot::DrawString( const DRAWBOT_UTF16Char *str, DRAWBOT_TextAlignment align, DRAWBOT_TextTruncation truncate, float truncation_width) const { DRAWBOT_BrushP brushP(_suiteP, _supplier_ref, &_brush_color); DRAWBOT_FontP fontP(_suiteP, _supplier_ref, _font_size); suites.SurfaceSuiteCurrent()->DrawString(_surface_ref, brushP.Get(), fontP.Get(), str, &_brush_pos, align, truncate, truncation_width); } void DrawbotBot::DrawString( const char *str, DRAWBOT_TextAlignment align, DRAWBOT_TextTruncation truncate, float truncation_width) const { DRAWBOT_UTF16Char u_str[256] = {'\0'}; DRAWBOT_UTF16Char *u = u_str; const char *c = str; if(*c != '\0') { do{ *u++ = *c++; }while(*c != '\0'); *u = '\0'; } DrawString(u_str, align, truncate, truncation_width); }opencolorio-1.1.0~dfsg0.orig/src/aftereffects/OpenColorIO_AE_Context.cpp0000644000175000017500000007323513223553423024435 0ustar mfvmfv/* Copyright (c) 2003-2012 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 "OpenColorIO_AE_Context.h" #include #include #include #include "ocioicc.h" #include "OpenColorIO_AE_Dialogs.h" static const char mac_delimiter = '/'; static const char win_delimiter = '\\'; #ifdef WIN_ENV static const char delimiter = win_delimiter; #else static const char delimiter = mac_delimiter; #endif static const int LUT3D_EDGE_SIZE = 32; Path::Path(const std::string &path, const std::string &dir) : _path(path), _dir(dir) { } Path::Path(const Path &path) { _path = path._path; _dir = path._dir; } std::string Path::full_path() const { if( !_path.empty() && is_relative(_path) && !_dir.empty() ) { std::vector path_vec = components( convert_delimiters(_path) ); std::vector dir_vec = components(_dir); int up_dirs = 0; int down_dirs = 0; while(down_dirs < path_vec.size() - 1 && (path_vec[down_dirs] == ".." || path_vec[down_dirs] == ".") ) { down_dirs++; if(path_vec[down_dirs] == "..") up_dirs++; } std::string path; if(path_type(_dir) == TYPE_MAC) path += mac_delimiter; for(int i=0; i < dir_vec.size() - up_dirs; i++) { path += dir_vec[i] + delimiter; } for(int i = down_dirs; i < path_vec.size() - 1; i++) { path += path_vec[i] + delimiter; } path += path_vec.back(); return path; } else { return _path; } } std::string Path::relative_path(bool force) const { if( _dir.empty() || _path.empty() || is_relative(_path) ) { return _path; } else { std::vector path_vec = components(_path); std::vector dir_vec = components(_dir); int match_idx = 0; while(match_idx < path_vec.size() && match_idx < dir_vec.size() && path_vec[match_idx] == dir_vec[match_idx]) match_idx++; if(match_idx == 0) { // can't do relative path if(force) return _path; else return ""; } else { std::string rel_path; // is the file in a folder below or actually inside the dir? if(match_idx == dir_vec.size()) { rel_path += std::string(".") + delimiter; } else { for(int i = match_idx; i < dir_vec.size(); i++) { rel_path += std::string("..") + delimiter; } } for(int i = match_idx; i < path_vec.size() - 1; i++) { rel_path += path_vec[i] + delimiter; } rel_path += path_vec.back(); return rel_path; } } } bool Path::exists() const { std::string path = full_path(); if(path.empty()) return false; std::ifstream f( path.c_str() ); return !!f; } Path::PathType Path::path_type(const std::string &path) { if( path.empty() ) { return TYPE_UNKNOWN; } if(path[0] == mac_delimiter) { return TYPE_MAC; } else if(path[1] == ':' && path[2] == win_delimiter) { return TYPE_WIN; } else if(path[0] == win_delimiter && path[1] == win_delimiter) { return TYPE_WIN; } else { size_t mac_pos = path.find(mac_delimiter); size_t win_pos = path.find(win_delimiter); if(mac_pos != std::string::npos && win_pos == std::string::npos) { return TYPE_MAC; } else if(mac_pos == std::string::npos && win_pos != std::string::npos) { return TYPE_WIN; } else if(mac_pos == std::string::npos && win_pos == std::string::npos) { return TYPE_UNKNOWN; } else // neither npos? { if(mac_pos < win_pos) return TYPE_MAC; else return TYPE_WIN; } } } bool Path::is_relative(const std::string &path) { Path::PathType type = path_type(path); if(type == TYPE_MAC) { return (path[0] != mac_delimiter); } else if(type == TYPE_WIN) { return !( (path[1] == ':' && path[2] == win_delimiter) || (path[0] == win_delimiter && path[1] == win_delimiter) ); } else { // TYPE_UNKNOWN // just a filename perhaps? // should never have this: even a file in the same directory will be ./file.ocio // we'll assume it's relative, but raise a stink during debugging assert(type != TYPE_UNKNOWN); return true; } } std::string Path::convert_delimiters(const std::string &path) { #ifdef WIN_ENV const char search = mac_delimiter; const char replace = win_delimiter; #else const char search = win_delimiter; const char replace = mac_delimiter; #endif std::string path_copy = path; for(int i=0; i < path_copy.size(); i++) { if(path_copy[i] == search) path_copy[i] = replace; } return path_copy; } std::vector Path::components(const std::string &path) { std::vector vec; size_t pos = 0; size_t len = path.size(); size_t start, finish; while(path[pos] == delimiter && pos < len) pos++; while(pos < len) { start = pos; while(path[pos] != delimiter && pos < len) pos++; finish = ((pos == len - 1) ? pos : pos - 1); vec.push_back( path.substr(start, 1 + finish - start) ); while(path[pos] == delimiter && pos < len) pos++; } return vec; } #pragma mark- OpenColorIO_AE_Context::OpenColorIO_AE_Context(const std::string &path, OCIO_Source source) : _gl_init(false) { _action = OCIO_ACTION_NONE; _source = source; if(_source == OCIO_SOURCE_ENVIRONMENT) { char *file = getenv("OCIO"); if(file) { _path = file; } else throw OCIO::Exception("No $OCIO environment variable."); } else if(_source == OCIO_SOURCE_STANDARD) { _config_name = path; _path = GetStdConfigPath(_config_name); if( _path.empty() ) throw OCIO::Exception("Error getting config."); } else { _path = path; } if(!_path.empty()) { std::string the_extension = _path.substr( _path.find_last_of('.') + 1 ); if(the_extension == "ocio") { _config = OCIO::Config::CreateFromFile( _path.c_str() ); _config->sanityCheck(); for(int i=0; i < _config->getNumColorSpaces(); ++i) { const char *colorSpaceName = _config->getColorSpaceNameByIndex(i); OCIO::ConstColorSpaceRcPtr colorSpace = _config->getColorSpace(colorSpaceName); const char *family = colorSpace->getFamily(); _inputs.push_back(colorSpaceName); const std::string fullPath = (family == NULL ? colorSpaceName : std::string(family) + "/" + colorSpaceName); _inputsFullPath.push_back(fullPath); } for(int i=0; i < _config->getNumDisplays(); ++i) { _devices.push_back( _config->getDisplay(i) ); } OCIO::ConstColorSpaceRcPtr defaultInput = _config->getColorSpace(OCIO::ROLE_DEFAULT); const char *defaultInputName = (defaultInput ? defaultInput->getName() : OCIO::ROLE_DEFAULT); setupConvert(defaultInputName, defaultInputName); const char *defaultDisplay = _config->getDefaultDisplay(); const char *defaultTransform = _config->getDefaultView(defaultDisplay); _device = defaultDisplay; _transform = defaultTransform; } else { _config = OCIO::Config::Create(); setupLUT(false, OCIO_INTERP_LINEAR); } } else throw OCIO::Exception("Got nothin"); } OpenColorIO_AE_Context::OpenColorIO_AE_Context(const ArbitraryData *arb_data, const std::string &dir) : _gl_init(false) { _action = OCIO_ACTION_NONE; _source = arb_data->source; if(_source == OCIO_SOURCE_ENVIRONMENT) { char *file = getenv("OCIO"); if(file) { _path = file; } else throw OCIO::Exception("No $OCIO environment variable."); } else if(_source == OCIO_SOURCE_STANDARD) { _config_name = arb_data->path; _path = GetStdConfigPath(_config_name); if( _path.empty() ) throw OCIO::Exception("Error getting config."); } else { Path absolute_path(arb_data->path, dir); Path relative_path(arb_data->relative_path, dir); if( absolute_path.exists() ) { _path = absolute_path.full_path(); } else { _path = relative_path.full_path(); } } if(!_path.empty()) { std::string the_extension = _path.substr( _path.find_last_of('.') + 1 ); if(the_extension == "ocio") { _config = OCIO::Config::CreateFromFile( _path.c_str() ); _config->sanityCheck(); for(int i=0; i < _config->getNumColorSpaces(); ++i) { const char *colorSpaceName = _config->getColorSpaceNameByIndex(i); OCIO::ConstColorSpaceRcPtr colorSpace = _config->getColorSpace(colorSpaceName); const char *family = colorSpace->getFamily(); _inputs.push_back(colorSpaceName); const std::string fullPath = (family == NULL ? colorSpaceName : std::string(family) + "/" + colorSpaceName); _inputsFullPath.push_back(fullPath); } for(int i=0; i < _config->getNumDisplays(); ++i) { _devices.push_back( _config->getDisplay(i) ); } if(arb_data->action == OCIO_ACTION_CONVERT) { setupConvert(arb_data->input, arb_data->output); _device = arb_data->device; _transform = arb_data->transform; } else { setupDisplay(arb_data->input, arb_data->device, arb_data->transform); _output = arb_data->output; } } else { _config = OCIO::Config::Create(); setupLUT(arb_data->invert, arb_data->interpolation); } } else throw OCIO::Exception("Got nothin"); } OpenColorIO_AE_Context::~OpenColorIO_AE_Context() { if(_gl_init) { glDeleteShader(_fragShader); glDeleteProgram(_program); glDeleteTextures(1, &_imageTexID); if(_bufferWidth != 0 && _bufferHeight != 0) glDeleteRenderbuffersEXT(1, &_renderBuffer); } } bool OpenColorIO_AE_Context::Verify(const ArbitraryData *arb_data, const std::string &dir) { if(_source != arb_data->source) return false; if(_source == OCIO_SOURCE_STANDARD) { if(_config_name != arb_data->path) return false; } else if(_source == OCIO_SOURCE_CUSTOM) { // comparing the paths, cheking relative path only if necessary if(_path != arb_data->path) { std::string rel_path(arb_data->relative_path); if( !dir.empty() && !rel_path.empty() ) { Path relative_path(rel_path, dir); if( _path != relative_path.full_path() ) return false; } else return false; } } // we can switch between Convert and Display, but not LUT and non-LUT if((arb_data->action == OCIO_ACTION_NONE) || (_action == OCIO_ACTION_LUT && arb_data->action != OCIO_ACTION_LUT) || (_action != OCIO_ACTION_LUT && arb_data->action == OCIO_ACTION_LUT) ) { return false; } bool force_reset = (_action != arb_data->action); // If the type and path are compatible, we can patch up // differences here and return true. // Returning false means the context will be deleted and rebuilt. if(arb_data->action == OCIO_ACTION_LUT) { if(_invert != (bool)arb_data->invert || _interpolation != arb_data->interpolation || force_reset) { setupLUT(arb_data->invert, arb_data->interpolation); } } else if(arb_data->action == OCIO_ACTION_CONVERT) { if(_input != arb_data->input || _output != arb_data->output || force_reset) { setupConvert(arb_data->input, arb_data->output); } } else if(arb_data->action == OCIO_ACTION_DISPLAY) { if(_input != arb_data->input || _device != arb_data->device || _transform != arb_data->transform || force_reset) { setupDisplay(arb_data->input, arb_data->device, arb_data->transform); } } else throw OCIO::Exception("Bad OCIO type"); return true; } void OpenColorIO_AE_Context::setupConvert(const char *input, const char *output) { OCIO::ColorSpaceTransformRcPtr transform = OCIO::ColorSpaceTransform::Create(); transform->setSrc(input); transform->setDst(output); transform->setDirection(OCIO::TRANSFORM_DIR_FORWARD); _input = input; _output = output; _processor = _config->getProcessor(transform); _action = OCIO_ACTION_CONVERT; UpdateOCIOGLState(); } void OpenColorIO_AE_Context::setupDisplay(const char *input, const char *device, const char *xform) { _transforms.clear(); bool xformValid = false; for(int i=0; i < _config->getNumViews(device); i++) { const std::string transformName = _config->getView(device, i); if(transformName == xform) xformValid = true; _transforms.push_back(transformName); } if(!xformValid) xform = _config->getDefaultView(device); OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create(); transform->setInputColorSpaceName(input); transform->setDisplay(device); transform->setView(xform); _input = input; _device = device; _transform = xform; _processor = _config->getProcessor(transform); _action = OCIO_ACTION_DISPLAY; UpdateOCIOGLState(); } void OpenColorIO_AE_Context::setupLUT(bool invert, OCIO_Interp interpolation) { OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create(); if(interpolation != OCIO_INTERP_NEAREST && interpolation != OCIO_INTERP_LINEAR && interpolation != OCIO_INTERP_TETRAHEDRAL && interpolation != OCIO_INTERP_BEST) { interpolation = OCIO_INTERP_LINEAR; } transform->setSrc( _path.c_str() ); transform->setInterpolation(static_cast(interpolation)); transform->setDirection(invert ? OCIO::TRANSFORM_DIR_INVERSE : OCIO::TRANSFORM_DIR_FORWARD); _processor = _config->getProcessor(transform); _invert = invert; _interpolation = interpolation; _action = OCIO_ACTION_LUT; UpdateOCIOGLState(); } bool OpenColorIO_AE_Context::ExportLUT(const std::string &path, const std::string &display_icc_path) { std::string the_extension = path.substr( path.find_last_of('.') + 1 ); try{ if(the_extension == "icc") { int cubesize = 32; int whitepointtemp = 6505; std::string copyright = "OpenColorIO, Sony Imageworks"; // create a description tag from the filename size_t filename_start = path.find_last_of(delimiter) + 1; size_t filename_end = path.find_last_of('.') - 1; std::string description = path.substr(path.find_last_of(delimiter) + 1, 1 + filename_end - filename_start); SaveICCProfileToFile(path, _processor, cubesize, whitepointtemp, display_icc_path, description, copyright, false); } else { // this code lovingly pulled from ociobakelut // need an extension->format map (yes, just did this one call up) std::map extensions; for(int i=0; i < OCIO::Baker::getNumFormats(); ++i) { const char *extension = OCIO::Baker::getFormatExtensionByIndex(i); const char *format = OCIO::Baker::getFormatNameByIndex(i); extensions[ extension ] = format; } std::string format = extensions[ the_extension ]; OCIO::BakerRcPtr baker = OCIO::Baker::Create(); baker->setFormat(format.c_str()); if(_action == OCIO_ACTION_CONVERT) { baker->setConfig(_config); baker->setInputSpace(_input.c_str()); baker->setTargetSpace(_output.c_str()); std::ofstream f(path.c_str()); baker->bake(f); } else if(_action == OCIO_ACTION_DISPLAY) { OCIO::ConfigRcPtr editableConfig = _config->createEditableCopy(); OCIO::ColorSpaceRcPtr inputColorSpace = OCIO::ColorSpace::Create(); std::string inputspace = "RawInput"; inputColorSpace->setName(inputspace.c_str()); editableConfig->addColorSpace(inputColorSpace); OCIO::ColorSpaceRcPtr outputColorSpace = OCIO::ColorSpace::Create(); std::string outputspace = "ProcessedOutput"; outputColorSpace->setName(outputspace.c_str()); OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create(); transform->setInputColorSpaceName(_input.c_str()); transform->setView(_transform.c_str()); transform->setDisplay(_device.c_str()); outputColorSpace->setTransform(transform, OCIO::COLORSPACE_DIR_FROM_REFERENCE); editableConfig->addColorSpace(outputColorSpace); baker->setConfig(editableConfig); baker->setInputSpace(inputspace.c_str()); baker->setTargetSpace(outputspace.c_str()); std::ofstream f(path.c_str()); baker->bake(f); } else if(_action == OCIO_ACTION_LUT) { OCIO::ConfigRcPtr editableConfig = OCIO::Config::Create(); OCIO::ColorSpaceRcPtr inputColorSpace = OCIO::ColorSpace::Create(); std::string inputspace = "RawInput"; inputColorSpace->setName(inputspace.c_str()); editableConfig->addColorSpace(inputColorSpace); OCIO::ColorSpaceRcPtr outputColorSpace = OCIO::ColorSpace::Create(); std::string outputspace = "ProcessedOutput"; outputColorSpace->setName(outputspace.c_str()); OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create(); transform = OCIO::FileTransform::Create(); transform->setSrc(_path.c_str()); transform->setInterpolation(static_cast(_interpolation)); transform->setDirection(_invert ? OCIO::TRANSFORM_DIR_INVERSE : OCIO::TRANSFORM_DIR_FORWARD); outputColorSpace->setTransform(transform, OCIO::COLORSPACE_DIR_FROM_REFERENCE); editableConfig->addColorSpace(outputColorSpace); baker->setConfig(editableConfig); baker->setInputSpace(inputspace.c_str()); baker->setTargetSpace(outputspace.c_str()); std::ofstream f(path.c_str()); baker->bake(f); } } }catch(...) { return false; } return true; } void OpenColorIO_AE_Context::InitOCIOGL() { if(!_gl_init) { SetPluginContext(); glGenTextures(1, &_imageTexID); glGenTextures(1, &_lut3dTexID); int num3Dentries = 3*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE; _lut3d.resize(num3Dentries); memset(&_lut3d[0], 0, sizeof(float)*num3Dentries); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_3D, _lut3dTexID); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F_ARB, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, 0, GL_RGB,GL_FLOAT, &_lut3d[0]); _fragShader = 0; _program = 0; _bufferWidth = _bufferHeight = 0; _gl_init = true; SetAEContext(); } } static const char * g_fragShaderText = "" "\n" "uniform sampler2D tex1;\n" "uniform sampler3D tex2;\n" "\n" "void main()\n" "{\n" " vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n" " gl_FragColor = OCIODisplay(col, tex2);\n" "}\n"; static GLuint CompileShaderText(GLenum shaderType, const char *text) { GLuint shader; GLint stat; shader = glCreateShader(shaderType); glShaderSource(shader, 1, (const GLchar **) &text, NULL); glCompileShader(shader); glGetShaderiv(shader, GL_COMPILE_STATUS, &stat); if (!stat) { GLchar log[1000]; GLsizei len; glGetShaderInfoLog(shader, 1000, &len, log); return 0; } return shader; } static GLuint LinkShaders(GLuint fragShader) { if (!fragShader) return 0; GLuint program = glCreateProgram(); if (fragShader) glAttachShader(program, fragShader); glLinkProgram(program); // check link { GLint stat; glGetProgramiv(program, GL_LINK_STATUS, &stat); if (!stat) { GLchar log[1000]; GLsizei len; glGetProgramInfoLog(program, 1000, &len, log); //fprintf(stderr, "Shader link error:\n%s\n", log); return 0; } } return program; } void OpenColorIO_AE_Context::UpdateOCIOGLState() { if(_gl_init) { SetPluginContext(); // Step 1: Create a GPU Shader Description OCIO::GpuShaderDesc shaderDesc; shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0); shaderDesc.setFunctionName("OCIODisplay"); shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE); // Step 2: Compute the 3D LUT std::string lut3dCacheID = _processor->getGpuLut3DCacheID(shaderDesc); if(lut3dCacheID != _lut3dcacheid) { _lut3dcacheid = lut3dCacheID; _processor->getGpuLut3D(&_lut3d[0], shaderDesc); } // Step 3: Compute the Shader std::string shaderCacheID = _processor->getGpuShaderTextCacheID(shaderDesc); if(_program == 0 || shaderCacheID != _shadercacheid) { _shadercacheid = shaderCacheID; std::ostringstream os; os << _processor->getGpuShaderText(shaderDesc) << "\n"; os << g_fragShaderText; if(_fragShader) glDeleteShader(_fragShader); _fragShader = CompileShaderText(GL_FRAGMENT_SHADER, os.str().c_str()); if(_program) glDeleteProgram(_program); _program = LinkShaders(_fragShader); } SetAEContext(); } } bool OpenColorIO_AE_Context::ProcessWorldGL(PF_EffectWorld *float_world) { if(!_gl_init) { InitOCIOGL(); UpdateOCIOGLState(); } if(_program == 0 || _fragShader == 0) return false; SetPluginContext(); GLint max; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); if(max < float_world->width || max < float_world->height || GL_NO_ERROR != glGetError()) { SetAEContext(); return false; } PF_PixelFloat *pix = (PF_PixelFloat *)float_world->data; float *rgba_origin = &pix->red; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, _imageTexID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, float_world->width, float_world->height, 0, GL_RGBA, GL_FLOAT, rgba_origin); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glBindTexture(GL_TEXTURE_3D, _lut3dTexID); glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, GL_RGB, GL_FLOAT, &_lut3d[0]); glUseProgram(_program); glUniform1i(glGetUniformLocation(_program, "tex1"), 0); glUniform1i(glGetUniformLocation(_program, "tex2"), 1); if(GL_NO_ERROR != glGetError()) { SetAEContext(); return false; } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, GetFrameBuffer()); if(_bufferWidth != float_world->width || _bufferHeight != float_world->height) { if(_bufferWidth != 0 && _bufferHeight != 0) glDeleteRenderbuffersEXT(1, &_renderBuffer); _bufferWidth = float_world->width; _bufferHeight = float_world->height; glGenRenderbuffersEXT(1, &_renderBuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, _renderBuffer); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, _bufferWidth, _bufferHeight); // attach renderbuffer to framebuffer glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, _renderBuffer); } if(GL_FRAMEBUFFER_COMPLETE_EXT != glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)) { SetAEContext(); return false; } glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glViewport(0, 0, float_world->width, float_world->height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, float_world->width, 0.0, float_world->height, -100.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glEnable(GL_TEXTURE_2D); glClearColor(0.1f, 0.1f, 0.1f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1, 1, 1); glPushMatrix(); glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, float_world->height); glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex2f(float_world->width, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex2f(float_world->width, float_world->height); glEnd(); glPopMatrix(); glDisable(GL_TEXTURE_2D); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); glReadPixels(0, 0, float_world->width, float_world->height, GL_RGBA, GL_FLOAT, rgba_origin); glFinish(); SetAEContext(); return true; } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/OpenColorIO_AE_PiPL.r0000644000175000017500000000555613223553423023275 0ustar mfvmfv/* Copyright (c) 2003-2012 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 "AEConfig.h" #include "AE_EffectVers.h" #ifndef AE_OS_WIN #include "AE_General.r" #endif resource 'PiPL' (16000) { { /* array properties: 12 elements */ /* [1] */ Kind { AEEffect }, /* [2] */ Name { "OpenColorIO" }, /* [3] */ Category { "Utility" }, #ifdef AE_OS_WIN #ifdef AE_PROC_INTELx64 CodeWin64X86 {"PluginMain"}, #else CodeWin32X86 {"PluginMain"}, #endif #else #ifdef AE_PROC_INTELx64 CodeMacIntel64 {"PluginMain"}, #else CodeMachOPowerPC {"PluginMain"}, CodeMacIntel32 {"PluginMain"}, #endif #endif /* [6] */ AE_PiPL_Version { 2, 0 }, /* [7] */ AE_Effect_Spec_Version { PF_PLUG_IN_VERSION, PF_PLUG_IN_SUBVERS }, /* [8] */ AE_Effect_Version { 525824 /* 2.0 */ }, /* [9] */ AE_Effect_Info_Flags { 0 }, /* [10] */ AE_Effect_Global_OutFlags { 50365504 }, AE_Effect_Global_OutFlags_2 { 37896 }, /* [11] */ AE_Effect_Match_Name { "OpenColorIO" }, /* [12] */ AE_Reserved_Info { 0 } } }; opencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/0000755000175000017500000000000013223553423020126 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/vc9/0000755000175000017500000000000013223553423020627 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/vc9/OpenColorABI.h0000644000175000017500000000751413223553423023223 0ustar mfvmfv/* 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_OCIO_OPENCOLORABI_H #define INCLUDED_OCIO_OPENCOLORABI_H // Makefile configuration options #define OCIO_NAMESPACE OpenColorIO #define OCIO_USE_BOOST_PTR 1 #define OCIO_VERSION "1.0.9" #define OCIO_VERSION_NS v1 /* Version as a single 4-byte hex number, e.g. 0x01050200 == 1.5.2 Use this for numeric comparisons, e.g. #if OCIO_VERSION_HEX >= ... Note: in the case where SOVERSION is overridden at compile-time, this will reflect the original API version number. */ #define OCIO_VERSION_HEX ((1 << 24) | \ (0 << 16) | \ (9 << 8)) // Namespace / version mojo #define OCIO_NAMESPACE_ENTER namespace OCIO_NAMESPACE { namespace OCIO_VERSION_NS #define OCIO_NAMESPACE_EXIT using namespace OCIO_VERSION_NS; } #define OCIO_NAMESPACE_USING using namespace OCIO_NAMESPACE; // shared_ptr / dynamic_pointer_cast #if OCIO_USE_BOOST_PTR #include #define OCIO_SHARED_PTR boost::shared_ptr #define OCIO_DYNAMIC_POINTER_CAST boost::dynamic_pointer_cast #elif __GNUC__ >= 4 #include #define OCIO_SHARED_PTR std::tr1::shared_ptr #define OCIO_DYNAMIC_POINTER_CAST std::tr1::dynamic_pointer_cast #else #error OCIO needs gcc 4 or later to get access to (or specify USE_BOOST_PTR instead) #endif #ifdef OpenColorIO_SHARED // If supported, define OCIOEXPORT, OCIOHIDDEN // (used to choose which symbols to export from OpenColorIO) #if defined __linux__ || __APPLE__ #if __GNUC__ >= 4 #define OCIOEXPORT __attribute__ ((visibility("default"))) #define OCIOHIDDEN __attribute__ ((visibility("hidden"))) #else #define OCIOEXPORT #define OCIOHIDDEN #endif #elif defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) || defined(_MSC_VER) // Windows requires you to export from the main library and then import in any others #if defined OpenColorIO_EXPORTS #define OCIOEXPORT __declspec(dllexport) #else #define OCIOEXPORT __declspec(dllimport) #endif #define OCIOHIDDEN #else // Others platforms not supported atm #define OCIOEXPORT #define OCIOHIDDEN #endif #else #define OCIOEXPORT #define OCIOHIDDEN #endif // Windows defines these troublesome macros that collide with std::limits #if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) || defined(_MSC_VER) #undef min #undef max #endif #endif // INCLUDED_OCIO_OPENCOLORABI_H opencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/vc9/aftereffects/0000755000175000017500000000000013223553423023270 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/vc9/aftereffects/OpenColorIO_AE.vcproj0000644000175000017500000003047213223553423027220 0ustar mfvmfv opencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/vc9/aftereffects/OpenColorIO_AE.sln0000644000175000017500000000674013223553423026512 0ustar mfvmfv Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenColorIO_AE", "OpenColorIO_AE.vcproj", "{78FCC6BC-06A9-43AE-827A-1B68FFB7D75F}" ProjectSection(ProjectDependencies) = postProject {069FB60C-57CE-4D0F-9EC2-068E2A3F2930} = {069FB60C-57CE-4D0F-9EC2-068E2A3F2930} {8B308357-C548-49D9-9134-8A61D57D524C} = {8B308357-C548-49D9-9134-8A61D57D524C} {A19BA95E-D8ED-4958-883B-32561AF905EA} = {A19BA95E-D8ED-4958-883B-32561AF905EA} {CC244BA5-4CA8-4B4F-B4CA-3394BF9E9FED} = {CC244BA5-4CA8-4B4F-B4CA-3394BF9E9FED} {F1DAC6DE-348A-4215-87B2-7584578291AC} = {F1DAC6DE-348A-4215-87B2-7584578291AC} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenColorIO", "..\OpenColorIO.vcproj", "{8B308357-C548-49D9-9134-8A61D57D524C}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lcms", "..\ext\lcms.vcproj", "{069FB60C-57CE-4D0F-9EC2-068E2A3F2930}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxml", "..\ext\tinyxml.vcproj", "{A19BA95E-D8ED-4958-883B-32561AF905EA}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml", "..\ext\yaml.vcproj", "{F1DAC6DE-348A-4215-87B2-7584578291AC}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glew", "..\ext\glew.vcproj", "{CC244BA5-4CA8-4B4F-B4CA-3394BF9E9FED}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {78FCC6BC-06A9-43AE-827A-1B68FFB7D75F}.Debug|x64.ActiveCfg = Debug|x64 {78FCC6BC-06A9-43AE-827A-1B68FFB7D75F}.Debug|x64.Build.0 = Debug|x64 {78FCC6BC-06A9-43AE-827A-1B68FFB7D75F}.Release|x64.ActiveCfg = Release|x64 {78FCC6BC-06A9-43AE-827A-1B68FFB7D75F}.Release|x64.Build.0 = Release|x64 {8B308357-C548-49D9-9134-8A61D57D524C}.Debug|x64.ActiveCfg = Debug|x64 {8B308357-C548-49D9-9134-8A61D57D524C}.Debug|x64.Build.0 = Debug|x64 {8B308357-C548-49D9-9134-8A61D57D524C}.Release|x64.ActiveCfg = Release|x64 {8B308357-C548-49D9-9134-8A61D57D524C}.Release|x64.Build.0 = Release|x64 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Debug|x64.ActiveCfg = Debug|x64 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Debug|x64.Build.0 = Debug|x64 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Release|x64.ActiveCfg = Release|x64 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Release|x64.Build.0 = Release|x64 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Debug|x64.ActiveCfg = Debug|x64 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Debug|x64.Build.0 = Debug|x64 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Release|x64.ActiveCfg = Release|x64 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Release|x64.Build.0 = Release|x64 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Debug|x64.ActiveCfg = Debug|x64 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Debug|x64.Build.0 = Debug|x64 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Release|x64.ActiveCfg = Release|x64 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Release|x64.Build.0 = Release|x64 {CC244BA5-4CA8-4B4F-B4CA-3394BF9E9FED}.Debug|x64.ActiveCfg = Debug|x64 {CC244BA5-4CA8-4B4F-B4CA-3394BF9E9FED}.Debug|x64.Build.0 = Debug|x64 {CC244BA5-4CA8-4B4F-B4CA-3394BF9E9FED}.Release|x64.ActiveCfg = Release|x64 {CC244BA5-4CA8-4B4F-B4CA-3394BF9E9FED}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal opencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/vc9/ext/0000755000175000017500000000000013223553423021427 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/vc9/ext/lcms.vcproj0000644000175000017500000003372113223553423023620 0ustar mfvmfv opencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/vc9/ext/tinyxml.vcproj0000644000175000017500000002756413223553423024376 0ustar mfvmfv opencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/vc9/ext/glew.vcproj0000644000175000017500000002776013223553423023626 0ustar mfvmfv opencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/vc9/ext/yaml.vcproj0000644000175000017500000004126413223553423023625 0ustar mfvmfv opencolorio-1.1.0~dfsg0.orig/src/aftereffects/vc/vc9/OpenColorIO.vcproj0000644000175000017500000005023713223553423024213 0ustar mfvmfv opencolorio-1.1.0~dfsg0.orig/src/aftereffects/OpenColorIO_AE_ArbData.cpp0000644000175000017500000003326513223553423024306 0ustar mfvmfv/* Copyright (c) 2003-2012 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 "OpenColorIO_AE.h" #include "OpenColorIO_AE_Context.h" #include PF_Err ArbNewDefault(PF_InData *in_data, PF_OutData *out_data, void *refconPV, PF_ArbitraryH *arbPH) { PF_Err err = PF_Err_NONE; if(arbPH) { *arbPH = PF_NEW_HANDLE( sizeof(ArbitraryData) ); if(*arbPH) { ArbitraryData *arb_data = (ArbitraryData *)PF_LOCK_HANDLE(*arbPH); // set up defaults arb_data->version = CURRENT_ARB_VERSION; arb_data->action = OCIO_ACTION_NONE; arb_data->invert = FALSE; arb_data->storage = OCIO_STORAGE_NONE; arb_data->storage_size = 0; arb_data->source = OCIO_SOURCE_NONE; arb_data->interpolation = OCIO_INTERP_LINEAR; arb_data->path[0] = '\0'; arb_data->relative_path[0] = '\0'; arb_data->input[0] = '\0'; arb_data->output[0] = '\0'; arb_data->transform[0] = '\0'; arb_data->device[0] = '\0'; arb_data->look[0] = '\0'; // set default with environment variable if it's set char *file = std::getenv("OCIO"); if(file) { try { OpenColorIO_AE_Context context(file, OCIO_SOURCE_ENVIRONMENT); strncpy(arb_data->path, file, ARB_PATH_LEN); arb_data->action = context.getAction(); arb_data->source = OCIO_SOURCE_ENVIRONMENT; if(arb_data->action != OCIO_ACTION_LUT) { strncpy(arb_data->input, context.getInput().c_str(), ARB_SPACE_LEN); strncpy(arb_data->output, context.getOutput().c_str(), ARB_SPACE_LEN); strncpy(arb_data->transform, context.getTransform().c_str(), ARB_SPACE_LEN); strncpy(arb_data->device, context.getDevice().c_str(), ARB_SPACE_LEN); } } catch(...) {} } PF_UNLOCK_HANDLE(*arbPH); } } return err; } static PF_Err ArbDispose(PF_InData *in_data, PF_OutData *out_data, void *refconPV, PF_ArbitraryH arbH) { if(arbH) PF_DISPOSE_HANDLE(arbH); return PF_Err_NONE; } static void CopyArbData(ArbitraryData *out_arb_data, ArbitraryData *in_arb_data) { // copy contents out_arb_data->version = in_arb_data->version; out_arb_data->action = in_arb_data->action; out_arb_data->invert = in_arb_data->invert; out_arb_data->storage = in_arb_data->storage; out_arb_data->storage_size = in_arb_data->storage_size; out_arb_data->source = in_arb_data->source; out_arb_data->interpolation = in_arb_data->interpolation; strcpy(out_arb_data->path, in_arb_data->path); strcpy(out_arb_data->relative_path, in_arb_data->relative_path); strcpy(out_arb_data->input, in_arb_data->input); strcpy(out_arb_data->output, in_arb_data->output); strcpy(out_arb_data->transform, in_arb_data->transform); strcpy(out_arb_data->device, in_arb_data->device); strcpy(out_arb_data->look, in_arb_data->look); } static PF_Err ArbCopy(PF_InData *in_data, PF_OutData *out_data, void *refconPV, PF_ArbitraryH src_arbH, PF_ArbitraryH *dst_arbPH) { PF_Err err = PF_Err_NONE; if(src_arbH && dst_arbPH) { // allocate using the creation function err = ArbNewDefault(in_data, out_data, refconPV, dst_arbPH); if(!err) { ArbitraryData *in_arb_data = (ArbitraryData *)PF_LOCK_HANDLE(src_arbH), *out_arb_data = (ArbitraryData *)PF_LOCK_HANDLE(*dst_arbPH); CopyArbData(out_arb_data, in_arb_data); PF_UNLOCK_HANDLE(src_arbH); PF_UNLOCK_HANDLE(*dst_arbPH); } } return err; } static PF_Err ArbFlatSize(PF_InData *in_data, PF_OutData *out_data, void *refconPV, PF_ArbitraryH arbH, A_u_long *flat_data_sizePLu) { // flat is the same size as inflated if(arbH) *flat_data_sizePLu = PF_GET_HANDLE_SIZE(arbH); return PF_Err_NONE; } static void SwapArbData(ArbitraryData *arb_data) { } static PF_Err ArbFlatten(PF_InData *in_data, PF_OutData *out_data, void *refconPV, PF_ArbitraryH arbH, A_u_long buf_sizeLu, void *flat_dataPV) { PF_Err err = PF_Err_NONE; if(arbH && flat_dataPV) { // they provide the buffer, we just move data ArbitraryData *in_arb_data = (ArbitraryData *)PF_LOCK_HANDLE(arbH), *out_arb_data = (ArbitraryData *)flat_dataPV; assert(buf_sizeLu >= PF_GET_HANDLE_SIZE(arbH)); CopyArbData(out_arb_data, in_arb_data); #ifdef AE_BIG_ENDIAN // not that we're doing a PPC version of this... SwapArbData(out_arb_data); #endif PF_UNLOCK_HANDLE(arbH); } return err; } static PF_Err ArbUnFlatten(PF_InData *in_data, PF_OutData *out_data, void *refconPV, A_u_long buf_sizeLu, const void *flat_dataPV, PF_ArbitraryH *arbPH) { PF_Err err = PF_Err_NONE; if(arbPH && flat_dataPV) { // they provide a flat buffer, we have to make the handle err = ArbNewDefault(in_data, out_data, refconPV, arbPH); if(!err && *arbPH) { ArbitraryData *in_arb_data = (ArbitraryData *)flat_dataPV, *out_arb_data = (ArbitraryData *)PF_LOCK_HANDLE(*arbPH); assert(buf_sizeLu <= PF_GET_HANDLE_SIZE(*arbPH)); CopyArbData(out_arb_data, in_arb_data); #ifdef AE_BIG_ENDIAN SwapArbData(out_arb_data); #endif PF_UNLOCK_HANDLE(*arbPH); } } return err; } static PF_Err ArbInterpolate(PF_InData *in_data, PF_OutData *out_data, void *refconPV, PF_ArbitraryH left_arbH, PF_ArbitraryH right_arbH, PF_FpLong tF, PF_ArbitraryH *interpPH) { PF_Err err = PF_Err_NONE; assert(FALSE); // we shouldn't be doing this if(left_arbH && right_arbH && interpPH) { // allocate using our own func err = ArbNewDefault(in_data, out_data, refconPV, interpPH); if(!err && *interpPH) { // we're just going to copy the left_data ArbitraryData *in_arb_data = (ArbitraryData *)PF_LOCK_HANDLE(left_arbH), *out_arb_data = (ArbitraryData *)PF_LOCK_HANDLE(*interpPH); CopyArbData(out_arb_data, in_arb_data); PF_UNLOCK_HANDLE(left_arbH); PF_UNLOCK_HANDLE(*interpPH); } } return err; } static PF_Err ArbCompare(PF_InData *in_data, PF_OutData *out_data, void *refconPV, PF_ArbitraryH a_arbH, PF_ArbitraryH b_arbH, PF_ArbCompareResult *compareP) { PF_Err err = PF_Err_NONE; if(a_arbH && b_arbH) { ArbitraryData *a_data = (ArbitraryData *)PF_LOCK_HANDLE(a_arbH), *b_data = (ArbitraryData *)PF_LOCK_HANDLE(b_arbH); if( a_data->version == b_data->version && a_data->action == b_data->action && a_data->invert == b_data->invert && a_data->source == b_data->source && a_data->interpolation == b_data->interpolation && !strcmp(a_data->path, b_data->path) && !strcmp(a_data->input, b_data->input) && !strcmp(a_data->output, b_data->output) && !strcmp(a_data->transform, b_data->transform) && !strcmp(a_data->device, b_data->device) && !strcmp(a_data->look, b_data->look) ) { *compareP = PF_ArbCompare_EQUAL; } else { *compareP = PF_ArbCompare_NOT_EQUAL; } PF_UNLOCK_HANDLE(a_arbH); PF_UNLOCK_HANDLE(b_arbH); } return err; } PF_Err HandleArbitrary( PF_InData *in_data, PF_OutData *out_data, PF_ParamDef *params[], PF_LayerDef *output, PF_ArbParamsExtra *extra) { PF_Err err = PF_Err_NONE; if(extra->id == OCIO_DATA_ID) { switch(extra->which_function) { case PF_Arbitrary_NEW_FUNC: err = ArbNewDefault(in_data, out_data, extra->u.new_func_params.refconPV, extra->u.new_func_params.arbPH); break; case PF_Arbitrary_DISPOSE_FUNC: err = ArbDispose(in_data, out_data, extra->u.dispose_func_params.refconPV, extra->u.dispose_func_params.arbH); break; case PF_Arbitrary_COPY_FUNC: err = ArbCopy(in_data, out_data, extra->u.copy_func_params.refconPV, extra->u.copy_func_params.src_arbH, extra->u.copy_func_params.dst_arbPH); break; case PF_Arbitrary_FLAT_SIZE_FUNC: err = ArbFlatSize(in_data, out_data, extra->u.flat_size_func_params.refconPV, extra->u.flat_size_func_params.arbH, extra->u.flat_size_func_params.flat_data_sizePLu); break; case PF_Arbitrary_FLATTEN_FUNC: err = ArbFlatten(in_data, out_data, extra->u.flatten_func_params.refconPV, extra->u.flatten_func_params.arbH, extra->u.flatten_func_params.buf_sizeLu, extra->u.flatten_func_params.flat_dataPV); break; case PF_Arbitrary_UNFLATTEN_FUNC: err = ArbUnFlatten(in_data, out_data, extra->u.unflatten_func_params.refconPV, extra->u.unflatten_func_params.buf_sizeLu, extra->u.unflatten_func_params.flat_dataPV, extra->u.unflatten_func_params.arbPH); break; case PF_Arbitrary_INTERP_FUNC: err = ArbInterpolate(in_data, out_data, extra->u.interp_func_params.refconPV, extra->u.interp_func_params.left_arbH, extra->u.interp_func_params.right_arbH, extra->u.interp_func_params.tF, extra->u.interp_func_params.interpPH); break; case PF_Arbitrary_COMPARE_FUNC: err = ArbCompare(in_data, out_data, extra->u.compare_func_params.refconPV, extra->u.compare_func_params.a_arbH, extra->u.compare_func_params.b_arbH, extra->u.compare_func_params.compareP); break; // these are necessary for copying and pasting keyframes // for now, we better not be called to do this case PF_Arbitrary_PRINT_SIZE_FUNC: assert(FALSE); break; case PF_Arbitrary_PRINT_FUNC: assert(FALSE); break; case PF_Arbitrary_SCAN_FUNC: assert(FALSE); break; } } return err; } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/OpenColorIO_AE_GL.h0000644000175000017500000000414613223553423022753 0ustar mfvmfv/* Copyright (c) 2003-2012 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 _OPENCOLORIO_AE_GL_H_ #define _OPENCOLORIO_AE_GL_H_ #include "AEConfig.h" #ifdef AE_OS_WIN #include #include #elif defined(AE_OS_MAC) #include #include #include #include #include #endif void GlobalSetup_GL(); bool HaveOpenGL(); // must surround plug-in OpenGL calls with these functions so that AE // doesn't know we're borrowing the OpenGL renderer void SetPluginContext(); void SetAEContext(); GLuint GetFrameBuffer(); void GlobalSetdown_GL(); #endif // _OPENCOLORIO_AE_GL_H_opencolorio-1.1.0~dfsg0.orig/src/aftereffects/OpenColorIO_AE_Context.h0000644000175000017500000001137013223553423024072 0ustar mfvmfv/* Copyright (c) 2003-2012 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 _OPENCOLORIO_AE_CONTEXT_H_ #define _OPENCOLORIO_AE_CONTEXT_H_ #include #include #include "OpenColorIO_AE.h" #include "OpenColorIO_AE_GL.h" #include namespace OCIO = OCIO_NAMESPACE; // yeah, this probably could/should go in a seperate file class Path { public: Path(const std::string &path, const std::string &dir); Path(const Path &path); ~Path() {} std::string full_path() const; std::string relative_path(bool force) const; bool exists() const; private: std::string _path; std::string _dir; typedef enum { TYPE_UNKNOWN = 0, TYPE_MAC, TYPE_WIN } PathType; static PathType path_type(const std::string &path); static bool is_relative(const std::string &path); static std::string convert_delimiters(const std::string &path); static std::vector components(const std::string &path); }; class OpenColorIO_AE_Context { public: OpenColorIO_AE_Context(const std::string &path, OCIO_Source source); OpenColorIO_AE_Context(const ArbitraryData *arb_data, const std::string &dir); ~OpenColorIO_AE_Context(); bool Verify(const ArbitraryData *arb_data, const std::string &dir); void setupConvert(const char *input, const char *output); void setupDisplay(const char *input, const char *device, const char *transform); void setupLUT(bool invert, OCIO_Interp interpolation); typedef std::vector SpaceVec; OCIO_Action getAction() const { return _action; } const std::string & getInput() const { return _input; } const std::string & getOutput() const { return _output; } const std::string & getDevice() const { return _device; } const std::string & getTransform() const { return _transform; } const SpaceVec & getInputs(bool fullPath=false) const { return fullPath ? _inputsFullPath : _inputs; } const SpaceVec & getDevices() const { return _devices; } const SpaceVec & getTransforms() const { return _transforms; } OCIO::ConstConfigRcPtr config() const { return _config; } OCIO::ConstProcessorRcPtr processor() const { return _processor; } bool ExportLUT(const std::string &path, const std::string &display_icc_path); bool ProcessWorldGL(PF_EffectWorld *float_world); private: std::string _path; OCIO_Source _source; std::string _config_name; OCIO_Action _action; std::string _input; std::string _output; std::string _device; std::string _transform; SpaceVec _inputs; SpaceVec _inputsFullPath; SpaceVec _devices; SpaceVec _transforms; bool _invert; OCIO_Interp _interpolation; OCIO::ConstConfigRcPtr _config; OCIO::ConstProcessorRcPtr _processor; bool _gl_init; GLuint _fragShader; GLuint _program; GLuint _imageTexID; GLuint _lut3dTexID; std::vector _lut3d; std::string _lut3dcacheid; std::string _shadercacheid; std::string _inputColorSpace; std::string _display; std::string _transformName; GLuint _renderBuffer; int _bufferWidth; int _bufferHeight; void InitOCIOGL(); void UpdateOCIOGLState(); }; #endif // _OPENCOLORIO_AE_CONTEXT_H_opencolorio-1.1.0~dfsg0.orig/src/aftereffects/mac/0000755000175000017500000000000013223553423020256 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/aftereffects/mac/OpenColorIO_AE_MonitorProfileChooser_Controller.h0000644000175000017500000000363613223553423031712 0ustar mfvmfv/* Copyright (c) 2003-2012 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. */ #import @interface OpenColorIO_AE_MonitorProfileChooser_Controller : NSObject { IBOutlet NSPopUpButton *profileMenu; IBOutlet NSWindow *window; NSMutableArray *name_array; NSMapTable *profile_map; } - (IBAction)clickOK:(NSButton *)sender; - (IBAction)clickCancel:(NSButton *)sender; - (NSWindow *)getWindow; - (BOOL)getMonitorProfile:(char *)path bufferSize:(int)buf_len; @end opencolorio-1.1.0~dfsg0.orig/src/aftereffects/mac/OpenColorIO_AE.plugin-Info.plist0000755000175000017500000000132113223553423026216 0ustar mfvmfv CFBundleIdentifier org.OpenColorIO.AfterEffects CFBundleInfoDictionaryVersion 6.0 CFBundleName OpenColorIO CFBundleExecutable OpenColorIO CFBundlePackageType eFKT CFBundleSignature FXTC NSAppleScriptEnabled No NSHumanReadableCopyright © 2011 OpenColorIO LSRequiresCarbon opencolorio-1.1.0~dfsg0.orig/src/aftereffects/mac/OpenColorIO_AE_Menu.h0000644000175000017500000000400613223553423024110 0ustar mfvmfv/* Copyright (c) 2003-2012 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. */ #import @interface OpenColorIO_AE_Menu : NSView { NSArray *menu_items; NSInteger chosen_item; NSMenu *text_menu; NSMenuItem *chosen_menu_item; } // index-based menu - (id)init:(NSArray *)menuItems selectedItem:(NSInteger)selected; - (void)showMenu; - (IBAction)menuItemAction:(id)sender; - (NSInteger)selectedItem; // text-based menu - (id)initWithTextMenu:(NSMenu *)menu; - (void)showTextMenu; - (IBAction)textMenuItemAction:(id)sender; - (NSMenuItem *)selectedTextMenuItem; @end opencolorio-1.1.0~dfsg0.orig/src/aftereffects/mac/OpenColorIO_AE_MonitorProfileChooser.xib0000644000175000017500000005060713223553423030042 0ustar mfvmfv 1050 10K549 851 1038.36 461.00 com.apple.InterfaceBuilder.CocoaPlugin 851 YES YES com.apple.InterfaceBuilder.CocoaPlugin YES YES YES YES OpenColorIO_AE_MonitorProfileChooser_Controller FirstResponder NSApplication 1 2 {{196, 369}, {364, 141}} 544735232 OpenColorIO NSWindow {3.40282e+38, 3.40282e+38} 256 YES 268 {{125, 87}, {222, 26}} YES -2076049856 2048 LucidaGrande 13 1044 109199615 129 400 75 YES OtherViews YES -1 1 YES YES 2 268 {{17, 94}, {106, 17}} YES 68288064 138413056 Monitor Profile: 6 System controlColor 3 MC42NjY2NjY2ODY1AA 6 System controlTextColor 3 MAA 268 {{254, 12}, {96, 32}} YES 67239424 134217728 OK -2038284033 129 DQ 200 25 268 {{158, 12}, {96, 32}} YES 67239424 134217728 Cancel -2038284033 129 Gw 200 25 {364, 141} {{0, 0}, {1680, 1028}} {3.40282e+38, 3.40282e+38} YES profileMenu 15 window 16 clickCancel: 17 clickOK: 18 YES 0 -2 File's Owner -1 First Responder -3 Application 1 YES 2 YES 3 YES 4 YES 5 YES 9 YES 10 11 YES 12 13 YES 14 YES YES 1.IBEditorWindowLastContentRect 1.IBPluginDependency 1.IBWindowTemplateEditedContentRect 1.NSWindowTemplate.visibleAtLaunch 1.WindowOrigin 1.editorWindowContentRectSynchronizationRect 10.IBPluginDependency 11.IBPluginDependency 11.IBViewBoundsToFrameTransform 12.IBPluginDependency 13.IBPluginDependency 13.IBViewBoundsToFrameTransform 14.IBPluginDependency 2.IBPluginDependency 3.IBPluginDependency 3.IBViewBoundsToFrameTransform 4.IBPluginDependency 5.IBEditorWindowLastContentRect 5.IBPluginDependency 9.IBPluginDependency 9.IBViewBoundsToFrameTransform YES {{498, 559}, {364, 141}} com.apple.InterfaceBuilder.CocoaPlugin {{498, 559}, {364, 141}} {196, 240} {{202, 428}, {480, 270}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDfgAAwigAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDfgAAwigAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDFAAAw1oAAA com.apple.InterfaceBuilder.CocoaPlugin {{598, 628}, {110, 4}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABCIAAAw1gAAA YES YES YES YES 18 YES OpenColorIO_AE_MonitorProfileChooser_Controller NSObject YES YES clickCancel: clickOK: YES NSButton NSButton YES YES clickCancel: clickOK: YES clickCancel: NSButton clickOK: NSButton YES YES profileMenu window YES NSPopUpButton NSWindow YES YES profileMenu window YES profileMenu NSPopUpButton window NSWindow IBProjectSource OpenColorIO_AE_MonitorProfileChooser_Controller.h 0 IBCocoaFramework com.apple.InterfaceBuilder.CocoaPlugin.macosx com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 YES OpenColorIO_AE.xcodeproj 3 opencolorio-1.1.0~dfsg0.orig/src/aftereffects/mac/OpenColorIO_AE_Dialogs_Cocoa.mm0000644000175000017500000002613213223553423026060 0ustar mfvmfv/* Copyright (c) 2003-2012 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 "OpenColorIO_AE_Dialogs.h" #import "OpenColorIO_AE_MonitorProfileChooser_Controller.h" #import "OpenColorIO_AE_Menu.h" bool OpenFile(char *path, int buf_len, const ExtensionMap &extensions, const void *hwnd) { NSOpenPanel *panel = [NSOpenPanel openPanel]; [panel setTitle:@"OpenColorIO"]; NSMutableArray *extension_array = [[NSMutableArray alloc] init]; std::string message = "Formats: "; bool first_one = true; for(ExtensionMap::const_iterator i = extensions.begin(); i != extensions.end(); i++) { [extension_array addObject:[NSString stringWithUTF8String:i->first.c_str()]]; if(first_one) first_one = false; else message += ", "; message += "." + i->first; } [panel setMessage:[NSString stringWithUTF8String:message.c_str()]]; NSInteger result = [panel runModalForTypes:extension_array]; [extension_array release]; if(result == NSOKButton) { return [[panel filename] getCString:path maxLength:buf_len encoding:NSASCIIStringEncoding]; } else return false; } bool SaveFile(char *path, int buf_len, const ExtensionMap &extensions, const void *hwnd) { NSSavePanel *panel = [NSSavePanel savePanel]; [panel setTitle:@"OpenColorIO"]; NSMutableArray *extension_array = [[NSMutableArray alloc] init]; std::string message = "Formats: "; bool first_one = true; for(ExtensionMap::const_iterator i = extensions.begin(); i != extensions.end(); i++) { [extension_array addObject:[NSString stringWithUTF8String:i->first.c_str()]]; if(first_one) first_one = false; else message += ", "; message += i->second + " (." + i->first + ")"; } [panel setAllowedFileTypes:extension_array]; [panel setMessage:[NSString stringWithUTF8String:message.c_str()]]; NSInteger result = [panel runModal]; [extension_array release]; if(result == NSOKButton) { return [[panel filename] getCString:path maxLength:buf_len encoding:NSASCIIStringEncoding]; } else return false; } bool GetMonitorProfile(char *path, int buf_len, const void *hwnd) { bool hit_ok = false; Class ui_controller_class = [[NSBundle bundleWithIdentifier:@"org.OpenColorIO.AfterEffects"] classNamed:@"OpenColorIO_AE_MonitorProfileChooser_Controller"]; if(ui_controller_class) { OpenColorIO_AE_MonitorProfileChooser_Controller *ui_controller = [[ui_controller_class alloc] init]; if(ui_controller) { NSWindow *my_window = [ui_controller getWindow]; if(my_window) { NSInteger result = [NSApp runModalForWindow:my_window]; if(result == NSRunStoppedResponse) { [ui_controller getMonitorProfile:path bufferSize:buf_len]; hit_ok = true; } [my_window release]; } [ui_controller release]; } } return hit_ok; } void GetStdConfigs(ConfigVec &configs) { const char *ocio_dir = "/Library/Application Support/OpenColorIO/"; NSFileManager *man = [NSFileManager defaultManager]; NSDirectoryEnumerator *enumerator = [man enumeratorAtPath:[NSString stringWithUTF8String:ocio_dir]]; for(NSString *file in enumerator) { std::string config_path(ocio_dir); config_path += [file UTF8String]; config_path += "/config.ocio"; [enumerator skipDescendents]; if([man fileExistsAtPath:[NSString stringWithUTF8String:config_path.c_str()]]) { configs.push_back( [file UTF8String] ); } } } std::string GetStdConfigPath(const std::string &name) { const char *ocio_dir = "/Library/Application Support/OpenColorIO/"; std::string config_path = ocio_dir + name + "/config.ocio"; if( [[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:config_path.c_str()]] ) { return config_path; } else { return ""; } } int PopUpMenu(const MenuVec &menu_items, int selected_index, const void *hwnd) { NSMutableArray *item_array = [NSMutableArray array]; for(MenuVec::const_iterator i = menu_items.begin(); i != menu_items.end(); i++) { [item_array addObject:[NSString stringWithUTF8String:i->c_str()]]; } OpenColorIO_AE_Menu *menu = [[OpenColorIO_AE_Menu alloc] init:item_array selectedItem:selected_index]; [menu showMenu]; NSInteger item = [menu selectedItem]; [menu release]; return item; } bool ColorSpacePopUpMenu(OCIO::ConstConfigRcPtr config, std::string &colorSpace, bool selectRoles, const void *hwnd) { NSMenu *menu = [[[NSMenu alloc] initWithTitle:@"ColorSpace Pop-Up"] autorelease]; [menu setAutoenablesItems:NO]; for(int i=0; i < config->getNumColorSpaces(); ++i) { const char *colorSpaceName = config->getColorSpaceNameByIndex(i); OCIO::ConstColorSpaceRcPtr colorSpacePtr = config->getColorSpace(colorSpaceName); const char *family = colorSpacePtr->getFamily(); NSString *colorSpacePath = nil; if(family == NULL) { colorSpacePath = [NSString stringWithUTF8String:colorSpaceName]; } else { colorSpacePath = [NSString stringWithFormat:@"%s/%s", family, colorSpaceName]; } NSArray *pathComponents = [colorSpacePath pathComponents]; NSMenu *currentMenu = menu; for(int j=0; j < [pathComponents count]; j++) { NSString *componentName = [pathComponents objectAtIndex:j]; if(j == ([pathComponents count] - 1)) { NSMenuItem *newItem = [currentMenu addItemWithTitle:componentName action:@selector(textMenuItemAction:) keyEquivalent:@""]; if(colorSpace == [componentName UTF8String]) { [newItem setState:NSOnState]; } } else { NSMenuItem *componentItem = [currentMenu itemWithTitle:componentName]; if(componentItem == nil) { componentItem = [currentMenu addItemWithTitle:componentName action:NULL keyEquivalent:@""]; NSMenu *subMenu = [[[NSMenu alloc] initWithTitle:componentName] autorelease]; [subMenu setAutoenablesItems:NO]; [componentItem setSubmenu:subMenu]; } currentMenu = [componentItem submenu]; } } } if(config->getNumRoles() > 0) { NSMenuItem *rolesItem = [menu insertItemWithTitle:@"Roles" action:NULL keyEquivalent:@"" atIndex:0]; NSMenu *rolesMenu = [[[NSMenu alloc] initWithTitle:@"Roles"] autorelease]; [rolesMenu setAutoenablesItems:NO]; [rolesItem setSubmenu:rolesMenu]; for(int i=0; i < config->getNumRoles(); i++) { NSString *roleName = [NSString stringWithUTF8String:config->getRoleName(i)]; OCIO::ConstColorSpaceRcPtr colorSpacePtr = config->getColorSpace([roleName UTF8String]); NSString *colorSpaceName = [NSString stringWithUTF8String:colorSpacePtr->getName()]; SEL selector = (selectRoles ? @selector(textMenuItemAction:) : NULL); NSMenuItem *roleItem = [rolesMenu addItemWithTitle:roleName action:selector keyEquivalent:@""]; if(colorSpace == [roleName UTF8String]) { [roleItem setState:NSOnState]; } NSMenu *roleMenu = [[[NSMenu alloc] initWithTitle:roleName] autorelease]; [roleMenu setAutoenablesItems:NO]; [roleItem setSubmenu:roleMenu]; NSMenuItem *roleColorSpaceItem = [roleMenu addItemWithTitle:colorSpaceName action:@selector(textMenuItemAction:) keyEquivalent:@""]; if(colorSpace == [colorSpaceName UTF8String]) { [roleColorSpaceItem setState:NSOnState]; } } [menu insertItem:[NSMenuItem separatorItem] atIndex:1]; } OpenColorIO_AE_Menu *ocio_menu = [[OpenColorIO_AE_Menu alloc] initWithTextMenu:menu]; [ocio_menu showTextMenu]; NSMenuItem *item = [ocio_menu selectedTextMenuItem]; bool selected = false; if(item != nil) { colorSpace = [[item title] UTF8String]; selected = true; } [ocio_menu release]; return selected; } void ErrorMessage(const char *message, const void *hwnd) { NSAlert *alert = [[NSAlert alloc] init]; [alert setMessageText:[NSString stringWithUTF8String:message]]; [alert runModal]; [alert release]; } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/mac/OpenColorIO_AE_MonitorProfileChooser_Controller.m0000644000175000017500000001451413223553423031714 0ustar mfvmfv/* Copyright (c) 2003-2012 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. */ #import "OpenColorIO_AE_MonitorProfileChooser_Controller.h" typedef struct { NSMutableArray *name_array; NSMapTable *profile_map; const char *monitor_profile_path; char *monitor_profile_name; } IterateData; static OSErr profIterateProc(CMProfileIterateData* data, void* refcon) { OSErr err = noErr; IterateData *i_data = (IterateData *)refcon; if(data->header.dataColorSpace == cmRGBData && data->location.locType == cmPathBasedProfile) { [i_data->name_array addObject:[NSString stringWithUTF8String:data->asciiName]]; [i_data->profile_map setObject:[NSString stringWithUTF8String:data->location.u.pathLoc.path] forKey:[NSString stringWithUTF8String:data->asciiName] ]; if( i_data->monitor_profile_path && !strcmp(data->location.u.pathLoc.path, i_data->monitor_profile_path) ) { strncpy(i_data->monitor_profile_name, data->asciiName, 255); } } return err; } @implementation OpenColorIO_AE_MonitorProfileChooser_Controller - (id)init { self = [super init]; if(!([NSBundle loadNibNamed:@"OpenColorIO_AE_MonitorProfileChooser" owner:self])) return nil; [window center]; // Originally tried to implement this with two NSArrays, one with paths and // one with profile names (ICC descriptions). The problem is that when you // add items to NSArrays one at a time, they auto-sort. But then it turns out I // WANT them to sort because the profiles come in random order and the menu looks // terrible if they're not sorted. // So I make an NSArray to set up the menu and an NSMapTable to convert from the // selected menu item to the actual path. Got that? name_array = [[NSMutableArray alloc] init]; profile_map = [[NSMapTable alloc] init]; // get monitor profile path // Oddly enough, the "Name" given to me by ColorSync for this is often "Display", // but if you get the profile's description, you get something like // "Apple Cinema HD Display". So to see if ColorSync runs accross the the monitor's // profile so I can select it, I have to compare the paths, and then save the name // I'm currently getting. CMProfileRef prof; CMProfileLocation profLoc; UInt32 locationSize = cmCurrentProfileLocationSize; // Get the main GDevice. CGDirectDisplayID theAVID = CGMainDisplayID(); // Get the profile for that AVID. CMError err = CMGetProfileByAVID(theAVID, &prof); // Get location (FSRef) for that profile err = NCMGetProfileLocation(prof, &profLoc, &locationSize); const char *monitor_profile_path = NULL; char monitor_profile_name[256] = { '\0' }; if(profLoc.locType == cmPathBasedProfile) { monitor_profile_path = profLoc.u.pathLoc.path; } // build profile map and name array IterateData i_data = { name_array, profile_map, monitor_profile_path, monitor_profile_name }; UInt32 seed = 0; UInt32 count; CMProfileIterateUPP iterateUPP; iterateUPP = NewCMProfileIterateUPP((CMProfileIterateProcPtr)&profIterateProc); err = CMIterateColorSyncFolder(iterateUPP, &seed, &count, (void *)&i_data); DisposeCMProfileIterateUPP(iterateUPP); // set up menu with array [profileMenu addItemsWithTitles:name_array]; // choose the display profile name if we have it (usually "Display") if(monitor_profile_name[0] != '\0') { [profileMenu selectItemWithTitle:[NSString stringWithUTF8String:monitor_profile_name]]; } else if(monitor_profile_path != NULL) { // somehow the display profile wasn't found during iteration // so let's add it CFStringRef m_name; err = CMCopyProfileDescriptionString(prof, &m_name); NSString *ns_name = (NSString *)monitor_profile_name; [profile_map setObject:[NSString stringWithUTF8String:monitor_profile_path] forKey:ns_name ]; [profileMenu addItemWithTitle:ns_name]; [profileMenu selectItemWithTitle:ns_name]; CFRelease(m_name); } return self; } - (void)dealloc { [name_array release]; [profile_map release]; [super dealloc]; } - (IBAction)clickOK:(NSButton *)sender { [NSApp stopModal]; } - (IBAction)clickCancel:(NSButton *)sender { [NSApp abortModal]; } - (NSWindow *)getWindow { return window; } - (BOOL)getMonitorProfile:(char *)path bufferSize:(int)buf_len { NSString *icc_name = [[profileMenu selectedItem] title]; NSString *icc_path = [profile_map objectForKey:icc_name]; return [icc_path getCString:path maxLength:buf_len encoding:NSMacOSRomanStringEncoding]; } @end opencolorio-1.1.0~dfsg0.orig/src/aftereffects/mac/OpenColorIO_AE_GL_Cocoa.mm0000644000175000017500000001115113223553423024773 0ustar mfvmfv/* Copyright (c) 2003-2012 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 "OpenColorIO_AE_GL.h" #import static NSWindow *g_win = nil; static AGLContext g_context = NULL; static GLuint g_framebuffer; static bool HaveRequiredExtensions() { const GLubyte *strVersion = glGetString(GL_VERSION); const GLubyte *strExt = glGetString(GL_EXTENSIONS); if(strVersion == NULL || strExt == NULL) return false; float gl_version; sscanf((char *)strVersion, "%f", &gl_version); #define CheckExtension(N) gluCheckExtension((const GLubyte *)N, strExt) return (gl_version >= 2.0 && CheckExtension("GL_ARB_color_buffer_float") && CheckExtension("GL_ARB_texture_float") && CheckExtension("GL_ARB_vertex_program") && CheckExtension("GL_ARB_vertex_shader") && CheckExtension("GL_ARB_texture_cube_map") && CheckExtension("GL_ARB_fragment_shader") && CheckExtension("GL_ARB_draw_buffers") && CheckExtension("GL_ARB_framebuffer_object") ); } void GlobalSetup_GL() { GLint aAttribs[64]; u_short nIndexS= -1; aAttribs[++nIndexS] = AGL_RGBA; aAttribs[++nIndexS] = AGL_DOUBLEBUFFER; aAttribs[++nIndexS] = AGL_COLOR_FLOAT; aAttribs[++nIndexS] = AGL_RED_SIZE; aAttribs[++nIndexS] = 32; aAttribs[++nIndexS] = AGL_GREEN_SIZE; aAttribs[++nIndexS] = 32; aAttribs[++nIndexS] = AGL_BLUE_SIZE; aAttribs[++nIndexS] = 32; aAttribs[++nIndexS] = AGL_ALPHA_SIZE; aAttribs[++nIndexS] = 32; aAttribs[++nIndexS] = AGL_NONE; AGLPixelFormat oPixelFormat = aglChoosePixelFormat(NULL, 0, aAttribs); if(oPixelFormat) { g_context = aglCreateContext(oPixelFormat, NULL); aglDestroyPixelFormat(oPixelFormat); } if(g_context == NULL) return; g_win = [[NSWindow alloc] initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]; aglSetDrawable(g_context, (AGLDrawable)[[g_win graphicsContext] graphicsPort]); glFlush(); SetPluginContext(); GLint units; glGetIntegerv(GL_MAX_TEXTURE_UNITS, &units); if( !HaveRequiredExtensions() || units < 2) { GlobalSetdown_GL(); SetAEContext(); return; } glGenFramebuffersEXT(1, &g_framebuffer); SetAEContext(); } bool HaveOpenGL() { return (g_context != NULL && g_win != nil); } static AGLContext g_ae_context; void SetPluginContext() { g_ae_context = aglGetCurrentContext(); aglSetCurrentContext(g_context); } void SetAEContext() { // g_ae_context might be NULL...so be it aglSetCurrentContext(g_ae_context); } GLuint GetFrameBuffer() { return g_framebuffer; } void GlobalSetdown_GL() { if(g_context) { aglDestroyContext(g_context); g_context = NULL; glDeleteFramebuffersEXT(1, &g_framebuffer); } if(g_win) { [g_win release]; g_win = nil; } } opencolorio-1.1.0~dfsg0.orig/src/aftereffects/mac/OpenColorIO_AE_Menu.m0000644000175000017500000001155613223553423024125 0ustar mfvmfv/* Copyright (c) 2003-2012 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. */ #import "OpenColorIO_AE_Menu.h" @implementation OpenColorIO_AE_Menu - (id)init:(NSArray *)menuItems selectedItem:(NSInteger)selected { self = [super init]; menu_items = menuItems; chosen_item = selected; return self; } - (void)showMenu { // Doing some pretty weird stuff here. // I need to bring up a contextual menu without AE giving me an NSView. // To get the screen position, I use global NSApp methods. // And I need to make an NSView to give to popUpContextMenu: // so I can catch the selectors it sends, so I made this an NSView subclass. NSMenu *menu = [[NSMenu alloc] initWithTitle:@"Pop-Up"]; [menu setAutoenablesItems:FALSE]; NSUInteger i; for(i=0; i < [menu_items count]; i++) { if( [[menu_items objectAtIndex:i] isEqualToString:@"(-"] ) { [menu addItem:[NSMenuItem separatorItem]]; } else { NSMenuItem *item = [menu addItemWithTitle:[menu_items objectAtIndex:i] action:@selector(menuItemAction:) keyEquivalent:@""]; [item setTag:i]; if(i == chosen_item) [item setState:NSOnState]; if([[menu_items objectAtIndex:i] isEqualToString:@"$OCIO"] && NULL == getenv("OCIO")) { [item setEnabled:FALSE]; [item setState:NSOffState]; } else if([[menu_items objectAtIndex:i] isEqualToString:@"(nada)"]) { [item setTitle:@"No configs in /Library/Application Support/OpenColorIO/"]; [item setEnabled:FALSE]; } } } id fakeMouseEvent=[NSEvent mouseEventWithType:NSLeftMouseDown location: [[NSApp keyWindow] convertScreenToBase:[NSEvent mouseLocation]] modifierFlags:0 timestamp:0 windowNumber: [[NSApp keyWindow] windowNumber] context:nil eventNumber:0 clickCount:1 pressure:0]; [NSMenu popUpContextMenu:menu withEvent:fakeMouseEvent forView:self]; [menu release]; } - (IBAction)menuItemAction:(id)sender { NSMenuItem *item = (NSMenuItem *)sender; chosen_item = [item tag]; } - (NSInteger)selectedItem { return chosen_item; } - (id)initWithTextMenu:(NSMenu *)menu { self = [super init]; text_menu = menu; chosen_menu_item = nil; return self; } - (void)showTextMenu { id fakeMouseEvent=[NSEvent mouseEventWithType:NSLeftMouseDown location: [[NSApp keyWindow] convertScreenToBase:[NSEvent mouseLocation]] modifierFlags:0 timestamp:0 windowNumber: [[NSApp keyWindow] windowNumber] context:nil eventNumber:0 clickCount:1 pressure:0]; [NSMenu popUpContextMenu:text_menu withEvent:fakeMouseEvent forView:self]; } - (IBAction)textMenuItemAction:(id)sender { NSMenuItem *item = (NSMenuItem *)sender; chosen_menu_item = item; } - (NSMenuItem *)selectedTextMenuItem { return chosen_menu_item; } @end opencolorio-1.1.0~dfsg0.orig/src/aftereffects/OpenColorIO_AE_Dialogs.h0000644000175000017500000000505013223553423024026 0ustar mfvmfv/* Copyright (c) 2003-2012 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 _OPENCOLORIC_AE_DIALOG_H_ #define _OPENCOLORIC_AE_DIALOG_H_ #include #include #include #include namespace OCIO = OCIO_NAMESPACE; typedef std::map ExtensionMap; // map[ ext ] = format bool OpenFile(char *path, int buf_len, const ExtensionMap &extensions, const void *hwnd); bool SaveFile(char *path, int buf_len, const ExtensionMap &extensions, const void *hwnd); bool GetMonitorProfile(char *path, int buf_len, const void *hwnd); typedef std::vector ConfigVec; void GetStdConfigs(ConfigVec &configs); std::string GetStdConfigPath(const std::string &name); typedef std::vector MenuVec; int PopUpMenu(const MenuVec &menu_items, int selected_index, const void *hwnd); bool ColorSpacePopUpMenu(OCIO::ConstConfigRcPtr config, std::string &colorSpace, bool selectRoles, const void *hwnd); void ErrorMessage(const char *message, const void *hwnd); #ifdef SUPPLY_HINSTANCE void SetHInstance(void *hInstance); #endif #endif // _OPENCOLORIC_AE_DIALOG_H_opencolorio-1.1.0~dfsg0.orig/src/nuke/0000755000175000017500000000000013223553423016017 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/nuke/CMakeLists.txt0000644000175000017500000000674413223553423020572 0ustar mfvmfvif(APPLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -undefined dynamic_lookup") endif() include_directories( ${CMAKE_SOURCE_DIR}/export/ ${CMAKE_BINARY_DIR}/export/ ${Nuke_INCLUDE_DIR} ) ############################################################################### ### NukeOCIOColorSpace ### add_library(NukeOCIOColorSpace MODULE OCIOColorSpace/OCIOColorSpace.cpp ) target_link_OCIO(NukeOCIOColorSpace #${Nuke_LIBRARIES} ) set_target_properties(NukeOCIOColorSpace PROPERTIES PREFIX "" OUTPUT_NAME "OCIOColorSpace" ) ############################################################################### ### NukeOCIODisplay ### add_library(NukeOCIODisplay MODULE OCIODisplay/OCIODisplay.cpp ) target_link_OCIO(NukeOCIODisplay #${Nuke_LIBRARIES} ) set_target_properties(NukeOCIODisplay PROPERTIES PREFIX "" OUTPUT_NAME "OCIODisplay" ) ############################################################################### ### NukeOCIOFileTransform ### add_library(NukeOCIOFileTransform MODULE OCIOFileTransform/OCIOFileTransform.cpp ) target_link_OCIO(NukeOCIOFileTransform #${Nuke_LIBRARIES} ) set_target_properties(NukeOCIOFileTransform PROPERTIES PREFIX "" OUTPUT_NAME "OCIOFileTransform" ) ############################################################################### ### NukeOCIOLogConvert ### add_library(NukeOCIOLogConvert MODULE OCIOLogConvert/OCIOLogConvert.cpp ) target_link_OCIO(NukeOCIOLogConvert #${Nuke_LIBRARIES} ) set_target_properties(NukeOCIOLogConvert PROPERTIES PREFIX "" OUTPUT_NAME "OCIOLogConvert" ) ############################################################################### ### NukeOCIOLookTransform ### add_library(NukeOCIOLookTransform MODULE OCIOLookTransform/OCIOLookTransform.cpp ) target_link_OCIO(NukeOCIOLookTransform #${Nuke_LIBRARIES} ) set_target_properties(NukeOCIOLookTransform PROPERTIES PREFIX "" OUTPUT_NAME "OCIOLookTransform" ) ############################################################################### ### NukeOCIOCDLTransform ### add_library(NukeOCIOCDLTransform MODULE OCIOCDLTransform/OCIOCDLTransform.cpp ) target_link_OCIO(NukeOCIOCDLTransform #${Nuke_LIBRARIES} ) set_target_properties(NukeOCIOCDLTransform PROPERTIES PREFIX "" OUTPUT_NAME "OCIOCDLTransform" ) ############################################################################### ### Nuke Targets ### add_custom_target(Nuke DEPENDS NukeOCIOColorSpace DEPENDS NukeOCIODisplay DEPENDS NukeOCIOFileTransform DEPENDS NukeOCIOLogConvert DEPENDS NukeOCIOCDLTransform ) install(TARGETS NukeOCIOColorSpace EXPORT OpenColorIO DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib/nuke${Nuke_API_VERSION}) install(TARGETS NukeOCIODisplay EXPORT OpenColorIO DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib/nuke${Nuke_API_VERSION}) install(TARGETS NukeOCIOLogConvert EXPORT OpenColorIO DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib/nuke${Nuke_API_VERSION}) install(TARGETS NukeOCIOFileTransform EXPORT OpenColorIO DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib/nuke${Nuke_API_VERSION}) install(TARGETS NukeOCIOLookTransform EXPORT OpenColorIO DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib/nuke${Nuke_API_VERSION}) install(TARGETS NukeOCIOCDLTransform EXPORT OpenColorIO DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib/nuke${Nuke_API_VERSION}) install(DIRECTORY ${CMAKE_SOURCE_DIR}/share/nuke DESTINATION ${CMAKE_INSTALL_PREFIX}/share/ PATTERN .svn EXCLUDE) opencolorio-1.1.0~dfsg0.orig/src/nuke/OCIOLookTransform/0000755000175000017500000000000013223553423021271 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/nuke/OCIOLookTransform/OCIOLookTransform.h0000644000175000017500000001120413223553423024712 0ustar mfvmfv#ifndef INCLUDED_OCIO_NUKE_COLORSPACECONVERSION_H_ #define INCLUDED_OCIO_NUKE_COLORSPACECONVERSION_H_ // Include these early, for Nuke's headers under gcc 4.4.2. #include #include #include #include #include #include namespace OCIO = OCIO_NAMESPACE; /*! * Iop that uses OpenColorIO to perform colorspace conversions */ class OCIOLookTransform : public DD::Image::PixelIop { protected: bool m_hasColorSpaces; //!< Were colorspaces found for both input and output? If not, always error. std::string m_look; std::string m_lookhelp; int m_dirIndex; int m_inputColorSpaceIndex; int m_outputColorSpaceIndex; std::vector m_colorSpaceNames; //!< list of input and output colorspace names (memory for const char* s below) std::vector m_inputColorSpaceCstrNames; //!< list for the pulldown list knob (used raw) std::vector m_outputColorSpaceCstrNames; bool m_ignoreErrors; OCIO::ConstContextRcPtr getLocalContext(); OCIO::ConstProcessorRcPtr m_processor; /*! Controlled by hidden "version" knob, incremented to redraw image */ int m_reload_version; public: OCIOLookTransform(Node *node); virtual ~OCIOLookTransform(); // These are public so the nuke wrapper can introspect into it // TODO: use 'friend' instead std::string m_contextKey1; std::string m_contextValue1; std::string m_contextKey2; std::string m_contextValue2; std::string m_contextKey3; std::string m_contextValue3; std::string m_contextKey4; std::string m_contextValue4; static const DD::Image::Op::Description description; /*! Return the command name that will be stored in Nuke scripts. */ virtual const char *Class() const; /*! * Return a name for this class that will be shown to the user. The * default implementation returns Class(). You can return a different * (ie more user-friendly) name instead here, and there is no need for * this to be unique. * * Nuke currently will remove any trailing digits and underscores from * this and add a new number to make a unique name for the new node. * * \return "OCIOLookTransform" */ virtual const char *displayName() const; /*! * Return help information for this node. This information is in the * pop-up window that the user gets when they hit the [?] button in * the lower-left corner of the control panel. */ virtual const char *node_help() const; /*! * Define the knobs that will be presented in the control panel. */ virtual void knobs(DD::Image::Knob_Callback f); /*! * Specify the channels required from input n to produce the channels * in mask by modifying mask in-place. (At least one channel in the * input is assumed.) * * Since colorspace conversions can have channel cross-talk, any rgb * output channel requires all its rgb bretheren. (Non-rgb * are passed through.) */ virtual void in_channels(int n, DD::Image::ChannelSet& mask) const; /*! * Calculate the output pixel data. * \param rowY vertical line number * \param rowX inclusive left bound * \param rowXBound exclusive right bound * \param outputChannels a subset of out_channels(), the required channels to be produced */ virtual void pixel_engine( const DD::Image::Row& in, int rowY, int rowX, int rowXBound, DD::Image::ChannelMask outputChannels, DD::Image::Row& out); protected: /*! * Check that colorspaces are available, and that the transform * is not a noop. (As OCIO whether a given transform is a noop, since it * can do more analysis than just name matching.) */ virtual void _validate(bool for_real); /*! * Ensure Node hash is reflects all parameters */ virtual void append(DD::Image::Hash& nodehash); /*! * Hide and show UI elements based on other parameters. Also handles reload button */ virtual int knob_changed(DD::Image::Knob* k); }; static DD::Image::Op* build(Node *node); #endif // INCLUDED_OCIO_NUKE_COLORSPACECONVERSION_H_ opencolorio-1.1.0~dfsg0.orig/src/nuke/OCIOLookTransform/OCIOLookTransform.cpp0000644000175000017500000004250213223553423025252 0ustar mfvmfv/** * OpenColorIO ColorSpace Iop. */ #include "OCIOLookTransform.h" namespace OCIO = OCIO_NAMESPACE; #include #include #include #include #include #include #include #include #include // Should we use cascasing ColorSpace menus #if defined kDDImageVersionInteger && (kDDImageVersionInteger>=62300) #define OCIO_CASCADE #endif OCIOLookTransform::OCIOLookTransform(Node *n) : DD::Image::PixelIop(n) { m_hasColorSpaces = false; m_inputColorSpaceIndex = 0; m_outputColorSpaceIndex = 0; m_dirIndex = 0; m_ignoreErrors = false; m_reload_version = 1; // Query the colorspace names from the current config // TODO (when to) re-grab the list of available colorspaces? How to save/load? OCIO::ConstConfigRcPtr config; std::string linear; try { config = OCIO::GetCurrentConfig(); OCIO::ConstColorSpaceRcPtr linearcs = config->getColorSpace(OCIO::ROLE_SCENE_LINEAR); if(!linearcs) throw std::runtime_error("ROLE_SCENE_LINEAR not defined."); linear = linearcs->getName(); if(config->getNumLooks()>0) { m_look = config->getLookNameByIndex(0); } std::ostringstream os; os << "Specify the look(s) to apply, as predefined in the OpenColorIO "; os << "configuration. This may be the name of a single look, or a "; os << "combination of looks using the 'look syntax' (outlined below)\n\n"; std::string firstlook = "a"; std::string secondlook = "b"; if(config->getNumLooks()>0) { os << "Looks: "; for(int i = 0; igetNumLooks(); ++i) { if(i!=0) os << ", "; const char * lookname = config->getLookNameByIndex(i); os << lookname; if(i==0) firstlook = lookname; if(i==1) secondlook = lookname; } os << "\n\n"; } else { os << "NO LOOKS DEFINED -- "; os << "This node cannot be used until looks are added to the OCIO Configuration. "; os << "See opencolorio.org for examples.\n\n"; } os << "Look Syntax:\n"; os << "Multiple looks are combined with commas: '"; os << firstlook << ", " << secondlook << "'\n"; os << "Direction is specified with +/- prefixes: '"; os << "+" << firstlook << ", -" << secondlook << "'\n"; os << "Missing look 'fallbacks' specified with |: '"; os << firstlook << ", -" << secondlook << " | -" << secondlook << "'"; m_lookhelp = os.str(); } catch (const OCIO::Exception& e) { std::cerr << "OCIOLookTransform: " << e.what() << std::endl; } catch (...) { std::cerr << "OCIOLookTransform: Unknown exception during OCIO setup." << std::endl; } if(!config) { m_hasColorSpaces = false; return; } for(int i = 0; i < config->getNumColorSpaces(); i++) { std::string csname = config->getColorSpaceNameByIndex(i); #ifdef OCIO_CASCADE std::string family = config->getColorSpace(csname.c_str())->getFamily(); if(family.empty()) m_colorSpaceNames.push_back(csname.c_str()); else m_colorSpaceNames.push_back(family + "/" + csname); #else m_colorSpaceNames.push_back(csname); #endif if(csname == linear) { m_inputColorSpaceIndex = i; m_outputColorSpaceIndex = i; } } // Step 2: Create a cstr array for passing to Nuke // (This must be done in a second pass, lest the original strings be reallocated) for(unsigned int i=0; i

(pyobject); if(ptr->isconst && ptr->constcppobj) return *ptr->constcppobj; if(allowCast && !ptr->isconst && ptr->cppobj) return *ptr->cppobj; throw Exception("PyObject must be a valid OCIO type"); } template inline C GetConstPyOCIO(PyObject* pyobject, PyTypeObject& type, bool allowCast = true) { if(!IsPyOCIOType(pyobject, type)) throw Exception("PyObject must be an OCIO type"); P * ptr = reinterpret_cast

(pyobject); C cptr; if(ptr->isconst && ptr->constcppobj) cptr = DynamicPtrCast(*ptr->constcppobj); if(allowCast && !ptr->isconst && ptr->cppobj) cptr = DynamicPtrCast(*ptr->cppobj); if(!cptr) throw Exception("PyObject must be a valid OCIO type"); return cptr; } template inline C GetEditablePyOCIO(PyObject* pyobject, PyTypeObject& type) { if(!IsPyOCIOType(pyobject, type)) throw Exception("PyObject must be an OCIO type"); P * ptr = reinterpret_cast

(pyobject); if(!ptr->isconst && ptr->cppobj) return *ptr->cppobj; throw Exception("PyObject must be a editable OCIO type"); } template inline C GetEditablePyOCIO(PyObject* pyobject, PyTypeObject& type) { if(!IsPyOCIOType(pyobject, type)) throw Exception("PyObject must be an OCIO type"); P * ptr = reinterpret_cast

(pyobject); C cptr; if(!ptr->isconst && ptr->cppobj) cptr = DynamicPtrCast(*ptr->cppobj); if(!cptr) throw Exception("PyObject must be a editable OCIO type"); return cptr; } /////////////////////////////////////////////////////////////////////////// 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); int ConvertPyObjectToEnvironmentMode(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 &data); PyObject* CreatePyListFromFloatVector(const std::vector &data); PyObject* CreatePyListFromDoubleVector(const std::vector &data); PyObject* CreatePyListFromStringVector(const std::vector &data); PyObject* CreatePyListFromTransformVector(const std::vector &data); PyObject* CreatePyDictFromStringMap(const std::map &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 &data); bool FillFloatVectorFromPySequence(PyObject* datalist, std::vector &data); bool FillDoubleVectorFromPySequence(PyObject* datalist, std::vector &data); bool FillStringVectorFromPySequence(PyObject* datalist, std::vector &data); bool FillTransformVectorFromPySequence(PyObject* datalist, std::vector &data); /////////////////////////////////////////////////////////////////////////// void Python_Handle_Exception(); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyConstants.cpp0000644000175000017500000002574413223553423021367 0ustar mfvmfv/* 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 #include #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; MOD_DEF(m, const_cast(moduleName.c_str()), CONSTANTS__DOC__, LocalModuleMethods); Py_INCREF(m); // Add Module Constants PyModule_AddStringConstant(m, "LOGGING_LEVEL_NONE", const_cast(LoggingLevelToString(LOGGING_LEVEL_NONE))); PyModule_AddStringConstant(m, "LOGGING_LEVEL_WARNING", const_cast(LoggingLevelToString(LOGGING_LEVEL_WARNING))); PyModule_AddStringConstant(m, "LOGGING_LEVEL_INFO", const_cast(LoggingLevelToString(LOGGING_LEVEL_INFO))); PyModule_AddStringConstant(m, "LOGGING_LEVEL_DEBUG", const_cast(LoggingLevelToString(LOGGING_LEVEL_DEBUG))); PyModule_AddStringConstant(m, "LOGGING_LEVEL_UNKNOWN", const_cast(LoggingLevelToString(LOGGING_LEVEL_UNKNOWN))); PyModule_AddStringConstant(m, "TRANSFORM_DIR_UNKNOWN", const_cast(TransformDirectionToString(TRANSFORM_DIR_UNKNOWN))); PyModule_AddStringConstant(m, "TRANSFORM_DIR_FORWARD", const_cast(TransformDirectionToString(TRANSFORM_DIR_FORWARD))); PyModule_AddStringConstant(m, "TRANSFORM_DIR_INVERSE", const_cast(TransformDirectionToString(TRANSFORM_DIR_INVERSE))); PyModule_AddStringConstant(m, "COLORSPACE_DIR_UNKNOWN", const_cast(ColorSpaceDirectionToString(COLORSPACE_DIR_UNKNOWN))); PyModule_AddStringConstant(m, "COLORSPACE_DIR_TO_REFERENCE", const_cast(ColorSpaceDirectionToString(COLORSPACE_DIR_TO_REFERENCE))); PyModule_AddStringConstant(m, "COLORSPACE_DIR_FROM_REFERENCE", const_cast(ColorSpaceDirectionToString(COLORSPACE_DIR_FROM_REFERENCE))); PyModule_AddStringConstant(m, "BIT_DEPTH_UNKNOWN", const_cast(BitDepthToString(BIT_DEPTH_UNKNOWN))); PyModule_AddStringConstant(m, "BIT_DEPTH_UINT8", const_cast(BitDepthToString(BIT_DEPTH_UINT8))); PyModule_AddStringConstant(m, "BIT_DEPTH_UINT10", const_cast(BitDepthToString(BIT_DEPTH_UINT10))); PyModule_AddStringConstant(m, "BIT_DEPTH_UINT12", const_cast(BitDepthToString(BIT_DEPTH_UINT12))); PyModule_AddStringConstant(m, "BIT_DEPTH_UINT14", const_cast(BitDepthToString(BIT_DEPTH_UINT14))); PyModule_AddStringConstant(m, "BIT_DEPTH_UINT16", const_cast(BitDepthToString(BIT_DEPTH_UINT16))); PyModule_AddStringConstant(m, "BIT_DEPTH_UINT32", const_cast(BitDepthToString(BIT_DEPTH_UINT32))); PyModule_AddStringConstant(m, "BIT_DEPTH_F16", const_cast(BitDepthToString(BIT_DEPTH_F16))); PyModule_AddStringConstant(m, "BIT_DEPTH_F32", const_cast(BitDepthToString(BIT_DEPTH_F32))); PyModule_AddStringConstant(m, "ALLOCATION_UNKNOWN", const_cast(AllocationToString(ALLOCATION_UNKNOWN))); PyModule_AddStringConstant(m, "ALLOCATION_UNIFORM", const_cast(AllocationToString(ALLOCATION_UNIFORM))); PyModule_AddStringConstant(m, "ALLOCATION_LG2", const_cast(AllocationToString(ALLOCATION_LG2))); PyModule_AddStringConstant(m, "INTERP_UNKNOWN", const_cast(InterpolationToString(INTERP_UNKNOWN))); PyModule_AddStringConstant(m, "INTERP_NEAREST", const_cast(InterpolationToString(INTERP_NEAREST))); PyModule_AddStringConstant(m, "INTERP_LINEAR", const_cast(InterpolationToString(INTERP_LINEAR))); PyModule_AddStringConstant(m, "INTERP_TETRAHEDRAL", const_cast(InterpolationToString(INTERP_TETRAHEDRAL))); PyModule_AddStringConstant(m, "INTERP_BEST", const_cast(InterpolationToString(INTERP_BEST))); PyModule_AddStringConstant(m, "GPU_LANGUAGE_UNKNOWN", const_cast(GpuLanguageToString(GPU_LANGUAGE_UNKNOWN))); PyModule_AddStringConstant(m, "GPU_LANGUAGE_CG", const_cast(GpuLanguageToString(GPU_LANGUAGE_CG))); PyModule_AddStringConstant(m, "GPU_LANGUAGE_GLSL_1_0", const_cast(GpuLanguageToString(GPU_LANGUAGE_GLSL_1_0))); PyModule_AddStringConstant(m, "GPU_LANGUAGE_GLSL_1_3", const_cast(GpuLanguageToString(GPU_LANGUAGE_GLSL_1_3))); PyModule_AddStringConstant(m, "ENV_ENVIRONMENT_UNKNOWN", const_cast(EnvironmentModeToString(ENV_ENVIRONMENT_UNKNOWN))); PyModule_AddStringConstant(m, "ENV_ENVIRONMENT_LOAD_PREDEFINED", const_cast(EnvironmentModeToString(ENV_ENVIRONMENT_LOAD_PREDEFINED))); PyModule_AddStringConstant(m, "ENV_ENVIRONMENT_LOAD_ALL", const_cast(EnvironmentModeToString(ENV_ENVIRONMENT_LOAD_ALL))); PyModule_AddStringConstant(m, "ROLE_DEFAULT", const_cast(ROLE_DEFAULT)); PyModule_AddStringConstant(m, "ROLE_REFERENCE", const_cast(ROLE_REFERENCE)); PyModule_AddStringConstant(m, "ROLE_DATA", const_cast(ROLE_DATA)); PyModule_AddStringConstant(m, "ROLE_COLOR_PICKING", const_cast(ROLE_COLOR_PICKING)); PyModule_AddStringConstant(m, "ROLE_SCENE_LINEAR", const_cast(ROLE_SCENE_LINEAR)); PyModule_AddStringConstant(m, "ROLE_COMPOSITING_LOG", const_cast(ROLE_COMPOSITING_LOG)); PyModule_AddStringConstant(m, "ROLE_COLOR_TIMING", const_cast(ROLE_COLOR_TIMING)); PyModule_AddStringConstant(m, "ROLE_TEXTURE_PAINT", const_cast(ROLE_TEXTURE_PAINT)); PyModule_AddStringConstant(m, "ROLE_MATTE_PAINT", const_cast(ROLE_MATTE_PAINT)); // Add the module PyModule_AddObject(enclosingModule, "Constants", m); } namespace { PyObject * PyOCIO_Constants_GetInverseTransformDirection(PyObject * /*module*/, PyObject * args) { OCIO_PYTRY_ENTER() char* s = 0; if (!PyArg_ParseTuple(args, "s:GetInverseTransformDirection", &s)) return NULL; TransformDirection dir = TransformDirectionFromString(s); dir = GetInverseTransformDirection(dir); return PyString_FromString(TransformDirectionToString(dir)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Constants_CombineTransformDirections(PyObject * /*module*/, PyObject * args) { OCIO_PYTRY_ENTER() 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)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Constants_BitDepthIsFloat(PyObject * /*module*/, PyObject * args) { OCIO_PYTRY_ENTER() char* s = 0; if (!PyArg_ParseTuple(args, "s:BitDepthIsFloat", &s)) return NULL; BitDepth bitdepth = BitDepthFromString(s); return PyBool_FromLong(BitDepthIsFloat(bitdepth)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Constants_BitDepthToInt(PyObject * /*module*/, PyObject * args) { OCIO_PYTRY_ENTER() char* s = 0; if (!PyArg_ParseTuple(args, "s:BitDepthToInt", &s)) return NULL; BitDepth bitdepth = BitDepthFromString(s); return PyInt_FromLong(BitDepthToInt(bitdepth)); OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyContext.cpp0000644000175000017500000004066413223553423021035 0ustar mfvmfv/* 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 #include #include #include "PyUtil.h" #include "PyDoc.h" OCIO_NAMESPACE_ENTER { PyObject * BuildConstPyContext(ConstContextRcPtr context) { return BuildConstPyOCIO(context, PyOCIO_ContextType); } PyObject * BuildEditablePyContext(ContextRcPtr context) { return BuildEditablePyOCIO(context, PyOCIO_ContextType); } bool IsPyContext(PyObject * pyobject) { return IsPyOCIOType(pyobject, PyOCIO_ContextType); } bool IsPyContextEditable(PyObject * pyobject) { return IsPyEditable(pyobject, PyOCIO_ContextType); } ConstContextRcPtr GetConstContext(PyObject * pyobject, bool allowCast) { return GetConstPyOCIO(pyobject, PyOCIO_ContextType, allowCast); } ContextRcPtr GetEditableContext(PyObject * pyobject) { return GetEditablePyOCIO(pyobject, PyOCIO_ContextType); } namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_Context_init(PyOCIO_Context * self, PyObject * args, PyObject * kwds); void PyOCIO_Context_delete(PyOCIO_Context * self, PyObject * args); PyObject * PyOCIO_Context_str(PyObject * self); 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_getNumStringVars(PyObject * self, PyObject * args); PyObject * PyOCIO_Context_getStringVarNameByIndex(PyObject * self, PyObject * args); PyObject * PyOCIO_Context_clearStringVars(PyObject * self); PyObject * PyOCIO_Context_setEnvironmentMode(PyObject * self, PyObject * args); PyObject * PyOCIO_Context_getEnvironmentMode(PyObject * self); 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__ }, { "getNumStringVars", PyOCIO_Context_getNumStringVars, METH_VARARGS, CONTEXT_GETNUMSTRINGVARS__DOC__ }, { "getStringVarNameByIndex", PyOCIO_Context_getStringVarNameByIndex, METH_VARARGS, CONTEXT_GETSTRINGVARNAMEBYINDEX__DOC__ }, { "clearStringVars", (PyCFunction) PyOCIO_Context_clearStringVars, METH_NOARGS, CONTEXT_CLEARSTRINGVARS__DOC__ }, { "setEnvironmentMode", PyOCIO_Context_setEnvironmentMode, METH_VARARGS, CONTEXT_SETENVIRONMENTMODE__DOC__ }, { "getEnvironmentMode", (PyCFunction) PyOCIO_Context_getEnvironmentMode, METH_NOARGS, CONTEXT_GETENVIRONMENTMODE__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 = { PyVarObject_HEAD_INIT(NULL, 0) //ob_size OCIO_PYTHON_NAMESPACE(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 PyOCIO_Context_str, //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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_Context_init(PyOCIO_Context *self, PyObject * /*args*/, PyObject * /*kwds*/) { OCIO_PYTRY_ENTER() return BuildPyObject(self, Context::Create()); OCIO_PYTRY_EXIT(-1) } void PyOCIO_Context_delete(PyOCIO_Context *self, PyObject * /*args*/) { DeletePyObject(self); } PyObject * PyOCIO_Context_str(PyObject * self) { OCIO_PYTRY_ENTER() ConstContextRcPtr context = GetConstContext(self, true); std::ostringstream out; out << *context; return PyString_FromString(out.str().c_str()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_isEditable(PyObject * self) { return PyBool_FromLong(IsPyContextEditable(self)); } PyObject * PyOCIO_Context_createEditableCopy(PyObject * self) { OCIO_PYTRY_ENTER() ConstContextRcPtr context = GetConstContext(self, true); ContextRcPtr copy = context->createEditableCopy(); return BuildEditablePyContext(copy); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_getCacheID(PyObject * self) { OCIO_PYTRY_ENTER() ConstContextRcPtr context = GetConstContext(self, true); return PyString_FromString(context->getCacheID()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_getSearchPath(PyObject * self) { OCIO_PYTRY_ENTER() ConstContextRcPtr context = GetConstContext(self, true); return PyString_FromString(context->getSearchPath()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_setSearchPath(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* path = 0; if (!PyArg_ParseTuple(args, "s:setSearchPath", &path)) return NULL; ContextRcPtr context = GetEditableContext(self); context->setSearchPath(path); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_getWorkingDir(PyObject * self) { OCIO_PYTRY_ENTER() ConstContextRcPtr context = GetConstContext(self, true); return PyString_FromString(context->getWorkingDir()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_setWorkingDir(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* dirname = 0; if (!PyArg_ParseTuple(args, "s:setWorkingDir", &dirname)) return NULL; ContextRcPtr context = GetEditableContext(self); context->setWorkingDir(dirname); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_getStringVar(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args, "s:getStringVar", &name)) return NULL; ConstContextRcPtr context = GetConstContext(self, true); return PyString_FromString(context->getStringVar(name)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_setStringVar(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_getNumStringVars(PyObject * self, PyObject * /*args*/) { OCIO_PYTRY_ENTER() ConstContextRcPtr context = GetConstContext(self, true); return PyInt_FromLong(context->getNumStringVars()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_getStringVarNameByIndex(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() int index = 0; if (!PyArg_ParseTuple(args,"i:getStringVarNameByIndex", &index)) return NULL; ConstContextRcPtr context = GetConstContext(self, true); return PyString_FromString(context->getStringVarNameByIndex(index)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_clearStringVars(PyObject * self) { OCIO_PYTRY_ENTER() ContextRcPtr context = GetEditableContext(self); context->clearStringVars(); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_setEnvironmentMode(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() EnvironmentMode mode; if (!PyArg_ParseTuple(args, "O&:setEnvironmentMode", ConvertPyObjectToEnvironmentMode, &mode)) return NULL; ContextRcPtr context = GetEditableContext(self); context->setEnvironmentMode(mode); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_getEnvironmentMode(PyObject * self) { OCIO_PYTRY_ENTER() ConstContextRcPtr context = GetConstContext(self, true); EnvironmentMode mode = context->getEnvironmentMode(); return PyString_FromString(EnvironmentModeToString(mode)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_loadEnvironment(PyObject * self) { OCIO_PYTRY_ENTER() ContextRcPtr context = GetEditableContext(self); context->loadEnvironment(); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_resolveStringVar(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* str = 0; if (!PyArg_ParseTuple(args,"s:resolveStringVar", &str)) return NULL; ConstContextRcPtr context = GetConstContext(self, true); return PyString_FromString(context->resolveStringVar(str)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Context_resolveFileLocation(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* filename = 0; if (!PyArg_ParseTuple(args,"s:resolveFileLocation", &filename)) return NULL; ConstContextRcPtr context = GetConstContext(self, true); return PyString_FromString(context->resolveFileLocation(filename)); OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyDisplayTransform.cpp0000644000175000017500000004317413223553423022711 0ustar mfvmfv/* 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 #include #include "PyUtil.h" #include "PyDoc.h" #define GetConstDisplayTransform(pyobject) GetConstPyOCIO(pyobject, \ PyOCIO_DisplayTransformType) #define GetEditableDisplayTransform(pyobject) GetEditablePyOCIO(pyobject, \ PyOCIO_DisplayTransformType) OCIO_NAMESPACE_ENTER { 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 = { PyVarObject_HEAD_INIT(NULL, 0) OCIO_PYTHON_NAMESPACE(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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_DisplayTransform_init(PyOCIO_Transform * self, PyObject * args, PyObject * kwds) { OCIO_PYTRY_ENTER() DisplayTransformRcPtr ptr = DisplayTransform::Create(); int ret = BuildPyTransformObject(self, ptr); char* inputColorSpaceName = NULL; char* display = NULL; char* view = NULL; char* direction = NULL; static const char *kwlist[] = { "inputColorSpaceName", "display", "view", "direction", NULL }; if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ssss", const_cast(kwlist), &inputColorSpaceName, &display, &view, &direction)) return -1; if(inputColorSpaceName) ptr->setInputColorSpaceName(inputColorSpaceName); if(display) ptr->setDisplay(display); if(view) ptr->setView(view); if(direction) ptr->setDirection(TransformDirectionFromString(direction)); return ret; OCIO_PYTRY_EXIT(-1) } PyObject * PyOCIO_DisplayTransform_getInputColorSpaceName(PyObject * self) { OCIO_PYTRY_ENTER() ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self); return PyString_FromString(transform->getInputColorSpaceName()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_setInputColorSpaceName(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args, "s:setInputColorSpaceName", &name)) return NULL; DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); transform->setInputColorSpaceName(name); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_getLinearCC(PyObject * self) { OCIO_PYTRY_ENTER() ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self); return BuildConstPyTransform(transform->getLinearCC()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_setLinearCC(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_getColorTimingCC(PyObject * self) { OCIO_PYTRY_ENTER() ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self); return BuildConstPyTransform(transform->getColorTimingCC()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_setColorTimingCC(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_getChannelView(PyObject * self) { OCIO_PYTRY_ENTER() ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self); return BuildConstPyTransform(transform->getChannelView()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_setChannelView(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_getDisplay(PyObject * self) { OCIO_PYTRY_ENTER() ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self); return PyString_FromString(transform->getDisplay()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_setDisplay(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* str = 0; if (!PyArg_ParseTuple(args, "s:setDisplay", &str)) return NULL; DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); transform->setDisplay(str); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_getView(PyObject * self) { OCIO_PYTRY_ENTER() ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self); return PyString_FromString(transform->getView()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_setView(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* str = 0; if (!PyArg_ParseTuple(args, "s:setView", &str)) return NULL; DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); transform->setView(str); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_getDisplayCC(PyObject * self) { OCIO_PYTRY_ENTER() ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self); return BuildConstPyTransform(transform->getDisplayCC()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_setDisplayCC(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_getLooksOverride(PyObject * self) { OCIO_PYTRY_ENTER() ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self); return PyString_FromString(transform->getLooksOverride()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_setLooksOverride(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* str = 0; if (!PyArg_ParseTuple(args,"s:setLooksOverride", &str)) return NULL; DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); transform->setLooksOverride(str); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_getLooksOverrideEnabled(PyObject * self) { OCIO_PYTRY_ENTER() ConstDisplayTransformRcPtr transform = GetConstDisplayTransform(self); return PyBool_FromLong(transform->getLooksOverrideEnabled()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_DisplayTransform_setLooksOverrideEnabled(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() bool enabled = false; if (!PyArg_ParseTuple(args, "O&:setLooksOverrideEnabled", ConvertPyObjectToBool, &enabled)) return NULL; DisplayTransformRcPtr transform = GetEditableDisplayTransform(self); transform->setLooksOverrideEnabled(enabled); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyLook.cpp0000644000175000017500000003377513223553423020322 0ustar mfvmfv/* 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 #include #include #include "PyUtil.h" #include "PyDoc.h" OCIO_NAMESPACE_ENTER { PyObject * BuildConstPyLook(ConstLookRcPtr look) { return BuildConstPyOCIO(look, PyOCIO_LookType); } PyObject * BuildEditablePyLook(LookRcPtr look) { return BuildEditablePyOCIO(look, PyOCIO_LookType); } bool IsPyLook(PyObject * pyobject) { return IsPyOCIOType(pyobject, PyOCIO_LookType); } bool IsPyLookEditable(PyObject * pyobject) { return IsPyEditable(pyobject, PyOCIO_LookType); } ConstLookRcPtr GetConstLook(PyObject * pyobject, bool allowCast) { return GetConstPyOCIO(pyobject, PyOCIO_LookType, allowCast); } LookRcPtr GetEditableLook(PyObject * pyobject) { return GetEditablePyOCIO(pyobject, PyOCIO_LookType); } namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_Look_init(PyOCIO_Look * self, PyObject * args, PyObject * kwds); void PyOCIO_Look_delete(PyOCIO_Look * self, PyObject * args); PyObject * PyOCIO_Look_str(PyObject * self); 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_getDescription(PyObject * self); PyObject * PyOCIO_Look_setDescription(PyObject * self, PyObject * args); PyObject * PyOCIO_Look_getTransform(PyObject * self); PyObject * PyOCIO_Look_setTransform(PyObject * self, PyObject * args); PyObject * PyOCIO_Look_getInverseTransform(PyObject * self); PyObject * PyOCIO_Look_setInverseTransform(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__ }, { "getDescription", (PyCFunction) PyOCIO_Look_getDescription, METH_NOARGS, LOOK_GETDESCRIPTION__DOC__ }, { "setDescription", PyOCIO_Look_setDescription, METH_VARARGS, LOOK_SETDESCRIPTION__DOC__ }, { "getTransform", (PyCFunction) PyOCIO_Look_getTransform, METH_NOARGS, LOOK_GETTRANSFORM__DOC__ }, { "setTransform", PyOCIO_Look_setTransform, METH_VARARGS, LOOK_SETTRANSFORM__DOC__ }, { "getInverseTransform", (PyCFunction) PyOCIO_Look_getInverseTransform, METH_VARARGS, LOOK_GETINVERSETRANSFORM__DOC__ }, { "setInverseTransform", PyOCIO_Look_setInverseTransform, METH_VARARGS, LOOK_SETINVERSETRANSFORM__DOC__ }, { NULL, NULL, 0, NULL } }; } /////////////////////////////////////////////////////////////////////////// /// PyTypeObject PyOCIO_LookType = { PyVarObject_HEAD_INIT(NULL, 0) //ob_size OCIO_PYTHON_NAMESPACE(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 PyOCIO_Look_str, //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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_Look_init(PyOCIO_Look *self, PyObject * args, PyObject * kwds) { OCIO_PYTRY_ENTER() LookRcPtr ptr = Look::Create(); /*int ret =*/ BuildPyObject(self, ptr); char* name = NULL; char* processSpace = NULL; char* description = NULL; PyObject* pytransform = NULL; const char* kwlist[] = { "name", "processSpace", "transform", "description", NULL }; if(!PyArg_ParseTupleAndKeywords(args, kwds, "|ssOs", const_cast(kwlist), &name, &processSpace, &pytransform, &description)) return -1; if(name) ptr->setName(name); if(processSpace) ptr->setProcessSpace(processSpace); if(pytransform) { ConstTransformRcPtr transform = GetConstTransform(pytransform, true); ptr->setTransform(transform); } if(description) ptr->setDescription(description); return 0; OCIO_PYTRY_EXIT(-1) } void PyOCIO_Look_delete(PyOCIO_Look *self, PyObject * /*args*/) { DeletePyObject(self); } PyObject * PyOCIO_Look_str(PyObject * self) { OCIO_PYTRY_ENTER() ConstLookRcPtr look = GetConstLook(self, true); std::ostringstream out; out << *look; return PyString_FromString(out.str().c_str()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Look_isEditable(PyObject * self) { return PyBool_FromLong(IsPyLookEditable(self)); } PyObject * PyOCIO_Look_createEditableCopy(PyObject * self) { OCIO_PYTRY_ENTER() ConstLookRcPtr look = GetConstLook(self, true); LookRcPtr copy = look->createEditableCopy(); return BuildEditablePyLook(copy); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Look_getName(PyObject * self) { OCIO_PYTRY_ENTER() ConstLookRcPtr look = GetConstLook(self, true); return PyString_FromString(look->getName()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Look_setName(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args, "s:setName", &name)) return NULL; LookRcPtr look = GetEditableLook(self); look->setName(name); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Look_getProcessSpace(PyObject * self) { OCIO_PYTRY_ENTER() ConstLookRcPtr look = GetConstLook(self, true); return PyString_FromString(look->getProcessSpace()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Look_setProcessSpace(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* processSpace = 0; if (!PyArg_ParseTuple(args,"s:setProcessSpace", &processSpace)) return NULL; LookRcPtr look = GetEditableLook(self); look->setProcessSpace(processSpace); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Look_getDescription(PyObject * self) { OCIO_PYTRY_ENTER() ConstLookRcPtr look = GetConstLook(self, true); return PyString_FromString(look->getDescription()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Look_setDescription(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* description = 0; if (!PyArg_ParseTuple(args, "s:setDescription", &description)) return NULL; LookRcPtr look = GetEditableLook(self); look->setDescription(description); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Look_getTransform(PyObject * self) { OCIO_PYTRY_ENTER() ConstLookRcPtr look = GetConstLook(self, true); ConstTransformRcPtr transform = look->getTransform(); return BuildConstPyTransform(transform); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Look_setTransform(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Look_getInverseTransform(PyObject * self) { OCIO_PYTRY_ENTER() ConstLookRcPtr look = GetConstLook(self, true); ConstTransformRcPtr transform = look->getInverseTransform(); return BuildConstPyTransform(transform); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Look_setInverseTransform(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pytransform = 0; if (!PyArg_ParseTuple(args, "O:setTransform", &pytransform)) return NULL; ConstTransformRcPtr transform = GetConstTransform(pytransform, true); LookRcPtr look = GetEditableLook(self); look->setInverseTransform(transform); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyConfig.cpp0000644000175000017500000013341413223553423020612 0ustar mfvmfv/* 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 #include #include #include "PyUtil.h" #include "PyDoc.h" OCIO_NAMESPACE_ENTER { PyObject * BuildConstPyConfig(ConstConfigRcPtr config) { return BuildConstPyOCIO(config, PyOCIO_ConfigType); } PyObject * BuildEditablePyConfig(ConfigRcPtr config) { return BuildEditablePyOCIO(config, PyOCIO_ConfigType); } bool IsPyConfig(PyObject * pyobject) { return IsPyOCIOType(pyobject, PyOCIO_ConfigType); } bool IsPyConfigEditable(PyObject * pyobject) { return IsPyEditable(pyobject, PyOCIO_ConfigType); } ConstConfigRcPtr GetConstConfig(PyObject * pyobject, bool allowCast) { return GetConstPyOCIO(pyobject, PyOCIO_ConfigType, allowCast); } ConfigRcPtr GetEditableConfig(PyObject * pyobject) { return GetEditablePyOCIO(pyobject, PyOCIO_ConfigType); } namespace { /////////////////////////////////////////////////////////////////////// /// PyObject * PyOCIO_Config_CreateFromEnv(PyObject * cls); PyObject * PyOCIO_Config_CreateFromFile(PyObject * cls, PyObject * args); PyObject * PyOCIO_Config_CreateFromStream(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_repr(PyObject * self); 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_addEnvironmentVar(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_getNumEnvironmentVars(PyObject * self); PyObject * PyOCIO_Config_getEnvironmentVarNameByIndex(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_getEnvironmentVarDefault(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_getEnvironmentVarDefaults(PyObject * self); PyObject * PyOCIO_Config_clearEnvironmentVars(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_getNumColorSpaces(PyObject * self); PyObject * PyOCIO_Config_getColorSpaceNameByIndex(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_getColorSpaces(PyObject * self); // py interface only PyObject * PyOCIO_Config_getColorSpace(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_getIndexForColorSpace(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_isStrictParsingEnabled(PyObject * self); PyObject * PyOCIO_Config_setStrictParsingEnabled(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_setRole(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_getNumRoles(PyObject * self); PyObject * PyOCIO_Config_hasRole(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_getRoleName(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_getDefaultDisplay(PyObject * self); PyObject * PyOCIO_Config_getNumDisplays(PyObject * self); PyObject * PyOCIO_Config_getDisplay(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_getDisplays(PyObject * self); PyObject * PyOCIO_Config_getDefaultView(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_getNumViews(PyObject * self, PyObject * args); PyObject * PyOCIO_Config_getView(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_getNumLooks(PyObject * self); PyObject * PyOCIO_Config_getLookNameByIndex(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__ }, { "CreateFromStream", PyOCIO_Config_CreateFromStream, METH_VARARGS | METH_CLASS, CONFIG_CREATEFROMSTREAM__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__ }, { "addEnvironmentVar", PyOCIO_Config_addEnvironmentVar, METH_VARARGS, CONFIG_ADDENVIRONMENTVAR__DOC__ }, { "getNumEnvironmentVars", (PyCFunction)PyOCIO_Config_getNumEnvironmentVars, METH_NOARGS, CONFIG_GETNUMENVIRONMENTVARS__DOC__ }, { "getEnvironmentVarNameByIndex", PyOCIO_Config_getEnvironmentVarNameByIndex, METH_VARARGS, CONFIG_GETENVIRONMENTVARNAMEBYINDEX__DOC__ }, { "getEnvironmentVarDefault", PyOCIO_Config_getEnvironmentVarDefault, METH_VARARGS, CONFIG_GETENVIRONMENTVARDEFAULT__DOC__ }, { "getEnvironmentVarDefaults", (PyCFunction)PyOCIO_Config_getEnvironmentVarDefaults, METH_NOARGS, CONFIG_GETENVIRONMENTVARDEFAULTS__DOC__ }, { "clearEnvironmentVars", (PyCFunction)PyOCIO_Config_clearEnvironmentVars, METH_NOARGS, CONFIG_CLEARENVIRONMENTVARS__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__ }, { "getNumColorSpaces", (PyCFunction) PyOCIO_Config_getNumColorSpaces, METH_VARARGS, CONFIG_GETNUMCOLORSPACES__DOC__ }, { "getColorSpaceNameByIndex", PyOCIO_Config_getColorSpaceNameByIndex, METH_VARARGS, CONFIG_GETCOLORSPACENAMEBYINDEX__DOC__ }, { "getColorSpaces", (PyCFunction) PyOCIO_Config_getColorSpaces, METH_NOARGS, CONFIG_GETCOLORSPACES__DOC__ }, { "getColorSpace", PyOCIO_Config_getColorSpace, METH_VARARGS, CONFIG_GETCOLORSPACE__DOC__ }, { "getIndexForColorSpace", PyOCIO_Config_getIndexForColorSpace, METH_VARARGS, CONFIG_GETINDEXFORCOLORSPACE__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__ }, { "isStrictParsingEnabled", (PyCFunction) PyOCIO_Config_isStrictParsingEnabled, METH_NOARGS, CONFIG_ISSTRICTPARSINGENABLED__DOC__ }, { "setStrictParsingEnabled", PyOCIO_Config_setStrictParsingEnabled, METH_VARARGS, CONFIG_SETSTRICTPARSINGENABLED__DOC__ }, { "setRole", PyOCIO_Config_setRole, METH_VARARGS, CONFIG_SETROLE__DOC__ }, { "getNumRoles", (PyCFunction) PyOCIO_Config_getNumRoles, METH_NOARGS, CONFIG_GETNUMROLES__DOC__ }, { "hasRole", PyOCIO_Config_hasRole, METH_VARARGS, CONFIG_HASROLE__DOC__ }, { "getRoleName", PyOCIO_Config_getRoleName, METH_VARARGS, CONFIG_GETROLENAME__DOC__ }, { "getDefaultDisplay", (PyCFunction) PyOCIO_Config_getDefaultDisplay, METH_NOARGS, CONFIG_GETDEFAULTDISPLAY__DOC__ }, { "getNumDisplays", (PyCFunction) PyOCIO_Config_getNumDisplays, METH_NOARGS, CONFIG_GETNUMDISPLAYS__DOC__ }, { "getDisplay", PyOCIO_Config_getDisplay, METH_VARARGS, CONFIG_GETDISPLAY__DOC__ }, { "getDisplays", (PyCFunction) PyOCIO_Config_getDisplays, METH_NOARGS, CONFIG_GETDISPLAYS__DOC__ }, { "getDefaultView", PyOCIO_Config_getDefaultView, METH_VARARGS, CONFIG_GETDEFAULTVIEW__DOC__ }, { "getNumViews", PyOCIO_Config_getNumViews, METH_VARARGS, CONFIG_GETNUMVIEWS__DOC__ }, { "getView", PyOCIO_Config_getView, METH_VARARGS, CONFIG_GETVIEW__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_VARARGS|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__ }, { "getNumLooks", (PyCFunction) PyOCIO_Config_getNumLooks, METH_NOARGS, CONFIG_GETNUMLOOKS__DOC__ }, { "getLookNameByIndex", PyOCIO_Config_getLookNameByIndex, METH_VARARGS, CONFIG_GETLOOKNAMEBYINDEX__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_VARARGS|METH_KEYWORDS, CONFIG_GETPROCESSOR__DOC__ }, { NULL, NULL, 0, NULL } }; } /////////////////////////////////////////////////////////////////////////// /// PyTypeObject PyOCIO_ConfigType = { PyVarObject_HEAD_INIT(NULL, 0) //obsize OCIO_PYTHON_NAMESPACE(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 PyOCIO_Config_repr, //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 }; namespace { /////////////////////////////////////////////////////////////////////// /// PyObject * PyOCIO_Config_CreateFromEnv(PyObject * /*self*/) { OCIO_PYTRY_ENTER() return BuildConstPyConfig(Config::CreateFromEnv()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_CreateFromFile(PyObject * /*self*/, PyObject * args) { OCIO_PYTRY_ENTER() char* filename = 0; if (!PyArg_ParseTuple(args,"s:CreateFromFile", &filename)) return NULL; return BuildConstPyConfig(Config::CreateFromFile(filename)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_CreateFromStream(PyObject * /*self*/, PyObject * args) { OCIO_PYTRY_ENTER() char* stream = 0; if (!PyArg_ParseTuple(args,"s:CreateFromStream", &stream)) return NULL; std::istringstream is; is.str(stream); return BuildConstPyConfig(Config::CreateFromStream(is)); OCIO_PYTRY_EXIT(NULL) } int PyOCIO_Config_init(PyOCIO_Config *self, PyObject * /*args*/, PyObject * /*kwds*/) { OCIO_PYTRY_ENTER() return BuildPyObject(self, Config::Create()); OCIO_PYTRY_EXIT(-1) } void PyOCIO_Config_delete(PyOCIO_Config *self, PyObject * /*args*/) { DeletePyObject(self); } PyObject * PyOCIO_Config_repr(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); std::ostringstream out; out << *config; return PyString_FromString(out.str().c_str()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_isEditable(PyObject * self) { return PyBool_FromLong(IsPyConfigEditable(self)); } PyObject * PyOCIO_Config_createEditableCopy(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); ConfigRcPtr copy = config->createEditableCopy(); return BuildEditablePyConfig(copy); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_sanityCheck(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); config->sanityCheck(); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getDescription(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getDescription()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_setDescription(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* desc = 0; if (!PyArg_ParseTuple(args, "s:setDescription", &desc)) return NULL; ConfigRcPtr config = GetEditableConfig(self); config->setDescription(desc); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_serialize(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); std::ostringstream os; config->serialize(os); return PyString_FromString(os.str().c_str()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getCacheID(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pycontext = NULL; if (!PyArg_ParseTuple(args, "|O:getCacheID", &pycontext)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); ConstContextRcPtr context; if(pycontext != NULL) context = GetConstContext(pycontext, true); else context = config->getCurrentContext(); return PyString_FromString(config->getCacheID(context)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getCurrentContext(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return BuildConstPyContext(config->getCurrentContext()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_addEnvironmentVar(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; char* value = 0; if (!PyArg_ParseTuple(args, "ss:addEnvironmentVar", &name, &value)) return NULL; ConfigRcPtr config = GetEditableConfig(self); config->addEnvironmentVar(name, value); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getNumEnvironmentVars(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyInt_FromLong(config->getNumEnvironmentVars()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getEnvironmentVarNameByIndex(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() int index = 0; if (!PyArg_ParseTuple(args,"i:getEnvironmentVarNameByIndex", &index)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getEnvironmentVarNameByIndex(index)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getEnvironmentVarDefault(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args, "s:getEnvironmentVarDefault", &name)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); std::string var = config->getEnvironmentVarDefault(name); return PyString_FromString(var.c_str()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getEnvironmentVarDefaults(PyObject * self) { OCIO_PYTRY_ENTER() std::map data; ConstConfigRcPtr config = GetConstConfig(self, true); for(int i = 0; i < config->getNumEnvironmentVars(); ++i) { const char* name = config->getEnvironmentVarNameByIndex(i); const char* value = config->getEnvironmentVarDefault(name); data.insert(std::pair(name, value)); } return CreatePyDictFromStringMap(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_clearEnvironmentVars(PyObject * self) { OCIO_PYTRY_ENTER() ConfigRcPtr config = GetEditableConfig(self); config->clearEnvironmentVars(); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getSearchPath(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getSearchPath()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_setSearchPath(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* path = 0; if (!PyArg_ParseTuple(args, "s:setSearchPath", &path)) return NULL; ConfigRcPtr config = GetEditableConfig(self); config->setSearchPath(path); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getWorkingDir(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getWorkingDir()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_setWorkingDir(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* path = 0; if (!PyArg_ParseTuple(args, "s:setWorkingDir", &path)) return NULL; ConfigRcPtr config = GetEditableConfig(self); config->setWorkingDir(path); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getNumColorSpaces(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyInt_FromLong(config->getNumColorSpaces()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getColorSpaceNameByIndex(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() int index = 0; if (!PyArg_ParseTuple(args,"i:getColorSpaceNameByIndex", &index)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getColorSpaceNameByIndex(index)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getColorSpaces(PyObject * self) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getColorSpace(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args,"s:getColorSpace", &name)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); return BuildConstPyColorSpace(config->getColorSpace(name)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getIndexForColorSpace(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args,"s:getIndexForColorSpace", &name)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); return PyInt_FromLong(config->getIndexForColorSpace(name)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_addColorSpace(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() ConfigRcPtr config = GetEditableConfig(self); PyObject* pyColorSpace = 0; if (!PyArg_ParseTuple(args, "O:addColorSpace", &pyColorSpace)) return NULL; config->addColorSpace(GetConstColorSpace(pyColorSpace, true)); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_clearColorSpaces(PyObject * self) { OCIO_PYTRY_ENTER() ConfigRcPtr config = GetEditableConfig(self); config->clearColorSpaces(); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_parseColorSpaceFromString(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_isStrictParsingEnabled(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyBool_FromLong(config->isStrictParsingEnabled()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_setStrictParsingEnabled(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() bool enabled = false; if (!PyArg_ParseTuple(args, "O&:setStrictParsingEnabled", ConvertPyObjectToBool, &enabled)) return NULL; ConfigRcPtr config = GetEditableConfig(self); config->setStrictParsingEnabled(enabled); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_setRole(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getNumRoles(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyInt_FromLong(config->getNumRoles()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_hasRole(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* str = 0; if (!PyArg_ParseTuple(args, "s:hasRole", &str)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); return PyBool_FromLong(config->hasRole(str)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getRoleName(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() int index = 0; if (!PyArg_ParseTuple(args,"i:getRoleName", &index)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getRoleName(index)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getDefaultDisplay(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getDefaultDisplay()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getNumDisplays(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyInt_FromLong(config->getNumDisplays()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getDisplay(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() int index = 0; if (!PyArg_ParseTuple(args,"i:getDisplay", &index)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getDisplay(index)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getDisplays(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); std::vector data; int numDevices = config->getNumDisplays(); for(int i = 0; i < numDevices; ++i) data.push_back(config->getDisplay(i)); return CreatePyListFromStringVector(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getDefaultView(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* display = 0; if (!PyArg_ParseTuple(args, "s:getDefaultView", &display)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getDefaultView(display)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getNumViews(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* display = 0; if (!PyArg_ParseTuple(args, "s:getNumViews", &display)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); return PyInt_FromLong(config->getNumViews(display)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getView(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* display = 0; int index = 0; if (!PyArg_ParseTuple(args, "si:getNumViews", &display, &index)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getView(display, index)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getViews(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* display = 0; if (!PyArg_ParseTuple(args, "s:getViews", &display)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); std::vector data; int num = config->getNumViews(display); for(int i=0; i < num; ++i) data.push_back(config->getView(display, i)); return CreatePyListFromStringVector(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getDisplayColorSpaceName(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getDisplayLooks(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_addDisplay(PyObject * self, PyObject * args, PyObject * kwargs) { OCIO_PYTRY_ENTER() 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(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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_clearDisplays(PyObject * self) { OCIO_PYTRY_ENTER() ConfigRcPtr config = GetEditableConfig(self); config->clearDisplays(); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_setActiveDisplays(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() ConfigRcPtr config = GetEditableConfig(self); char* displays = 0; if (!PyArg_ParseTuple(args, "s:setActiveDisplays", &displays)) return NULL; config->setActiveDisplays(displays); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getActiveDisplays(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getActiveDisplays()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_setActiveViews(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() ConfigRcPtr config = GetEditableConfig(self); char* views = 0; if (!PyArg_ParseTuple(args, "s:setActiveViews", &views)) return NULL; config->setActiveViews(views); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getActiveViews(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getActiveViews()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_setDefaultLumaCoefs(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() ConfigRcPtr config = GetEditableConfig(self); PyObject* pyCoef = 0; if (!PyArg_ParseTuple(args, "O:setDefaultLumaCoefs", &pyCoef)) return 0; std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getDefaultLumaCoefs(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); std::vector coef(3); config->getDefaultLumaCoefs(&coef[0]); return CreatePyListFromFloatVector(coef); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getLook(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); char* str = 0; if (!PyArg_ParseTuple(args, "s:getLook", &str)) return NULL; return BuildConstPyLook(config->getLook(str)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getNumLooks(PyObject * self) { OCIO_PYTRY_ENTER() ConstConfigRcPtr config = GetConstConfig(self, true); return PyInt_FromLong(config->getNumLooks()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getLookNameByIndex(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() int index = 0; if (!PyArg_ParseTuple(args,"i:getLookNameByIndex", &index)) return NULL; ConstConfigRcPtr config = GetConstConfig(self, true); return PyString_FromString(config->getLookNameByIndex(index)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getLooks(PyObject * self) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_addLook(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() ConfigRcPtr config = GetEditableConfig(self); PyObject * pyLook = 0; if (!PyArg_ParseTuple(args, "O:addLook", &pyLook)) return NULL; config->addLook(GetConstLook(pyLook, true)); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_clearLooks(PyObject * self) { OCIO_PYTRY_ENTER() ConfigRcPtr config = GetEditableConfig(self); config->clearLooks(); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Config_getProcessor(PyObject * self, PyObject * args, PyObject * kwargs) { OCIO_PYTRY_ENTER() // 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(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; 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; } ConstColorSpaceRcPtr cs2; 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)); OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyProcessor.cpp0000644000175000017500000004330113223553423021357 0ustar mfvmfv/* 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 #include #include #include "PyUtil.h" #include "PyDoc.h" OCIO_NAMESPACE_ENTER { PyObject * BuildConstPyProcessor(ConstProcessorRcPtr processor) { return BuildConstPyOCIO(processor, PyOCIO_ProcessorType); } bool IsPyProcessor(PyObject * pyobject) { return IsPyOCIOType(pyobject, PyOCIO_ProcessorType); } ConstProcessorRcPtr GetConstProcessor(PyObject * pyobject) { return GetConstPyOCIO(pyobject, PyOCIO_ProcessorType); } 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 = { PyVarObject_HEAD_INIT(NULL, 0) //ob_size OCIO_PYTHON_NAMESPACE(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 }; /////////////////////////////////////////////////////////////////////////// /// 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*/) { DeletePyObject(self); } PyObject * PyOCIO_Processor_isNoOp(PyObject * self) { OCIO_PYTRY_ENTER() ConstProcessorRcPtr processor = GetConstProcessor(self); return PyBool_FromLong(processor->isNoOp()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Processor_hasChannelCrosstalk(PyObject * self) { OCIO_PYTRY_ENTER() ConstProcessorRcPtr processor = GetConstProcessor(self); return PyBool_FromLong(processor->hasChannelCrosstalk()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Processor_getMetadata(PyObject * self) { OCIO_PYTRY_ENTER() ConstProcessorRcPtr processor = GetConstProcessor(self); return BuildConstPyProcessorMetadata(processor->getMetadata()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Processor_applyRGB(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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 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], long(data.size()/3), 1, 3); processor->apply(img); return CreatePyListFromFloatVector(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Processor_applyRGBA(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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 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], long(data.size()/4), 1, 4); processor->apply(img); return CreatePyListFromFloatVector(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Processor_getCpuCacheID(PyObject * self) { OCIO_PYTRY_ENTER() ConstProcessorRcPtr processor = GetConstProcessor(self); return PyString_FromString(processor->getCpuCacheID()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Processor_getGpuShaderText(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyobject = 0; if (!PyArg_ParseTuple(args, "O:getGpuShaderText", &pyobject)) return NULL; ConstProcessorRcPtr processor = GetConstProcessor(self); if(IsPyOCIOType(pyobject, PyOCIO_GpuShaderDescType)) { ConstGpuShaderDescRcPtr desc = GetConstGpuShaderDesc(pyobject); return PyString_FromString(processor->getGpuShaderText(*desc.get())); } // DEPRECIATED GpuShaderDesc dict support TODO: remove GpuShaderDesc shaderDesc; FillShaderDescFromPyDict(shaderDesc, pyobject); return PyString_FromString(processor->getGpuShaderText(shaderDesc)); // DEPRECIATED OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Processor_getGpuShaderTextCacheID(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyobject = 0; if (!PyArg_ParseTuple(args, "O:getGpuShaderTextCacheID", &pyobject)) return NULL; ConstProcessorRcPtr processor = GetConstProcessor(self); if(IsPyOCIOType(pyobject, PyOCIO_GpuShaderDescType)) { ConstGpuShaderDescRcPtr desc = GetConstGpuShaderDesc(pyobject); return PyString_FromString(processor->getGpuShaderTextCacheID(*desc.get())); } // DEPRECIATED GpuShaderDesc dict support TODO: remove GpuShaderDesc shaderDesc; FillShaderDescFromPyDict(shaderDesc, pyobject); return PyString_FromString(processor->getGpuShaderTextCacheID(shaderDesc)); // DEPRECIATED OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Processor_getGpuLut3D(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyobject = 0; if (!PyArg_ParseTuple(args, "O:getGpuLut3D", &pyobject)) return NULL; ConstProcessorRcPtr processor = GetConstProcessor(self); if(IsPyOCIOType(pyobject, PyOCIO_GpuShaderDescType)) { ConstGpuShaderDescRcPtr desc = GetConstGpuShaderDesc(pyobject); int len = desc->getLut3DEdgeLen(); std::vector lut3d(3*len*len*len); // TODO: return more compact binary data? (ex array, ...) processor->getGpuLut3D(&lut3d[0], *desc.get()); return CreatePyListFromFloatVector(lut3d); } // DEPRECIATED GpuShaderDesc dict support TODO: remove GpuShaderDesc shaderDesc; FillShaderDescFromPyDict(shaderDesc, pyobject); int len = shaderDesc.getLut3DEdgeLen(); std::vector lut3d(3*len*len*len); // TODO: return more compact binary data? (ex array, ...) processor->getGpuLut3D(&lut3d[0], shaderDesc); return CreatePyListFromFloatVector(lut3d); // DEPRECIATED OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_Processor_getGpuLut3DCacheID(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyobject = 0; if (!PyArg_ParseTuple(args,"O:getGpuLut3DCacheID", &pyobject)) return NULL; ConstProcessorRcPtr processor = GetConstProcessor(self); if(IsPyOCIOType(pyobject, PyOCIO_GpuShaderDescType)) { ConstGpuShaderDescRcPtr desc = GetConstGpuShaderDesc(pyobject); return PyString_FromString(processor->getGpuLut3DCacheID(*desc.get())); } // DEPRECIATED GpuShaderDesc dict support TODO: remove GpuShaderDesc shaderDesc; FillShaderDescFromPyDict(shaderDesc, pyobject); return PyString_FromString(processor->getGpuLut3DCacheID(shaderDesc)); // DEPRECIATED OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyAllocationTransform.cpp0000644000175000017500000002436713223553423023374 0ustar mfvmfv/* 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 #include #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. #define GetConstAllocationTransform(pyobject) GetConstPyOCIO(pyobject, \ PyOCIO_AllocationTransformType) #define GetEditableAllocationTransform(pyobject) GetEditablePyOCIO(pyobject, \ PyOCIO_AllocationTransformType) OCIO_NAMESPACE_ENTER { 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_getNumVars(PyObject * self); 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__ }, { "getNumVars", (PyCFunction) PyOCIO_AllocationTransform_getNumVars, METH_VARARGS, ALLOCATIONTRANSFORM_GETNUMVARS__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 = { PyVarObject_HEAD_INIT(NULL, 0) //ob_size OCIO_PYTHON_NAMESPACE(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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_AllocationTransform_init(PyOCIO_Transform * self, PyObject * args, PyObject * kwds) { OCIO_PYTRY_ENTER() AllocationTransformRcPtr ptr = AllocationTransform::Create(); int ret = BuildPyTransformObject(self, ptr); char* allocation = NULL; PyObject* pyvars = 0; char* direction = NULL; static const char *kwlist[] = { "allocation", "vars", "direction", NULL }; if(!PyArg_ParseTupleAndKeywords(args, kwds, "|sOs", const_cast(kwlist), &allocation, &pyvars, &direction)) return -1; if(allocation) ptr->setAllocation(AllocationFromString(allocation)); if (pyvars) { std::vector vars; if(!FillFloatVectorFromPySequence(pyvars, vars) || (vars.size() < 2 || vars.size() > 3)) { PyErr_SetString(PyExc_TypeError, "vars must be a float array, size 2 or 3"); return 0; } ptr->setVars(static_cast(vars.size()), &vars[0]); } if(direction) ptr->setDirection(TransformDirectionFromString(direction)); return ret; OCIO_PYTRY_EXIT(-1) } PyObject * PyOCIO_AllocationTransform_getAllocation(PyObject * self) { OCIO_PYTRY_ENTER() ConstAllocationTransformRcPtr transform = GetConstAllocationTransform(self); return PyString_FromString( AllocationToString( transform->getAllocation()) ); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_AllocationTransform_setAllocation(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() Allocation hwalloc; if (!PyArg_ParseTuple(args,"O&:setAllocation", ConvertPyObjectToAllocation, &hwalloc)) return NULL; AllocationTransformRcPtr transform = GetEditableAllocationTransform(self); transform->setAllocation(hwalloc); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_AllocationTransform_getNumVars(PyObject * self) { OCIO_PYTRY_ENTER() ConstAllocationTransformRcPtr transform = GetConstAllocationTransform(self); return PyInt_FromLong(transform->getNumVars()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_AllocationTransform_getVars(PyObject * self) { OCIO_PYTRY_ENTER() ConstAllocationTransformRcPtr transform = GetConstAllocationTransform(self); std::vector vars(transform->getNumVars()); if(!vars.empty()) transform->getVars(&vars[0]); return CreatePyListFromFloatVector(vars); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_AllocationTransform_setVars(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject * pyvars = 0; if (!PyArg_ParseTuple(args,"O:setVars", &pyvars)) return NULL; std::vector 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(vars.size()), &vars[0]); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyGroupTransform.cpp0000644000175000017500000002633313223553423022376 0ustar mfvmfv/* 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 #include #include "PyUtil.h" #include "PyDoc.h" #define GetConstGroupTransform(pyobject) GetConstPyOCIO(pyobject, \ PyOCIO_GroupTransformType) #define GetEditableGroupTransform(pyobject) GetEditablePyOCIO(pyobject, \ PyOCIO_GroupTransformType) OCIO_NAMESPACE_ENTER { 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 = { PyVarObject_HEAD_INIT(NULL, 0) OCIO_PYTHON_NAMESPACE(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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_GroupTransform_init(PyOCIO_Transform * self, PyObject * args, PyObject * kwds) { OCIO_PYTRY_ENTER() GroupTransformRcPtr ptr = GroupTransform::Create(); int ret = BuildPyTransformObject(self, ptr); PyObject* pytransforms = Py_None; char* direction = NULL; static const char *kwlist[] = { "transforms", "direction", NULL }; if(!PyArg_ParseTupleAndKeywords(args, kwds, "|Os", const_cast(kwlist), &pytransforms, &direction )) return -1; if(pytransforms != Py_None) { std::vector data; if(!FillTransformVectorFromPySequence(pytransforms, data)) { PyErr_SetString(PyExc_TypeError, "Kwarg 'transforms' must be a transform array."); return -1; } for(unsigned int i=0; ipush_back(data[i]); } if(direction) ptr->setDirection(TransformDirectionFromString(direction)); return ret; OCIO_PYTRY_EXIT(-1) } PyObject * PyOCIO_GroupTransform_getTransform(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() int index = 0; if (!PyArg_ParseTuple(args,"i:getTransform", &index)) return NULL; ConstGroupTransformRcPtr transform = GetConstGroupTransform(self); ConstTransformRcPtr childTransform = transform->getTransform(index); return BuildConstPyTransform(childTransform); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GroupTransform_getTransforms(PyObject * self) { OCIO_PYTRY_ENTER() ConstGroupTransformRcPtr transform = GetConstGroupTransform(self); std::vector transforms; for(int i = 0; i < transform->size(); ++i) transforms.push_back(transform->getTransform(i)); return CreatePyListFromTransformVector(transforms); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GroupTransform_setTransforms(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pytransforms = 0; if (!PyArg_ParseTuple(args,"O:setTransforms", &pytransforms)) return NULL; GroupTransformRcPtr transform = GetEditableGroupTransform(self); std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GroupTransform_size(PyObject * self) { OCIO_PYTRY_ENTER() ConstGroupTransformRcPtr transform = GetConstGroupTransform(self); return PyInt_FromLong(transform->size()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GroupTransform_push_back(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GroupTransform_clear(PyObject * self) { OCIO_PYTRY_ENTER() GroupTransformRcPtr transform = GetEditableGroupTransform(self); transform->clear(); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GroupTransform_empty(PyObject * self) { OCIO_PYTRY_ENTER() ConstGroupTransformRcPtr transform = GetConstGroupTransform(self); return PyBool_FromLong(transform->empty()); OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyProcessorMetadata.cpp0000644000175000017500000001706713223553423023032 0ustar mfvmfv/* 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 #include #include "PyUtil.h" #include "PyDoc.h" OCIO_NAMESPACE_ENTER { PyObject * BuildConstPyProcessorMetadata(ConstProcessorMetadataRcPtr metadata) { return BuildConstPyOCIO(metadata, PyOCIO_ProcessorMetadataType); } bool IsPyProcessorMetadata(PyObject * pyobject) { return IsPyOCIOType(pyobject, PyOCIO_ProcessorMetadataType); } ConstProcessorMetadataRcPtr GetConstProcessorMetadata(PyObject * pyobject) { return GetConstPyOCIO(pyobject, PyOCIO_ProcessorMetadataType); } 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 = { PyVarObject_HEAD_INIT(NULL, 0) //ob_size OCIO_PYTHON_NAMESPACE(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 }; 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*/) { DeletePyObject(self); } PyObject * PyOCIO_ProcessorMetadata_getFiles(PyObject * self) { OCIO_PYTRY_ENTER() ConstProcessorMetadataRcPtr metadata = GetConstProcessorMetadata(self); std::vector data; for(int i = 0; i < metadata->getNumFiles(); ++i) data.push_back(metadata->getFile(i)); return CreatePyListFromStringVector(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ProcessorMetadata_getLooks(PyObject * self) { OCIO_PYTRY_ENTER() ConstProcessorMetadataRcPtr metadata = GetConstProcessorMetadata(self); std::vector data; for(int i = 0; i < metadata->getNumLooks(); ++i) data.push_back(metadata->getLook(i)); return CreatePyListFromStringVector(data); OCIO_PYTRY_EXIT(NULL) } } // anon namespace } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyGpuShaderDesc.cpp0000644000175000017500000002422613223553423022066 0ustar mfvmfv/* 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 #include #include "PyUtil.h" #include "PyDoc.h" OCIO_NAMESPACE_ENTER { ConstGpuShaderDescRcPtr GetConstGpuShaderDesc(PyObject * pyobject) { return GetConstPyOCIO(pyobject, PyOCIO_GpuShaderDescType); } GpuShaderDescRcPtr GetEditableGpuShaderDesc(PyObject * pyobject) { return GetEditablePyOCIO(pyobject, PyOCIO_GpuShaderDescType); } namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_GpuShaderDesc_init(PyOCIO_GpuShaderDesc * self, PyObject * args, PyObject * kwds); void PyOCIO_GpuShaderDesc_delete(PyOCIO_GpuShaderDesc * self, PyObject * args); PyObject * PyOCIO_GpuShaderDesc_setLanguage(PyObject * self, PyObject * args); PyObject * PyOCIO_GpuShaderDesc_getLanguage(PyObject * self); PyObject * PyOCIO_GpuShaderDesc_setFunctionName(PyObject * self, PyObject * args); PyObject * PyOCIO_GpuShaderDesc_getFunctionName(PyObject * self); PyObject * PyOCIO_GpuShaderDesc_setLut3DEdgeLen(PyObject * self, PyObject * args); PyObject * PyOCIO_GpuShaderDesc_getLut3DEdgeLen(PyObject * self); PyObject * PyOCIO_GpuShaderDesc_getCacheID(PyObject * self); /////////////////////////////////////////////////////////////////////// /// PyMethodDef PyOCIO_GpuShaderDesc_methods[] = { { "setLanguage", PyOCIO_GpuShaderDesc_setLanguage, METH_VARARGS, GPUSHADERDESC_SETLANGUAGE__DOC__ }, { "getLanguage", (PyCFunction) PyOCIO_GpuShaderDesc_getLanguage, METH_NOARGS, GPUSHADERDESC_GETLANGUAGE__DOC__ }, { "setFunctionName", PyOCIO_GpuShaderDesc_setFunctionName, METH_VARARGS, GPUSHADERDESC_SETFUNCTIONNAME__DOC__ }, { "getFunctionName", (PyCFunction) PyOCIO_GpuShaderDesc_getFunctionName, METH_NOARGS, GPUSHADERDESC_GETFUNCTIONNAME__DOC__ }, { "setLut3DEdgeLen", PyOCIO_GpuShaderDesc_setLut3DEdgeLen, METH_VARARGS, GPUSHADERDESC_SETLUT3DEDGELEN__DOC__ }, { "getLut3DEdgeLen", (PyCFunction) PyOCIO_GpuShaderDesc_getLut3DEdgeLen, METH_NOARGS, GPUSHADERDESC_GETLUT3DEDGELEN__DOC__ }, { "getCacheID", (PyCFunction) PyOCIO_GpuShaderDesc_getCacheID, METH_NOARGS, GPUSHADERDESC_GETCACHEID__DOC__ }, { NULL, NULL, 0, NULL } }; } /////////////////////////////////////////////////////////////////////////// /// PyTypeObject PyOCIO_GpuShaderDescType = { PyVarObject_HEAD_INIT(NULL, 0) //ob_size OCIO_PYTHON_NAMESPACE(GpuShaderDesc), //tp_name sizeof(PyOCIO_GpuShaderDesc), //tp_basicsize 0, //tp_itemsize (destructor)PyOCIO_GpuShaderDesc_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 GPUSHADERDESC__DOC__, //tp_doc 0, //tp_traverse 0, //tp_clear 0, //tp_richcompare 0, //tp_weaklistoffset 0, //tp_iter 0, //tp_iternext PyOCIO_GpuShaderDesc_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_GpuShaderDesc_init, //tp_init 0, //tp_alloc 0, //tp_new 0, //tp_free 0, //tp_is_gc }; namespace { /////////////////////////////////////////////////////////////////////// /// void GpuShaderDesc_deleter(GpuShaderDesc* d) { delete d; } int PyOCIO_GpuShaderDesc_init(PyOCIO_GpuShaderDesc* self, PyObject * /*args*/, PyObject * /*kwds*/) { OCIO_PYTRY_ENTER() return BuildPyObject(self, GpuShaderDescRcPtr(new GpuShaderDesc(), GpuShaderDesc_deleter)); OCIO_PYTRY_EXIT(-1) } void PyOCIO_GpuShaderDesc_delete(PyOCIO_GpuShaderDesc *self, PyObject * /*args*/) { DeletePyObject(self); } PyObject * PyOCIO_GpuShaderDesc_setLanguage(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* lang = 0; if (!PyArg_ParseTuple(args, "s:setLanguage", &lang)) return NULL; GpuShaderDescRcPtr desc = GetEditableGpuShaderDesc(self); desc->setLanguage(GpuLanguageFromString(lang)); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GpuShaderDesc_getLanguage(PyObject * self) { OCIO_PYTRY_ENTER() ConstGpuShaderDescRcPtr desc = GetConstGpuShaderDesc(self); GpuLanguage lang = desc->getLanguage(); return PyString_FromString(GpuLanguageToString(lang)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GpuShaderDesc_setFunctionName(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args, "s:setFunctionName", &name)) return NULL; GpuShaderDescRcPtr desc = GetEditableGpuShaderDesc(self); desc->setFunctionName(name); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GpuShaderDesc_getFunctionName(PyObject * self) { OCIO_PYTRY_ENTER() ConstGpuShaderDescRcPtr desc = GetConstGpuShaderDesc(self); return PyString_FromString(desc->getFunctionName()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GpuShaderDesc_setLut3DEdgeLen(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() int len = 0; if (!PyArg_ParseTuple(args,"i:setLut3DEdgeLen", &len)) return NULL; GpuShaderDescRcPtr desc = GetEditableGpuShaderDesc(self); desc->setLut3DEdgeLen(len); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GpuShaderDesc_getLut3DEdgeLen(PyObject * self) { OCIO_PYTRY_ENTER() ConstGpuShaderDescRcPtr desc = GetConstGpuShaderDesc(self); return PyInt_FromLong(desc->getLut3DEdgeLen()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GpuShaderDesc_getCacheID(PyObject * self) { OCIO_PYTRY_ENTER() ConstGpuShaderDescRcPtr desc = GetConstGpuShaderDesc(self); return PyString_FromString(desc->getCacheID()); OCIO_PYTRY_EXIT(NULL) } } // anon namespace } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyLogTransform.cpp0000644000175000017500000001616213223553423022022 0ustar mfvmfv/* 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 #include #include "PyUtil.h" #include "PyDoc.h" #define GetConstLogTransform(pyobject) GetConstPyOCIO(pyobject, \ PyOCIO_LogTransformType) #define GetEditableLogTransform(pyobject) GetEditablePyOCIO(pyobject, \ PyOCIO_LogTransformType) OCIO_NAMESPACE_ENTER { 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 = { PyVarObject_HEAD_INIT(NULL, 0) OCIO_PYTHON_NAMESPACE(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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_LogTransform_init(PyOCIO_Transform * self, PyObject * args, PyObject * kwds) { OCIO_PYTRY_ENTER() static const char *kwlist[] = { "base", "direction", NULL }; float base = -1.0f; // -1.0 is an illegal value for log transform base char* direction = NULL; if(!PyArg_ParseTupleAndKeywords(args, kwds, "|fs", const_cast(kwlist), &base, &direction )) return -1; LogTransformRcPtr ptr = LogTransform::Create(); int ret = BuildPyTransformObject(self, ptr); if(base != -1.0f) ptr->setBase(base); if(direction) ptr->setDirection(TransformDirectionFromString(direction)); return ret; OCIO_PYTRY_EXIT(-1) } PyObject * PyOCIO_LogTransform_getBase(PyObject * self) { OCIO_PYTRY_ENTER() ConstLogTransformRcPtr transform = GetConstLogTransform(self); return PyFloat_FromDouble(transform->getBase()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_LogTransform_setBase(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() float base; if (!PyArg_ParseTuple(args, "f:setBase", &base)) return NULL; LogTransformRcPtr transform = GetEditableLogTransform(self); transform->setBase(base); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyMain.cpp0000644000175000017500000002004313223553423020262 0ustar mfvmfv/* 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 #include namespace OCIO = OCIO_NAMESPACE; #include "PyUtil.h" #include "PyDoc.h" namespace { PyObject * PyOCIO_ClearAllCaches(PyObject * /* self */) { OCIO_PYTRY_ENTER() OCIO::ClearAllCaches(); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GetLoggingLevel(PyObject * /* self */) { OCIO_PYTRY_ENTER() return PyString_FromString( OCIO::LoggingLevelToString(OCIO::GetLoggingLevel())); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_SetLoggingLevel(PyObject * /*self*/, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_GetCurrentConfig(PyObject * /* self */) { OCIO_PYTRY_ENTER() return OCIO::BuildConstPyConfig(OCIO::GetCurrentConfig()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_SetCurrentConfig(PyObject * /*self*/, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(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; } inline bool AddObjectToModule(PyTypeObject& o, const char* n, PyObject* m) { o.tp_new = PyType_GenericNew; if(PyType_Ready(&o) < 0) return false; Py_INCREF(&o); PyModule_AddObject(m, n, (PyObject *)&o); return true; } // fwd declare void AddConstantsModule(PyObject *enclosingModule); } OCIO_NAMESPACE_EXIT MOD_INIT(PyOpenColorIO) { PyObject * m; MOD_DEF(m, OCIO_STRINGIFY(PYOCIO_NAME), OCIO::OPENCOLORIO__DOC__, PyOCIO_methods); if (m == NULL) return MOD_ERROR_VAL; PyModule_AddStringConstant(m, "version", OCIO::GetVersion()); PyModule_AddIntConstant(m, "hexversion", OCIO::GetVersionHex()); // Create Exceptions, and add to the module char Exception[] = OCIO_PYTHON_NAMESPACE(Exception); char ExceptionMissingFile[] = OCIO_PYTHON_NAMESPACE(ExceptionMissingFile); #if PY_MAJOR_VERSION >= 2 && PY_MINOR_VERSION >= 7 OCIO::SetExceptionPyType(PyErr_NewExceptionWithDoc(Exception, const_cast(OCIO::EXCEPTION__DOC__), OCIO::GetExceptionPyType(), NULL)); OCIO::SetExceptionMissingFilePyType(PyErr_NewExceptionWithDoc(ExceptionMissingFile, const_cast(OCIO::EXCEPTIONMISSINGFILE__DOC__), OCIO::GetExceptionMissingFilePyType(), NULL)); #else OCIO::SetExceptionPyType(PyErr_NewException(Exception, OCIO::GetExceptionPyType(), NULL)); OCIO::SetExceptionMissingFilePyType(PyErr_NewException(ExceptionMissingFile, OCIO::GetExceptionMissingFilePyType(), NULL)); #endif PyModule_AddObject(m, "Exception", OCIO::GetExceptionPyType()); PyModule_AddObject(m, "ExceptionMissingFile", OCIO::GetExceptionMissingFilePyType()); // Register Classes OCIO::AddObjectToModule(OCIO::PyOCIO_ColorSpaceType, "ColorSpace", m); OCIO::AddObjectToModule(OCIO::PyOCIO_ConfigType, "Config", m); OCIO::AddConstantsModule(m); OCIO::AddObjectToModule(OCIO::PyOCIO_ContextType, "Context", m); OCIO::AddObjectToModule(OCIO::PyOCIO_LookType, "Look", m); OCIO::AddObjectToModule(OCIO::PyOCIO_ProcessorType, "Processor", m); OCIO::AddObjectToModule(OCIO::PyOCIO_ProcessorMetadataType, "ProcessorMetadata", m); OCIO::AddObjectToModule(OCIO::PyOCIO_GpuShaderDescType, "GpuShaderDesc", m); OCIO::AddObjectToModule(OCIO::PyOCIO_BakerType, "Baker", m); OCIO::AddObjectToModule(OCIO::PyOCIO_TransformType, "Transform", m); { OCIO::AddObjectToModule(OCIO::PyOCIO_AllocationTransformType, "AllocationTransform", m); OCIO::AddObjectToModule(OCIO::PyOCIO_CDLTransformType, "CDLTransform", m); OCIO::AddObjectToModule(OCIO::PyOCIO_ColorSpaceTransformType, "ColorSpaceTransform", m); OCIO::AddObjectToModule(OCIO::PyOCIO_DisplayTransformType, "DisplayTransform", m); OCIO::AddObjectToModule(OCIO::PyOCIO_ExponentTransformType, "ExponentTransform", m); OCIO::AddObjectToModule(OCIO::PyOCIO_FileTransformType, "FileTransform", m); OCIO::AddObjectToModule(OCIO::PyOCIO_GroupTransformType, "GroupTransform", m); OCIO::AddObjectToModule(OCIO::PyOCIO_LogTransformType, "LogTransform", m); OCIO::AddObjectToModule(OCIO::PyOCIO_LookTransformType, "LookTransform", m); OCIO::AddObjectToModule(OCIO::PyOCIO_MatrixTransformType, "MatrixTransform", m); } return MOD_SUCCESS_VAL(m); } opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyUtil.cpp0000644000175000017500000005424513223553423020326 0ustar mfvmfv/* 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 #include #include #include "PyUtil.h" OCIO_NAMESPACE_ENTER { /////////////////////////////////////////////////////////////////////////// // http://docs.python.org/c-api/object.html#PyObject_IsTrue int ConvertPyObjectToBool(PyObject *object, void *valuePtr) { bool *boolPtr = static_cast(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(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(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(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(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(valuePtr); if(!PyString_Check(object)) { PyErr_SetString(PyExc_ValueError, "Object is not a string."); return 0; } *gpuLanguagePtr = GpuLanguageFromString(PyString_AsString( object )); return 1; } int ConvertPyObjectToEnvironmentMode(PyObject *object, void *valuePtr) { EnvironmentMode* environmentmodePtr = static_cast(valuePtr); if(!PyString_Check(object)) { PyErr_SetString(PyExc_ValueError, "Object is not a string."); return 0; } *environmentmodePtr = EnvironmentModeFromString(PyString_AsString( object )); return 1; } /////////////////////////////////////////////////////////////////////////// bool GetIntFromPyObject(PyObject* object, int* val) { if(!val || !object) return false; if( PyInt_Check( object ) ) { *val = static_cast( PyInt_AS_LONG( object ) ); return true; } if( PyFloat_Check( object ) ) { *val = static_cast( PyFloat_AS_DOUBLE( object ) ); return true; } PyObject* intObject = PyNumber_Int(object); if(intObject) { *val = static_cast( 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( PyFloat_AS_DOUBLE( object ) ); return true; } if( PyInt_Check( object ) ) { *val = static_cast( PyInt_AS_LONG( object ) ); return true; } PyObject* floatObject = PyNumber_Float(object); if(floatObject) { *val = static_cast( 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( 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 &data) { PyObject* returnlist = PyList_New( data.size() ); if(!returnlist) return 0; for(unsigned int i =0; i &data) { PyObject* returnlist = PyList_New( data.size() ); if(!returnlist) return 0; for(unsigned int i =0; i &data) { PyObject* returnlist = PyList_New( data.size() ); if(!returnlist) return 0; for(unsigned int i =0; i &data) { PyObject* returnlist = PyList_New( data.size() ); if(!returnlist) return 0; for(unsigned int i =0; i &data) { PyObject* returnlist = PyList_New( data.size() ); if(!returnlist) return 0; for(unsigned int i =0; i &data) { PyObject* returndict = PyDict_New(); if(!returndict) return 0; std::map::const_iterator iter; for(iter = data.begin(); iter != data.end(); ++iter) { int ret = PyDict_SetItem(returndict, PyString_FromString(iter->first.c_str()), PyString_FromString(iter->second.c_str())); if(ret) { Py_DECREF(returndict); return NULL; } } return returndict; } 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(PyList_GET_SIZE(pyobj)); } else if(PyTuple_Check(pyobj)) { return static_cast(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 &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 &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 &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 &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 &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 opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyLookTransform.cpp0000644000175000017500000002267113223553423022207 0ustar mfvmfv/* 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 #include #include "PyUtil.h" #include "PyDoc.h" #define GetConstLookTransform(pyobject) GetConstPyOCIO(pyobject, PyOCIO_LookTransformType) #define GetEditableLookTransform(pyobject) GetEditablePyOCIO(pyobject, PyOCIO_LookTransformType) OCIO_NAMESPACE_ENTER { 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 = { PyVarObject_HEAD_INIT(NULL, 0) //ob_size OCIO_PYTHON_NAMESPACE(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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_LookTransform_init(PyOCIO_Transform * self, PyObject * args, PyObject * kwds) { OCIO_PYTRY_ENTER() LookTransformRcPtr ptr = LookTransform::Create(); int ret = BuildPyTransformObject(self, ptr); 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(kwlist), &src, &dst, &looks, &direction)) return -1; if(src) ptr->setSrc(src); if(dst) ptr->setDst(dst); if(looks) ptr->setLooks(looks); if(direction) ptr->setDirection(TransformDirectionFromString(direction)); return ret; OCIO_PYTRY_EXIT(-1) } PyObject * PyOCIO_LookTransform_getSrc(PyObject * self) { OCIO_PYTRY_ENTER() ConstLookTransformRcPtr transform = GetConstLookTransform(self); return PyString_FromString(transform->getSrc()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_LookTransform_setSrc(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() const char* str = 0; if (!PyArg_ParseTuple(args, "s:setSrc", &str)) return NULL; LookTransformRcPtr transform = GetEditableLookTransform(self); transform->setSrc(str); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_LookTransform_getDst(PyObject * self) { OCIO_PYTRY_ENTER() ConstLookTransformRcPtr transform = GetConstLookTransform(self); return PyString_FromString(transform->getDst()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_LookTransform_setDst(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() const char* str = 0; if (!PyArg_ParseTuple(args, "s:setDst", &str)) return NULL; LookTransformRcPtr transform = GetEditableLookTransform(self); transform->setDst(str); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_LookTransform_getLooks(PyObject * self) { OCIO_PYTRY_ENTER() ConstLookTransformRcPtr transform = GetConstLookTransform(self); return PyString_FromString( transform->getLooks() ); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_LookTransform_setLooks(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() const char* str = 0; if (!PyArg_ParseTuple(args, "s:setLooks", &str)) return NULL; LookTransformRcPtr transform = GetEditableLookTransform(self); transform->setLooks(str); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyColorSpace.cpp0000644000175000017500000005320213223553423021433 0ustar mfvmfv/* 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 #include #include #include "PyUtil.h" #include "PyDoc.h" OCIO_NAMESPACE_ENTER { PyObject * BuildConstPyColorSpace(ConstColorSpaceRcPtr colorSpace) { return BuildConstPyOCIO(colorSpace, PyOCIO_ColorSpaceType); } PyObject * BuildEditablePyColorSpace(ColorSpaceRcPtr colorSpace) { return BuildEditablePyOCIO(colorSpace, PyOCIO_ColorSpaceType); } bool IsPyColorSpace(PyObject * pyobject) { return IsPyOCIOType(pyobject, PyOCIO_ColorSpaceType); } bool IsPyColorSpaceEditable(PyObject * pyobject) { return IsPyEditable(pyobject, PyOCIO_ColorSpaceType); } ConstColorSpaceRcPtr GetConstColorSpace(PyObject * pyobject, bool allowCast) { return GetConstPyOCIO(pyobject, PyOCIO_ColorSpaceType, allowCast); } ColorSpaceRcPtr GetEditableColorSpace(PyObject * pyobject) { return GetEditablePyOCIO(pyobject, PyOCIO_ColorSpaceType); } namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_ColorSpace_init(PyOCIO_ColorSpace * self, PyObject * args, PyObject * kwds); void PyOCIO_ColorSpace_delete(PyOCIO_ColorSpace * self, PyObject * args); PyObject * PyOCIO_ColorSpace_str(PyObject * self); 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 = { PyVarObject_HEAD_INIT(NULL, 0) //ob_size OCIO_PYTHON_NAMESPACE(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 PyOCIO_ColorSpace_str, //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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_ColorSpace_init(PyOCIO_ColorSpace * self, PyObject * args, PyObject * kwds) { OCIO_PYTRY_ENTER() ColorSpaceRcPtr ptr = ColorSpace::Create(); int ret = BuildPyObject(self, ptr); 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(kwlist), &name, &family, &equalityGroup, &description, &bitDepth, ConvertPyObjectToBool, &isData, &allocation, &allocationVars, &toRefTransform, &fromRefTransform)) return -1; if(name) ptr->setName(name); if(family) ptr->setFamily(family); if(equalityGroup) ptr->setEqualityGroup(equalityGroup); if(description) ptr->setDescription(description); if(bitDepth) ptr->setBitDepth(BitDepthFromString(bitDepth)); ptr->setIsData(isData); // TODO: Do not rely on the default value if(allocation) ptr->setAllocation(AllocationFromString(allocation)); if(allocationVars) { std::vector vars; if(!FillFloatVectorFromPySequence(allocationVars, vars)) { PyErr_SetString(PyExc_TypeError, "allocationVars kwarg must be a float array."); return -1; } ptr->setAllocationVars(static_cast(vars.size()), &vars[0]); } if(toRefTransform) { ConstTransformRcPtr transform = GetConstTransform(toRefTransform, true); ptr->setTransform(transform, COLORSPACE_DIR_TO_REFERENCE); } if(fromRefTransform) { ConstTransformRcPtr transform = GetConstTransform(fromRefTransform, true); ptr->setTransform(transform, COLORSPACE_DIR_FROM_REFERENCE); } return ret; OCIO_PYTRY_EXIT(-1) } void PyOCIO_ColorSpace_delete(PyOCIO_ColorSpace *self, PyObject * /*args*/) { DeletePyObject(self); } PyObject * PyOCIO_ColorSpace_str(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); std::ostringstream out; out << *colorSpace; return PyString_FromString(out.str().c_str()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_isEditable(PyObject * self) { return PyBool_FromLong(IsPyColorSpaceEditable(self)); } PyObject * PyOCIO_ColorSpace_createEditableCopy(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); ColorSpaceRcPtr copy = colorSpace->createEditableCopy(); return BuildEditablePyColorSpace(copy); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_getName(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); return PyString_FromString(colorSpace->getName()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_setName(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args, "s:setName", &name)) return NULL; ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); colorSpace->setName(name); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_getFamily(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); return PyString_FromString(colorSpace->getFamily()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_setFamily(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args, "s:setFamily", &name)) return NULL; ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); colorSpace->setFamily(name); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_getEqualityGroup(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); return PyString_FromString(colorSpace->getEqualityGroup()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_setEqualityGroup(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args, "s:setEqualityGroup", &name)) return NULL; ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); colorSpace->setEqualityGroup(name); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_getDescription(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); return PyString_FromString(colorSpace->getDescription()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_setDescription(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args, "s:setDescription", &name)) return NULL; ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); colorSpace->setDescription(name); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_getBitDepth(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); return PyString_FromString( BitDepthToString(colorSpace->getBitDepth())); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_setBitDepth(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() char* name = 0; if (!PyArg_ParseTuple(args, "s:setBitDepth", &name)) return NULL; ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); colorSpace->setBitDepth(BitDepthFromString(name)); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_isData(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); return PyBool_FromLong(colorSpace->isData()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_setIsData(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() bool isData = false; if (!PyArg_ParseTuple(args, "O&:setIsData", ConvertPyObjectToBool, &isData)) return NULL; ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); colorSpace->setIsData(isData); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_getAllocation(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); return PyString_FromString(AllocationToString(colorSpace->getAllocation())); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_setAllocation(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() Allocation hwalloc; if (!PyArg_ParseTuple(args, "O&:setAllocation", ConvertPyObjectToAllocation, &hwalloc)) return NULL; ColorSpaceRcPtr colorSpace = GetEditableColorSpace(self); colorSpace->setAllocation(hwalloc); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_getAllocationVars(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceRcPtr colorSpace = GetConstColorSpace(self, true); std::vector allocationvars(colorSpace->getAllocationNumVars()); if(!allocationvars.empty()) colorSpace->getAllocationVars(&allocationvars[0]); return CreatePyListFromFloatVector(allocationvars); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_setAllocationVars(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyvars = 0; if (!PyArg_ParseTuple(args, "O:setAllocationVars", &pyvars)) return NULL; std::vector 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(vars.size()), &vars[0]); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_getTransform(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpace_setTransform(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() 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; OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyExponentTransform.cpp0000644000175000017500000001762313223553423023104 0ustar mfvmfv/* 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 #include #include "PyUtil.h" #include "PyDoc.h" #define GetConstExponentTransform(pyobject) GetConstPyOCIO(pyobject, \ PyOCIO_ExponentTransformType) #define GetEditableExponentTransform(pyobject) GetEditablePyOCIO(pyobject, \ PyOCIO_ExponentTransformType) OCIO_NAMESPACE_ENTER { 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 = { PyVarObject_HEAD_INIT(NULL, 0) OCIO_PYTHON_NAMESPACE(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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_ExponentTransform_init(PyOCIO_Transform * self, PyObject * args, PyObject * kwds) { OCIO_PYTRY_ENTER() static const char *kwlist[] = { "value", "direction", NULL }; PyObject* pyvalue = Py_None; char* direction = NULL; if(!PyArg_ParseTupleAndKeywords(args, kwds, "|Os", const_cast(kwlist), &pyvalue, &direction )) return -1; ExponentTransformRcPtr ptr = ExponentTransform::Create(); int ret = BuildPyTransformObject(self, ptr); if(pyvalue != Py_None) { std::vector data; if(!FillFloatVectorFromPySequence(pyvalue, data) || (data.size() != 4)) { PyErr_SetString(PyExc_TypeError, "Value argument must be a float array, size 4"); return -1; } ptr->setValue(&data[0]); } if(direction) ptr->setDirection(TransformDirectionFromString(direction)); return ret; OCIO_PYTRY_EXIT(-1) } PyObject * PyOCIO_ExponentTransform_getValue(PyObject * self) { OCIO_PYTRY_ENTER() ConstExponentTransformRcPtr transform = GetConstExponentTransform(self); std::vector data(4); transform->getValue(&data[0]); return CreatePyListFromFloatVector(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ExponentTransform_setValue(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyData = 0; if (!PyArg_ParseTuple(args, "O:setValue", &pyData)) return NULL; ExponentTransformRcPtr transform = GetEditableExponentTransform(self); std::vector 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; OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyMatrixTransform.cpp0000644000175000017500000005151013223553423022541 0ustar mfvmfv/* 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 #include #include "PyUtil.h" #include "PyDoc.h" #define GetConstMatrixTransform(pyobject) GetConstPyOCIO(pyobject, \ PyOCIO_MatrixTransformType) #define GetEditableMatrixTransform(pyobject) GetEditablePyOCIO(pyobject, \ PyOCIO_MatrixTransformType) OCIO_NAMESPACE_ENTER { namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_MatrixTransform_init(PyOCIO_Transform * self, PyObject * args, PyObject * kwds); PyObject * PyOCIO_MatrixTransform_equals(PyObject * self, PyObject * args); 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[] = { { "equals", PyOCIO_MatrixTransform_equals, METH_VARARGS, MATRIXTRANSFORM_EQUALS__DOC__ }, { "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 = { PyVarObject_HEAD_INIT(NULL, 0) OCIO_PYTHON_NAMESPACE(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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_MatrixTransform_init(PyOCIO_Transform * self, PyObject * args, PyObject * kwds) { OCIO_PYTRY_ENTER() MatrixTransformRcPtr ptr = MatrixTransform::Create(); int ret = BuildPyTransformObject(self, ptr); PyObject* pymatrix = 0; PyObject* pyoffset = 0; char* direction = NULL; static const char *kwlist[] = { "matrix", "offset", "direction", NULL }; if(!PyArg_ParseTupleAndKeywords(args, kwds, "|OOs", const_cast(kwlist), &pymatrix, &pyoffset, &direction)) return -1; if (pymatrix) { std::vector matrix; if(!FillFloatVectorFromPySequence(pymatrix, matrix) || (matrix.size() != 16)) { PyErr_SetString(PyExc_TypeError, "matrix must be a float array, size 16"); return 0; } ptr->setMatrix(&matrix[0]); } if (pyoffset) { std::vector offset; if(!FillFloatVectorFromPySequence(pyoffset, offset) || (offset.size() != 4)) { PyErr_SetString(PyExc_TypeError, "offset must be a float array, size 4"); return 0; } ptr->setOffset(&offset[0]); } if(direction) ptr->setDirection(TransformDirectionFromString(direction)); return ret; OCIO_PYTRY_EXIT(-1) } PyObject * PyOCIO_MatrixTransform_equals(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyobject = 0; if (!PyArg_ParseTuple(args,"O:equals", &pyobject)) return NULL; if(!IsPyOCIOType(pyobject, PyOCIO_MatrixTransformType)) throw Exception("MatrixTransform.equals requires a MatrixTransform argument"); ConstMatrixTransformRcPtr transform = GetConstMatrixTransform(self); ConstMatrixTransformRcPtr in = GetConstMatrixTransform(pyobject); return PyBool_FromLong(transform->equals(*in.get())); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_MatrixTransform_getValue(PyObject * self) { OCIO_PYTRY_ENTER() ConstMatrixTransformRcPtr transform = GetConstMatrixTransform(self); std::vector matrix(16); std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_MatrixTransform_setValue(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pymatrix = 0; PyObject* pyoffset = 0; if (!PyArg_ParseTuple(args, "OO:setValue", &pymatrix, &pyoffset)) return NULL; std::vector matrix; std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_MatrixTransform_getMatrix(PyObject * self) { OCIO_PYTRY_ENTER() ConstMatrixTransformRcPtr transform = GetConstMatrixTransform(self); std::vector matrix(16); transform->getMatrix(&matrix[0]); return CreatePyListFromFloatVector(matrix); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_MatrixTransform_setMatrix(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pymatrix = 0; if (!PyArg_ParseTuple(args,"O:setValue", &pymatrix)) return NULL; std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_MatrixTransform_getOffset(PyObject * self) { OCIO_PYTRY_ENTER() ConstMatrixTransformRcPtr transform = GetConstMatrixTransform(self); std::vector offset(4); transform->getOffset(&offset[0]); return CreatePyListFromFloatVector(offset); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_MatrixTransform_setOffset(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyoffset = 0; if (!PyArg_ParseTuple(args, "O:setValue", &pyoffset)) return NULL; std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_MatrixTransform_Identity(PyObject * /*self*/) { OCIO_PYTRY_ENTER() std::vector matrix(16); std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_MatrixTransform_Fit(PyObject * /*self*/, PyObject * args) { OCIO_PYTRY_ENTER() 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 oldmin; if(!FillFloatVectorFromPySequence(pyoldmin, oldmin) || (oldmin.size() != 4)) { PyErr_SetString(PyExc_TypeError, "First argument must be a float array, size 4"); return 0; } std::vector oldmax; if(!FillFloatVectorFromPySequence(pyoldmax, oldmax) || (oldmax.size() != 4)) { PyErr_SetString(PyExc_TypeError, "Second argument must be a float array, size 4"); return 0; } std::vector newmin; if(!FillFloatVectorFromPySequence(pynewmin, newmin) || (newmin.size() != 4)) { PyErr_SetString(PyExc_TypeError, "Third argument must be a float array, size 4"); return 0; } std::vector newmax; if(!FillFloatVectorFromPySequence(pynewmax, newmax) || (newmax.size() != 4)) { PyErr_SetString(PyExc_TypeError, "Fourth argument must be a float array, size 4"); return 0; } std::vector matrix(16); std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_MatrixTransform_Sat(PyObject * /*self*/, PyObject * args) { OCIO_PYTRY_ENTER() float sat = 0.0; PyObject* pyluma = 0; if (!PyArg_ParseTuple(args,"fO:Sat", &sat, &pyluma)) return NULL; std::vector 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 matrix(16); std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_MatrixTransform_Scale(PyObject * /*self*/, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyscale = 0; if (!PyArg_ParseTuple(args,"O:Scale", &pyscale)) return NULL; std::vector 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 matrix(16); std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_MatrixTransform_View(PyObject * /*self*/, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pychannelhot = 0; PyObject* pyluma = 0; if (!PyArg_ParseTuple(args,"OO:View", &pychannelhot, &pyluma)) return NULL; std::vector channelhot; if(!FillIntVectorFromPySequence(pychannelhot, channelhot) || (channelhot.size() != 4)) { PyErr_SetString(PyExc_TypeError, "First argument must be a bool/int array, size 4"); return 0; } std::vector 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 matrix(16); std::vector 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; OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyCDLTransform.cpp0000644000175000017500000004725713223553423021714 0ustar mfvmfv/* 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 #include #include "PyUtil.h" #include "PyDoc.h" #define GetConstCDLTransform(pyobject) GetConstPyOCIO(pyobject, PyOCIO_CDLTransformType) #define GetEditableCDLTransform(pyobject) GetEditablePyOCIO(pyobject, PyOCIO_CDLTransformType) OCIO_NAMESPACE_ENTER { namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_CDLTransform_init(PyOCIO_Transform * self, PyObject * args, PyObject * kwds); PyObject * PyOCIO_CDLTransform_CreateFromFile(PyObject * self, PyObject * args); 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[] = { { "CreateFromFile", PyOCIO_CDLTransform_CreateFromFile, METH_VARARGS, CDLTRANSFORM_CREATEFROMFILE__DOC__ }, { "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 = { PyVarObject_HEAD_INIT(NULL, 0) OCIO_PYTHON_NAMESPACE(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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_CDLTransform_init(PyOCIO_Transform *self, PyObject* args, PyObject* kwds) { OCIO_PYTRY_ENTER() CDLTransformRcPtr ptr = CDLTransform::Create(); int ret = BuildPyTransformObject(self, ptr); PyObject* pyslope = NULL; PyObject* pyoffset = NULL; PyObject* pypower = NULL; float sat = -1.0; // -1.0 is an illegal value for saturation char* direction = NULL; char* id = NULL; char* description = NULL; static const char *kwlist[] = { "slope", "offset", "power", "sat", "direction", "id", "description", NULL }; if(!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOfsss", const_cast(kwlist), &pyslope, &pyoffset, &pypower, &sat, &direction, &id, &description)) return -1; if (pyslope) { std::vector slope; if(!FillFloatVectorFromPySequence(pyslope, slope) || (slope.size() != 3)) { PyErr_SetString(PyExc_TypeError, "slope must be a float array, size 3"); return 0; } ptr->setSlope(&slope[0]); } if (pyoffset) { std::vector offset; if(!FillFloatVectorFromPySequence(pyoffset, offset) || (offset.size() != 3)) { PyErr_SetString(PyExc_TypeError, "offset must be a float array, size 3"); return 0; } ptr->setOffset(&offset[0]); } if (pypower) { std::vector power; if(!FillFloatVectorFromPySequence(pypower, power) || (power.size() != 3)) { PyErr_SetString(PyExc_TypeError, "power must be a float array, size 3"); return 0; } ptr->setPower(&power[0]); } if(sat >= 0.0f) ptr->setSat(sat); if(direction) ptr->setDirection(TransformDirectionFromString(direction)); if(id) ptr->setID(id); if(id) ptr->setDescription(description); return ret; OCIO_PYTRY_EXIT(-1) } PyObject * PyOCIO_CDLTransform_CreateFromFile(PyObject * /*self*/, PyObject * args) { OCIO_PYTRY_ENTER() const char * src = 0; const char * cccid = 0; if (!PyArg_ParseTuple(args, "ss:CreateFromFile", &src, &cccid)) return NULL; return BuildEditablePyTransform(CDLTransform::CreateFromFile(src, cccid)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_equals(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyother = 0; if (!PyArg_ParseTuple(args, "O:equals", &pyother)) return NULL; ConstCDLTransformRcPtr transform = GetConstCDLTransform(self); if(IsPyOCIOType(pyother, PyOCIO_CDLTransformType)) return PyBool_FromLong(false); ConstCDLTransformRcPtr other = GetConstCDLTransform(pyother); return PyBool_FromLong(transform->equals(other)); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_getXML(PyObject * self) { OCIO_PYTRY_ENTER() ConstCDLTransformRcPtr transform = GetConstCDLTransform(self); return PyString_FromString(transform->getXML()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_setXML(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() const char* str = 0; if (!PyArg_ParseTuple(args, "s:setXML", &str)) return NULL; CDLTransformRcPtr transform = GetEditableCDLTransform(self); transform->setXML(str); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_getSlope(PyObject * self) { OCIO_PYTRY_ENTER() ConstCDLTransformRcPtr transform = GetConstCDLTransform(self); std::vector data(3); transform->getSlope(&data[0]); return CreatePyListFromFloatVector(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_getOffset(PyObject * self) { OCIO_PYTRY_ENTER() ConstCDLTransformRcPtr transform = GetConstCDLTransform(self); std::vector data(3); transform->getOffset(&data[0]); return CreatePyListFromFloatVector(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_getPower(PyObject * self) { OCIO_PYTRY_ENTER() ConstCDLTransformRcPtr transform = GetConstCDLTransform(self); std::vector data(3); transform->getPower(&data[0]); return CreatePyListFromFloatVector(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_getSOP(PyObject * self) { OCIO_PYTRY_ENTER() ConstCDLTransformRcPtr transform = GetConstCDLTransform(self); std::vector data(9); transform->getSOP(&data[0]); return CreatePyListFromFloatVector(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_getSat(PyObject * self) { OCIO_PYTRY_ENTER() ConstCDLTransformRcPtr transform = GetConstCDLTransform(self); return PyFloat_FromDouble(transform->getSat()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_setSlope(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyData = 0; if (!PyArg_ParseTuple(args, "O:setSlope", &pyData)) return NULL; CDLTransformRcPtr transform = GetEditableCDLTransform(self); std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_setOffset(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyData = 0; if (!PyArg_ParseTuple(args, "O:setOffset", &pyData)) return NULL; CDLTransformRcPtr transform = GetEditableCDLTransform(self); std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_setPower(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyData = 0; if (!PyArg_ParseTuple(args, "O:setPower", &pyData)) return NULL; CDLTransformRcPtr transform = GetEditableCDLTransform(self); std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_setSOP(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() PyObject* pyData = 0; if (!PyArg_ParseTuple(args, "O:setSOP", &pyData)) return NULL; CDLTransformRcPtr transform = GetEditableCDLTransform(self); std::vector 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; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_setSat(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() float sat; if (!PyArg_ParseTuple(args, "f:setSat", &sat)) return NULL; CDLTransformRcPtr transform = GetEditableCDLTransform(self); transform->setSat(sat); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_getSatLumaCoefs(PyObject * self) { OCIO_PYTRY_ENTER() ConstCDLTransformRcPtr transform = GetConstCDLTransform(self); std::vector data(3); transform->getSatLumaCoefs(&data[0]); return CreatePyListFromFloatVector(data); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_getID(PyObject * self) { OCIO_PYTRY_ENTER() ConstCDLTransformRcPtr transform = GetConstCDLTransform(self); return PyString_FromString(transform->getID()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_setID(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() const char* str = 0; if (!PyArg_ParseTuple(args, "s:setID", &str)) return NULL; CDLTransformRcPtr transform = GetEditableCDLTransform(self); transform->setID(str); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_getDescription(PyObject * self) { OCIO_PYTRY_ENTER() ConstCDLTransformRcPtr transform = GetConstCDLTransform(self); return PyString_FromString(transform->getDescription()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_CDLTransform_setDescription(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() const char* str = 0; if (!PyArg_ParseTuple(args, "s:setDescription", &str)) return NULL; CDLTransformRcPtr transform = GetEditableCDLTransform(self); transform->setDescription(str); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/pyglue/createPyDocH.py0000644000175000017500000000611613223553423021252 0ustar mfvmfv#!/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 = open(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 \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(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(GpuShaderDesc)) fileh.write("%s\n" % GetDocStrings(Baker)) 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() opencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/0000755000175000017500000000000013223553423017524 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/OpenColorIOTestSuite.py0000644000175000017500000000240313223553423024077 0ustar mfvmfv import unittest, os, sys sys.path.append(os.path.join(sys.argv[1], "src", "pyglue")) import PyOpenColorIO as OCIO from MainTest import * from ConstantsTest import * from ConfigTest import * from ContextTest import * from LookTest import * from ColorSpaceTest import * from GpuShaderDescTest import * from Baker import * from TransformsTest import * class FooTest(unittest.TestCase): def test_interface(self): pass def suite(): suite = unittest.TestSuite() suite.addTest(MainTest("test_interface")) suite.addTest(ConstantsTest("test_interface")) suite.addTest(ConfigTest("test_interface")) suite.addTest(ConfigTest("test_is_editable")) suite.addTest(ContextTest("test_interface")) suite.addTest(LookTest("test_interface")) suite.addTest(ColorSpaceTest("test_interface")) suite.addTest(TransformsTest("test_interface")) # Processor # ProcessorMetadata suite.addTest(GpuShaderDescTest("test_interface")) suite.addTest(BakerTest("test_interface")) # PackedImageDesc # PlanarImageDesc return suite if __name__ == '__main__': runner = unittest.TextTestRunner() test_suite = suite() result = runner.run(test_suite) if result.wasSuccessful() == False: sys.exit(1) sys.exit(0) opencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/GpuShaderDescTest.py0000644000175000017500000000116413223553423023421 0ustar mfvmfv import unittest, os, sys sys.path.append(os.path.join(sys.argv[1], "src", "pyglue")) import PyOpenColorIO as OCIO class GpuShaderDescTest(unittest.TestCase): def test_interface(self): desc = OCIO.GpuShaderDesc() desc.setLanguage(OCIO.Constants.GPU_LANGUAGE_GLSL_1_3) self.assertEqual(OCIO.Constants.GPU_LANGUAGE_GLSL_1_3, desc.getLanguage()) desc.setFunctionName("foo123") self.assertEqual("foo123", desc.getFunctionName()) desc.setLut3DEdgeLen(32) self.assertEqual(32, desc.getLut3DEdgeLen()) self.assertEqual("glsl_1.3 foo123 32", desc.getCacheID()) opencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/MainTest.py0000644000175000017500000000245313223553423021626 0ustar mfvmfv import unittest, os, sys sys.path.append(os.path.join(sys.argv[1], "src", "pyglue")) import PyOpenColorIO as OCIO class MainTest(unittest.TestCase): FOO ="""ocio_profile_version: 1 search_path: \"\" strictparsing: false luma: [0.2126, 0.7152, 0.0722] roles: default: raw displays: sRGB: - ! {name: Raw, colorspace: raw} active_displays: [] active_views: [] colorspaces: - ! name: raw family: raw equalitygroup: \"\" bitdepth: 32f description: | A raw color space. Conversions to and from this space are no-ops. isdata: true allocation: uniform """ def test_interface(self): OCIO.ClearAllCaches() #self.assertEqual("1.0.8", OCIO.version) #self.assertEqual(16779264, OCIO.hexversion) self.assertEqual(OCIO.Constants.LOGGING_LEVEL_INFO, OCIO.GetLoggingLevel()) OCIO.SetLoggingLevel(OCIO.Constants.LOGGING_LEVEL_NONE) self.assertEqual(OCIO.Constants.LOGGING_LEVEL_NONE, OCIO.GetLoggingLevel()) foo = OCIO.GetCurrentConfig() self.assertEqual(self.FOO, foo.serialize()) OCIO.SetLoggingLevel(OCIO.Constants.LOGGING_LEVEL_INFO) bar = OCIO.Config().CreateFromStream(foo.serialize()) OCIO.SetCurrentConfig(bar) wee = OCIO.GetCurrentConfig() opencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/CMakeLists.txt0000644000175000017500000000073213223553423022266 0ustar mfvmfv ############################################################################### ### PYTHON UNIT TESTS ### add_custom_target(PYTests COMMAND ${PYTHON} OpenColorIOTestSuite.py ${CMAKE_BINARY_DIR} DEPENDS PyOpenColorIO WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Setting Up and Running PYTHON OCIO UNIT tests") add_test(pyglue "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target PYTests)opencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/ContextTest.py0000644000175000017500000000275413223553423022372 0ustar mfvmfv import unittest, os, sys sys.path.append(os.path.join(sys.argv[1], "src", "pyglue")) import PyOpenColorIO as OCIO class ContextTest(unittest.TestCase): def test_interface(self): cont = OCIO.Context() cont.setSearchPath("testing123") cont.setWorkingDir("/dir/123") self.assertEqual("$4c2d66a612fc25ddd509591e1dead57b", cont.getCacheID()) self.assertEqual("testing123", cont.getSearchPath()) self.assertEqual("/dir/123", cont.getWorkingDir()) cont.setStringVar("TeSt", "foobar") self.assertEqual("foobar", cont.getStringVar("TeSt")) self.assertEqual(1, cont.getNumStringVars()) self.assertEqual("TeSt", cont.getStringVarNameByIndex(0)) cont.loadEnvironment() self.assertNotEqual(0, cont.getNumStringVars()) cont.setStringVar("TEST1", "foobar") self.assertEqual("/foo/foobar/bar", cont.resolveStringVar("/foo/${TEST1}/bar")) cont.clearStringVars() self.assertEqual(0, cont.getNumStringVars()) self.assertEqual(OCIO.Constants.ENV_ENVIRONMENT_LOAD_PREDEFINED, cont.getEnvironmentMode()) cont.setEnvironmentMode(OCIO.Constants.ENV_ENVIRONMENT_LOAD_ALL) self.assertEqual(OCIO.Constants.ENV_ENVIRONMENT_LOAD_ALL, cont.getEnvironmentMode()) try: cont.setSearchPath("testing123") foo = cont.resolveFileLocation("test.lut") print(foo) except OCIO.ExceptionMissingFile as e: #print e pass opencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/LookTest.py0000644000175000017500000000172513223553423021647 0ustar mfvmfv import unittest, os, sys sys.path.append(os.path.join(sys.argv[1], "src", "pyglue")) import PyOpenColorIO as OCIO class LookTest(unittest.TestCase): def test_interface(self): lk = OCIO.Look() lk.setName("coollook") self.assertEqual("coollook", lk.getName()) lk.setProcessSpace("somespace") self.assertEqual("somespace", lk.getProcessSpace()) lk.setDescription("this is a test") self.assertEqual("this is a test", lk.getDescription()) et = OCIO.ExponentTransform() et.setValue([0.1, 0.2, 0.3, 0.4]) lk.setTransform(et) oet = lk.getTransform() vals = oet.getValue() self.assertAlmostEqual(0.2, vals[1], delta=1e-8) iet = OCIO.ExponentTransform() iet.setValue([-0.1, -0.2, -0.3, -0.4]) lk.setInverseTransform(iet) ioet = lk.getInverseTransform() vals2 = ioet.getValue() self.assertAlmostEqual(-0.2, vals2[1], delta=1e-8) opencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/TransformsTest.py0000644000175000017500000003373513223553423023107 0ustar mfvmfv import unittest, os, sys sys.path.append(os.path.join(sys.argv[1], "src", "pyglue")) import PyOpenColorIO as OCIO class TransformsTest(unittest.TestCase): def test_interface(self): ### AllocationTransform ### at = OCIO.AllocationTransform() self.assertEqual(OCIO.Constants.ALLOCATION_UNIFORM, at.getAllocation()) at.setAllocation(OCIO.Constants.ALLOCATION_LG2) self.assertEqual(OCIO.Constants.ALLOCATION_LG2, at.getAllocation()) self.assertEqual(0, at.getNumVars()) at.setVars([0.1, 0.2, 0.3]) self.assertEqual(3, at.getNumVars()) newvars = at.getVars() self.assertAlmostEqual(0.2, newvars[1], delta=1e-8) at2 = OCIO.AllocationTransform(OCIO.Constants.ALLOCATION_LG2, [0.1, 0.2, 0.3], OCIO.Constants.TRANSFORM_DIR_INVERSE) self.assertEqual(OCIO.Constants.ALLOCATION_LG2, at2.getAllocation()) self.assertEqual(3, at2.getNumVars()) newvars2 = at2.getVars() for i in range(0, 3): self.assertAlmostEqual(float(i+1)/10.0, newvars2[i], delta=1e-7) self.assertEqual(OCIO.Constants.TRANSFORM_DIR_INVERSE, at2.getDirection()) at3 = OCIO.AllocationTransform(allocation=OCIO.Constants.ALLOCATION_LG2, vars=[0.1, 0.2, 0.3], direction=OCIO.Constants.TRANSFORM_DIR_INVERSE) self.assertEqual(OCIO.Constants.ALLOCATION_LG2, at3.getAllocation()) self.assertEqual(3, at3.getNumVars()) newvars3 = at3.getVars() for i in range(0, 3): self.assertAlmostEqual(float(i+1)/10.0, newvars3[i], delta=1e-7) self.assertEqual(OCIO.Constants.TRANSFORM_DIR_INVERSE, at3.getDirection()) ### Base Transform method tests ### self.assertEqual(OCIO.Constants.TRANSFORM_DIR_FORWARD, at.getDirection()) at.setDirection(OCIO.Constants.TRANSFORM_DIR_UNKNOWN) self.assertEqual(OCIO.Constants.TRANSFORM_DIR_UNKNOWN, at.getDirection()) ### CDLTransform ### cdl = OCIO.CDLTransform() CC = "" CC += "" CC += "this is a descipt" CC += "1.1 1.2 1.32.1 2.2 2.3" CC += "3.1 3.2 3.3" CC += "" CC += "" CC += "0.7" CC += "" CC += "" # Don't want to deal with getting the correct path so this runs #cdlfile = OCIO.CDLTransform().CreateFromFile("../OpenColorIO/src/jniglue/tests/org/OpenColorIO/test.cc", "foo") #self.assertEqual(CC, cdlfile.getXML()) cdl.setXML(CC) self.assertEqual(CC, cdl.getXML()) match = cdl.createEditableCopy() match.setOffset([1.0, 1.0, 1.0]) self.assertEqual(False, cdl.equals(match)) cdl.setSlope([0.1, 0.2, 0.3]) cdl.setOffset([1.1, 1.2, 1.3]) cdl.setPower([2.1, 2.2, 2.3]) cdl.setSat(0.5) CC2 = "" CC2 += "" CC2 += "this is a descipt" CC2 += "0.1 0.2 0.3" CC2 += "1.1 1.2 1.3" CC2 += "2.1 2.2 2.3" CC2 += "" CC2 += "" CC2 += "0.5" CC2 += """" self.assertEqual(CC2, cdl.getXML()) cdl.setSOP([1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9]) newsop = cdl.getSOP() self.assertAlmostEqual(1.5, newsop[4], delta=1e-8) slope = cdl.getSlope() self.assertAlmostEqual(1.2, slope[1], delta=1e-7) offset = cdl.getOffset() self.assertAlmostEqual(1.6, offset[2], delta=1e-7) power = cdl.getPower() self.assertAlmostEqual(1.7, power[0], delta=1e-7) self.assertAlmostEqual(0.5, cdl.getSat(), delta=1e-8) luma = cdl.getSatLumaCoefs() self.assertAlmostEqual(0.2126, luma[0], delta=1e-8) self.assertAlmostEqual(0.7152, luma[1], delta=1e-8) self.assertAlmostEqual(0.0722, luma[2], delta=1e-8) cdl.setID("foobar123") self.assertEqual("foobar123", cdl.getID()) cdl.setDescription("bar") self.assertEqual("bar", cdl.getDescription()) cdl2 = OCIO.CDLTransform([0.1, 0.2, 0.3], [1.1, 1.2, 1.3], [2.1, 2.2, 2.3], 0.5, OCIO.Constants.TRANSFORM_DIR_INVERSE, 'foobar123', 'bar') slope2 = cdl2.getSlope() offset2 = cdl2.getOffset() power2 = cdl2.getPower() luma2 = cdl2.getSatLumaCoefs() for i in range(0, 3): self.assertAlmostEqual(float(i+1)/10.0, slope2[i], delta=1e-7) self.assertAlmostEqual(float(i+1)/10.0+1, offset2[i], delta=1e-7) self.assertAlmostEqual(float(i+1)/10.0+2, power2[i], delta=1e-7) self.assertAlmostEqual(0.5, cdl2.getSat(), delta=1e-8) self.assertAlmostEqual(0.2126, luma2[0], delta=1e-8) self.assertAlmostEqual(0.7152, luma2[1], delta=1e-8) self.assertAlmostEqual(0.0722, luma2[2], delta=1e-8) self.assertEqual(OCIO.Constants.TRANSFORM_DIR_INVERSE, cdl2.getDirection()) self.assertEqual('foobar123', cdl2.getID()) self.assertEqual('bar', cdl2.getDescription()) cdl3 = OCIO.CDLTransform(slope=[0.1, 0.2, 0.3], offset=[1.1, 1.2, 1.3], power=[2.1, 2.2, 2.3], sat=0.5, direction=OCIO.Constants.TRANSFORM_DIR_INVERSE, id='foobar123', description='bar') slope3 = cdl2.getSlope() offset3 = cdl2.getOffset() power3 = cdl2.getPower() luma3 = cdl2.getSatLumaCoefs() for i in range(0, 3): self.assertAlmostEqual(float(i+1)/10.0, slope3[i], delta=1e-7) self.assertAlmostEqual(float(i+1)/10.0+1, offset3[i], delta=1e-7) self.assertAlmostEqual(float(i+1)/10.0+2, power3[i], delta=1e-7) self.assertAlmostEqual(0.5, cdl3.getSat(), delta=1e-8) self.assertAlmostEqual(0.2126, luma3[0], delta=1e-8) self.assertAlmostEqual(0.7152, luma3[1], delta=1e-8) self.assertAlmostEqual(0.0722, luma3[2], delta=1e-8) self.assertEqual(OCIO.Constants.TRANSFORM_DIR_INVERSE, cdl3.getDirection()) self.assertEqual('foobar123', cdl3.getID()) self.assertEqual('bar', cdl3.getDescription()) ### ColorSpaceTransform ### ct = OCIO.ColorSpaceTransform() ct.setSrc("foo") self.assertEqual("foo", ct.getSrc()) ct.setDst("bar") self.assertEqual("bar", ct.getDst()) ### DisplayTransform ### dt = OCIO.DisplayTransform() dt.setInputColorSpaceName("lin18") self.assertEqual("lin18", dt.getInputColorSpaceName()) dt.setLinearCC(ct) foo = dt.getLinearCC() dt.setColorTimingCC(cdl) blah = dt.getColorTimingCC() dt.setChannelView(at) wee = dt.getChannelView() dt.setDisplay("sRGB") self.assertEqual("sRGB", dt.getDisplay()) dt.setView("foobar") self.assertEqual("foobar", dt.getView()) cdl.setXML(CC) dt.setDisplayCC(cdl) cdldt = dt.getDisplayCC() self.assertEqual(CC, cdldt.getXML()) dt.setLooksOverride("darkgrade") self.assertEqual("darkgrade", dt.getLooksOverride()) dt.setLooksOverrideEnabled(True) self.assertEqual(True, dt.getLooksOverrideEnabled()) dt2 = OCIO.DisplayTransform("lin18", "sRGB", "foobar", OCIO.Constants.TRANSFORM_DIR_INVERSE) self.assertEqual("lin18", dt2.getInputColorSpaceName()) self.assertEqual("sRGB", dt2.getDisplay()) self.assertEqual("foobar", dt2.getView()) self.assertEqual(OCIO.Constants.TRANSFORM_DIR_INVERSE, dt2.getDirection()) dt3 = OCIO.DisplayTransform(inputColorSpaceName="lin18", display="sRGB", view="foobar", direction=OCIO.Constants.TRANSFORM_DIR_INVERSE) self.assertEqual("lin18", dt3.getInputColorSpaceName()) self.assertEqual("sRGB", dt3.getDisplay()) self.assertEqual("foobar", dt3.getView()) self.assertEqual(OCIO.Constants.TRANSFORM_DIR_INVERSE, dt3.getDirection()) ### ExponentTransform ### et = OCIO.ExponentTransform() et.setValue([0.1, 0.2, 0.3, 0.4]) evals = et.getValue() self.assertAlmostEqual(0.3, evals[2], delta=1e-7) ### FileTransform ### ft = OCIO.FileTransform() ft.setSrc("foo") self.assertEqual("foo", ft.getSrc()) ft.setCCCId("foobar") self.assertEqual("foobar", ft.getCCCId()) ft.setInterpolation(OCIO.Constants.INTERP_NEAREST) self.assertEqual(OCIO.Constants.INTERP_NEAREST, ft.getInterpolation()) self.assertEqual(17, ft.getNumFormats()) self.assertEqual("flame", ft.getFormatNameByIndex(0)) self.assertEqual("3dl", ft.getFormatExtensionByIndex(0)) ### GroupTransform ### gt = OCIO.GroupTransform() gt.push_back(et) gt.push_back(ft) self.assertEqual(2, gt.size()) self.assertEqual(False, gt.empty()) foo = gt.getTransform(0) self.assertEqual(OCIO.Constants.TRANSFORM_DIR_FORWARD, foo.getDirection()) gt.clear() self.assertEqual(0, gt.size()) ### LogTransform ### lt = OCIO.LogTransform() lt.setBase(10.0) self.assertEqual(10.0, lt.getBase()) ### LookTransform ### lkt = OCIO.LookTransform() lkt.setSrc("foo") self.assertEqual("foo", lkt.getSrc()) lkt.setDst("bar") self.assertEqual("bar", lkt.getDst()) lkt.setLooks("bar;foo") self.assertEqual("bar;foo", lkt.getLooks()) ### MatrixTransform ### mt = OCIO.MatrixTransform() mmt = mt.createEditableCopy() mt.setValue([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6], [0.1, 0.2, 0.3, 0.4]) self.assertEqual(False, mt.equals(mmt)) m44_1, offset_1 = mt.getValue() self.assertAlmostEqual(0.3, m44_1[2], delta=1e-7) self.assertAlmostEqual(0.2, offset_1[1], delta=1e-7) mt.setMatrix([1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6]) m44_2 = mt.getMatrix() self.assertAlmostEqual(1.3, m44_2[2], delta=1e-7) mt.setOffset([1.1, 1.2, 1.3, 1.4]) offset_2 = mt.getOffset() self.assertAlmostEqual(1.4, offset_2[3]) mt.Fit([0.1, 0.1, 0.1, 0.1], [0.9, 0.9, 0.9, 0.9], [0.0, 0.0, 0.0, 0.0], [1.1, 1.1, 1.1, 1.1]) m44_3 = mt.getMatrix() self.assertAlmostEqual(1.3, m44_3[2], delta=1e-7) m44_3, offset_2 = mt.Identity() self.assertAlmostEqual(0.0, m44_3[1], delta=1e-7) m44_2, offset_2 = mt.Sat(0.5, [0.2126, 0.7152, 0.0722]) self.assertAlmostEqual(0.3576, m44_2[1], delta=1e-7) m44_2, offset_2 = mt.Scale([0.9, 0.8, 0.7, 1.]) self.assertAlmostEqual(0.9, m44_2[0], delta=1e-7) m44_2, offset_2 = mt.View([1, 1, 1, 0], [0.2126, 0.7152, 0.0722]) self.assertAlmostEqual(0.0722, m44_2[2], delta=1e-7) mt4 = OCIO.MatrixTransform([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6], [0.1, 0.2, 0.3, 0.4], OCIO.Constants.TRANSFORM_DIR_INVERSE) m44_4, offset_4 = mt4.getValue() for i in range(0, 16): self.assertAlmostEqual(float(i+1)/10.0, m44_4[i], delta=1e-7) for i in range(0, 4): self.assertAlmostEqual(float(i+1)/10.0, offset_4[i], delta=1e-7) self.assertEqual(mt4.getDirection(), OCIO.Constants.TRANSFORM_DIR_INVERSE) mt5 = OCIO.MatrixTransform(matrix=[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6], offset=[0.1, 0.2, 0.3, 0.4], direction=OCIO.Constants.TRANSFORM_DIR_INVERSE) m44_5, offset_5 = mt5.getValue() for i in range(0, 16): self.assertAlmostEqual(float(i+1)/10.0, m44_5[i], delta=1e-7) for i in range(0, 4): self.assertAlmostEqual(float(i+1)/10.0, offset_5[i], delta=1e-7) self.assertEqual(mt5.getDirection(), OCIO.Constants.TRANSFORM_DIR_INVERSE) ### TruelightTransform ### """ tt = OCIO.TruelightTransform() tt.setConfigRoot("/some/path") self.assertEqual("/some/path", tt.getConfigRoot()) tt.setProfile("profileA") self.assertEqual("profileA", tt.getProfile()) tt.setCamera("incam") self.assertEqual("incam", tt.getCamera()) tt.setInputDisplay("dellmon") self.assertEqual("dellmon", tt.getInputDisplay()) tt.setRecorder("blah") self.assertEqual("blah", tt.getRecorder()) tt.setPrint("kodasomething") self.assertEqual("kodasomething", tt.getPrint()) tt.setLamp("foobar") self.assertEqual("foobar", tt.getLamp()) tt.setOutputCamera("somecam") self.assertEqual("somecam", tt.getOutputCamera()) tt.setDisplay("sRGB") self.assertEqual("sRGB", tt.getDisplay()) tt.setCubeInput("log") self.assertEqual("log", tt.getCubeInput()) """ opencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/Baker.py0000644000175000017500000000455013223553423021126 0ustar mfvmfv import unittest, os, sys sys.path.append(os.path.join(sys.argv[1], "src", "pyglue")) import PyOpenColorIO as OCIO class BakerTest(unittest.TestCase): SIMPLE_PROFILE = """ocio_profile_version: 1 strictparsing: false colorspaces: - ! name: lnh bitdepth: 16f isdata: false allocation: lg2 - ! name: test bitdepth: 8ui isdata: false allocation: uniform to_reference: ! {value: [2.2, 2.2, 2.2, 1]}""" EXPECTED_LUT = """CSPLUTV100 3D BEGIN METADATA this is some metadata! END METADATA 4 0.000977 0.039373 1.587401 64.000000 0.000000 0.333333 0.666667 1.000000 4 0.000977 0.039373 1.587401 64.000000 0.000000 0.333333 0.666667 1.000000 4 0.000977 0.039373 1.587401 64.000000 0.000000 0.333333 0.666667 1.000000 2 2 2 0.042823 0.042823 0.042823 6.622026 0.042823 0.042823 0.042823 6.622026 0.042823 6.622026 6.622026 0.042823 0.042823 0.042823 6.622026 6.622026 0.042823 6.622026 0.042823 6.622026 6.622026 6.622026 6.622026 6.622026 """ def test_interface(self): bake = OCIO.Baker() bakee = bake.createEditableCopy() cfg = OCIO.Config().CreateFromStream(self.SIMPLE_PROFILE) self.assertEqual(2, cfg.getNumColorSpaces()) bakee.setConfig(cfg) cfg2 = bakee.getConfig() self.assertEqual(2, cfg2.getNumColorSpaces()) bakee.setFormat("cinespace") self.assertEqual("cinespace", bakee.getFormat()) bakee.setType("3D") self.assertEqual("3D", bakee.getType()) bakee.setMetadata("this is some metadata!") self.assertEqual("this is some metadata!", bakee.getMetadata()) bakee.setInputSpace("lnh") self.assertEqual("lnh", bakee.getInputSpace()) bakee.setLooks("foo, +bar") self.assertEqual("foo, +bar", bakee.getLooks()) bakee.setLooks("") bakee.setTargetSpace("test") self.assertEqual("test", bakee.getTargetSpace()) bakee.setShaperSize(4) self.assertEqual(4, bakee.getShaperSize()) bakee.setCubeSize(2) self.assertEqual(2, bakee.getCubeSize()) output = bakee.bake() self.assertEqual(self.EXPECTED_LUT, output) self.assertEqual(6, bakee.getNumFormats()) self.assertEqual("cinespace", bakee.getFormatNameByIndex(2)) self.assertEqual("3dl", bakee.getFormatExtensionByIndex(1)) opencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/ColorSpaceTest.py0000644000175000017500000000240213223553423022766 0ustar mfvmfv import unittest, os, sys sys.path.append(os.path.join(sys.argv[1], "src", "pyglue")) import PyOpenColorIO as OCIO class ColorSpaceTest(unittest.TestCase): def test_interface(self): cs = OCIO.ColorSpace() cs.setName("mynewcolspace") self.assertEqual("mynewcolspace", cs.getName()) cs.setFamily("fam1") self.assertEqual("fam1", cs.getFamily()) cs.setEqualityGroup("match1") self.assertEqual("match1", cs.getEqualityGroup()) cs.setDescription("this is a test") self.assertEqual("this is a test", cs.getDescription()) cs.setBitDepth(OCIO.Constants.BIT_DEPTH_F16) self.assertEqual(OCIO.Constants.BIT_DEPTH_F16, cs.getBitDepth()) cs.setIsData(False) self.assertEqual(False, cs.isData()) cs.setAllocation(OCIO.Constants.ALLOCATION_LG2) self.assertEqual(OCIO.Constants.ALLOCATION_LG2, cs.getAllocation()) cs.setAllocationVars([0.1, 0.2, 0.3]) self.assertEqual(3, len(cs.getAllocationVars())) lt = OCIO.LogTransform() lt.setBase(10.0) cs.setTransform(lt, OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE) ott = cs.getTransform(OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE) self.assertEquals(10.0, ott.getBase()) opencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/ConfigTest.py0000644000175000017500000002350413223553423022147 0ustar mfvmfv import unittest, os, sys sys.path.append(os.path.join(sys.argv[1], "src", "pyglue")) import PyOpenColorIO as OCIO import platform osname = platform.system() class ConfigTest(unittest.TestCase): SIMPLE_PROFILE = """ocio_profile_version: 1 search_path: luts strictparsing: false luma: [0.2126, 0.7152, 0.0722] roles: default: raw scene_linear: lnh displays: sRGB: - ! {name: Film1D, colorspace: vd8} - ! {name: Raw, colorspace: raw} active_displays: [] active_views: [] colorspaces: - ! name: raw family: raw equalitygroup: "" bitdepth: 32f description: | A raw color space. Conversions to and from this space are no-ops. isdata: true allocation: uniform - ! name: lnh family: ln equalitygroup: "" bitdepth: 16f description: | The show reference space. This is a sensor referred linear representation of the scene with primaries that correspond to scanned film. 0.18 in this space corresponds to a properly exposed 18% grey card. isdata: false allocation: lg2 - ! name: vd8 family: vd8 equalitygroup: "" bitdepth: 8ui description: | how many transforms can we use? isdata: false allocation: uniform to_reference: ! children: - ! {value: [2.2, 2.2, 2.2, 1]} - ! {matrix: [1, 2, 3, 4, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], offset: [1, 2, 0, 0]} - ! {slope: [0.9, 1, 1], offset: [0.1, 0.3, 0.4], power: [1.1, 1.1, 1.1], sat: 0.9} """ def setUp(self): osx_hack = '' if osname=="Darwin": osx_hack = """ // OSX segfault work-around: Force a no-op sampling of the 3d lut. texture3D(lut3d, 0.96875 * out_pixel.rgb + 0.015625).rgb;""" self.GLSLResult = """ // Generated by OpenColorIO vec4 pytestocio(in vec4 inPixel, const sampler3D lut3d) { vec4 out_pixel = inPixel; out_pixel = out_pixel * mat4(1.08749, -0.0794667, -0.00802222, 0, -0.0236222, 1.03164, -0.00802222, 0, -0.0236222, -0.0794667, 1.10309, 0, 0, 0, 0, 1); out_pixel = pow(max(out_pixel, vec4(0, 0, 0, 0)), vec4(0.909091, 0.909091, 0.909091, 1)); out_pixel = out_pixel * mat4(1.11111, -2, -3, -4, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); out_pixel = vec4(4.68889, -2.3, -0.4, -0) + out_pixel; out_pixel = pow(max(out_pixel, vec4(0, 0, 0, 0)), vec4(0.454545, 0.454545, 0.454545, 1));""" \ + osx_hack + \ """ return out_pixel; } """ def test_is_editable(self): cfg = OCIO.Config().CreateFromStream(self.SIMPLE_PROFILE) self.assertEqual(cfg.isEditable(), False) cfg = cfg.createEditableCopy() self.assertEqual(cfg.isEditable(), True) ctx = cfg.getCurrentContext() self.assertEqual(ctx.isEditable(), False) ctx = ctx.createEditableCopy() self.assertEqual(ctx.isEditable(), True) ctx.setEnvironmentMode(OCIO.Constants.ENV_ENVIRONMENT_LOAD_ALL) def test_interface(self): _cfg = OCIO.Config().CreateFromStream(self.SIMPLE_PROFILE) _cfge = _cfg.createEditableCopy() _cfge.clearEnvironmentVars() self.assertEqual(0, _cfge.getNumEnvironmentVars()) _cfge.addEnvironmentVar("FOO", "test1") _cfge.addEnvironmentVar("FOO2", "test2${FOO}") self.assertEqual(2, _cfge.getNumEnvironmentVars()) self.assertEqual("FOO", _cfge.getEnvironmentVarNameByIndex(0)) self.assertEqual("FOO2", _cfge.getEnvironmentVarNameByIndex(1)) self.assertEqual("test1", _cfge.getEnvironmentVarDefault("FOO")) self.assertEqual("test2${FOO}", _cfge.getEnvironmentVarDefault("FOO2")) self.assertEqual("test2test1", _cfge.getCurrentContext().resolveStringVar("${FOO2}")) self.assertEqual({'FOO': 'test1', 'FOO2': 'test2${FOO}'}, _cfge.getEnvironmentVarDefaults()) _cfge.clearEnvironmentVars() self.assertEqual(0, _cfge.getNumEnvironmentVars()) self.assertEqual("luts", _cfge.getSearchPath()) _cfge.setSearchPath("otherdir") self.assertEqual("otherdir", _cfge.getSearchPath()) _cfge.sanityCheck() _cfge.setDescription("testdesc") self.assertEqual("testdesc", _cfge.getDescription()) self.assertEqual(self.SIMPLE_PROFILE, _cfg.serialize()) #self.assertEqual("$07d1fb1509eeae1837825fd4242f8a69:$885ad1683add38a11f7bbe34e8bf9ac0", # _cfg.getCacheID()) con = _cfg.getCurrentContext() self.assertNotEqual(0, con.getNumStringVars()) #self.assertEqual("", _cfg.getCacheID(con)) #self.assertEqual("", _cfge.getWorkingDir()) _cfge.setWorkingDir("/foobar") self.assertEqual("/foobar", _cfge.getWorkingDir()) self.assertEqual(3, _cfge.getNumColorSpaces()) self.assertEqual("lnh", _cfge.getColorSpaceNameByIndex(1)) lnh = _cfge.getColorSpace("lnh") self.assertEqual("ln", lnh.getFamily()) self.assertEqual(0, _cfge.getIndexForColorSpace("foobar")) cs = OCIO.ColorSpace() cs.setName("blah") _cfge.addColorSpace(cs) self.assertEqual(3, _cfge.getIndexForColorSpace("blah")) #_cfge.clearColorSpaces() #_cfge.parseColorSpaceFromString("foo") self.assertEqual(False, _cfg.isStrictParsingEnabled()) _cfge.setStrictParsingEnabled(True) self.assertEqual(True, _cfge.isStrictParsingEnabled()) self.assertEqual(2, _cfge.getNumRoles()) self.assertEqual(False, _cfg.hasRole("foo")) _cfge.setRole("foo", "vd8") self.assertEqual(3, _cfge.getNumRoles()) self.assertEqual(True, _cfge.hasRole("foo")) self.assertEqual("foo", _cfge.getRoleName(1)) self.assertEqual("sRGB", _cfge.getDefaultDisplay()) self.assertEqual(1, _cfge.getNumDisplays()) self.assertEqual("sRGB", _cfge.getDisplay(0)) self.assertEqual("Film1D", _cfge.getDefaultView("sRGB")) self.assertEqual(2, _cfge.getNumViews("sRGB")) self.assertEqual("Raw", _cfge.getView("sRGB", 1)) self.assertEqual("vd8", _cfge.getDisplayColorSpaceName("sRGB", "Film1D")) self.assertEqual("", _cfg.getDisplayLooks("sRGB", "Film1D")) _cfge.addDisplay("foo", "bar", "foo", "wee") _cfge.clearDisplays() _cfge.setActiveDisplays("sRGB") self.assertEqual("sRGB", _cfge.getActiveDisplays()) _cfge.setActiveViews("Film1D") self.assertEqual("Film1D", _cfge.getActiveViews()) luma = _cfge.getDefaultLumaCoefs() self.assertAlmostEqual(0.2126, luma[0], delta=1e-8) _cfge.setDefaultLumaCoefs([0.1, 0.2, 0.3]) tnewluma = _cfge.getDefaultLumaCoefs() self.assertAlmostEqual(0.1, tnewluma[0], delta=1e-8) self.assertEqual(0, _cfge.getNumLooks()) lk = OCIO.Look() lk.setName("coollook") lk.setProcessSpace("somespace") et = OCIO.ExponentTransform() et.setValue([0.1, 0.2, 0.3, 0.4]) lk.setTransform(et) iet = OCIO.ExponentTransform() iet.setValue([-0.1, -0.2, -0.3, -0.4]) lk.setInverseTransform(iet) _cfge.addLook(lk) self.assertEqual(1, _cfge.getNumLooks()) self.assertEqual("coollook", _cfge.getLookNameByIndex(0)) glk = _cfge.getLook("coollook") self.assertEqual("somespace", glk.getProcessSpace()) _cfge.clearLooks() self.assertEqual(0, _cfge.getNumLooks()) #getProcessor(context, srcColorSpace, dstColorSpace) #getProcessor(context, srcName,dstName); #getProcessor(transform); #getProcessor(transform, direction); #getProcessor(context, transform, direction); _proc = _cfg.getProcessor("lnh", "vd8") self.assertEqual(False, _proc.isNoOp()) self.assertEqual(True, _proc.hasChannelCrosstalk()) #float packedpix[] = new float[]{0.48f, 0.18f, 0.9f, 1.0f, # 0.48f, 0.18f, 0.18f, 1.0f, # 0.48f, 0.18f, 0.18f, 1.0f, # 0.48f, 0.18f, 0.18f, 1.0f }; #FloatBuffer buf = ByteBuffer.allocateDirect(2 * 2 * 4 * Float.SIZE / 8).asFloatBuffer(); #buf.put(packedpix); #PackedImageDesc foo = new PackedImageDesc(buf, 2, 2, 4); #_proc.apply(foo); #FloatBuffer wee = foo.getData(); #self.assertEqual(-2.4307251581696764E-35f, wee.get(2), 1e-8); # TODO: these should work in-place rgbfoo = _proc.applyRGB([0.48, 0.18, 0.18]) self.assertAlmostEqual(1.9351075, rgbfoo[0], delta=1e-7); # TODO: these should work in-place rgbafoo = _proc.applyRGBA([0.48, 0.18, 0.18, 1.0]) self.assertAlmostEqual(1.0, rgbafoo[3], delta=1e-8) #self.assertEqual("$a92ef63abd9edf61ad5a7855da064648", _proc.getCpuCacheID()) desc = OCIO.GpuShaderDesc() desc.setLanguage(OCIO.Constants.GPU_LANGUAGE_GLSL_1_3) desc.setFunctionName("pytestocio") desc.setLut3DEdgeLen(32) glsl = _proc.getGpuShaderText(desc) self.assertEqual(self.GLSLResult, glsl) # old DEPRECIATED GpuShaderDesc dict support desc2 = {"language": OCIO.Constants.GPU_LANGUAGE_GLSL_1_3, "functionName": "pytestocio", "lut3DEdgeLen": 32} glsl = _proc.getGpuShaderText(desc2) self.assertEqual(self.GLSLResult, glsl) #self.assertEqual("$1dead2bf42974cd1769164e45a0c9e40", _proc.getGpuShaderTextCacheID(desc)) #self.assertEqual("$1dead2bf42974cd1769164e45a0c9e40", _proc.getGpuShaderTextCacheID(desc2)) len = desc.getLut3DEdgeLen() size = 3 * len * len * len self.assertEqual(0.0, _proc.getGpuLut3D(desc2)[size-1]); self.assertEqual("", _proc.getGpuLut3DCacheID(desc)) self.assertEqual("", _proc.getGpuLut3DCacheID(desc2)) del _cfge del _cfg opencolorio-1.1.0~dfsg0.orig/src/pyglue/tests/ConstantsTest.py0000644000175000017500000000777313223553423022730 0ustar mfvmfv import unittest, os, sys sys.path.append(os.path.join(sys.argv[1], "src", "pyglue")) import PyOpenColorIO as OCIO class ConstantsTest(unittest.TestCase): def test_interface(self): # LoggingLevel self.assertEqual(OCIO.Constants.LOGGING_LEVEL_NONE, "none") self.assertEqual(OCIO.Constants.LOGGING_LEVEL_WARNING, "warning") self.assertEqual(OCIO.Constants.LOGGING_LEVEL_INFO, "info") self.assertEqual(OCIO.Constants.LOGGING_LEVEL_DEBUG, "debug") self.assertEqual(OCIO.Constants.LOGGING_LEVEL_UNKNOWN, "unknown") # TransformDirection self.assertEqual(OCIO.Constants.TRANSFORM_DIR_UNKNOWN, "unknown") self.assertEqual(OCIO.Constants.TRANSFORM_DIR_FORWARD, "forward") self.assertEqual(OCIO.Constants.TRANSFORM_DIR_INVERSE, "inverse") self.assertEqual(OCIO.Constants.GetInverseTransformDirection(OCIO.Constants.TRANSFORM_DIR_UNKNOWN), OCIO.Constants.TRANSFORM_DIR_UNKNOWN) self.assertEqual(OCIO.Constants.GetInverseTransformDirection(OCIO.Constants.TRANSFORM_DIR_FORWARD), OCIO.Constants.TRANSFORM_DIR_INVERSE) self.assertEqual(OCIO.Constants.GetInverseTransformDirection(OCIO.Constants.TRANSFORM_DIR_INVERSE), OCIO.Constants.TRANSFORM_DIR_FORWARD) # ColorSpaceDirection self.assertEqual(OCIO.Constants.COLORSPACE_DIR_UNKNOWN, "unknown") self.assertEqual(OCIO.Constants.COLORSPACE_DIR_TO_REFERENCE, "to_reference") self.assertEqual(OCIO.Constants.COLORSPACE_DIR_FROM_REFERENCE, "from_reference") # BitDepth self.assertEqual(OCIO.Constants.BIT_DEPTH_UNKNOWN, "unknown") self.assertEqual(OCIO.Constants.BIT_DEPTH_UINT8, "8ui") self.assertEqual(OCIO.Constants.BIT_DEPTH_UINT10, "10ui") self.assertEqual(OCIO.Constants.BIT_DEPTH_UINT12, "12ui") self.assertEqual(OCIO.Constants.BIT_DEPTH_UINT14, "14ui") self.assertEqual(OCIO.Constants.BIT_DEPTH_UINT16, "16ui") self.assertEqual(OCIO.Constants.BIT_DEPTH_UINT32, "32ui") self.assertEqual(OCIO.Constants.BIT_DEPTH_F16, "16f") self.assertEqual(OCIO.Constants.BIT_DEPTH_F32, "32f") # Allocation self.assertEqual(OCIO.Constants.ALLOCATION_UNKNOWN, "unknown") self.assertEqual(OCIO.Constants.ALLOCATION_UNIFORM, "uniform") self.assertEqual(OCIO.Constants.ALLOCATION_LG2, "lg2") # Interpolation self.assertEqual(OCIO.Constants.INTERP_UNKNOWN, "unknown") self.assertEqual(OCIO.Constants.INTERP_NEAREST, "nearest") self.assertEqual(OCIO.Constants.INTERP_LINEAR, "linear") self.assertEqual(OCIO.Constants.INTERP_TETRAHEDRAL, "tetrahedral") self.assertEqual(OCIO.Constants.INTERP_BEST, "best") # GpuLanguage self.assertEqual(OCIO.Constants.GPU_LANGUAGE_UNKNOWN, "unknown") self.assertEqual(OCIO.Constants.GPU_LANGUAGE_CG, "cg") self.assertEqual(OCIO.Constants.GPU_LANGUAGE_GLSL_1_0, "glsl_1.0") self.assertEqual(OCIO.Constants.GPU_LANGUAGE_GLSL_1_3, "glsl_1.3") # EnvironmentMode self.assertEqual(OCIO.Constants.ENV_ENVIRONMENT_UNKNOWN, "unknown") self.assertEqual(OCIO.Constants.ENV_ENVIRONMENT_LOAD_PREDEFINED, "loadpredefined") self.assertEqual(OCIO.Constants.ENV_ENVIRONMENT_LOAD_ALL, "loadall") # Roles self.assertEqual(OCIO.Constants.ROLE_DEFAULT, "default") self.assertEqual(OCIO.Constants.ROLE_REFERENCE, "reference") self.assertEqual(OCIO.Constants.ROLE_DATA, "data") self.assertEqual(OCIO.Constants.ROLE_COLOR_PICKING, "color_picking") self.assertEqual(OCIO.Constants.ROLE_SCENE_LINEAR, "scene_linear") self.assertEqual(OCIO.Constants.ROLE_COMPOSITING_LOG, "compositing_log") self.assertEqual(OCIO.Constants.ROLE_COLOR_TIMING, "color_timing") self.assertEqual(OCIO.Constants.ROLE_TEXTURE_PAINT, "texture_paint") self.assertEqual(OCIO.Constants.ROLE_MATTE_PAINT, "matte_paint") opencolorio-1.1.0~dfsg0.orig/src/pyglue/PyColorSpaceTransform.cpp0000644000175000017500000002063413223553423023332 0ustar mfvmfv/* 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 #include #include "PyUtil.h" #include "PyDoc.h" #define GetConstColorSpaceTransform(pyobject) GetConstPyOCIO(pyobject, \ PyOCIO_ColorSpaceTransformType) #define GetEditableColorSpaceTransform(pyobject) GetEditablePyOCIO(pyobject, \ PyOCIO_ColorSpaceTransformType); OCIO_NAMESPACE_ENTER { 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 = { PyVarObject_HEAD_INIT(NULL, 0) OCIO_PYTHON_NAMESPACE(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 }; namespace { /////////////////////////////////////////////////////////////////////// /// int PyOCIO_ColorSpaceTransform_init(PyOCIO_Transform * self, PyObject * args, PyObject * kwds) { OCIO_PYTRY_ENTER() ColorSpaceTransformRcPtr ptr = ColorSpaceTransform::Create(); int ret = BuildPyTransformObject(self, ptr); 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(kwlist), &src, &dst, &direction)) return -1; if(src) ptr->setSrc(src); if(dst) ptr->setDst(dst); if(direction) ptr->setDirection(TransformDirectionFromString(direction)); return ret; OCIO_PYTRY_EXIT(-1) } PyObject * PyOCIO_ColorSpaceTransform_getSrc(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceTransformRcPtr transform = GetConstColorSpaceTransform(self); return PyString_FromString(transform->getSrc()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpaceTransform_setSrc(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() const char* str = 0; if (!PyArg_ParseTuple(args, "s:setSrc", &str)) return NULL; ColorSpaceTransformRcPtr transform = GetEditableColorSpaceTransform(self); transform->setSrc(str); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpaceTransform_getDst(PyObject * self) { OCIO_PYTRY_ENTER() ConstColorSpaceTransformRcPtr transform = GetConstColorSpaceTransform(self); return PyString_FromString(transform->getDst()); OCIO_PYTRY_EXIT(NULL) } PyObject * PyOCIO_ColorSpaceTransform_setDst(PyObject * self, PyObject * args) { OCIO_PYTRY_ENTER() const char* str = 0; if (!PyArg_ParseTuple(args, "s:setDst", &str)) return NULL; ColorSpaceTransformRcPtr transform = GetEditableColorSpaceTransform(self); transform->setDst(str); Py_RETURN_NONE; OCIO_PYTRY_EXIT(NULL) } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/0000755000175000017500000000000013223553423016005 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/core/CDLTransform.h0000644000175000017500000000424413223553423020460 0ustar mfvmfv/* 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_OCIO_CDLTRANSFORM_H #define INCLUDED_OCIO_CDLTRANSFORM_H #include #include #include #include OCIO_NAMESPACE_ENTER { typedef std::map CDLTransformMap; typedef std::vector CDLTransformVec; void ClearCDLTransformFileCache(); void LoadCDL(CDLTransform * cdl, const char * xml); void LoadCDL(CDLTransform * cdl, TiXmlElement * root); void GetCDLTransforms(CDLTransformMap & transformMap, CDLTransformVec & transformVec, TiXmlElement * cccroot); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/OCIOYaml.cpp0000644000175000017500000020151113223553423020065 0ustar mfvmfv/* 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 #include #ifndef WIN32 // fwd declare yaml-cpp visibility #pragma GCC visibility push(hidden) namespace YAML { class Exception; class BadDereference; class RepresentationException; class EmitterException; class ParserException; class InvalidScalar; class KeyNotFound; template class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; template <> class TypedKeyNotFound; } #pragma GCC visibility pop #endif #ifdef WIN32 #pragma warning( push ) #pragma warning( disable: 4146 ) #endif #include #ifdef WIN32 #pragma warning( pop ) #endif #include "Logging.h" #include "MathUtils.h" #include "pystring/pystring.h" #include "PathUtils.h" #include "ParseUtils.h" #include "Display.h" #include "OCIOYaml.h" OCIO_NAMESPACE_ENTER { namespace { #ifdef OLDYAML typedef YAML::Iterator Iterator; #else typedef YAML::const_iterator Iterator; #endif // Iterator access // Note: The ownership semantics have changed between yaml-cpp 0.3.x and 0.5.x . // Returning a const reference to a yaml node screws with the internal yaml-cpp smart ptr // implementation in the newer version. Luckily, the compiler does not care if we maintain // const YAML::Node & = get_first(iter) syntax at the call site even when returning an actual object // (instead of the reference as expected). #ifdef OLDYAML inline const YAML::Node& get_first(const Iterator &it) { return it.first(); } #else inline YAML::Node get_first(const Iterator &it) { return it->first; } #endif #ifdef OLDYAML inline const YAML::Node& get_second(const Iterator &it) { return it.second(); } #else inline YAML::Node get_second(const Iterator &it) { return it->second; } #endif // Basic types inline void load(const YAML::Node& node, bool& x) { #ifdef OLDYAML node.Read(x); #else x = node.as(); #endif } inline void load(const YAML::Node& node, int& x) { #ifdef OLDYAML node.Read(x); #else x = node.as(); #endif } inline void load(const YAML::Node& node, float& x) { #ifdef OLDYAML node.Read(x); #else x = node.as(); #endif } inline void load(const YAML::Node& node, std::string& x) { #ifdef OLDYAML node.Read(x); #else x = node.as(); #endif } inline void load(const YAML::Node& node, std::vector& x) { #ifdef OLDYAML node >> x; #else x = node.as >(); #endif } inline void load(const YAML::Node& node, std::vector& x) { #ifdef OLDYAML node >> x; #else x = node.as >(); #endif } // Enums inline void load(const YAML::Node& node, BitDepth& depth) { std::string str; load(node, str); depth = BitDepthFromString(str.c_str()); } inline void save(YAML::Emitter& out, BitDepth depth) { out << BitDepthToString(depth); } inline void load(const YAML::Node& node, Allocation& alloc) { std::string str; load(node, str); alloc = AllocationFromString(str.c_str()); } inline void save(YAML::Emitter& out, Allocation alloc) { out << AllocationToString(alloc); } inline void load(const YAML::Node& node, ColorSpaceDirection& dir) { std::string str; load(node, str); dir = ColorSpaceDirectionFromString(str.c_str()); } inline void save(YAML::Emitter& out, ColorSpaceDirection dir) { out << ColorSpaceDirectionToString(dir); } inline void load(const YAML::Node& node, TransformDirection& dir) { std::string str; load(node, str); dir = TransformDirectionFromString(str.c_str()); } inline void save(YAML::Emitter& out, TransformDirection dir) { out << TransformDirectionToString(dir); } inline void load(const YAML::Node& node, Interpolation& interp) { std::string str; load(node, str); interp = InterpolationFromString(str.c_str()); } inline void save(YAML::Emitter& out, Interpolation interp) { out << InterpolationToString(interp); } // inline void LogUnknownKeyWarning(const std::string & name, const YAML::Node& tag) { std::string key; load(tag, key); std::ostringstream os; os << "Unknown key in " << name << ": '" << key << "'."; LogWarning(os.str()); } // View inline void load(const YAML::Node& node, View& v) { if(node.Tag() != "View") return; std::string key, stringval; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "name") { load(second, stringval); v.name = stringval; } else if(key == "colorspace") { load(second, stringval); v.colorspace = stringval; } else if(key == "looks" || key == "look") { load(second, stringval); v.looks = stringval; } else { LogUnknownKeyWarning(node.Tag(), first); } } if(v.name.empty()) { throw Exception("View does not specify 'name'."); } if(v.colorspace.empty()) { std::ostringstream os; os << "View '" << v.name << "' "; os << "does not specify colorspace."; throw Exception(os.str().c_str()); } } inline void save(YAML::Emitter& out, View view) { out << YAML::VerbatimTag("View"); out << YAML::Flow; out << YAML::BeginMap; out << YAML::Key << "name" << YAML::Value << view.name; out << YAML::Key << "colorspace" << YAML::Value << view.colorspace; if(!view.looks.empty()) out << YAML::Key << "looks" << YAML::Value << view.looks; out << YAML::EndMap; } // Common Transform inline void EmitBaseTransformKeyValues(YAML::Emitter & out, const ConstTransformRcPtr & t) { if(t->getDirection() != TRANSFORM_DIR_FORWARD) { out << YAML::Key << "direction"; out << YAML::Value << YAML::Flow; save(out, t->getDirection()); } } // AllocationTransform inline void load(const YAML::Node& node, AllocationTransformRcPtr& t) { t = AllocationTransform::Create(); std::string key; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "allocation") { Allocation val; load(second, val); t->setAllocation(val); } else if(key == "vars") { std::vector val; load(second, val); if(!val.empty()) { t->setVars(static_cast(val.size()), &val[0]); } } else if(key == "direction") { TransformDirection val; load(second, val); t->setDirection(val); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstAllocationTransformRcPtr t) { out << YAML::VerbatimTag("AllocationTransform"); out << YAML::Flow << YAML::BeginMap; out << YAML::Key << "allocation"; out << YAML::Value << YAML::Flow; save(out, t->getAllocation()); if(t->getNumVars() > 0) { std::vector vars(t->getNumVars()); t->getVars(&vars[0]); out << YAML::Key << "vars"; out << YAML::Flow << YAML::Value << vars; } EmitBaseTransformKeyValues(out, t); out << YAML::EndMap; } // CDLTransform inline void load(const YAML::Node& node, CDLTransformRcPtr& t) { t = CDLTransform::Create(); std::string key; std::vector floatvecval; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "slope") { load(second, floatvecval); if(floatvecval.size() != 3) { std::ostringstream os; os << "CDLTransform parse error, 'slope' field must be 3 "; os << "floats. Found '" << floatvecval.size() << "'."; throw Exception(os.str().c_str()); } t->setSlope(&floatvecval[0]); } else if(key == "offset") { load(second, floatvecval); if(floatvecval.size() != 3) { std::ostringstream os; os << "CDLTransform parse error, 'offset' field must be 3 "; os << "floats. Found '" << floatvecval.size() << "'."; throw Exception(os.str().c_str()); } t->setOffset(&floatvecval[0]); } else if(key == "power") { load(second, floatvecval); if(floatvecval.size() != 3) { std::ostringstream os; os << "CDLTransform parse error, 'power' field must be 3 "; os << "floats. Found '" << floatvecval.size() << "'."; throw Exception(os.str().c_str()); } t->setPower(&floatvecval[0]); } else if(key == "saturation" || key == "sat") { float val = 0.0f; load(second, val); t->setSat(val); } else if(key == "direction") { TransformDirection val; load(second, val); t->setDirection(val); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstCDLTransformRcPtr t) { out << YAML::VerbatimTag("CDLTransform"); out << YAML::Flow << YAML::BeginMap; std::vector slope(3); t->getSlope(&slope[0]); if(!IsVecEqualToOne(&slope[0], 3)) { out << YAML::Key << "slope"; out << YAML::Value << YAML::Flow << slope; } std::vector offset(3); t->getOffset(&offset[0]); if(!IsVecEqualToZero(&offset[0], 3)) { out << YAML::Key << "offset"; out << YAML::Value << YAML::Flow << offset; } std::vector power(3); t->getPower(&power[0]); if(!IsVecEqualToOne(&power[0], 3)) { out << YAML::Key << "power"; out << YAML::Value << YAML::Flow << power; } if(!IsScalarEqualToOne(t->getSat())) { out << YAML::Key << "sat" << YAML::Value << t->getSat(); } EmitBaseTransformKeyValues(out, t); out << YAML::EndMap; } // ColorSpaceTransform inline void load(const YAML::Node& node, ColorSpaceTransformRcPtr& t) { t = ColorSpaceTransform::Create(); std::string key, stringval; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "src") { load(second, stringval); t->setSrc(stringval.c_str()); } else if(key == "dst") { load(second, stringval); t->setDst(stringval.c_str()); } else if(key == "direction") { TransformDirection val; load(second, val); t->setDirection(val); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstColorSpaceTransformRcPtr t) { out << YAML::VerbatimTag("ColorSpaceTransform"); out << YAML::Flow << YAML::BeginMap; out << YAML::Key << "src" << YAML::Value << t->getSrc(); out << YAML::Key << "dst" << YAML::Value << t->getDst(); EmitBaseTransformKeyValues(out, t); out << YAML::EndMap; } // ExponentTransform inline void load(const YAML::Node& node, ExponentTransformRcPtr& t) { t = ExponentTransform::Create(); std::string key; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "value") { std::vector val; load(second, val); if(val.size() != 4) { std::ostringstream os; os << "ExponentTransform parse error, value field must be 4 "; os << "floats. Found '" << val.size() << "'."; throw Exception(os.str().c_str()); } t->setValue(&val[0]); } else if(key == "direction") { TransformDirection val; load(second, val); t->setDirection(val); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstExponentTransformRcPtr t) { out << YAML::VerbatimTag("ExponentTransform"); out << YAML::Flow << YAML::BeginMap; std::vector value(4, 0.0); t->getValue(&value[0]); out << YAML::Key << "value"; out << YAML::Value << YAML::Flow << value; EmitBaseTransformKeyValues(out, t); out << YAML::EndMap; } // FileTransform inline void load(const YAML::Node& node, FileTransformRcPtr& t) { t = FileTransform::Create(); std::string key, stringval; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "src") { load(second, stringval); t->setSrc(stringval.c_str()); } else if(key == "cccid") { load(second, stringval); t->setCCCId(stringval.c_str()); } else if(key == "interpolation") { Interpolation val; load(second, val); t->setInterpolation(val); } else if(key == "direction") { TransformDirection val; load(second, val); t->setDirection(val); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstFileTransformRcPtr t) { out << YAML::VerbatimTag("FileTransform"); out << YAML::Flow << YAML::BeginMap; out << YAML::Key << "src" << YAML::Value << t->getSrc(); const char * cccid = t->getCCCId(); if(cccid && *cccid) { out << YAML::Key << "cccid" << YAML::Value << t->getCCCId(); } out << YAML::Key << "interpolation"; out << YAML::Value; save(out, t->getInterpolation()); EmitBaseTransformKeyValues(out, t); out << YAML::EndMap; } // GroupTransform void load(const YAML::Node& node, TransformRcPtr& t); void save(YAML::Emitter& out, ConstTransformRcPtr t); inline void load(const YAML::Node& node, GroupTransformRcPtr& t) { t = GroupTransform::Create(); std::string key; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "children") { for(unsigned i = 0; i < second.size(); ++i) { TransformRcPtr childTransform; load(second[i], childTransform); // TODO: consider the forwards-compatibility implication of // throwing an exception. Should this be a warning, instead? if(!childTransform) { throw Exception("Child transform could not be parsed."); } t->push_back(childTransform); } } else if(key == "direction") { TransformDirection val; load(second, val); t->setDirection(val); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstGroupTransformRcPtr t) { out << YAML::VerbatimTag("GroupTransform"); out << YAML::BeginMap; EmitBaseTransformKeyValues(out, t); out << YAML::Key << "children"; out << YAML::Value; out << YAML::BeginSeq; for(int i = 0; i < t->size(); ++i) { save(out, t->getTransform(i)); } out << YAML::EndSeq; out << YAML::EndMap; } // LogTransform inline void load(const YAML::Node& node, LogTransformRcPtr& t) { t = LogTransform::Create(); std::string key; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "base") { float val = 0.0f; load(second, val); t->setBase(val); } else if(key == "direction") { TransformDirection val; load(second, val); t->setDirection(val); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstLogTransformRcPtr t) { out << YAML::VerbatimTag("LogTransform"); out << YAML::Flow << YAML::BeginMap; out << YAML::Key << "base" << YAML::Value << t->getBase(); EmitBaseTransformKeyValues(out, t); out << YAML::EndMap; } // LookTransform inline void load(const YAML::Node& node, LookTransformRcPtr& t) { t = LookTransform::Create(); std::string key, stringval; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "src") { load(second, stringval); t->setSrc(stringval.c_str()); } else if(key == "dst") { load(second, stringval); t->setDst(stringval.c_str()); } else if(key == "looks") { load(second, stringval); t->setLooks(stringval.c_str()); } else if(key == "direction") { TransformDirection val; load(second, val); t->setDirection(val); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstLookTransformRcPtr t) { out << YAML::VerbatimTag("LookTransform"); out << YAML::Flow << YAML::BeginMap; out << YAML::Key << "src" << YAML::Value << t->getSrc(); out << YAML::Key << "dst" << YAML::Value << t->getDst(); out << YAML::Key << "looks" << YAML::Value << t->getLooks(); EmitBaseTransformKeyValues(out, t); out << YAML::EndMap; } // MatrixTransform inline void load(const YAML::Node& node, MatrixTransformRcPtr& t) { t = MatrixTransform::Create(); std::string key; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "matrix") { std::vector val; load(second, val); if(val.size() != 16) { std::ostringstream os; os << "MatrixTransform parse error, matrix field must be 16 "; os << "floats. Found '" << val.size() << "'."; throw Exception(os.str().c_str()); } t->setMatrix(&val[0]); } else if(key == "offset") { std::vector val; load(second, val); if(val.size() != 4) { std::ostringstream os; os << "MatrixTransform parse error, offset field must be 4 "; os << "floats. Found '" << val.size() << "'."; throw Exception(os.str().c_str()); } t->setOffset(&val[0]); } else if(key == "direction") { TransformDirection val; load(second, val); t->setDirection(val); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstMatrixTransformRcPtr t) { out << YAML::VerbatimTag("MatrixTransform"); out << YAML::Flow << YAML::BeginMap; std::vector matrix(16, 0.0); t->getMatrix(&matrix[0]); if(!IsM44Identity(&matrix[0])) { out << YAML::Key << "matrix"; out << YAML::Value << YAML::Flow << matrix; } std::vector offset(4, 0.0); t->getOffset(&offset[0]); if(!IsVecEqualToZero(&offset[0],4)) { out << YAML::Key << "offset"; out << YAML::Value << YAML::Flow << offset; } EmitBaseTransformKeyValues(out, t); out << YAML::EndMap; } // TruelightTransform inline void load(const YAML::Node& node, TruelightTransformRcPtr& t) { t = TruelightTransform::Create(); std::string key, stringval; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "config_root") { load(second, stringval); t->setConfigRoot(stringval.c_str()); } else if(key == "profile") { load(second, stringval); t->setProfile(stringval.c_str()); } else if(key == "camera") { load(second, stringval); t->setCamera(stringval.c_str()); } else if(key == "input_display") { load(second, stringval); t->setInputDisplay(stringval.c_str()); } else if(key == "recorder") { load(second, stringval); t->setRecorder(stringval.c_str()); } else if(key == "print") { load(second, stringval); t->setPrint(stringval.c_str()); } else if(key == "lamp") { load(second, stringval); t->setLamp(stringval.c_str()); } else if(key == "output_camera") { load(second, stringval); t->setOutputCamera(stringval.c_str()); } else if(key == "display") { load(second, stringval); t->setDisplay(stringval.c_str()); } else if(key == "cube_input") { load(second, stringval); t->setCubeInput(stringval.c_str()); } else if(key == "direction") { TransformDirection val; load(second, val); t->setDirection(val); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstTruelightTransformRcPtr t) { out << YAML::VerbatimTag("TruelightTransform"); out << YAML::Flow << YAML::BeginMap; if(strcmp(t->getConfigRoot(), "") != 0) { out << YAML::Key << "config_root"; out << YAML::Value << YAML::Flow << t->getConfigRoot(); } if(strcmp(t->getProfile(), "") != 0) { out << YAML::Key << "profile"; out << YAML::Value << YAML::Flow << t->getProfile(); } if(strcmp(t->getCamera(), "") != 0) { out << YAML::Key << "camera"; out << YAML::Value << YAML::Flow << t->getCamera(); } if(strcmp(t->getInputDisplay(), "") != 0) { out << YAML::Key << "input_display"; out << YAML::Value << YAML::Flow << t->getInputDisplay(); } if(strcmp(t->getRecorder(), "") != 0) { out << YAML::Key << "recorder"; out << YAML::Value << YAML::Flow << t->getRecorder(); } if(strcmp(t->getPrint(), "") != 0) { out << YAML::Key << "print"; out << YAML::Value << YAML::Flow << t->getPrint(); } if(strcmp(t->getLamp(), "") != 0) { out << YAML::Key << "lamp"; out << YAML::Value << YAML::Flow << t->getLamp(); } if(strcmp(t->getOutputCamera(), "") != 0) { out << YAML::Key << "output_camera"; out << YAML::Value << YAML::Flow << t->getOutputCamera(); } if(strcmp(t->getDisplay(), "") != 0) { out << YAML::Key << "display"; out << YAML::Value << YAML::Flow << t->getDisplay(); } if(strcmp(t->getCubeInput(), "") != 0) { out << YAML::Key << "cube_input"; out << YAML::Value << YAML::Flow << t->getCubeInput(); } EmitBaseTransformKeyValues(out, t); out << YAML::EndMap; } // Transform void load(const YAML::Node& node, TransformRcPtr& t) { if(node.Type() != YAML::NodeType::Map) { std::ostringstream os; os << "Unsupported Transform type encountered: (" << node.Type() << ") in OCIO profile. "; os << "Only Mapping types supported."; throw Exception(os.str().c_str()); } std::string type = node.Tag(); if(type == "AllocationTransform") { AllocationTransformRcPtr temp; load(node, temp); t = temp; } else if(type == "CDLTransform") { CDLTransformRcPtr temp; load(node, temp); t = temp; } else if(type == "ColorSpaceTransform") { ColorSpaceTransformRcPtr temp; load(node, temp); t = temp; } // TODO: DisplayTransform else if(type == "ExponentTransform") { ExponentTransformRcPtr temp; load(node, temp); t = temp; } else if(type == "FileTransform") { FileTransformRcPtr temp; load(node, temp); t = temp; } else if(type == "GroupTransform") { GroupTransformRcPtr temp; load(node, temp); t = temp; } else if(type == "LogTransform") { LogTransformRcPtr temp; load(node, temp); t = temp; } else if(type == "LookTransform") { LookTransformRcPtr temp; load(node, temp); t = temp; } else if(type == "MatrixTransform") { MatrixTransformRcPtr temp; load(node, temp); t = temp; } else if(type == "TruelightTransform") { TruelightTransformRcPtr temp; load(node, temp); t = temp; } else { // TODO: add a new empty (better name?) aka passthru Transform() // which does nothing. This is so upsupported ! types don't // throw an exception. Alternativly this could be caught in the // GroupTransformRcPtr >> operator with some type of // supported_tag() method // TODO: consider the forwards-compatibility implication of // throwing an exception. Should this be a warning, instead? // t = EmptyTransformRcPtr(new EmptyTransform(), &deleter); std::ostringstream os; os << "Unsupported transform type !<" << type << "> in OCIO profile. "; throw Exception(os.str().c_str()); } } void save(YAML::Emitter& out, ConstTransformRcPtr t) { if(ConstAllocationTransformRcPtr Allocation_tran = \ DynamicPtrCast(t)) save(out, Allocation_tran); else if(ConstCDLTransformRcPtr CDL_tran = \ DynamicPtrCast(t)) save(out, CDL_tran); else if(ConstColorSpaceTransformRcPtr ColorSpace_tran = \ DynamicPtrCast(t)) save(out, ColorSpace_tran); else if(ConstExponentTransformRcPtr Exponent_tran = \ DynamicPtrCast(t)) save(out, Exponent_tran); else if(ConstFileTransformRcPtr File_tran = \ DynamicPtrCast(t)) save(out, File_tran); else if(ConstGroupTransformRcPtr Group_tran = \ DynamicPtrCast(t)) save(out, Group_tran); else if(ConstLogTransformRcPtr Log_tran = \ DynamicPtrCast(t)) save(out, Log_tran); else if(ConstLookTransformRcPtr Look_tran = \ DynamicPtrCast(t)) save(out, Look_tran); else if(ConstMatrixTransformRcPtr Matrix_tran = \ DynamicPtrCast(t)) save(out, Matrix_tran); else if(ConstTruelightTransformRcPtr Truelight_tran = \ DynamicPtrCast(t)) save(out, Truelight_tran); else throw Exception("Unsupported Transform() type for serialization."); } // ColorSpace inline void load(const YAML::Node& node, ColorSpaceRcPtr& cs) { if(node.Tag() != "ColorSpace") return; // not a ! tag std::string key, stringval; bool boolval; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "name") { load(second, stringval); cs->setName(stringval.c_str()); } else if(key == "description") { load(second, stringval); cs->setDescription(stringval.c_str()); } else if(key == "family") { load(second, stringval); cs->setFamily(stringval.c_str()); } else if(key == "equalitygroup") { load(second, stringval); cs->setEqualityGroup(stringval.c_str()); } else if(key == "bitdepth") { BitDepth ret; load(second, ret); cs->setBitDepth(ret); } else if(key == "isdata") { load(second, boolval); cs->setIsData(boolval); } else if(key == "allocation") { Allocation val; load(second, val); cs->setAllocation(val); } else if(key == "allocationvars") { std::vector val; load(second, val); if(!val.empty()) cs->setAllocationVars(static_cast(val.size()), &val[0]); } else if(key == "to_reference") { TransformRcPtr val; load(second, val); cs->setTransform(val, COLORSPACE_DIR_TO_REFERENCE); } else if(key == "from_reference") { TransformRcPtr val; load(second, val); cs->setTransform(val, COLORSPACE_DIR_FROM_REFERENCE); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstColorSpaceRcPtr cs) { out << YAML::VerbatimTag("ColorSpace"); out << YAML::BeginMap; out << YAML::Key << "name" << YAML::Value << cs->getName(); out << YAML::Key << "family" << YAML::Value << cs->getFamily(); out << YAML::Key << "equalitygroup" << YAML::Value << cs->getEqualityGroup(); out << YAML::Key << "bitdepth" << YAML::Value; save(out, cs->getBitDepth()); if(cs->getDescription() != NULL && strlen(cs->getDescription()) > 0) { out << YAML::Key << "description"; out << YAML::Value << YAML::Literal << cs->getDescription(); } out << YAML::Key << "isdata" << YAML::Value << cs->isData(); out << YAML::Key << "allocation" << YAML::Value; save(out, cs->getAllocation()); if(cs->getAllocationNumVars() > 0) { std::vector allocationvars(cs->getAllocationNumVars()); cs->getAllocationVars(&allocationvars[0]); out << YAML::Key << "allocationvars"; out << YAML::Flow << YAML::Value << allocationvars; } ConstTransformRcPtr toref = \ cs->getTransform(COLORSPACE_DIR_TO_REFERENCE); if(toref) { out << YAML::Key << "to_reference" << YAML::Value; save(out, toref); } ConstTransformRcPtr fromref = \ cs->getTransform(COLORSPACE_DIR_FROM_REFERENCE); if(fromref) { out << YAML::Key << "from_reference" << YAML::Value; save(out, fromref); } out << YAML::EndMap; out << YAML::Newline; } // Look inline void load(const YAML::Node& node, LookRcPtr& look) { if(node.Tag() != "Look") return; std::string key, stringval; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "name") { load(second, stringval); look->setName(stringval.c_str()); } else if(key == "process_space") { load(second, stringval); look->setProcessSpace(stringval.c_str()); } else if(key == "transform") { TransformRcPtr val; load(second, val); look->setTransform(val); } else if(key == "inverse_transform") { TransformRcPtr val; load(second, val); look->setInverseTransform(val); } else if(key == "description") { load(second, stringval); look->setDescription(stringval.c_str()); } else { LogUnknownKeyWarning(node.Tag(), first); } } } inline void save(YAML::Emitter& out, ConstLookRcPtr look) { out << YAML::VerbatimTag("Look"); out << YAML::BeginMap; out << YAML::Key << "name" << YAML::Value << look->getName(); out << YAML::Key << "process_space" << YAML::Value << look->getProcessSpace(); if (look->getDescription() != NULL && strlen(look->getDescription()) > 0) { out << YAML::Key << "description"; out << YAML::Value << YAML::Literal << look->getDescription(); } if(look->getTransform()) { out << YAML::Key << "transform"; out << YAML::Value; save(out, look->getTransform()); } if(look->getInverseTransform()) { out << YAML::Key << "inverse_transform"; out << YAML::Value; save(out, look->getInverseTransform()); } out << YAML::EndMap; out << YAML::Newline; } // Config inline void load(const YAML::Node& node, ConfigRcPtr& c, const char* filename) { // check profile version int profile_version = 0; #ifdef OLDYAML if(node.FindValue("ocio_profile_version") == NULL) #else if(node["ocio_profile_version"] == NULL) #endif { std::ostringstream os; os << "The specified file "; os << "does not appear to be an OCIO configuration."; throw Exception (os.str().c_str()); } load(node["ocio_profile_version"], profile_version); if(profile_version > 1) { std::ostringstream os; os << "This .ocio config "; if(filename && *filename) { os << " '" << filename << "' "; } os << "is version " << profile_version << ". "; os << "This version of the OpenColorIO library (" << OCIO_VERSION ") "; os << "is not known to be able to load this profile. "; os << "An attempt will be made, but there are no guarantees that the "; os << "results will be accurate. Continue at your own risk."; LogWarning(os.str()); } std::string key, stringval; bool boolval = false; EnvironmentMode mode = ENV_ENVIRONMENT_LOAD_ALL; for (Iterator iter = node.begin(); iter != node.end(); ++iter) { const YAML::Node& first = get_first(iter); const YAML::Node& second = get_second(iter); load(first, key); if (second.Type() == YAML::NodeType::Null) continue; if(key == "ocio_profile_version") { } // Already handled above. else if(key == "environment") { mode = ENV_ENVIRONMENT_LOAD_PREDEFINED; if(second.Type() != YAML::NodeType::Map) { std::ostringstream os; os << "'environment' field needs to be a (name: key) map."; throw Exception(os.str().c_str()); } for (Iterator it = second.begin(); it != second.end(); ++it) { std::string k, v; load(get_first(it), k); load(get_second(it), v); c->addEnvironmentVar(k.c_str(), v.c_str()); } } else if(key == "search_path" || key == "resource_path") { load(second, stringval); c->setSearchPath(stringval.c_str()); } else if(key == "strictparsing") { load(second, boolval); c->setStrictParsingEnabled(boolval); } else if(key == "description") { load(second, stringval); c->setDescription(stringval.c_str()); } else if(key == "luma") { std::vector val; load(second, val); if(val.size() != 3) { std::ostringstream os; os << "'luma' field must be 3 "; os << "floats. Found '" << val.size() << "'."; throw Exception(os.str().c_str()); } c->setDefaultLumaCoefs(&val[0]); } else if(key == "roles") { if(second.Type() != YAML::NodeType::Map) { std::ostringstream os; os << "'roles' field needs to be a (name: key) map."; throw Exception(os.str().c_str()); } for (Iterator it = second.begin(); it != second.end(); ++it) { std::string k, v; load(get_first(it), k); load(get_second(it), v); c->setRole(k.c_str(), v.c_str()); } } else if(key == "displays") { if(second.Type() != YAML::NodeType::Map) { std::ostringstream os; os << "'displays' field needs to be a (name: key) map."; throw Exception(os.str().c_str()); } for (Iterator it = second.begin(); it != second.end(); ++it) { std::string display; load(get_first(it), display); const YAML::Node& dsecond = get_second(it); for(unsigned i = 0; i < dsecond.size(); ++i) { View view; load(dsecond[i], view); c->addDisplay(display.c_str(), view.name.c_str(), view.colorspace.c_str(), view.looks.c_str()); } } } else if(key == "active_displays") { std::vector display; load(second, display); std::string displays = JoinStringEnvStyle(display); c->setActiveDisplays(displays.c_str()); } else if(key == "active_views") { std::vector view; load(second, view); std::string views = JoinStringEnvStyle(view); c->setActiveViews(views.c_str()); } else if(key == "colorspaces") { if(second.Type() != YAML::NodeType::Sequence) { std::ostringstream os; os << "'colorspaces' field needs to be a (- !) list."; throw Exception(os.str().c_str()); } for(unsigned i = 0; i < second.size(); ++i) { if(second[i].Tag() == "ColorSpace") { ColorSpaceRcPtr cs = ColorSpace::Create(); load(second[i], cs); for(int ii = 0; ii < c->getNumColorSpaces(); ++ii) { if(strcmp(c->getColorSpaceNameByIndex(ii), cs->getName()) == 0) { std::ostringstream os; os << "Colorspace with name '" << cs->getName() << "' already defined."; throw Exception(os.str().c_str()); } } c->addColorSpace(cs); } else { std::ostringstream os; os << "Unknown element found in colorspaces:"; os << second[i].Tag() << ". Only ColorSpace(s)"; os << " currently handled."; LogWarning(os.str()); } } } else if(key == "looks") { if(second.Type() != YAML::NodeType::Sequence) { std::ostringstream os; os << "'looks' field needs to be a (- !) list."; throw Exception(os.str().c_str()); } for(unsigned i = 0; i < second.size(); ++i) { if(second[i].Tag() == "Look") { LookRcPtr look = Look::Create(); load(second[i], look); c->addLook(look); } else { std::ostringstream os; os << "Unknown element found in looks:"; os << second[i].Tag() << ". Only Look(s)"; os << " currently handled."; LogWarning(os.str()); } } } else { LogUnknownKeyWarning("profile", first); } } if(filename) { std::string realfilename = pystring::os::path::abspath(filename); std::string configrootdir = pystring::os::path::dirname(realfilename); c->setWorkingDir(configrootdir.c_str()); } c->setEnvironmentMode(mode); c->loadEnvironment(); if(mode == ENV_ENVIRONMENT_LOAD_ALL) { std::ostringstream os; os << "This .ocio config "; if(filename && *filename) { os << " '" << filename << "' "; } os << "has no environment section defined. The default behaviour is to "; os << "load all environment variables (" << c->getNumEnvironmentVars() << ")"; os << ", which reduces the efficiency of OCIO's caching. Considering "; os << "predefining the environment variables used."; LogDebug(os.str()); } } inline void save(YAML::Emitter& out, const Config* c) { out << YAML::Block; out << YAML::BeginMap; out << YAML::Key << "ocio_profile_version" << YAML::Value << 1; out << YAML::Newline; #ifndef OLDYAML out << YAML::Newline; #endif if(c->getNumEnvironmentVars() > 0) { out << YAML::Key << "environment"; out << YAML::Value << YAML::BeginMap; for(int i = 0; i < c->getNumEnvironmentVars(); ++i) { const char* name = c->getEnvironmentVarNameByIndex(i); out << YAML::Key << name; out << YAML::Value << c->getEnvironmentVarDefault(name); } out << YAML::EndMap; out << YAML::Newline; } out << YAML::Key << "search_path" << YAML::Value << c->getSearchPath(); out << YAML::Key << "strictparsing" << YAML::Value << c->isStrictParsingEnabled(); std::vector luma(3, 0.f); c->getDefaultLumaCoefs(&luma[0]); out << YAML::Key << "luma" << YAML::Value << YAML::Flow << luma; if(c->getDescription() != NULL && strlen(c->getDescription()) > 0) { out << YAML::Newline; out << YAML::Key << "description"; out << YAML::Value << c->getDescription(); out << YAML::Newline; } // Roles out << YAML::Newline; #ifndef OLDYAML out << YAML::Newline; #endif out << YAML::Key << "roles"; out << YAML::Value << YAML::BeginMap; for(int i = 0; i < c->getNumRoles(); ++i) { const char* role = c->getRoleName(i); if(role && *role) { ConstColorSpaceRcPtr colorspace = c->getColorSpace(role); if(colorspace) { out << YAML::Key << role; out << YAML::Value << c->getColorSpace(role)->getName(); } else { std::ostringstream os; os << "Colorspace associated to the role '" << role << "', does not exist."; throw Exception(os.str().c_str()); } } } out << YAML::EndMap; #ifndef OLDYAML out << YAML::Newline; #endif // Displays out << YAML::Newline; out << YAML::Key << "displays"; out << YAML::Value << YAML::BeginMap; for(int i = 0; i < c->getNumDisplays(); ++i) { const char* display = c->getDisplay(i); out << YAML::Key << display; out << YAML::Value << YAML::BeginSeq; for(int v = 0; v < c->getNumViews(display); ++v) { View dview; dview.name = c->getView(display, v); dview.colorspace = c->getDisplayColorSpaceName(display, dview.name.c_str()); if(c->getDisplayLooks(display, dview.name.c_str()) != NULL) dview.looks = c->getDisplayLooks(display, dview.name.c_str()); save(out, dview); } out << YAML::EndSeq; } out << YAML::EndMap; #ifndef OLDYAML out << YAML::Newline; #endif out << YAML::Newline; out << YAML::Key << "active_displays"; std::vector active_displays; if(c->getActiveDisplays() != NULL && strlen(c->getActiveDisplays()) > 0) SplitStringEnvStyle(active_displays, c->getActiveDisplays()); out << YAML::Value << YAML::Flow << active_displays; out << YAML::Key << "active_views"; std::vector active_views; if(c->getActiveViews() != NULL && strlen(c->getActiveViews()) > 0) SplitStringEnvStyle(active_views, c->getActiveViews()); out << YAML::Value << YAML::Flow << active_views; #ifndef OLDYAML out << YAML::Newline; #endif // Looks if(c->getNumLooks() > 0) { out << YAML::Newline; out << YAML::Key << "looks"; out << YAML::Value << YAML::BeginSeq; for(int i = 0; i < c->getNumLooks(); ++i) { const char* name = c->getLookNameByIndex(i); save(out, c->getLook(name)); } out << YAML::EndSeq; out << YAML::Newline; } // ColorSpaces { out << YAML::Newline; out << YAML::Key << "colorspaces"; out << YAML::Value << YAML::BeginSeq; for(int i = 0; i < c->getNumColorSpaces(); ++i) { const char* name = c->getColorSpaceNameByIndex(i); save(out, c->getColorSpace(name)); } out << YAML::EndSeq; } out << YAML::EndMap; } } /////////////////////////////////////////////////////////////////////////// void OCIOYaml::open(std::istream& istream, ConfigRcPtr& c, const char* filename) const { try { #ifdef OLDYAML YAML::Parser parser(istream); YAML::Node node; parser.GetNextDocument(node); #else YAML::Node node = YAML::Load(istream); #endif load(node, c, filename); } catch(const std::exception & e) { std::ostringstream os; os << "Error: Loading the OCIO profile "; if(filename) os << "'" << filename << "' "; os << "failed. " << e.what(); throw Exception(os.str().c_str()); } } void OCIOYaml::write(std::ostream& ostream, const Config* c) const { YAML::Emitter out; save(out, c); ostream << out.c_str(); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/ExponentOps.cpp0000644000175000017500000003135713223553423021004 0ustar mfvmfv/* 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 #include #include #include #include #include "ExponentOps.h" #include "GpuShaderUtils.h" #include "MathUtils.h" OCIO_NAMESPACE_ENTER { namespace { void ApplyClampExponent(float* rgbaBuffer, long numPixels, const float* exp4) { for(long pixelIndex=0; pixelIndex ExponentOpRcPtr; ExponentOp::ExponentOp(const double * exp4, TransformDirection direction): Op() { if(direction == TRANSFORM_DIR_UNKNOWN) { throw Exception("Cannot create ExponentOp with unspecified transform direction."); } if(direction == TRANSFORM_DIR_INVERSE) { for(int i=0; i<4; ++i) { if(!IsScalarEqualToZeroFlt(exp4[i])) { m_exp4[i] = 1.0 / exp4[i]; } else { throw Exception("Cannot apply ExponentOp op, Cannot apply 0.0 exponent in the inverse."); } } } else { memcpy(m_exp4, exp4, 4*sizeof(double)); } } OpRcPtr ExponentOp::clone() const { OpRcPtr op = OpRcPtr(new ExponentOp(m_exp4, TRANSFORM_DIR_FORWARD)); return op; } ExponentOp::~ExponentOp() { } std::string ExponentOp::getInfo() const { return ""; } std::string ExponentOp::getCacheID() const { return m_cacheID; } bool ExponentOp::isNoOp() const { return IsVecEqualToOneFlt(m_exp4, 4); } bool ExponentOp::isSameType(const OpRcPtr & op) const { ExponentOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; return true; } bool ExponentOp::isInverse(const OpRcPtr & op) const { ExponentOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; double combined[4] = { m_exp4[0]*typedRcPtr->m_exp4[0], m_exp4[1]*typedRcPtr->m_exp4[1], m_exp4[2]*typedRcPtr->m_exp4[2], m_exp4[3]*typedRcPtr->m_exp4[3] }; return IsVecEqualToOneFlt(combined, 4); } bool ExponentOp::canCombineWith(const OpRcPtr & op) const { return isSameType(op); } void ExponentOp::combineWith(OpRcPtrVec & ops, const OpRcPtr & secondOp) const { ExponentOpRcPtr typedRcPtr = DynamicPtrCast(secondOp); if(!typedRcPtr) { std::ostringstream os; os << "ExponentOp can only be combined with other "; os << "ExponentOps. secondOp:" << secondOp->getInfo(); throw Exception(os.str().c_str()); } double combined[4] = { m_exp4[0]*typedRcPtr->m_exp4[0], m_exp4[1]*typedRcPtr->m_exp4[1], m_exp4[2]*typedRcPtr->m_exp4[2], m_exp4[3]*typedRcPtr->m_exp4[3] }; if(!IsVecEqualToOneFlt(combined, 4)) { ops.push_back( ExponentOpRcPtr(new ExponentOp(combined, TRANSFORM_DIR_FORWARD)) ); } } bool ExponentOp::hasChannelCrosstalk() const { return false; } void ExponentOp::finalize() { // Create the cacheID std::ostringstream cacheIDStream; cacheIDStream << ""; m_cacheID = cacheIDStream.str(); } void ExponentOp::apply(float* rgbaBuffer, long numPixels) const { if(!rgbaBuffer) return; float exp[4] = { float(m_exp4[0]), float(m_exp4[1]), float(m_exp4[2]), float(m_exp4[3]) }; ApplyClampExponent(rgbaBuffer, numPixels, exp); } bool ExponentOp::supportsGpuShader() const { return true; } void ExponentOp::writeGpuShader(std::ostream & shader, const std::string & pixelName, const GpuShaderDesc & shaderDesc) const { float exp[4] = { float(m_exp4[0]), float(m_exp4[1]), float(m_exp4[2]), float(m_exp4[3]) }; GpuLanguage lang = shaderDesc.getLanguage(); float zerovec[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; shader << pixelName << " = pow("; shader << "max(" << pixelName << ", " << GpuTextHalf4(zerovec, lang) << ")"; shader << ", " << GpuTextHalf4(exp, lang) << ");\n"; } } // Anon namespace void CreateExponentOp(OpRcPtrVec & ops, const float * exp4, TransformDirection direction) { bool expIsIdentity = IsVecEqualToOne(exp4, 4); if(expIsIdentity) return; double d_exp[4] = { double(exp4[0]), double(exp4[1]), double(exp4[2]), double(exp4[3]) }; ops.push_back( ExponentOpRcPtr(new ExponentOp(d_exp, direction)) ); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST #include "UnitTest.h" OCIO_NAMESPACE_USING OIIO_ADD_TEST(ExponentOps, Value) { float exp1[4] = { 1.2f, 1.3f, 1.4f, 1.5f }; OpRcPtrVec ops; CreateExponentOp(ops, exp1, TRANSFORM_DIR_FORWARD); CreateExponentOp(ops, exp1, TRANSFORM_DIR_INVERSE); OIIO_CHECK_EQUAL(ops.size(), 2); for(unsigned int i=0; ifinalize(); } float error = 1e-6f; const float source[] = { 0.5f, 0.5f, 0.5f, 0.5f, }; const float result1[] = { 0.43527528164806206f, 0.40612619817811774f, 0.37892914162759955f, 0.35355339059327379f }; float tmp[4]; memcpy(tmp, source, 4*sizeof(float)); ops[0]->apply(tmp, 1); for(unsigned int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(tmp[i], result1[i], error); } ops[1]->apply(tmp, 1); for(unsigned int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(tmp[i], source[i], error); } } OIIO_ADD_TEST(ExponentOps, Inverse) { float exp1[4] = { 2.0f, 1.02345f, 5.651321f, 0.12345678910f }; float exp2[4] = { 2.0f, 2.0f, 2.0f, 2.0f }; OpRcPtrVec ops; CreateExponentOp(ops, exp1, TRANSFORM_DIR_FORWARD); CreateExponentOp(ops, exp1, TRANSFORM_DIR_INVERSE); CreateExponentOp(ops, exp2, TRANSFORM_DIR_FORWARD); CreateExponentOp(ops, exp2, TRANSFORM_DIR_INVERSE); OIIO_CHECK_EQUAL(ops.size(), 4); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[1])); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[2])); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[3]->clone())); OIIO_CHECK_EQUAL(ops[0]->isInverse(ops[0]), false); OIIO_CHECK_EQUAL(ops[0]->isInverse(ops[1]), true); OIIO_CHECK_EQUAL(ops[1]->isInverse(ops[0]), true); OIIO_CHECK_EQUAL(ops[0]->isInverse(ops[2]), false); OIIO_CHECK_EQUAL(ops[0]->isInverse(ops[3]), false); OIIO_CHECK_EQUAL(ops[3]->isInverse(ops[0]), false); OIIO_CHECK_EQUAL(ops[2]->isInverse(ops[3]), true); OIIO_CHECK_EQUAL(ops[3]->isInverse(ops[2]), true); OIIO_CHECK_EQUAL(ops[3]->isInverse(ops[3]), false); } OIIO_ADD_TEST(ExponentOps, Combining) { { float exp1[4] = { 2.0f, 2.0f, 2.0f, 1.0f }; float exp2[4] = { 1.2f, 1.2f, 1.2f, 1.0f }; OpRcPtrVec ops; CreateExponentOp(ops, exp1, TRANSFORM_DIR_FORWARD); CreateExponentOp(ops, exp2, TRANSFORM_DIR_FORWARD); OIIO_CHECK_EQUAL(ops.size(), 2); float error = 1e-6f; const float source[] = { 0.5f, 0.5f, 0.5f, 0.5f, }; const float result[] = { 0.18946457081379978f, 0.18946457081379978f, 0.18946457081379978f, 0.5f }; float tmp[4]; memcpy(tmp, source, 4*sizeof(float)); ops[0]->apply(tmp, 1); ops[1]->apply(tmp, 1); for(unsigned int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(tmp[i], result[i], error); } OpRcPtrVec combined; ops[0]->combineWith(combined, ops[1]); OIIO_CHECK_EQUAL(combined.size(), 1); float tmp2[4]; memcpy(tmp2, source, 4*sizeof(float)); combined[0]->apply(tmp2, 1); for(unsigned int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(tmp2[i], result[i], error); } } { float exp1[4] = {1.037289f, 1.019015f, 0.966082f, 1.0f}; OpRcPtrVec ops; CreateExponentOp(ops, exp1, TRANSFORM_DIR_FORWARD); CreateExponentOp(ops, exp1, TRANSFORM_DIR_INVERSE); OIIO_CHECK_EQUAL(ops.size(), 2); bool isInverse = ops[0]->isInverse(ops[1]); OIIO_CHECK_EQUAL(isInverse, true); } } #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/Lut3DOp.cpp0000644000175000017500000011105513223553423017746 0ustar mfvmfv/* 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 #include "HashUtils.h" #include "Lut3DOp.h" #include "MathUtils.h" #include #include #include #include OCIO_NAMESPACE_ENTER { Lut3D::Lut3D() { for(int i=0; i<3; ++i) { from_min[i] = 0.0f; from_max[i] = 1.0f; size[i] = 0; } } Lut3DRcPtr Lut3D::Create() { return Lut3DRcPtr(new Lut3D()); } std::string Lut3D::getCacheID() const { AutoMutex lock(m_cacheidMutex); if(lut.empty()) throw Exception("Cannot compute cacheID of invalid Lut3D"); if(!m_cacheID.empty()) return m_cacheID; md5_state_t state; md5_byte_t digest[16]; md5_init(&state); md5_append(&state, (const md5_byte_t *)from_min, (int)(3*sizeof(float))); md5_append(&state, (const md5_byte_t *)from_max, (int)(3*sizeof(float))); md5_append(&state, (const md5_byte_t *)size, (int)(3*sizeof(int))); md5_append(&state, (const md5_byte_t *)&lut[0], (int)(lut.size()*sizeof(float))); md5_finish(&state, digest); m_cacheID = GetPrintableHash(digest); return m_cacheID; } namespace { // Linear inline float lerp(float a, float b, float z) { return (b - a) * z + a; } inline void lerp_rgb(float* out, float* a, float* b, float* z) { out[0] = (b[0] - a[0]) * z[0] + a[0]; out[1] = (b[1] - a[1]) * z[1] + a[1]; out[2] = (b[2] - a[2]) * z[2] + a[2]; } // Bilinear inline float lerp(float a, float b, float c, float d, float y, float z) { return lerp(lerp(a, b, z), lerp(c, d, z), y); } inline void lerp_rgb(float* out, float* a, float* b, float* c, float* d, float* y, float* z) { float v1[3]; float v2[3]; lerp_rgb(v1, a, b, z); lerp_rgb(v2, c, d, z); lerp_rgb(out, v1, v2, y); } // Trilinear inline float lerp(float a, float b, float c, float d, float e, float f, float g, float h, float x, float y, float z) { return lerp(lerp(a,b,c,d,y,z), lerp(e,f,g,h,y,z), x); } inline void lerp_rgb(float* out, float* a, float* b, float* c, float* d, float* e, float* f, float* g, float* h, float* x, float* y, float* z) { float v1[3]; float v2[3]; lerp_rgb(v1, a,b,c,d,y,z); lerp_rgb(v2, e,f,g,h,y,z); lerp_rgb(out, v1, v2, x); } inline float lookupNearest_3D(int rIndex, int gIndex, int bIndex, int size_red, int size_green, int size_blue, const float* simple_rgb_lut, int channelIndex) { return simple_rgb_lut[ GetLut3DIndex_B(rIndex, gIndex, bIndex, size_red, size_green, size_blue) + channelIndex]; } inline void lookupNearest_3D_rgb(float* rgb, int rIndex, int gIndex, int bIndex, int size_red, int size_green, int size_blue, const float* simple_rgb_lut) { int offset = GetLut3DIndex_B(rIndex, gIndex, bIndex, size_red, size_green, size_blue); rgb[0] = simple_rgb_lut[offset]; rgb[1] = simple_rgb_lut[offset+1]; rgb[2] = simple_rgb_lut[offset+2]; } // Note: This function assumes that minVal is less than maxVal inline int clamp(float k, float minVal, float maxVal) { return static_cast(roundf(std::max(std::min(k, maxVal), minVal))); } /////////////////////////////////////////////////////////////////////// // Nearest Forward void Lut3D_Nearest(float* rgbaBuffer, long numPixels, const Lut3D & lut) { float maxIndex[3]; float mInv[3]; float b[3]; float mInv_x_maxIndex[3]; int lutSize[3]; const float* startPos = &(lut.lut[0]); for(int i=0; i<3; ++i) { maxIndex[i] = (float) (lut.size[i] - 1); mInv[i] = 1.0f / (lut.from_max[i] - lut.from_min[i]); b[i] = lut.from_min[i]; mInv_x_maxIndex[i] = (float) (mInv[i] * maxIndex[i]); lutSize[i] = lut.size[i]; } int localIndex[3]; for(long pixelIndex=0; pixelIndex::quiet_NaN(); rgbaBuffer[1] = std::numeric_limits::quiet_NaN(); rgbaBuffer[2] = std::numeric_limits::quiet_NaN(); } else { localIndex[0] = clamp(mInv_x_maxIndex[0] * (rgbaBuffer[0] - b[0]), 0.0f, maxIndex[0]); localIndex[1] = clamp(mInv_x_maxIndex[1] * (rgbaBuffer[1] - b[1]), 0.0f, maxIndex[1]); localIndex[2] = clamp(mInv_x_maxIndex[2] * (rgbaBuffer[2] - b[2]), 0.0f, maxIndex[2]); lookupNearest_3D_rgb(rgbaBuffer, localIndex[0], localIndex[1], localIndex[2], lutSize[0], lutSize[1], lutSize[2], startPos); } rgbaBuffer += 4; } } /////////////////////////////////////////////////////////////////////// // Linear Forward void Lut3D_Linear(float* rgbaBuffer, long numPixels, const Lut3D & lut) { float maxIndex[3]; float mInv[3]; float b[3]; float mInv_x_maxIndex[3]; int lutSize[3]; const float* startPos = &(lut.lut[0]); for(int i=0; i<3; ++i) { maxIndex[i] = (float) (lut.size[i] - 1); mInv[i] = 1.0f / (lut.from_max[i] - lut.from_min[i]); b[i] = lut.from_min[i]; mInv_x_maxIndex[i] = (float) (mInv[i] * maxIndex[i]); lutSize[i] = lut.size[i]; } for(long pixelIndex=0; pixelIndex::quiet_NaN(); rgbaBuffer[1] = std::numeric_limits::quiet_NaN(); rgbaBuffer[2] = std::numeric_limits::quiet_NaN(); } else { float localIndex[3]; int indexLow[3]; int indexHigh[3]; float delta[3]; float a[3]; float b_[3]; float c[3]; float d[3]; float e[3]; float f[3]; float g[3]; float h[4]; float x[4]; float y[4]; float z[4]; localIndex[0] = std::max(std::min(mInv_x_maxIndex[0] * (rgbaBuffer[0] - b[0]), maxIndex[0]), 0.0f); localIndex[1] = std::max(std::min(mInv_x_maxIndex[1] * (rgbaBuffer[1] - b[1]), maxIndex[1]), 0.0f); localIndex[2] = std::max(std::min(mInv_x_maxIndex[2] * (rgbaBuffer[2] - b[2]), maxIndex[2]), 0.0f); indexLow[0] = static_cast(std::floor(localIndex[0])); indexLow[1] = static_cast(std::floor(localIndex[1])); indexLow[2] = static_cast(std::floor(localIndex[2])); indexHigh[0] = static_cast(std::ceil(localIndex[0])); indexHigh[1] = static_cast(std::ceil(localIndex[1])); indexHigh[2] = static_cast(std::ceil(localIndex[2])); delta[0] = localIndex[0] - static_cast(indexLow[0]); delta[1] = localIndex[1] - static_cast(indexLow[1]); delta[2] = localIndex[2] - static_cast(indexLow[2]); // Lookup 8 corners of cube lookupNearest_3D_rgb(a, indexLow[0], indexLow[1], indexLow[2], lutSize[0], lutSize[1], lutSize[2], startPos); lookupNearest_3D_rgb(b_, indexLow[0], indexLow[1], indexHigh[2], lutSize[0], lutSize[1], lutSize[2], startPos); lookupNearest_3D_rgb(c, indexLow[0], indexHigh[1], indexLow[2], lutSize[0], lutSize[1], lutSize[2], startPos); lookupNearest_3D_rgb(d, indexLow[0], indexHigh[1], indexHigh[2], lutSize[0], lutSize[1], lutSize[2], startPos); lookupNearest_3D_rgb(e, indexHigh[0], indexLow[1], indexLow[2], lutSize[0], lutSize[1], lutSize[2], startPos); lookupNearest_3D_rgb(f, indexHigh[0], indexLow[1], indexHigh[2], lutSize[0], lutSize[1], lutSize[2], startPos); lookupNearest_3D_rgb(g, indexHigh[0], indexHigh[1], indexLow[2], lutSize[0], lutSize[1], lutSize[2], startPos); lookupNearest_3D_rgb(h, indexHigh[0], indexHigh[1], indexHigh[2], lutSize[0], lutSize[1], lutSize[2], startPos); // Also store the 3d interpolation coordinates x[0] = delta[0]; x[1] = delta[0]; x[2] = delta[0]; y[0] = delta[1]; y[1] = delta[1]; y[2] = delta[1]; z[0] = delta[2]; z[1] = delta[2]; z[2] = delta[2]; // Do a trilinear interpolation of the 8 corners // 4726.8 scanlines/sec lerp_rgb(rgbaBuffer, a, b_, c, d, e, f, g, h, x, y, z); } rgbaBuffer += 4; } } } void Lut3D_Tetrahedral(float* rgbaBuffer, long numPixels, const Lut3D & lut) { // Tetrahedral interoplation, as described by: // http://www.filmlight.ltd.uk/pdf/whitepapers/FL-TL-TN-0057-SoftwareLib.pdf // http://blogs.mathworks.com/steve/2006/11/24/tetrahedral-interpolation-for-colorspace-conversion/ // http://www.hpl.hp.com/techreports/98/HPL-98-95.html float maxIndex[3]; float mInv[3]; float b[3]; float mInv_x_maxIndex[3]; int lutSize[3]; const float* startPos = &(lut.lut[0]); for(int i=0; i<3; ++i) { maxIndex[i] = (float) (lut.size[i] - 1); mInv[i] = 1.0f / (lut.from_max[i] - lut.from_min[i]); b[i] = lut.from_min[i]; mInv_x_maxIndex[i] = (float) (mInv[i] * maxIndex[i]); lutSize[i] = lut.size[i]; } for(long pixelIndex=0; pixelIndex::quiet_NaN(); rgbaBuffer[1] = std::numeric_limits::quiet_NaN(); rgbaBuffer[2] = std::numeric_limits::quiet_NaN(); } else { float localIndex[3]; int indexLow[3]; int indexHigh[3]; float delta[3]; // Same index/delta calculation as linear interpolation localIndex[0] = std::max(std::min(mInv_x_maxIndex[0] * (rgbaBuffer[0] - b[0]), maxIndex[0]), 0.0f); localIndex[1] = std::max(std::min(mInv_x_maxIndex[1] * (rgbaBuffer[1] - b[1]), maxIndex[1]), 0.0f); localIndex[2] = std::max(std::min(mInv_x_maxIndex[2] * (rgbaBuffer[2] - b[2]), maxIndex[2]), 0.0f); indexLow[0] = static_cast(std::floor(localIndex[0])); indexLow[1] = static_cast(std::floor(localIndex[1])); indexLow[2] = static_cast(std::floor(localIndex[2])); indexHigh[0] = static_cast(std::ceil(localIndex[0])); indexHigh[1] = static_cast(std::ceil(localIndex[1])); indexHigh[2] = static_cast(std::ceil(localIndex[2])); delta[0] = localIndex[0] - static_cast(indexLow[0]); delta[1] = localIndex[1] - static_cast(indexLow[1]); delta[2] = localIndex[2] - static_cast(indexLow[2]); // Rebind for consistency with Truelight paper float fx = delta[0]; float fy = delta[1]; float fz = delta[2]; // Compute index into LUT for surrounding corners const int n000 = GetLut3DIndex_B(indexLow[0], indexLow[1], indexLow[2], lutSize[0], lutSize[1], lutSize[2]); const int n100 = GetLut3DIndex_B(indexHigh[0], indexLow[1], indexLow[2], lutSize[0], lutSize[1], lutSize[2]); const int n010 = GetLut3DIndex_B(indexLow[0], indexHigh[1], indexLow[2], lutSize[0], lutSize[1], lutSize[2]); const int n001 = GetLut3DIndex_B(indexLow[0], indexLow[1], indexHigh[2], lutSize[0], lutSize[1], lutSize[2]); const int n110 = GetLut3DIndex_B(indexHigh[0], indexHigh[1], indexLow[2], lutSize[0], lutSize[1], lutSize[2]); const int n101 = GetLut3DIndex_B(indexHigh[0], indexLow[1], indexHigh[2], lutSize[0], lutSize[1], lutSize[2]); const int n011 = GetLut3DIndex_B(indexLow[0], indexHigh[1], indexHigh[2], lutSize[0], lutSize[1], lutSize[2]); const int n111 = GetLut3DIndex_B(indexHigh[0], indexHigh[1], indexHigh[2], lutSize[0], lutSize[1], lutSize[2]); if (fx > fy) { if (fy > fz) { rgbaBuffer[0] = (1-fx) * startPos[n000] + (fx-fy) * startPos[n100] + (fy-fz) * startPos[n110] + (fz) * startPos[n111]; rgbaBuffer[1] = (1-fx) * startPos[n000+1] + (fx-fy) * startPos[n100+1] + (fy-fz) * startPos[n110+1] + (fz) * startPos[n111+1]; rgbaBuffer[2] = (1-fx) * startPos[n000+2] + (fx-fy) * startPos[n100+2] + (fy-fz) * startPos[n110+2] + (fz) * startPos[n111+2]; } else if (fx > fz) { rgbaBuffer[0] = (1-fx) * startPos[n000] + (fx-fz) * startPos[n100] + (fz-fy) * startPos[n101] + (fy) * startPos[n111]; rgbaBuffer[1] = (1-fx) * startPos[n000+1] + (fx-fz) * startPos[n100+1] + (fz-fy) * startPos[n101+1] + (fy) * startPos[n111+1]; rgbaBuffer[2] = (1-fx) * startPos[n000+2] + (fx-fz) * startPos[n100+2] + (fz-fy) * startPos[n101+2] + (fy) * startPos[n111+2]; } else { rgbaBuffer[0] = (1-fz) * startPos[n000] + (fz-fx) * startPos[n001] + (fx-fy) * startPos[n101] + (fy) * startPos[n111]; rgbaBuffer[1] = (1-fz) * startPos[n000+1] + (fz-fx) * startPos[n001+1] + (fx-fy) * startPos[n101+1] + (fy) * startPos[n111+1]; rgbaBuffer[2] = (1-fz) * startPos[n000+2] + (fz-fx) * startPos[n001+2] + (fx-fy) * startPos[n101+2] + (fy) * startPos[n111+2]; } } else { if (fz > fy) { rgbaBuffer[0] = (1-fz) * startPos[n000] + (fz-fy) * startPos[n001] + (fy-fx) * startPos[n011] + (fx) * startPos[n111]; rgbaBuffer[1] = (1-fz) * startPos[n000+1] + (fz-fy) * startPos[n001+1] + (fy-fx) * startPos[n011+1] + (fx) * startPos[n111+1]; rgbaBuffer[2] = (1-fz) * startPos[n000+2] + (fz-fy) * startPos[n001+2] + (fy-fx) * startPos[n011+2] + (fx) * startPos[n111+2]; } else if (fz > fx) { rgbaBuffer[0] = (1-fy) * startPos[n000] + (fy-fz) * startPos[n010] + (fz-fx) * startPos[n011] + (fx) * startPos[n111]; rgbaBuffer[1] = (1-fy) * startPos[n000+1] + (fy-fz) * startPos[n010+1] + (fz-fx) * startPos[n011+1] + (fx) * startPos[n111+1]; rgbaBuffer[2] = (1-fy) * startPos[n000+2] + (fy-fz) * startPos[n010+2] + (fz-fx) * startPos[n011+2] + (fx) * startPos[n111+2]; } else { rgbaBuffer[0] = (1-fy) * startPos[n000] + (fy-fx) * startPos[n010] + (fx-fz) * startPos[n110] + (fz) * startPos[n111]; rgbaBuffer[1] = (1-fy) * startPos[n000+1] + (fy-fx) * startPos[n010+1] + (fx-fz) * startPos[n110+1] + (fz) * startPos[n111+1]; rgbaBuffer[2] = (1-fy) * startPos[n000+2] + (fy-fx) * startPos[n010+2] + (fx-fz) * startPos[n110+2] + (fz) * startPos[n111+2]; } } } // !isnan rgbaBuffer += 4; } } void GenerateIdentityLut3D(float* img, int edgeLen, int numChannels, Lut3DOrder lut3DOrder) { if(!img) return; if(numChannels < 3) { throw Exception("Cannot generate idenitity 3d lut with less than 3 channels."); } float c = 1.0f / ((float)edgeLen - 1.0f); if(lut3DOrder == LUT3DORDER_FAST_RED) { for(int i=0; i(roundf(powf((float) numPixels, 1.0f/3.0f))); if(dim*dim*dim != numPixels) { std::ostringstream os; os << "Cannot infer 3D Lut size. "; os << numPixels << " element(s) does not correspond to a "; os << "unform cube edge length. (nearest edge length is "; os << dim << ")."; throw Exception(os.str().c_str()); } return dim; } namespace { class Lut3DOp : public Op { public: Lut3DOp(Lut3DRcPtr lut, Interpolation interpolation, TransformDirection direction); virtual ~Lut3DOp(); virtual OpRcPtr clone() const; virtual std::string getInfo() const; virtual std::string getCacheID() const; virtual bool isNoOp() const; virtual bool isSameType(const OpRcPtr & op) const; virtual bool isInverse(const OpRcPtr & op) const; virtual bool hasChannelCrosstalk() const; virtual void finalize(); virtual void apply(float* rgbaBuffer, long numPixels) const; virtual bool supportsGpuShader() const; virtual void writeGpuShader(std::ostream & shader, const std::string & pixelName, const GpuShaderDesc & shaderDesc) const; private: Lut3DRcPtr m_lut; Interpolation m_interpolation; TransformDirection m_direction; // Set in finalize std::string m_cacheID; }; typedef OCIO_SHARED_PTR Lut3DOpRcPtr; Lut3DOp::Lut3DOp(Lut3DRcPtr lut, Interpolation interpolation, TransformDirection direction): Op(), m_lut(lut), m_interpolation(interpolation), m_direction(direction) { } OpRcPtr Lut3DOp::clone() const { OpRcPtr op = OpRcPtr(new Lut3DOp(m_lut, m_interpolation, m_direction)); return op; } Lut3DOp::~Lut3DOp() { } std::string Lut3DOp::getInfo() const { return ""; } std::string Lut3DOp::getCacheID() const { return m_cacheID; } // TODO: compute real value for isNoOp bool Lut3DOp::isNoOp() const { return false; } bool Lut3DOp::isSameType(const OpRcPtr & op) const { Lut3DOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; return true; } bool Lut3DOp::isInverse(const OpRcPtr & op) const { Lut3DOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; if(GetInverseTransformDirection(m_direction) != typedRcPtr->m_direction) return false; return (m_lut->getCacheID() == typedRcPtr->m_lut->getCacheID()); } // TODO: compute real value for hasChannelCrosstalk bool Lut3DOp::hasChannelCrosstalk() const { return true; } void Lut3DOp::finalize() { if(m_direction != TRANSFORM_DIR_FORWARD) { std::ostringstream os; os << "3D Luts can only be applied in the forward direction. "; os << "(" << TransformDirectionToString(m_direction) << ")"; os << " specified."; throw Exception(os.str().c_str()); } // Validate the requested interpolation type switch(m_interpolation) { // These are the allowed values. case INTERP_NEAREST: case INTERP_LINEAR: case INTERP_TETRAHEDRAL: break; case INTERP_BEST: m_interpolation = INTERP_LINEAR; break; case INTERP_UNKNOWN: throw Exception("Cannot apply Lut3DOp, unspecified interpolation."); break; default: throw Exception("Cannot apply Lut3DOp, invalid interpolation specified."); } for(int i=0; i<3; ++i) { if(m_lut->size[i] == 0) { throw Exception("Cannot apply Lut3DOp, lut object is empty."); } // TODO if from_min[i] == from_max[i] } if(m_lut->size[0]*m_lut->size[1]*m_lut->size[2] * 3 != (int)m_lut->lut.size()) { throw Exception("Cannot apply Lut3DOp, specified size does not match data."); } // Create the cacheID std::ostringstream cacheIDStream; cacheIDStream << "getCacheID() << " "; cacheIDStream << InterpolationToString(m_interpolation) << " "; cacheIDStream << TransformDirectionToString(m_direction) << " "; cacheIDStream << ">"; m_cacheID = cacheIDStream.str(); } void Lut3DOp::apply(float* rgbaBuffer, long numPixels) const { if(m_interpolation == INTERP_NEAREST) { Lut3D_Nearest(rgbaBuffer, numPixels, *m_lut); } else if(m_interpolation == INTERP_LINEAR) { Lut3D_Linear(rgbaBuffer, numPixels, *m_lut); } else if(m_interpolation == INTERP_TETRAHEDRAL) { Lut3D_Tetrahedral(rgbaBuffer, numPixels, *m_lut); } } bool Lut3DOp::supportsGpuShader() const { return false; } void Lut3DOp::writeGpuShader(std::ostream & /*shader*/, const std::string & /*pixelName*/, const GpuShaderDesc & /*shaderDesc*/) const { throw Exception("Lut3DOp does not support analytical shader generation."); } } void CreateLut3DOp(OpRcPtrVec & ops, Lut3DRcPtr lut, Interpolation interpolation, TransformDirection direction) { ops.push_back( Lut3DOpRcPtr(new Lut3DOp(lut, interpolation, direction)) ); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST #include #include #ifndef WIN32 #include #endif namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" OIIO_ADD_TEST(Lut3DOp, NanInfValueCheck) { OCIO::Lut3DRcPtr lut = OCIO::Lut3D::Create(); lut->from_min[0] = 0.0f; lut->from_min[1] = 0.0f; lut->from_min[2] = 0.0f; lut->from_max[0] = 1.0f; lut->from_max[1] = 1.0f; lut->from_max[2] = 1.0f; lut->size[0] = 3; lut->size[1] = 3; lut->size[2] = 3; lut->lut.resize(lut->size[0]*lut->size[1]*lut->size[2]*3); GenerateIdentityLut3D(&lut->lut[0], lut->size[0], 3, OCIO::LUT3DORDER_FAST_RED); for(unsigned int i=0; ilut.size(); ++i) { lut->lut[i] = powf(lut->lut[i], 2.0f); } const float reference[4] = { std::numeric_limits::signaling_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::infinity(), -std::numeric_limits::infinity() }; float color[4]; memcpy(color, reference, 4*sizeof(float)); OCIO::Lut3D_Nearest(color, 1, *lut); memcpy(color, reference, 4*sizeof(float)); OCIO::Lut3D_Linear(color, 1, *lut); } OIIO_ADD_TEST(Lut3DOp, ValueCheck) { OCIO::Lut3DRcPtr lut = OCIO::Lut3D::Create(); lut->from_min[0] = 0.0f; lut->from_min[1] = 0.0f; lut->from_min[2] = 0.0f; lut->from_max[0] = 1.0f; lut->from_max[1] = 1.0f; lut->from_max[2] = 1.0f; lut->size[0] = 32; lut->size[1] = 32; lut->size[2] = 32; lut->lut.resize(lut->size[0]*lut->size[1]*lut->size[2]*3); GenerateIdentityLut3D(&lut->lut[0], lut->size[0], 3, OCIO::LUT3DORDER_FAST_RED); for(unsigned int i=0; ilut.size(); ++i) { lut->lut[i] = powf(lut->lut[i], 2.0f); } const float reference[] = { 0.0f, 0.2f, 0.3f, 1.0f, 0.1234f, 0.4567f, 0.9876f, 1.0f, 11.0f, -0.5f, 0.5010f, 1.0f }; const float nearest[] = { 0.0f, 0.03746097535f, 0.0842871964f, 1.0f, 0.01664932258f, 0.2039542049f, 1.0f, 1.0f, 1.0f, 0.0f, 0.2663891613f, 1.0f }; const float linear[] = { 0.0f, 0.04016649351f, 0.09021852165f, 1.0f, 0.01537752338f, 0.2087130845f, 0.9756000042f, 1.0f, 1.0f, 0.0f, 0.2512601018f, 1.0f }; float color[12]; // Check nearest memcpy(color, reference, 12*sizeof(float)); OCIO::Lut3D_Nearest(color, 3, *lut); for(unsigned int i=0; i<12; ++i) { OIIO_CHECK_CLOSE(color[i], nearest[i], 1e-8); } // Check linear memcpy(color, reference, 12*sizeof(float)); OCIO::Lut3D_Linear(color, 3, *lut); for(unsigned int i=0; i<12; ++i) { OIIO_CHECK_CLOSE(color[i], linear[i], 1e-8); } // Check tetrahedral memcpy(color, reference, 12*sizeof(float)); OCIO::Lut3D_Tetrahedral(color, 3, *lut); for(unsigned int i=0; i<12; ++i) { OIIO_CHECK_CLOSE(color[i], linear[i], 1e-7); // Note, max delta lowered from 1e-8 } } OIIO_ADD_TEST(Lut3DOp, InverseComparisonCheck) { OCIO::Lut3DRcPtr lut_a = OCIO::Lut3D::Create(); lut_a->from_min[0] = 0.0f; lut_a->from_min[1] = 0.0f; lut_a->from_min[2] = 0.0f; lut_a->from_max[0] = 1.0f; lut_a->from_max[1] = 1.0f; lut_a->from_max[2] = 1.0f; lut_a->size[0] = 32; lut_a->size[1] = 32; lut_a->size[2] = 32; lut_a->lut.resize(lut_a->size[0]*lut_a->size[1]*lut_a->size[2]*3); GenerateIdentityLut3D(&lut_a->lut[0], lut_a->size[0], 3, OCIO::LUT3DORDER_FAST_RED); OCIO::Lut3DRcPtr lut_b = OCIO::Lut3D::Create(); lut_b->from_min[0] = 0.5f; lut_b->from_min[1] = 0.5f; lut_b->from_min[2] = 0.5f; lut_b->from_max[0] = 1.0f; lut_b->from_max[1] = 1.0f; lut_b->from_max[2] = 1.0f; lut_b->size[0] = 32; lut_b->size[1] = 32; lut_b->size[2] = 32; lut_b->lut.resize(lut_b->size[0]*lut_b->size[1]*lut_b->size[2]*3); GenerateIdentityLut3D(&lut_b->lut[0], lut_b->size[0], 3, OCIO::LUT3DORDER_FAST_RED); OCIO::OpRcPtrVec ops; CreateLut3DOp(ops, lut_a, OCIO::INTERP_NEAREST, OCIO::TRANSFORM_DIR_FORWARD); CreateLut3DOp(ops, lut_a, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_INVERSE); CreateLut3DOp(ops, lut_b, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_FORWARD); CreateLut3DOp(ops, lut_b, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_INVERSE); OIIO_CHECK_EQUAL(ops.size(), 4); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[1])); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[2])); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[3]->clone())); OIIO_CHECK_EQUAL( ops[0]->isInverse(ops[1]), true); OIIO_CHECK_EQUAL( ops[0]->isInverse(ops[2]), false); OIIO_CHECK_EQUAL( ops[0]->isInverse(ops[2]), false); OIIO_CHECK_EQUAL( ops[0]->isInverse(ops[3]), false); OIIO_CHECK_EQUAL( ops[2]->isInverse(ops[3]), true); } OIIO_ADD_TEST(Lut3DOp, PerformanceCheck) { /* OCIO::Lut3D lut; lut.from_min[0] = 0.0f; lut.from_min[1] = 0.0f; lut.from_min[2] = 0.0f; lut.from_max[0] = 1.0f; lut.from_max[1] = 1.0f; lut.from_max[2] = 1.0f; lut.size[0] = 32; lut.size[1] = 32; lut.size[2] = 32; lut.lut.resize(lut.size[0]*lut.size[1]*lut.size[2]*3); GenerateIdentityLut3D(&lut.lut[0], lut.size[0], 3, OCIO::LUT3DORDER_FAST_RED); std::vector img; int xres = 2048; int yres = 1; int channels = 4; img.resize(xres*yres*channels); srand48(0); // create random values from -0.05 to 1.05 // (To simulate clipping performance) for(unsigned int i=0; i #include "CDLTransform.h" #include "PathUtils.h" #include "FileTransform.h" OCIO_NAMESPACE_ENTER { // TODO: Processors which the user hangs onto have local caches. // Should these be cleared? void ClearAllCaches() { ClearPathCaches(); ClearFileTransformCaches(); ClearCDLTransformFileCache(); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/CMakeLists.txt0000644000175000017500000001050213223553423020543 0ustar mfvmfv############################################################################### ### OCIO CORE ### include_directories( ${CMAKE_SOURCE_DIR}/export/ ${CMAKE_BINARY_DIR}/export/ ${CMAKE_SOURCE_DIR}/ext/oiio/src/include ${EXTERNAL_INCLUDE_DIRS} ) file(GLOB_RECURSE core_src_files "${CMAKE_SOURCE_DIR}/src/core/*.cpp") file(GLOB_RECURSE core_export_headers "${CMAKE_SOURCE_DIR}/export/OpenColorIO/*.h") message(STATUS "Create OpenColorABI.h from OpenColorABI.h.in") configure_file(${CMAKE_SOURCE_DIR}/export/OpenColorIO/OpenColorABI.h.in ${CMAKE_BINARY_DIR}/export/OpenColorABI.h @ONLY) list(APPEND core_export_headers ${CMAKE_BINARY_DIR}/export/OpenColorABI.h) # Process all warnings as errors if(WIN32) # On debug mode there are other kinds of warning... if("${CMAKE_BUILD_TYPE}" STREQUAL "Release") set(EXTERNAL_COMPILE_FLAGS "${EXTERNAL_COMPILE_FLAGS} /WX") endif() else() set(EXTERNAL_COMPILE_FLAGS "${EXTERNAL_COMPILE_FLAGS} -Werror") endif() # SHARED if(OCIO_BUILD_SHARED) add_library(OpenColorIO SHARED ${EXTERNAL_OBJECTS} ${core_src_files}) if(USE_EXTERNAL_TINYXML) target_link_libraries(OpenColorIO ${TINYXML_LIBRARIES}) else(USE_EXTERNAL_TINYXML) add_dependencies(OpenColorIO TINYXML_LIB) endif(USE_EXTERNAL_TINYXML) if(USE_EXTERNAL_YAML) target_link_libraries(OpenColorIO ${YAML_CPP_LIBRARIES}) else(USE_EXTERNAL_YAML) add_dependencies(OpenColorIO YAML_CPP_LIB) endif() if(EXTERNAL_LIBRARIES) target_link_libraries(OpenColorIO ${EXTERNAL_LIBRARIES}) endif() if(WIN32) # Mute a design issue where the Exception public class inherits # from a STL Exception. STL classes are never supposed to # be exported among different dynamic libraries. set(EXTERNAL_COMPILE_FLAGS "${EXTERNAL_COMPILE_FLAGS} /wd4275") endif() set_target_properties(OpenColorIO PROPERTIES OUTPUT_NAME OpenColorIO COMPILE_FLAGS "${EXTERNAL_COMPILE_FLAGS}" LINK_FLAGS "${EXTERNAL_LINK_FLAGS}") message(STATUS "Setting OCIO SOVERSION to: ${SOVERSION}") set_target_properties(OpenColorIO PROPERTIES VERSION ${OCIO_VERSION} SOVERSION ${SOVERSION}) install(TARGETS OpenColorIO EXPORT OpenColorIO ARCHIVE DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib${LIB_SUFFIX} LIBRARY DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib${LIB_SUFFIX} RUNTIME DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/bin ) endif() # STATIC if(OCIO_BUILD_STATIC) list(REMOVE_ITEM core_src_files ${CMAKE_SOURCE_DIR}/src/core/UnitTest.cpp) add_library(OpenColorIO_STATIC STATIC ${EXTERNAL_OBJECTS} ${core_src_files}) add_dependencies(OpenColorIO_STATIC TINYXML_LIB YAML_CPP_LIB) if(EXTERNAL_LIBRARIES) target_link_libraries(OpenColorIO_STATIC ${EXTERNAL_LIBRARIES}) endif() set_target_properties(OpenColorIO_STATIC PROPERTIES COMPILE_DEFINITIONS "OpenColorIO_STATIC") set_target_properties(OpenColorIO_STATIC PROPERTIES OUTPUT_NAME OpenColorIO ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/static" COMPILE_FLAGS "${EXTERNAL_COMPILE_FLAGS}" LINK_FLAGS "${EXTERNAL_LINK_FLAGS}") message(STATUS "Setting OCIO SOVERSION to: ${SOVERSION}") set_target_properties(OpenColorIO_STATIC PROPERTIES VERSION ${OCIO_VERSION} SOVERSION ${SOVERSION}) install(TARGETS OpenColorIO_STATIC EXPORT OpenColorIO ARCHIVE DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib/static) endif() macro(target_link_OCIO target) if(OCIO_BUILD_SHARED) target_link_libraries(${target} OpenColorIO ${ARGN}) elseif(OCIO_BUILD_STATIC) target_link_libraries(${target} OpenColorIO_STATIC ${ARGN}) set_target_properties(${target} PROPERTIES COMPILE_DEFINITIONS OpenColorIO_STATIC) endif() endmacro() # public interface install(FILES ${core_export_headers} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/OpenColorIO/) # pkg-config message(STATUS "Create OpenColorIO.pc from OpenColorIO.pc.in") configure_file(${CMAKE_SOURCE_DIR}/export/pkgconfig/OpenColorIO.pc.in ${CMAKE_CURRENT_BINARY_DIR}/OpenColorIO.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenColorIO.pc DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib${LIB_SUFFIX}/pkgconfig/) opencolorio-1.1.0~dfsg0.orig/src/core/Op.h0000644000175000017500000001211013223553423016527 0ustar mfvmfv/* 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_OCIO_OP_H #define INCLUDED_OCIO_OP_H #include #include #include OCIO_NAMESPACE_ENTER { struct AllocationData { Allocation allocation; std::vector vars; AllocationData(): allocation(ALLOCATION_UNIFORM) {}; std::string getCacheID() const; }; std::ostream& operator<< (std::ostream&, const AllocationData&); class Op; typedef OCIO_SHARED_PTR OpRcPtr; typedef std::vector OpRcPtrVec; std::string SerializeOpVec(const OpRcPtrVec & ops, int indent=0); bool IsOpVecNoOp(const OpRcPtrVec & ops); void FinalizeOpVec(OpRcPtrVec & opVec, bool optimize=true); void OptimizeOpVec(OpRcPtrVec & result); class Op { public: virtual ~Op(); virtual OpRcPtr clone() const = 0; //! Something short, and printable. // The type of stuff you'd want to see in debugging. virtual std::string getInfo() const = 0; //! This should yield a string of not unreasonable length. //! It can only be called after finalize() virtual std::string getCacheID() const = 0; //! Is the processing a noop? I.e, does apply do nothing. //! (Even no-ops may define Allocation though.) //! This must be implmented in a manner where its valid to call //! *prior* to finalize. (Optimizers may make use of it) virtual bool isNoOp() const = 0; virtual bool isSameType(const OpRcPtr & op) const = 0; virtual bool isInverse(const OpRcPtr & op) const = 0; virtual bool canCombineWith(const OpRcPtr & op) const; // Return a vector of result ops, which correspond to // THIS combinedWith secondOp. // // If the result is a noOp, it is valid for the resulting opsVec // to be empty. virtual void combineWith(OpRcPtrVec & ops, const OpRcPtr & secondOp) const; virtual bool hasChannelCrosstalk() const = 0; virtual void dumpMetadata(ProcessorMetadataRcPtr & /*metadata*/) const { } // This is called a single time after construction. // Final pre-processing and safety checks should happen here, // rather than in the constructor. virtual void finalize() = 0; // Render the specified pixels. // // This must be safe to call in a multi-threaded context. // Ops that have mutable data internally, or rely on external // caching, must thus be appropriately mutexed. virtual void apply(float* rgbaBuffer, long numPixels) const = 0; //! Does this op support gpu shader text generation virtual bool supportsGpuShader() const = 0; // TODO: If temp variables are ever needed, also pass tempvar prefix. virtual void writeGpuShader(std::ostream & shader, const std::string & pixelName, const GpuShaderDesc & shaderDesc) const = 0; private: Op& operator= (const Op &); }; std::ostream& operator<< (std::ostream&, const Op&); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/Processor.h0000644000175000017500000001170213223553423020136 0ustar mfvmfv/* 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_OCIO_PROCESSOR_H #define INCLUDED_OCIO_PROCESSOR_H #include #include #include "Mutex.h" #include "Op.h" #include "PrivateTypes.h" OCIO_NAMESPACE_ENTER { class Processor::Impl { private: ProcessorMetadataRcPtr m_metadata; OpRcPtrVec m_cpuOps; // These 3 op vecs represent the 3 stages in our gpu pipe. // 1) preprocess shader text // 2) 3d lut process lookup // 3) postprocess shader text OpRcPtrVec m_gpuOpsHwPreProcess; OpRcPtrVec m_gpuOpsCpuLatticeProcess; OpRcPtrVec m_gpuOpsHwPostProcess; mutable std::string m_cpuCacheID; // Cache the last last queried value, // for the specified shader description mutable std::string m_lastShaderDesc; mutable std::string m_shader; mutable std::string m_shaderCacheID; mutable std::vector m_lut3D; mutable std::string m_lut3DCacheID; mutable Mutex m_resultsCacheMutex; public: Impl(); ~Impl(); bool isNoOp() const; bool hasChannelCrosstalk() const; ConstProcessorMetadataRcPtr getMetadata() const; void apply(ImageDesc& img) const; void applyRGB(float * pixel) const; void applyRGBA(float * pixel) const; const char * getCpuCacheID() const; const char * getGpuShaderText(const GpuShaderDesc & gpuDesc) const; const char * getGpuShaderTextCacheID(const GpuShaderDesc & shaderDesc) const; void getGpuLut3D(float* lut3d, const GpuShaderDesc & shaderDesc) const; const char * getGpuLut3DCacheID(const GpuShaderDesc & shaderDesc) const; //////////////////////////////////////////// // // Builder functions, Not exposed void addColorSpaceConversion(const Config & config, const ConstContextRcPtr & context, const ConstColorSpaceRcPtr & srcColorSpace, const ConstColorSpaceRcPtr & dstColorSpace); void addTransform(const Config & config, const ConstContextRcPtr & context, const ConstTransformRcPtr& transform, TransformDirection direction); void finalize(); void calcGpuShaderText(std::ostream & shader, const GpuShaderDesc & shaderDesc) const; }; // TODO: Move these! // TODO: Its not ideal that buildops requires a config to be passed around // but the only alternative is to make build ops a function on it? // and even if it were, what about the build calls it dispatches to... // TODO: all of the build op functions shouldnt take a LocalProcessor class // Instead, they should take an abstract interface class that defines // registerOp(OpRcPtr op), annotateColorSpace, finalizeOps, etc. // of which LocalProcessor happens to be one example. // Then the only location in the codebase that knows of LocalProcessor is // in Config.cpp, which creates one. void BuildOps(OpRcPtrVec & ops, const Config & config, const ConstTransformRcPtr & transform, TransformDirection dir); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/Display.h0000644000175000017500000000600613223553423017565 0ustar mfvmfv/* 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_OCIO_DISPLAY_H #define INCLUDED_OCIO_DISPLAY_H #include #include #include #include #include "PrivateTypes.h" OCIO_NAMESPACE_ENTER { // Displays struct View { std::string name; std::string colorspace; std::string looks; View() { } View(const std::string & name_, const std::string & colorspace_, const std::string & looksList_) : name(name_), colorspace(colorspace_), looks(looksList_) { } }; typedef std::vector ViewVec; typedef std::map DisplayMap; // (display name : ViewVec) DisplayMap::iterator find_display(DisplayMap & displays, const std::string & display); DisplayMap::const_iterator find_display_const(const DisplayMap & displays, const std::string & display); int find_view(const ViewVec & vec, const std::string & name); void AddDisplay(DisplayMap & displays, const std::string & display, const std::string & view, const std::string & colorspace, const std::string & looks); void ComputeDisplays(StringVec & displayCache, const DisplayMap & displays, const StringVec & activeDisplays, const StringVec & activeDisplaysEnvOverride); } OCIO_NAMESPACE_EXIT #endifopencolorio-1.1.0~dfsg0.orig/src/core/FileFormatCDL.cpp0000644000175000017500000002156013223553423021070 0ustar mfvmfv/* Copyright (c) 2014 Cinesite VFX Ltd, 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 #include #include #include "CDLTransform.h" #include "FileTransform.h" #include "OpBuilders.h" #include "ParseUtils.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { //////////////////////////////////////////////////////////////// namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile () {}; ~LocalCachedFile() {}; CDLTransformMap transformMap; CDLTransformVec transformVec; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; typedef OCIO_SHARED_PTR TiXmlDocumentRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "ColorDecisionList"; info.extension = "cdl"; info.capabilities = FORMAT_CAPABILITY_READ; formatInfoVec.push_back(info); } // Try and load the format // Raise an exception if it can't be loaded. CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { std::ostringstream rawdata; rawdata << istream.rdbuf(); LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile()); TiXmlDocumentRcPtr doc = TiXmlDocumentRcPtr(new TiXmlDocument()); doc->Parse(rawdata.str().c_str()); if(doc->Error()) { std::ostringstream os; os << "XML Parse Error. "; os << doc->ErrorDesc() << " (line "; os << doc->ErrorRow() << ", character "; os << doc->ErrorCol() << ")"; throw Exception(os.str().c_str()); } TiXmlElement* rootElement = doc->RootElement(); GetCDLTransforms(cachedFile->transformMap, cachedFile->transformVec, rootElement); return cachedFile; } void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { LocalCachedFileRcPtr cachedFile = DynamicPtrCast(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build .cdl Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_UNKNOWN) { std::ostringstream os; os << "Cannot build ASC FileTransform,"; os << " unspecified transform direction."; throw Exception(os.str().c_str()); } // Below this point, we should throw ExceptionMissingFile on // errors rather than Exception // This is because we've verified that the cdl file is valid, // at now we're only querying whether the specified cccid can // be found. // // Using ExceptionMissingFile enables the missing looks fallback // mechanism to function properly. // At the time ExceptionMissingFile was named, we errently assumed // a 1:1 relationship between files and color corrections, which is // not true for .cdl files. // // In a future OCIO release, it may be more appropriate to // rename ExceptionMissingFile -> ExceptionMissingCorrection. // But either way, it's what we should throw below. std::string cccid = fileTransform.getCCCId(); cccid = context->resolveStringVar(cccid.c_str()); if(cccid.empty()) { std::ostringstream os; os << "You must specify which cccid to load from the ccc file"; os << " (either by name or index)."; throw ExceptionMissingFile(os.str().c_str()); } bool success=false; // Try to parse the cccid as a string id CDLTransformMap::const_iterator iter = cachedFile->transformMap.find(cccid); if(iter != cachedFile->transformMap.end()) { success = true; BuildCDLOps(ops, config, *(iter->second), newDir); } // Try to parse the cccid as an integer index // We want to be strict, so fail if leftover chars in the parse. if(!success) { int cccindex=0; if(StringToInt(&cccindex, cccid.c_str(), true)) { int maxindex = ((int)cachedFile->transformVec.size())-1; if(cccindex<0 || cccindex>maxindex) { std::ostringstream os; os << "The specified cccindex " << cccindex; os << " is outside the valid range for this file [0,"; os << maxindex << "]"; throw ExceptionMissingFile(os.str().c_str()); } success = true; BuildCDLOps(ops, config, *cachedFile->transformVec[cccindex], newDir); } } if(!success) { std::ostringstream os; os << "You must specify a valid cccid to load from the ccc file"; os << " (either by name or index). id='" << cccid << "' "; os << "is not found in the file, and is not parsable as an "; os << "integer index."; throw ExceptionMissingFile(os.str().c_str()); } } } FileFormat * CreateFileFormatCDL() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/ParseUtils.cpp0000644000175000017500000003757313223553423020623 0ustar mfvmfv/* 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 #include #include #include #include "ParseUtils.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { const char * BoolToString(bool val) { if(val) return "true"; return "false"; } bool BoolFromString(const char * s) { std::string str = pystring::lower(s); if((str == "true") || (str=="yes")) return true; return false; } const char * LoggingLevelToString(LoggingLevel level) { if(level == LOGGING_LEVEL_NONE) return "none"; else if(level == LOGGING_LEVEL_WARNING) return "warning"; else if(level == LOGGING_LEVEL_INFO) return "info"; else if(level == LOGGING_LEVEL_DEBUG) return "debug"; return "unknown"; } LoggingLevel LoggingLevelFromString(const char * s) { std::string str = pystring::lower(s); if(str == "0" || str == "none") return LOGGING_LEVEL_NONE; else if(str == "1" || str == "warning") return LOGGING_LEVEL_WARNING; else if(str == "2" || str == "info") return LOGGING_LEVEL_INFO; else if(str == "3" || str == "debug") return LOGGING_LEVEL_DEBUG; return LOGGING_LEVEL_UNKNOWN; } const char * TransformDirectionToString(TransformDirection dir) { if(dir == TRANSFORM_DIR_FORWARD) return "forward"; else if(dir == TRANSFORM_DIR_INVERSE) return "inverse"; return "unknown"; } TransformDirection TransformDirectionFromString(const char * s) { std::string str = pystring::lower(s); if(str == "forward") return TRANSFORM_DIR_FORWARD; else if(str == "inverse") return TRANSFORM_DIR_INVERSE; return TRANSFORM_DIR_UNKNOWN; } TransformDirection CombineTransformDirections(TransformDirection d1, TransformDirection d2) { // Any unknowns always combine to be unknown. if(d1 == TRANSFORM_DIR_UNKNOWN || d2 == TRANSFORM_DIR_UNKNOWN) return TRANSFORM_DIR_UNKNOWN; if(d1 == TRANSFORM_DIR_FORWARD && d2 == TRANSFORM_DIR_FORWARD) return TRANSFORM_DIR_FORWARD; if(d1 == TRANSFORM_DIR_INVERSE && d2 == TRANSFORM_DIR_INVERSE) return TRANSFORM_DIR_FORWARD; return TRANSFORM_DIR_INVERSE; } TransformDirection GetInverseTransformDirection(TransformDirection dir) { if(dir == TRANSFORM_DIR_FORWARD) return TRANSFORM_DIR_INVERSE; else if(dir == TRANSFORM_DIR_INVERSE) return TRANSFORM_DIR_FORWARD; return TRANSFORM_DIR_UNKNOWN; } const char * ColorSpaceDirectionToString(ColorSpaceDirection dir) { if(dir == COLORSPACE_DIR_TO_REFERENCE) return "to_reference"; else if(dir == COLORSPACE_DIR_FROM_REFERENCE) return "from_reference"; return "unknown"; } ColorSpaceDirection ColorSpaceDirectionFromString(const char * s) { std::string str = pystring::lower(s); if(str == "to_reference") return COLORSPACE_DIR_TO_REFERENCE; else if(str == "from_reference") return COLORSPACE_DIR_FROM_REFERENCE; return COLORSPACE_DIR_UNKNOWN; } const char * BitDepthToString(BitDepth bitDepth) { if(bitDepth == BIT_DEPTH_UINT8) return "8ui"; else if(bitDepth == BIT_DEPTH_UINT10) return "10ui"; else if(bitDepth == BIT_DEPTH_UINT12) return "12ui"; else if(bitDepth == BIT_DEPTH_UINT14) return "14ui"; else if(bitDepth == BIT_DEPTH_UINT16) return "16ui"; else if(bitDepth == BIT_DEPTH_UINT32) return "32ui"; else if(bitDepth == BIT_DEPTH_F16) return "16f"; else if(bitDepth == BIT_DEPTH_F32) return "32f"; return "unknown"; } BitDepth BitDepthFromString(const char * s) { std::string str = pystring::lower(s); if(str == "8ui") return BIT_DEPTH_UINT8; else if(str == "10ui") return BIT_DEPTH_UINT10; else if(str == "12ui") return BIT_DEPTH_UINT12; else if(str == "14ui") return BIT_DEPTH_UINT14; else if(str == "16ui") return BIT_DEPTH_UINT16; else if(str == "32ui") return BIT_DEPTH_UINT32; else if(str == "16f") return BIT_DEPTH_F16; else if(str == "32f") return BIT_DEPTH_F32; return BIT_DEPTH_UNKNOWN; } bool BitDepthIsFloat(BitDepth bitDepth) { if(bitDepth == BIT_DEPTH_F16) return true; else if(bitDepth == BIT_DEPTH_F32) return true; return false; } int BitDepthToInt(BitDepth bitDepth) { if(bitDepth == BIT_DEPTH_UINT8) return 8; else if(bitDepth == BIT_DEPTH_UINT10) return 10; else if(bitDepth == BIT_DEPTH_UINT12) return 12; else if(bitDepth == BIT_DEPTH_UINT14) return 14; else if(bitDepth == BIT_DEPTH_UINT16) return 16; else if(bitDepth == BIT_DEPTH_UINT32) return 32; return 0; } const char * AllocationToString(Allocation alloc) { if(alloc == ALLOCATION_UNIFORM) return "uniform"; else if(alloc == ALLOCATION_LG2) return "lg2"; return "unknown"; } Allocation AllocationFromString(const char * s) { std::string str = pystring::lower(s); if(str == "uniform") return ALLOCATION_UNIFORM; else if(str == "lg2") return ALLOCATION_LG2; return ALLOCATION_UNKNOWN; } const char * InterpolationToString(Interpolation interp) { if(interp == INTERP_NEAREST) return "nearest"; else if(interp == INTERP_LINEAR) return "linear"; else if(interp == INTERP_TETRAHEDRAL) return "tetrahedral"; else if(interp == INTERP_BEST) return "best"; return "unknown"; } Interpolation InterpolationFromString(const char * s) { std::string str = pystring::lower(s); if(str == "nearest") return INTERP_NEAREST; else if(str == "linear") return INTERP_LINEAR; else if(str == "tetrahedral") return INTERP_TETRAHEDRAL; else if(str == "best") return INTERP_BEST; return INTERP_UNKNOWN; } const char * GpuLanguageToString(GpuLanguage language) { if(language == GPU_LANGUAGE_CG) return "cg"; else if(language == GPU_LANGUAGE_GLSL_1_0) return "glsl_1.0"; else if(language == GPU_LANGUAGE_GLSL_1_3) return "glsl_1.3"; return "unknown"; } GpuLanguage GpuLanguageFromString(const char * s) { std::string str = pystring::lower(s); if(str == "cg") return GPU_LANGUAGE_CG; else if(str == "glsl_1.0") return GPU_LANGUAGE_GLSL_1_0; else if(str == "glsl_1.3") return GPU_LANGUAGE_GLSL_1_3; return GPU_LANGUAGE_UNKNOWN; } const char * EnvironmentModeToString(EnvironmentMode mode) { if(mode == ENV_ENVIRONMENT_LOAD_PREDEFINED) return "loadpredefined"; else if(mode == ENV_ENVIRONMENT_LOAD_ALL) return "loadall"; return "unknown"; } EnvironmentMode EnvironmentModeFromString(const char * s) { std::string str = pystring::lower(s); if(str == "loadpredefined") return ENV_ENVIRONMENT_LOAD_PREDEFINED; else if(str == "loadall") return ENV_ENVIRONMENT_LOAD_ALL; return ENV_ENVIRONMENT_UNKNOWN; } const char * ROLE_DEFAULT = "default"; const char * ROLE_REFERENCE = "reference"; const char * ROLE_DATA = "data"; const char * ROLE_COLOR_PICKING = "color_picking"; const char * ROLE_SCENE_LINEAR = "scene_linear"; const char * ROLE_COMPOSITING_LOG = "compositing_log"; const char * ROLE_COLOR_TIMING = "color_timing"; const char * ROLE_TEXTURE_PAINT = "texture_paint"; const char * ROLE_MATTE_PAINT = "matte_paint"; namespace { const int FLOAT_DECIMALS = 7; const int DOUBLE_DECIMALS = 16; } std::string FloatToString(float value) { std::ostringstream pretty; pretty.precision(FLOAT_DECIMALS); pretty << value; return pretty.str(); } std::string FloatVecToString(const float * fval, unsigned int size) { if(size<=0) return ""; std::ostringstream pretty; pretty.precision(FLOAT_DECIMALS); for(unsigned int i=0; i> x)) { return false; } if(fval) *fval = x; return true; } bool StringToInt(int * ival, const char * str, bool failIfLeftoverChars) { if(!str) return false; if(!ival) return false; std::istringstream i(str); char c=0; if (!(i >> *ival) || (failIfLeftoverChars && i.get(c))) return false; return true; } std::string DoubleToString(double value) { std::ostringstream pretty; pretty.precision(DOUBLE_DECIMALS); pretty << value; return pretty.str(); } bool StringVecToFloatVec(std::vector &floatArray, const std::vector &lineParts) { floatArray.resize(lineParts.size()); for(unsigned int i=0; i> x)) { return false; } floatArray[i] = x; } return true; } bool StringVecToIntVec(std::vector &intArray, const std::vector &lineParts) { intArray.resize(lineParts.size()); for(unsigned int i=0; i> x)) { return false; } intArray[i] = x; } return true; } //////////////////////////////////////////////////////////////////////////// // read the next non empty line, and store it in 'line' // return 'true' on success bool nextline(std::istream &istream, std::string &line) { while ( istream.good() ) { std::getline(istream, line); if(line.size() > 0 && line[line.size() - 1] == '\r') { line.resize(line.size() - 1); } if(!pystring::strip(line).empty()) { return true; } } line = ""; return false; } bool StrEqualsCaseIgnore(const std::string & a, const std::string & b) { return (pystring::lower(a) == pystring::lower(b)); } // If a ',' is in the string, split on it // If a ':' is in the string, split on it // Otherwise, assume a single string. // Also, strip whitespace from all parts. void SplitStringEnvStyle(std::vector & outputvec, const char * str) { if(!str) return; std::string s = pystring::strip(str); if(pystring::find(s, ",") > -1) { pystring::split(s, outputvec, ","); } else if(pystring::find(s, ":") > -1) { pystring::split(s, outputvec, ":"); } else { outputvec.push_back(s); } for(unsigned int i=0; i & outputvec) { return pystring::join(", ", outputvec); } // Ordering and capitalization from vec1 is preserved std::vector IntersectStringVecsCaseIgnore(const std::vector & vec1, const std::vector & vec2) { std::vector newvec; std::set allvalues; // Seed the set with all values from vec2 for(unsigned int i=0; i & vec, const std::string & str) { std::string teststr = pystring::lower(str); for(unsigned int i=0; i(i); } return -1; } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST OCIO_NAMESPACE_USING #include "UnitTest.h" OIIO_ADD_TEST(ParseUtils, StringToInt) { int ival = 0; bool success = false; success = StringToInt(&ival, "", false); OIIO_CHECK_EQUAL(success, false); success = StringToInt(&ival, "9", false); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 9); success = StringToInt(&ival, " 10 ", false); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 10); success = StringToInt(&ival, " 101", true); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 101); success = StringToInt(&ival, " 11x ", false); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 11); success = StringToInt(&ival, " 12x ", true); OIIO_CHECK_EQUAL(success, false); success = StringToInt(&ival, "13", true); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 13); success = StringToInt(&ival, "-14", true); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, -14); success = StringToInt(&ival, "x-15", false); OIIO_CHECK_EQUAL(success, false); success = StringToInt(&ival, "x-16", false); OIIO_CHECK_EQUAL(success, false); } #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/ScanlineHelper.h0000644000175000017500000000517413223553423021061 0ustar mfvmfv/* 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_OCIO_SCANLINEHELPER_H #define INCLUDED_OCIO_SCANLINEHELPER_H #include #include "ImagePacking.h" OCIO_NAMESPACE_ENTER { class ScanlineHelper { public: ScanlineHelper(ImageDesc& img); ~ScanlineHelper(); // Copy from the src image to our scanline, in our preferred // pixel layout. Return the number of pixels to process; void prepRGBAScanline(float** buffer, long* numPixels); // Write back the result of our work, from the scanline to our // destination image. void finishRGBAScanline(); private: GenericImageDesc m_img; // Copy mode float* m_buffer; long m_imagePixelIndex; int m_numPixelsCopied; // In place mode int m_yIndex; bool m_inPlaceMode; ScanlineHelper(const ScanlineHelper &); ScanlineHelper& operator= (const ScanlineHelper &); }; } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/GroupTransform.cpp0000644000175000017500000001354513223553423021511 0ustar mfvmfv/* 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 #include "OpBuilders.h" #include OCIO_NAMESPACE_ENTER { GroupTransformRcPtr GroupTransform::Create() { return GroupTransformRcPtr(new GroupTransform(), &deleter); } void GroupTransform::deleter(GroupTransform* t) { delete t; } namespace { typedef std::vector TransformRcPtrVec; } class GroupTransform::Impl { public: TransformDirection dir_; TransformRcPtrVec vec_; Impl() : dir_(TRANSFORM_DIR_FORWARD) { } ~Impl() { vec_.clear(); } Impl& operator= (const Impl & rhs) { dir_ = rhs.dir_; vec_.clear(); for(unsigned int i=0; icreateEditableCopy()); } return *this; } }; /////////////////////////////////////////////////////////////////////////// GroupTransform::GroupTransform() : m_impl(new GroupTransform::Impl) { } TransformRcPtr GroupTransform::createEditableCopy() const { GroupTransformRcPtr transform = GroupTransform::Create(); *(transform->m_impl) = *m_impl; return transform; } GroupTransform::~GroupTransform() { delete m_impl; m_impl = NULL; } GroupTransform& GroupTransform::operator= (const GroupTransform & rhs) { if(this!=&rhs) { *m_impl = *rhs.m_impl; } return *this; } TransformDirection GroupTransform::getDirection() const { return getImpl()->dir_; } void GroupTransform::setDirection(TransformDirection dir) { getImpl()->dir_ = dir; } int GroupTransform::size() const { return static_cast(getImpl()->vec_.size()); } ConstTransformRcPtr GroupTransform::getTransform(int index) const { if(index < 0 || index >= (int)getImpl()->vec_.size()) { std::ostringstream os; os << "Invalid transform index " << index << "."; throw Exception(os.str().c_str()); } return getImpl()->vec_[index]; } void GroupTransform::push_back(const ConstTransformRcPtr& transform) { getImpl()->vec_.push_back(transform->createEditableCopy()); } void GroupTransform::clear() { getImpl()->vec_.clear(); } bool GroupTransform::empty() const { return getImpl()->vec_.empty(); } std::ostream& operator<< (std::ostream& os, const GroupTransform& groupTransform) { os << ""; return os; } /////////////////////////////////////////////////////////////////////////// void BuildGroupOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, const GroupTransform& groupTransform, TransformDirection dir) { TransformDirection combinedDir = CombineTransformDirections(dir, groupTransform.getDirection()); if(combinedDir == TRANSFORM_DIR_FORWARD) { for(int i=0; i=0; --i) { ConstTransformRcPtr childTransform = groupTransform.getTransform(i); BuildOps(ops, config, context, childTransform, TRANSFORM_DIR_INVERSE); } } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/CDLTransform.cpp0000644000175000017500000006407713223553423021025 0ustar mfvmfv/* 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 #include #include #include #include "CDLTransform.h" #include "ExponentOps.h" #include "MatrixOps.h" #include "MathUtils.h" #include "Mutex.h" #include "OpBuilders.h" #include "ParseUtils.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { namespace { /* "" " " " " " 1 1 1 " " 0 0 0 " " 1 1 1 " " " " " " 1 " " " " "; */ // http://ticpp.googlecode.com/svn/docs/ticpp_8h-source.html#l01670 void SetTiXmlText( TiXmlElement* element, const char * value) { if ( element->NoChildren() ) { element->LinkEndChild( new TiXmlText( value ) ); } else { if ( 0 == element->GetText() ) { element->InsertBeforeChild( element->FirstChild(), TiXmlText( value ) ); } else { // There already is text, so change it element->FirstChild()->SetValue( value ); } } } std::string BuildXML(const CDLTransform & cdl) { TiXmlDocument doc; // TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" ); TiXmlElement * root = new TiXmlElement( "ColorCorrection" ); doc.LinkEndChild( root ); root->SetAttribute("id", cdl.getID()); TiXmlElement * sop = new TiXmlElement( "SOPNode" ); root->LinkEndChild( sop ); TiXmlElement * desc = new TiXmlElement( "Description" ); sop->LinkEndChild( desc ); SetTiXmlText(desc, cdl.getDescription()); TiXmlElement * slope = new TiXmlElement( "Slope" ); sop->LinkEndChild( slope ); float slopeval[3]; cdl.getSlope(slopeval); SetTiXmlText(slope, FloatVecToString(slopeval, 3).c_str()); TiXmlElement * offset = new TiXmlElement( "Offset" ); sop->LinkEndChild( offset ); float offsetval[3]; cdl.getOffset(offsetval); SetTiXmlText(offset, FloatVecToString(offsetval, 3).c_str()); TiXmlElement * power = new TiXmlElement( "Power" ); sop->LinkEndChild( power ); float powerval[3]; cdl.getPower(powerval); SetTiXmlText(power, FloatVecToString(powerval, 3).c_str()); TiXmlElement * sat = new TiXmlElement( "SatNode" ); root->LinkEndChild( sat ); TiXmlElement * saturation = new TiXmlElement( "Saturation" ); sat->LinkEndChild( saturation ); SetTiXmlText(saturation, FloatToString(cdl.getSat()).c_str()); TiXmlPrinter printer; printer.SetStreamPrinting(); doc.Accept( &printer ); return printer.Str(); } } void LoadCDL(CDLTransform * cdl, TiXmlElement * root) { if(!cdl) return; if(!root) { std::ostringstream os; os << "Error loading CDL xml. "; os << "Null root element."; throw Exception(os.str().c_str()); } if(std::string(root->Value()) != "ColorCorrection") { std::ostringstream os; os << "Error loading CDL xml. "; os << "Root element is type '" << root->Value() << "', "; os << "ColorCorrection expected."; throw Exception(os.str().c_str()); } TiXmlHandle handle( root ); const char * id = root->Attribute("id"); if(!id) id = ""; cdl->setID(id); TiXmlElement* desc = handle.FirstChild( "SOPNode" ).FirstChild("Description").ToElement(); if(desc) { const char * text = desc->GetText(); if(text) cdl->setDescription(text); } std::vector lineParts; std::vector floatArray; TiXmlElement* slope = handle.FirstChild( "SOPNode" ).FirstChild("Slope").ToElement(); if(slope) { const char * text = slope->GetText(); if(text) { pystring::split(pystring::strip(text), lineParts); if((lineParts.size() != 3) || (!StringVecToFloatVec(floatArray, lineParts))) { std::ostringstream os; os << "Error loading CDL xml. "; os << id << ".SOPNode.Slope text '"; os << text << "' is not convertible to 3 floats."; throw Exception(os.str().c_str()); } cdl->setSlope(&floatArray[0]); } } TiXmlElement* offset = handle.FirstChild( "SOPNode" ).FirstChild("Offset").ToElement(); if(offset) { const char * text = offset->GetText(); if(text) { pystring::split(pystring::strip(text), lineParts); if((lineParts.size() != 3) || (!StringVecToFloatVec(floatArray, lineParts))) { std::ostringstream os; os << "Error loading CDL xml. "; os << id << ".SOPNode.Offset text '"; os << text << "' is not convertible to 3 floats."; throw Exception(os.str().c_str()); } cdl->setOffset(&floatArray[0]); } } TiXmlElement* power = handle.FirstChild( "SOPNode" ).FirstChild("Power").ToElement(); if(power) { const char * text = power->GetText(); if(text) { pystring::split(pystring::strip(text), lineParts); if((lineParts.size() != 3) || (!StringVecToFloatVec(floatArray, lineParts))) { std::ostringstream os; os << "Error loading CDL xml. "; os << id << ".SOPNode.Power text '"; os << text << "' is not convertible to 3 floats."; throw Exception(os.str().c_str()); } cdl->setPower(&floatArray[0]); } } TiXmlElement* sat = handle.FirstChild( "SatNode" ).FirstChild("Saturation").ToElement(); if(sat) { const char * text = sat->GetText(); if(text) { float satval = 1.0f; if(!StringToFloat(&satval, text)) { std::ostringstream os; os << "Error loading CDL xml. "; os << id << ".SatNode.Saturation text '"; os << text << "' is not convertible to float."; throw Exception(os.str().c_str()); } cdl->setSat(satval); } } } void GetCDLTransforms(CDLTransformMap & transformMap, CDLTransformVec & transformVec, TiXmlElement * cccRootElement) { if(!cccRootElement) { std::ostringstream os; os << "GetCDLTransforms Error. "; os << "Null cccRootElement."; throw Exception(os.str().c_str()); } std::string rootElementType(cccRootElement->Value()); bool isCDL = (rootElementType == "ColorDecisionList"); const char* container = isCDL ? "ColorDecision" : "ColorCorrection"; if(!isCDL && rootElementType != "ColorCorrectionCollection") { std::ostringstream os; os << "GetCDLTransforms Error. "; os << "Root element is type '" << rootElementType << "', "; os << "ColorDecisionList or ColorCorrectionCollection expected."; throw Exception(os.str().c_str()); } TiXmlNode * child = cccRootElement->FirstChild(container); while(child) { TiXmlNode * xmlNode= (isCDL) ? child->FirstChild("ColorCorrection") : child; CDLTransformRcPtr transform = CDLTransform::Create(); LoadCDL(transform.get(), xmlNode->ToElement()); transformVec.push_back(transform); std::string id = transform->getID(); if(!id.empty()) { CDLTransformMap::iterator iter = transformMap.find(id); if(iter != transformMap.end()) { std::ostringstream os; os << "Error loading ccc xml. "; os << "Duplicate elements with '" << id << "' found. "; os << "If id is specified, it must be unique."; throw Exception(os.str().c_str()); } transformMap[id] = transform; } child = child->NextSibling(container); } } void LoadCDL(CDLTransform * cdl, const char * xml) { if(!xml || (strlen(xml) == 0)) { std::ostringstream os; os << "Error loading CDL xml. "; os << "Null string provided."; throw Exception(os.str().c_str()); } TiXmlDocument doc; doc.Parse(xml); if(doc.Error()) { std::ostringstream os; os << "Error loading CDL xml. "; os << doc.ErrorDesc() << " (line "; os << doc.ErrorRow() << ", character "; os << doc.ErrorCol() << ")"; throw Exception(os.str().c_str()); } if(!doc.RootElement()) { std::ostringstream os; os << "Error loading CDL xml, "; os << "please confirm the xml is valid."; throw Exception(os.str().c_str()); } LoadCDL(cdl, doc.RootElement()->ToElement()); } CDLTransformRcPtr CDLTransform::Create() { return CDLTransformRcPtr(new CDLTransform(), &deleter); } namespace { std::string GetCDLLocalCacheKey(const std::string & src, const std::string & cccid) { std::ostringstream os; os << src << " : " << cccid; return os.str(); } std::string GetCDLLocalCacheKey(const char * src, int cccindex) { std::ostringstream os; os << src << " : " << cccindex; return os.str(); } CDLTransformMap g_cache; StringBoolMap g_cacheSrcIsCC; Mutex g_cacheMutex; } void ClearCDLTransformFileCache() { AutoMutex lock(g_cacheMutex); g_cache.clear(); } // TODO: Expose functions for introspecting in ccc file // TODO: Share caching with normal cdl pathway CDLTransformRcPtr CDLTransform::CreateFromFile(const char * src, const char * cccid_) { if(!src || (strlen(src) == 0) ) { std::ostringstream os; os << "Error loading CDL xml. "; os << "Source file not specified."; throw Exception(os.str().c_str()); } std::string cccid; if(cccid_) cccid = cccid_; // Check cache AutoMutex lock(g_cacheMutex); // Use g_cacheSrcIsCC as a proxy for if we have loaded this source // file already (in which case it must be in cache, or an error) StringBoolMap::iterator srcIsCCiter = g_cacheSrcIsCC.find(src); if(srcIsCCiter != g_cacheSrcIsCC.end()) { // If the source file is known to be a pure ColorCorrection element, // null out the cccid so its ignored. if(srcIsCCiter->second) cccid = ""; // Search for the cccid by name CDLTransformMap::iterator iter = g_cache.find(GetCDLLocalCacheKey(src, cccid)); if(iter != g_cache.end()) { return iter->second; } // Search for cccid by index int cccindex=0; if(StringToInt(&cccindex, cccid.c_str(), true)) { iter = g_cache.find(GetCDLLocalCacheKey(src, cccindex)); if(iter != g_cache.end()) { return iter->second; } } std::ostringstream os; os << "The specified cccid/cccindex '" << cccid; os << "' could not be loaded from the src file '"; os << src; os << "'."; throw Exception (os.str().c_str()); } // Try to read all ccs from the file, into cache std::ifstream istream(src); if(istream.fail()) { std::ostringstream os; os << "Error could not read CDL source file '" << src; os << "'. Please verify the file exists and appropriate "; os << "permissions are set."; throw Exception (os.str().c_str()); } // Read the file into a string. std::ostringstream rawdata; rawdata << istream.rdbuf(); std::string xml = rawdata.str(); if(xml.empty()) { std::ostringstream os; os << "Error loading CDL xml. "; os << "The specified source file, '"; os << src << "' appears to be empty."; throw Exception(os.str().c_str()); } TiXmlDocument doc; doc.Parse(xml.c_str()); if(doc.Error()) { std::ostringstream os; os << "Error loading CDL xml from file '"; os << src << "'. "; os << doc.ErrorDesc() << " (line "; os << doc.ErrorRow() << ", character "; os << doc.ErrorCol() << ")"; throw Exception(os.str().c_str()); } if(!doc.RootElement()) { std::ostringstream os; os << "Error loading CDL xml from file '"; os << src << "'. "; os << "Please confirm the xml is valid."; throw Exception(os.str().c_str()); } std::string rootValue = doc.RootElement()->Value(); if(rootValue == "ColorCorrection") { // Load a single ColorCorrection into the cache CDLTransformRcPtr cdl = CDLTransform::Create(); LoadCDL(cdl.get(), doc.RootElement()->ToElement()); cccid = ""; g_cacheSrcIsCC[src] = true; g_cache[GetCDLLocalCacheKey(src, cccid)] = cdl; } else if(rootValue == "ColorCorrectionCollection") { // Load all CCs from the ColorCorrectionCollection // into the cache CDLTransformMap transformMap; CDLTransformVec transformVec; GetCDLTransforms(transformMap, transformVec, doc.RootElement()); if(transformVec.empty()) { std::ostringstream os; os << "Error loading ccc xml. "; os << "No ColorCorrection elements found in file '"; os << src << "'."; throw Exception(os.str().c_str()); } g_cacheSrcIsCC[src] = false; // Add all by transforms to cache // First by index, then by id for(unsigned int i=0; ifirst)] = iter->second; } } // The all transforms should be in the cache. Look it up, and try // to return it. { // Search for the cccid by name CDLTransformMap::iterator iter = g_cache.find(GetCDLLocalCacheKey(src, cccid)); if(iter != g_cache.end()) { return iter->second; } // Search for cccid by index int cccindex=0; if(StringToInt(&cccindex, cccid.c_str(), true)) { iter = g_cache.find(GetCDLLocalCacheKey(src, cccindex)); if(iter != g_cache.end()) { return iter->second; } } std::ostringstream os; os << "The specified cccid/cccindex '" << cccid; os << "' could not be loaded from the src file '"; os << src; os << "'."; throw Exception (os.str().c_str()); } } void CDLTransform::deleter(CDLTransform* t) { delete t; } class CDLTransform::Impl { public: TransformDirection dir_; float sop_[9]; float sat_; std::string id_; std::string description_; mutable std::string xml_; Impl() : dir_(TRANSFORM_DIR_FORWARD), sat_(1.0f) { sop_[0] = 1.0f; sop_[1] = 1.0f; sop_[2] = 1.0f; sop_[3] = 0.0f; sop_[4] = 0.0f; sop_[5] = 0.0f; sop_[6] = 1.0f; sop_[7] = 1.0f; sop_[8] = 1.0f; } ~Impl() { } Impl& operator= (const Impl & rhs) { dir_ = rhs.dir_; memcpy(sop_, rhs.sop_, sizeof(float)*9); sat_ = rhs.sat_; id_ = rhs.id_; description_ = rhs.description_; return *this; } }; /////////////////////////////////////////////////////////////////////////// CDLTransform::CDLTransform() : m_impl(new CDLTransform::Impl) { } TransformRcPtr CDLTransform::createEditableCopy() const { CDLTransformRcPtr transform = CDLTransform::Create(); *(transform->m_impl) = *m_impl; return transform; } CDLTransform::~CDLTransform() { delete m_impl; m_impl = NULL; } CDLTransform& CDLTransform::operator= (const CDLTransform & rhs) { *m_impl = *rhs.m_impl; return *this; } TransformDirection CDLTransform::getDirection() const { return getImpl()->dir_; } void CDLTransform::setDirection(TransformDirection dir) { getImpl()->dir_ = dir; } const char * CDLTransform::getXML() const { getImpl()->xml_ = BuildXML(*this); return getImpl()->xml_.c_str(); } void CDLTransform::setXML(const char * xml) { LoadCDL(this, xml); } // We use this approach, rather than comparing XML to get around the // case where setXML with extra data was provided. bool CDLTransform::equals(const ConstCDLTransformRcPtr & other) const { if(!other) return false; if(getImpl()->dir_ != other->getImpl()->dir_) return false; const float abserror = 1e-9f; for(int i=0; i<9; ++i) { if(!equalWithAbsError(getImpl()->sop_[i], other->getImpl()->sop_[i], abserror)) { return false; } } if(!equalWithAbsError(getImpl()->sat_, other->getImpl()->sat_, abserror)) { return false; } if(getImpl()->id_ != other->getImpl()->id_) { return false; } if(getImpl()->description_ != other->getImpl()->description_) { return false; } return true; } void CDLTransform::setSlope(const float * rgb) { memcpy(&getImpl()->sop_[0], rgb, sizeof(float)*3); } void CDLTransform::getSlope(float * rgb) const { memcpy(rgb, &getImpl()->sop_[0], sizeof(float)*3); } void CDLTransform::setOffset(const float * rgb) { memcpy(&getImpl()->sop_[3], rgb, sizeof(float)*3); } void CDLTransform::getOffset(float * rgb) const { memcpy(rgb, &getImpl()->sop_[3], sizeof(float)*3); } void CDLTransform::setPower(const float * rgb) { memcpy(&getImpl()->sop_[6], rgb, sizeof(float)*3); } void CDLTransform::getPower(float * rgb) const { memcpy(rgb, &getImpl()->sop_[6], sizeof(float)*3); } void CDLTransform::setSOP(const float * vec9) { memcpy(&getImpl()->sop_, vec9, sizeof(float)*9); } void CDLTransform::getSOP(float * vec9) const { memcpy(vec9, &getImpl()->sop_, sizeof(float)*9); } void CDLTransform::setSat(float sat) { getImpl()->sat_ = sat; } float CDLTransform::getSat() const { return getImpl()->sat_; } void CDLTransform::getSatLumaCoefs(float * rgb) const { if(!rgb) return; rgb[0] = 0.2126f; rgb[1] = 0.7152f; rgb[2] = 0.0722f; } void CDLTransform::setID(const char * id) { if(id) { getImpl()->id_ = id; } else { getImpl()->id_ = ""; } } const char * CDLTransform::getID() const { return getImpl()->id_.c_str(); } void CDLTransform::setDescription(const char * desc) { if(desc) { getImpl()->description_ = desc; } else { getImpl()->description_ = ""; } } const char * CDLTransform::getDescription() const { return getImpl()->description_.c_str(); } std::ostream& operator<< (std::ostream& os, const CDLTransform& t) { float sop[9]; t.getSOP(sop); os << ""; return os; } /////////////////////////////////////////////////////////////////////////// void BuildCDLOps(OpRcPtrVec & ops, const Config & /*config*/, const CDLTransform & cdlTransform, TransformDirection dir) { float scale4[] = { 1.0f, 1.0f, 1.0f, 1.0f }; cdlTransform.getSlope(scale4); float offset4[] = { 0.0f, 0.0f, 0.0f, 0.0f }; cdlTransform.getOffset(offset4); float power4[] = { 1.0f, 1.0f, 1.0f, 1.0f }; cdlTransform.getPower(power4); float lumaCoef3[] = { 1.0f, 1.0f, 1.0f }; cdlTransform.getSatLumaCoefs(lumaCoef3); float sat = cdlTransform.getSat(); TransformDirection combinedDir = CombineTransformDirections(dir, cdlTransform.getDirection()); // TODO: Confirm ASC Sat math is correct. // TODO: Handle Clamping conditions more explicitly if(combinedDir == TRANSFORM_DIR_FORWARD) { // 1) Scale + Offset CreateScaleOffsetOp(ops, scale4, offset4, TRANSFORM_DIR_FORWARD); // 2) Power + Clamp CreateExponentOp(ops, power4, TRANSFORM_DIR_FORWARD); // 3) Saturation + Clamp CreateSaturationOp(ops, sat, lumaCoef3, TRANSFORM_DIR_FORWARD); } else if(combinedDir == TRANSFORM_DIR_INVERSE) { // 3) Saturation + Clamp CreateSaturationOp(ops, sat, lumaCoef3, TRANSFORM_DIR_INVERSE); // 2) Power + Clamp CreateExponentOp(ops, power4, TRANSFORM_DIR_INVERSE); // 1) Scale + Offset CreateScaleOffsetOp(ops, scale4, offset4, TRANSFORM_DIR_INVERSE); } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatCCC.cpp0000644000175000017500000002161213223553423021054 0ustar mfvmfv/* 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 #include #include #include "CDLTransform.h" #include "FileTransform.h" #include "OpBuilders.h" #include "ParseUtils.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { //////////////////////////////////////////////////////////////// namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile () {}; ~LocalCachedFile() {}; CDLTransformMap transformMap; CDLTransformVec transformVec; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; typedef OCIO_SHARED_PTR TiXmlDocumentRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "ColorCorrectionCollection"; info.extension = "ccc"; info.capabilities = FORMAT_CAPABILITY_READ; formatInfoVec.push_back(info); } // Try and load the format // Raise an exception if it can't be loaded. CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { std::ostringstream rawdata; rawdata << istream.rdbuf(); LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile()); TiXmlDocumentRcPtr doc = TiXmlDocumentRcPtr(new TiXmlDocument()); doc->Parse(rawdata.str().c_str()); if(doc->Error()) { std::ostringstream os; os << "XML Parse Error. "; os << doc->ErrorDesc() << " (line "; os << doc->ErrorRow() << ", character "; os << doc->ErrorCol() << ")"; throw Exception(os.str().c_str()); } TiXmlElement* rootElement = doc->RootElement(); GetCDLTransforms(cachedFile->transformMap, cachedFile->transformVec, rootElement); return cachedFile; } void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { LocalCachedFileRcPtr cachedFile = DynamicPtrCast(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build .ccc Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_UNKNOWN) { std::ostringstream os; os << "Cannot build ASC FileTransform,"; os << " unspecified transform direction."; throw Exception(os.str().c_str()); } // Below this point, we should throw ExceptionMissingFile on // errors rather than Exception // This is because we've verified that the ccc file is valid, // at now we're only querying whether the specified cccid can // be found. // // Using ExceptionMissingFile enables the missing looks fallback // mechanism to function properly. // At the time ExceptionMissingFile was named, we errently assumed // a 1:1 relationship between files and color corrections, which is // not true for .ccc files. // // In a future OCIO release, it may be more appropriate to // rename ExceptionMissingFile -> ExceptionMissingCorrection. // But either way, it's what we should throw below. std::string cccid = fileTransform.getCCCId(); cccid = context->resolveStringVar(cccid.c_str()); if(cccid.empty()) { std::ostringstream os; os << "You must specify which cccid to load from the ccc file"; os << " (either by name or index)."; throw ExceptionMissingFile(os.str().c_str()); } bool success=false; // Try to parse the cccid as a string id CDLTransformMap::const_iterator iter = cachedFile->transformMap.find(cccid); if(iter != cachedFile->transformMap.end()) { success = true; BuildCDLOps(ops, config, *(iter->second), newDir); } // Try to parse the cccid as an integer index // We want to be strict, so fail if leftover chars in the parse. if(!success) { int cccindex=0; if(StringToInt(&cccindex, cccid.c_str(), true)) { int maxindex = ((int)cachedFile->transformVec.size())-1; if(cccindex<0 || cccindex>maxindex) { std::ostringstream os; os << "The specified cccindex " << cccindex; os << " is outside the valid range for this file [0,"; os << maxindex << "]"; throw ExceptionMissingFile(os.str().c_str()); } success = true; BuildCDLOps(ops, config, *cachedFile->transformVec[cccindex], newDir); } } if(!success) { std::ostringstream os; os << "You must specify a valid cccid to load from the ccc file"; os << " (either by name or index). id='" << cccid << "' "; os << "is not found in the file, and is not parsable as an "; os << "integer index."; throw ExceptionMissingFile(os.str().c_str()); } } } FileFormat * CreateFileFormatCCC() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/ExponentTransform.cpp0000644000175000017500000001111613223553423022205 0ustar mfvmfv/* 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 #include #include "ExponentOps.h" #include "OpBuilders.h" OCIO_NAMESPACE_ENTER { ExponentTransformRcPtr ExponentTransform::Create() { return ExponentTransformRcPtr(new ExponentTransform(), &deleter); } void ExponentTransform::deleter(ExponentTransform* t) { delete t; } class ExponentTransform::Impl { public: TransformDirection dir_; float value_[4]; Impl() : dir_(TRANSFORM_DIR_FORWARD) { for(int i=0; i<4; ++i) { value_[i] = 1.0f; } } ~Impl() { } Impl& operator= (const Impl & rhs) { dir_ = rhs.dir_; memcpy(value_, rhs.value_, 4*sizeof(float)); return *this; } }; /////////////////////////////////////////////////////////////////////////// ExponentTransform::ExponentTransform() : m_impl(new ExponentTransform::Impl) { } TransformRcPtr ExponentTransform::createEditableCopy() const { ExponentTransformRcPtr transform = ExponentTransform::Create(); *(transform->m_impl) = *m_impl; return transform; } ExponentTransform::~ExponentTransform() { delete m_impl; m_impl = NULL; } ExponentTransform& ExponentTransform::operator= (const ExponentTransform & rhs) { *m_impl = *rhs.m_impl; return *this; } TransformDirection ExponentTransform::getDirection() const { return getImpl()->dir_; } void ExponentTransform::setDirection(TransformDirection dir) { getImpl()->dir_ = dir; } void ExponentTransform::setValue(const float * vec4) { if(vec4) memcpy(getImpl()->value_, vec4, 4*sizeof(float)); } void ExponentTransform::getValue(float * vec4) const { if(vec4) memcpy(vec4, getImpl()->value_, 4*sizeof(float)); } std::ostream& operator<< (std::ostream& os, const ExponentTransform& t) { float exp[4]; t.getValue(exp); os << ""; return os; } /////////////////////////////////////////////////////////////////////////////////////////////////////// void BuildExponentOps(OpRcPtrVec & ops, const Config& /*config*/, const ExponentTransform & transform, TransformDirection dir) { TransformDirection combinedDir = CombineTransformDirections(dir, transform.getDirection()); float vec4[4]; transform.getValue(vec4); CreateExponentOp(ops, vec4, combinedDir); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/MathUtils.cpp0000644000175000017500000004474213223553423020436 0ustar mfvmfv/* 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 #include #include "MathUtils.h" OCIO_NAMESPACE_ENTER { namespace { const float FLTMIN = std::numeric_limits::min(); } bool IsScalarEqualToZero(float v) { return equalWithAbsError(v, 0.0f, FLTMIN); } bool IsScalarEqualToZeroFlt(double v) { return equalWithAbsError(float(v), 0.0f, FLTMIN); } bool IsScalarEqualToOne(float v) { return equalWithAbsError(v, 1.0f, FLTMIN); } bool IsScalarEqualToOneFlt(double v) { return equalWithAbsError(float(v), 1.0f, FLTMIN); } float GetSafeScalarInverse(float v, float defaultValue) { if(IsScalarEqualToZero(v)) return defaultValue; return 1.0f / v; } bool IsVecEqualToZero(const float* v, int size) { for(int i=0; i -GetHalfNormMin() && val GetHalfMax()) { return GetHalfMax(); } return val; } bool IsM44Identity(const float* m44) { int index=0; for(unsigned int j=0; j<4; ++j) { for(unsigned int i=0; i<4; ++i) { index = 4*j+i; if(i==j) { if(!IsScalarEqualToOne(m44[index])) return false; } else { if(!IsScalarEqualToZero(m44[index])) return false; } } } return true; } bool IsM44Diagonal(const float* m44) { for(int i=0; i<16; ++i) { if((i%5)==0) continue; // If we're on the diagonal, skip it if(!IsScalarEqualToZero(m44[i])) return false; } return true; } void GetM44Diagonal(float* out4, const float* m44) { for(int i=0; i<4; ++i) { out4[i] = m44[i*5]; } } // We use an intermediate double representation to make sure // there is minimal float precision error on the determinant's computation // (We have seen IsScalarEqualToZero sensitivities here on 32-bit // virtual machines) bool GetM44Inverse(float* inverse_out, const float* m_) { double m[16]; for(unsigned int i=0; i<16; ++i) m[i] = (double)m_[i]; double d10_21 = m[4]*m[9] - m[5]*m[8]; double d10_22 = m[4]*m[10] - m[6]*m[8]; double d10_23 = m[4]*m[11] - m[7]*m[8]; double d11_22 = m[5]*m[10] - m[6]*m[9]; double d11_23 = m[5]*m[11] - m[7]*m[9]; double d12_23 = m[6]*m[11] - m[7]*m[10]; double a00 = m[13]*d12_23 - m[14]*d11_23 + m[15]*d11_22; double a10 = m[14]*d10_23 - m[15]*d10_22 - m[12]*d12_23; double a20 = m[12]*d11_23 - m[13]*d10_23 + m[15]*d10_21; double a30 = m[13]*d10_22 - m[14]*d10_21 - m[12]*d11_22; double det = a00*m[0] + a10*m[1] + a20*m[2] + a30*m[3]; if(IsScalarEqualToZero((float)det)) return false; det = 1.0/det; double d00_31 = m[0]*m[13] - m[1]*m[12]; double d00_32 = m[0]*m[14] - m[2]*m[12]; double d00_33 = m[0]*m[15] - m[3]*m[12]; double d01_32 = m[1]*m[14] - m[2]*m[13]; double d01_33 = m[1]*m[15] - m[3]*m[13]; double d02_33 = m[2]*m[15] - m[3]*m[14]; double a01 = m[9]*d02_33 - m[10]*d01_33 + m[11]*d01_32; double a11 = m[10]*d00_33 - m[11]*d00_32 - m[8]*d02_33; double a21 = m[8]*d01_33 - m[9]*d00_33 + m[11]*d00_31; double a31 = m[9]*d00_32 - m[10]*d00_31 - m[8]*d01_32; double a02 = m[6]*d01_33 - m[7]*d01_32 - m[5]*d02_33; double a12 = m[4]*d02_33 - m[6]*d00_33 + m[7]*d00_32; double a22 = m[5]*d00_33 - m[7]*d00_31 - m[4]*d01_33; double a32 = m[4]*d01_32 - m[5]*d00_32 + m[6]*d00_31; double a03 = m[2]*d11_23 - m[3]*d11_22 - m[1]*d12_23; double a13 = m[0]*d12_23 - m[2]*d10_23 + m[3]*d10_22; double a23 = m[1]*d10_23 - m[3]*d10_21 - m[0]*d11_23; double a33 = m[0]*d11_22 - m[1]*d10_22 + m[2]*d10_21; inverse_out[0] = (float) (a00*det); inverse_out[1] = (float) (a01*det); inverse_out[2] = (float) (a02*det); inverse_out[3] = (float) (a03*det); inverse_out[4] = (float) (a10*det); inverse_out[5] = (float) (a11*det); inverse_out[6] = (float) (a12*det); inverse_out[7] = (float) (a13*det); inverse_out[8] = (float) (a20*det); inverse_out[9] = (float) (a21*det); inverse_out[10] = (float) (a22*det); inverse_out[11] = (float) (a23*det); inverse_out[12] = (float) (a30*det); inverse_out[13] = (float) (a31*det); inverse_out[14] = (float) (a32*det); inverse_out[15] = (float) (a33*det); return true; } void GetM44M44Product(float* mout, const float* m1_, const float* m2_) { float m1[16]; float m2[16]; memcpy(m1, m1_, 16*sizeof(float)); memcpy(m2, m2_, 16*sizeof(float)); mout[ 0] = m1[ 0]*m2[0] + m1[ 1]*m2[4] + m1[ 2]*m2[ 8] + m1[ 3]*m2[12]; mout[ 1] = m1[ 0]*m2[1] + m1[ 1]*m2[5] + m1[ 2]*m2[ 9] + m1[ 3]*m2[13]; mout[ 2] = m1[ 0]*m2[2] + m1[ 1]*m2[6] + m1[ 2]*m2[10] + m1[ 3]*m2[14]; mout[ 3] = m1[ 0]*m2[3] + m1[ 1]*m2[7] + m1[ 2]*m2[11] + m1[ 3]*m2[15]; mout[ 4] = m1[ 4]*m2[0] + m1[ 5]*m2[4] + m1[ 6]*m2[ 8] + m1[ 7]*m2[12]; mout[ 5] = m1[ 4]*m2[1] + m1[ 5]*m2[5] + m1[ 6]*m2[ 9] + m1[ 7]*m2[13]; mout[ 6] = m1[ 4]*m2[2] + m1[ 5]*m2[6] + m1[ 6]*m2[10] + m1[ 7]*m2[14]; mout[ 7] = m1[ 4]*m2[3] + m1[ 5]*m2[7] + m1[ 6]*m2[11] + m1[ 7]*m2[15]; mout[ 8] = m1[ 8]*m2[0] + m1[ 9]*m2[4] + m1[10]*m2[ 8] + m1[11]*m2[12]; mout[ 9] = m1[ 8]*m2[1] + m1[ 9]*m2[5] + m1[10]*m2[ 9] + m1[11]*m2[13]; mout[10] = m1[ 8]*m2[2] + m1[ 9]*m2[6] + m1[10]*m2[10] + m1[11]*m2[14]; mout[11] = m1[ 8]*m2[3] + m1[ 9]*m2[7] + m1[10]*m2[11] + m1[11]*m2[15]; mout[12] = m1[12]*m2[0] + m1[13]*m2[4] + m1[14]*m2[ 8] + m1[15]*m2[12]; mout[13] = m1[12]*m2[1] + m1[13]*m2[5] + m1[14]*m2[ 9] + m1[15]*m2[13]; mout[14] = m1[12]*m2[2] + m1[13]*m2[6] + m1[14]*m2[10] + m1[15]*m2[14]; mout[15] = m1[12]*m2[3] + m1[13]*m2[7] + m1[14]*m2[11] + m1[15]*m2[15]; } namespace { void GetM44V4Product(float* vout, const float* m, const float* v_) { float v[4]; memcpy(v, v_, 4*sizeof(float)); vout[0] = m[ 0]*v[0] + m[ 1]*v[1] + m[ 2]*v[2] + m[ 3]*v[3]; vout[1] = m[ 4]*v[0] + m[ 5]*v[1] + m[ 6]*v[2] + m[ 7]*v[3]; vout[2] = m[ 8]*v[0] + m[ 9]*v[1] + m[10]*v[2] + m[11]*v[3]; vout[3] = m[12]*v[0] + m[13]*v[1] + m[14]*v[2] + m[15]*v[3]; } void GetV4Sum(float* vout, const float* v1, const float* v2) { for(int i=0; i<4; ++i) { vout[i] = v1[i] + v2[i]; } } } // anon namespace // All m(s) are 4x4. All v(s) are size 4 vectors. // Return mout, vout, where mout*x+vout == m2*(m1*x+v1)+v2 // mout = m2*m1 // vout = m2*v1 + v2 void GetMxbCombine(float* mout, float* vout, const float* m1_, const float* v1_, const float* m2_, const float* v2_) { float m1[16]; float v1[4]; float m2[16]; float v2[4]; memcpy(m1, m1_, 16*sizeof(float)); memcpy(v1, v1_, 4*sizeof(float)); memcpy(m2, m2_, 16*sizeof(float)); memcpy(v2, v2_, 4*sizeof(float)); GetM44M44Product(mout, m2, m1); GetM44V4Product(vout, m2, v1); GetV4Sum(vout, vout, v2); } namespace { void GetMxbResult(float* vout, float* m, float* x, float* v) { GetM44V4Product(vout, m, x); GetV4Sum(vout, vout, v); } } // anon namespace bool GetMxbInverse(float* mout, float* vout, const float* m_, const float* v_) { float m[16]; float v[4]; memcpy(m, m_, 16*sizeof(float)); memcpy(v, v_, 4*sizeof(float)); if(!GetM44Inverse(mout, m)) return false; for(int i=0; i<4; ++i) { v[i] = -v[i]; } GetM44V4Product(vout, mout, v); return true; } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST OCIO_NAMESPACE_USING #include "UnitTest.h" OIIO_ADD_TEST(MathUtils, M44_is_diagonal) { { float m44[] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; bool isdiag = IsM44Diagonal(m44); OIIO_CHECK_EQUAL(isdiag, true); m44[1] += 1e-8f; isdiag = IsM44Diagonal(m44); OIIO_CHECK_EQUAL(isdiag, false); } } OIIO_ADD_TEST(MathUtils, IsScalarEqualToZero) { OIIO_CHECK_EQUAL(IsScalarEqualToZero(0.0f), true); OIIO_CHECK_EQUAL(IsScalarEqualToZero(-0.0f), true); OIIO_CHECK_EQUAL(IsScalarEqualToZero(-1.072883670794056e-09f), false); OIIO_CHECK_EQUAL(IsScalarEqualToZero(1.072883670794056e-09f), false); OIIO_CHECK_EQUAL(IsScalarEqualToZero(-1.072883670794056e-03f), false); OIIO_CHECK_EQUAL(IsScalarEqualToZero(1.072883670794056e-03f), false); OIIO_CHECK_EQUAL(IsScalarEqualToZero(-1.072883670794056e-01f), false); OIIO_CHECK_EQUAL(IsScalarEqualToZero(1.072883670794056e-01f), false); } OIIO_ADD_TEST(MathUtils, GetM44Inverse) { // This is a degenerate matrix, and shouldnt be invertible. float m[] = { 0.3f, 0.3f, 0.3f, 0.0f, 0.3f, 0.3f, 0.3f, 0.0f, 0.3f, 0.3f, 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; float mout[16]; bool invertsuccess = GetM44Inverse(mout, m); OIIO_CHECK_EQUAL(invertsuccess, false); } OIIO_ADD_TEST(MathUtils, M44_M44_product) { { float mout[16]; float m1[] = { 1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 3.0f, 1.0f }; float m2[] = { 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f, 0.0f, 1.0f }; GetM44M44Product(mout, m1, m2); float mcorrect[] = { 1.0f, 3.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 2.0f, 1.0f, 3.0f, 1.0f }; for(int i=0; i<16; ++i) { OIIO_CHECK_EQUAL(mout[i], mcorrect[i]); } } } OIIO_ADD_TEST(MathUtils, M44_V4_product) { { float vout[4]; float m[] = { 1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 3.0f, 1.0f }; float v[] = { 1.0f, 2.0f, 3.0f, 4.0f }; GetM44V4Product(vout, m, v); float vcorrect[] = { 5.0f, 5.0f, 4.0f, 15.0f }; for(int i=0; i<4; ++i) { OIIO_CHECK_EQUAL(vout[i], vcorrect[i]); } } } OIIO_ADD_TEST(MathUtils, V4_add) { { float vout[4]; float v1[] = { 1.0f, 2.0f, 3.0f, 4.0f }; float v2[] = { 3.0f, 1.0f, 4.0f, 1.0f }; GetV4Sum(vout, v1, v2); float vcorrect[] = { 4.0f, 3.0f, 7.0f, 5.0f }; for(int i=0; i<4; ++i) { OIIO_CHECK_EQUAL(vout[i], vcorrect[i]); } } } OIIO_ADD_TEST(MathUtils, mxb_eval) { { float vout[4]; float m[] = { 1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 3.0f, 1.0f }; float x[] = { 1.0f, 1.0f, 1.0f, 1.0f }; float v[] = { 1.0f, 2.0f, 3.0f, 4.0f }; GetMxbResult(vout, m, x, v); float vcorrect[] = { 4.0f, 4.0f, 5.0f, 9.0f }; for(int i=0; i<4; ++i) { OIIO_CHECK_EQUAL(vout[i], vcorrect[i]); } } } OIIO_ADD_TEST(MathUtils, Combine_two_mxb) { float m1[] = { 1.0f, 0.0f, 2.0f, 0.0f, 2.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }; float v1[] = { 1.0f, 2.0f, 3.0f, 4.0f }; float m2[] = { 2.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 3.0f, 0.0f, 1.0f,1.0f, 1.0f, 1.0f }; float v2[] = { 0.0f, 2.0f, 1.0f, 0.0f }; float tolerance = 1e-9f; { float x[] = { 1.0f, 1.0f, 1.0f, 1.0f }; float vout[4]; // Combine two mx+b operations, and apply to test point float mout[16]; float vcombined[4]; GetMxbCombine(mout, vout, m1, v1, m2, v2); GetMxbResult(vcombined, mout, x, vout); // Sequentially apply the two mx+b operations. GetMxbResult(vout, m1, x, v1); GetMxbResult(vout, m2, vout, v2); // Compare outputs for(int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(vcombined[i], vout[i], tolerance); } } { float x[] = { 6.0f, 0.5f, -2.0f, -0.1f }; float vout[4]; float mout[16]; float vcombined[4]; GetMxbCombine(mout, vout, m1, v1, m2, v2); GetMxbResult(vcombined, mout, x, vout); GetMxbResult(vout, m1, x, v1); GetMxbResult(vout, m2, vout, v2); for(int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(vcombined[i], vout[i], tolerance); } } { float x[] = { 26.0f, -0.5f, 0.005f, 12.1f }; float vout[4]; float mout[16]; float vcombined[4]; GetMxbCombine(mout, vout, m1, v1, m2, v2); GetMxbResult(vcombined, mout, x, vout); GetMxbResult(vout, m1, x, v1); GetMxbResult(vout, m2, vout, v2); // We pick a not so small tolerance, as we're dealing with // large numbers, and the error for CHECK_CLOSE is absolute. for(int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(vcombined[i], vout[i], 1e-3); } } } OIIO_ADD_TEST(MathUtils, mxb_invert) { { float m[] = { 1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 3.0f, 1.0f }; float x[] = { 1.0f, 0.5f, -1.0f, 60.0f }; float v[] = { 1.0f, 2.0f, 3.0f, 4.0f }; float vresult[4]; float mout[16]; float vout[4]; GetMxbResult(vresult, m, x, v); bool invertsuccess = GetMxbInverse(mout, vout, m, v); OIIO_CHECK_EQUAL(invertsuccess, true); GetMxbResult(vresult, mout, vresult, vout); float tolerance = 1e-9f; for(int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(vresult[i], x[i], tolerance); } } { float m[] = { 0.3f, 0.3f, 0.3f, 0.0f, 0.3f, 0.3f, 0.3f, 0.0f, 0.3f, 0.3f, 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; float v[] = { 0.0f, 0.0f, 0.0f, 0.0f }; float mout[16]; float vout[4]; bool invertsuccess = GetMxbInverse(mout, vout, m, v); OIIO_CHECK_EQUAL(invertsuccess, false); } } #endif opencolorio-1.1.0~dfsg0.orig/src/core/Lut1DOp.h0000644000175000017500000000704213223553423017411 0ustar mfvmfv/* 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_OCIO_LUT1DOP_H #define INCLUDED_OCIO_LUT1DOP_H #include #include "Mutex.h" #include "Op.h" #include OCIO_NAMESPACE_ENTER { // TODO: turn into a class instead of a struct? enum ErrorType { ERROR_ABSOLUTE = 1, ERROR_RELATIVE }; struct Lut1D; typedef OCIO_SHARED_PTR Lut1DRcPtr; struct Lut1D { static Lut1DRcPtr Create(); // This will compute the cacheid, and also // determine if the lut is a no-op. // If this lut is being read in from float ASCII text // a value of 1e-5 is preferable. // If this lut is being read in from integer ASCII // representation, the value will depend on the LSB // at the specified integer precision. // Example: reading 10-bit ints? Use 2/1023.0 // If you dont want to do the noop computation, // specify a 0.0 tolerance. // // TODO: Instead of having each user compute the error // individually, maybe they should specify the original file bitdepth? // (with appropriate precision tokens?) float maxerror; ErrorType errortype; float from_min[3]; float from_max[3]; typedef std::vector fv_t; fv_t luts[3]; std::string getCacheID() const; bool isNoOp() const; void unfinalize(); private: Lut1D(); mutable std::string m_cacheID; mutable bool m_isNoOp; mutable Mutex m_mutex; void finalize() const; }; typedef OCIO_SHARED_PTR Lut1DRcPtr; // This generates an identity 1d lut, from 0.0 to 1.0 void GenerateIdentityLut1D(float* img, int numElements, int numChannels); void CreateLut1DOp(OpRcPtrVec & ops, const Lut1DRcPtr & lut, Interpolation interpolation, TransformDirection direction); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatSpi1D.cpp0000644000175000017500000002270613223553423021411 0ustar mfvmfv/* 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 #include "FileTransform.h" #include "Lut1DOp.h" #include "pystring/pystring.h" #include #include /* Version 1 From -7.5 3.7555555555555555 Components 1 Length 4096 { 0.031525943963232252 0.045645604561056156 ... } */ OCIO_NAMESPACE_ENTER { //////////////////////////////////////////////////////////////// namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile() { lut = Lut1D::Create(); }; ~LocalCachedFile() {}; Lut1DRcPtr lut; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "spi1d"; info.extension = "spi1d"; info.capabilities = FORMAT_CAPABILITY_READ; formatInfoVec.push_back(info); } // Try and load the format // Raise an exception if it can't be loaded. CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { Lut1DRcPtr lut1d = Lut1D::Create(); // Parse Header Info int lut_size = -1; float from_min = 0.0; float from_max = 1.0; int version = -1; int components = -1; const int MAX_LINE_SIZE = 4096; char lineBuffer[MAX_LINE_SIZE]; // PARSE HEADER INFO { std::string headerLine(""); do { istream.getline(lineBuffer, MAX_LINE_SIZE); headerLine = std::string(lineBuffer); if(pystring::startswith(headerLine, "Version")) { if(sscanf(lineBuffer, "Version %d", &version)!=1) throw Exception("Invalid 'Version' Tag"); } else if(pystring::startswith(headerLine, "From")) { if(sscanf(lineBuffer, "From %f %f", &from_min, &from_max)!=2) throw Exception("Invalid 'From' Tag"); } else if(pystring::startswith(headerLine, "Components")) { if(sscanf(lineBuffer, "Components %d", &components)!=1) throw Exception("Invalid 'Components' Tag"); } else if(pystring::startswith(headerLine, "Length")) { if(sscanf(lineBuffer, "Length %d", &lut_size)!=1) throw Exception("Invalid 'Length' Tag"); } } while (istream.good() && !pystring::startswith(headerLine,"{")); } if(version == -1) throw Exception("Could not find 'Version' Tag"); if(version != 1) throw Exception("Only format version 1 supported."); if (lut_size == -1) throw Exception("Could not find 'Length' Tag"); if (components == -1) throw Exception("Could not find 'Components' Tag"); if (components<0 || components>3) throw Exception("Components must be [1,2,3]"); for(int i=0; i<3; ++i) { lut1d->from_min[i] = from_min; lut1d->from_max[i] = from_max; lut1d->luts[i].clear(); lut1d->luts[i].reserve(lut_size); } { istream.getline(lineBuffer, MAX_LINE_SIZE); int lineCount=0; float values[4]; while (istream.good()) { // If 1 component is specificed, use x1 x1 x1 defaultA if(components==1 && sscanf(lineBuffer,"%f",&values[0])==1) { lut1d->luts[0].push_back(values[0]); lut1d->luts[1].push_back(values[0]); lut1d->luts[2].push_back(values[0]); ++lineCount; } // If 2 components are specificed, use x1 x2 0.0 else if(components==2 && sscanf(lineBuffer,"%f %f",&values[0],&values[1])==2) { lut1d->luts[0].push_back(values[0]); lut1d->luts[1].push_back(values[1]); lut1d->luts[2].push_back(0.0); ++lineCount; } // If 3 component is specificed, use x1 x2 x3 defaultA else if(components==3 && sscanf(lineBuffer,"%f %f %f",&values[0],&values[1],&values[2])==3) { lut1d->luts[0].push_back(values[0]); lut1d->luts[1].push_back(values[1]); lut1d->luts[2].push_back(values[2]); ++lineCount; } if(lineCount == lut_size) break; istream.getline(lineBuffer, MAX_LINE_SIZE); } if(lineCount!=lut_size) throw Exception("Not enough entries found."); } // 1e-5 rel error is a good threshold when float numbers near 0 // are written out with 6 decimal places of precision. This is // a bit aggressive, I.e., changes in the 6th decimal place will // be considered roundoff error, but changes in the 5th decimal // will be considered lut 'intent'. // 1.0 // 1.000005 equal to 1.0 // 1.000007 equal to 1.0 // 1.000010 not equal // 0.0 // 0.000001 not equal lut1d->maxerror = 1e-5f; lut1d->errortype = ERROR_RELATIVE; LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile()); cachedFile->lut = lut1d; return cachedFile; } void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops, const Config& /*config*/, const ConstContextRcPtr & /*context*/, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { LocalCachedFileRcPtr cachedFile = DynamicPtrCast(untypedCachedFile); if(!cachedFile) // This should never happen. { std::ostringstream os; os << "Cannot build Spi1D Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); CreateLut1DOp(ops, cachedFile->lut, fileTransform.getInterpolation(), newDir); } } FileFormat * CreateFileFormatSpi1D() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/Platform.h0000644000175000017500000001230013223553423017736 0ustar mfvmfv/* 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_OCIO_PLATFORM_H #define INCLUDED_OCIO_PLATFORM_H /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. 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. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER 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 BASED 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 DAMAGES. */ // platform-specific includes #if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) || defined(_MSC_VER) #ifndef WINDOWS #define WINDOWS #endif #define _CRT_NONSTDC_NO_DEPRECATE 1 #define _CRT_SECURE_NO_DEPRECATE 1 #define NOMINMAX 1 // windows - defined for both Win32 and Win64 #include #include #include #include #include #else // assume linux/unix/posix #include #if !defined(__FreeBSD__) #include #endif #include #include #endif // defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) || defined(_MSC_VER) // general includes #include #include #include // missing functions on Windows #ifdef WINDOWS #define snprintf sprintf_s #define strtok_r strtok_s #define sscanf sscanf_s #define putenv _putenv typedef __int64 FilePos; #define fseeko _fseeki64 #define ftello _ftelli64 inline double log2(double x) { return log(x) * 1.4426950408889634; } #else typedef off_t FilePos; #endif // WINDOWS OCIO_NAMESPACE_ENTER { // TODO: Add proper endian detection using architecture / compiler mojo // In the meantime, hardcode to x86 #define OCIO_LITTLE_ENDIAN 1 // This is correct on x86 /* * Mutex classes */ #ifdef WINDOWS class _Mutex { public: _Mutex() { _mutex = CreateMutex(NULL, FALSE, NULL); } ~_Mutex() { CloseHandle(_mutex); } void lock() { WaitForSingleObject(_mutex, INFINITE); } void unlock() { ReleaseMutex(_mutex); } private: HANDLE _mutex; }; #else // assume linux/unix/posix class _Mutex { public: _Mutex() { pthread_mutex_init(&_mutex, 0); } ~_Mutex() { pthread_mutex_destroy(&_mutex); } void lock() { pthread_mutex_lock(&_mutex); } void unlock() { pthread_mutex_unlock(&_mutex); } private: pthread_mutex_t _mutex; }; #endif // WINDOWS namespace Platform { void getenv (const char* name, std::string& value); } } OCIO_NAMESPACE_EXIT #endif // INCLUDED_OCIO_PLATFORM_H opencolorio-1.1.0~dfsg0.orig/src/core/AllocationTransform.cpp0000644000175000017500000001332013223553423022471 0ustar mfvmfv/* 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 #include #include #include #include "AllocationOp.h" #include "OpBuilders.h" OCIO_NAMESPACE_ENTER { AllocationTransformRcPtr AllocationTransform::Create() { return AllocationTransformRcPtr(new AllocationTransform(), &deleter); } void AllocationTransform::deleter(AllocationTransform* t) { delete t; } class AllocationTransform::Impl { public: TransformDirection dir_; Allocation allocation_; std::vector vars_; Impl() : dir_(TRANSFORM_DIR_FORWARD), allocation_(ALLOCATION_UNIFORM) { } ~Impl() { } Impl& operator= (const Impl & rhs) { dir_ = rhs.dir_; allocation_ = rhs.allocation_; vars_ = rhs.vars_; return *this; } }; /////////////////////////////////////////////////////////////////////////// AllocationTransform::AllocationTransform() : m_impl(new AllocationTransform::Impl) { } TransformRcPtr AllocationTransform::createEditableCopy() const { AllocationTransformRcPtr transform = AllocationTransform::Create(); *(transform->m_impl) = *m_impl; return transform; } AllocationTransform::~AllocationTransform() { delete m_impl; m_impl = NULL; } AllocationTransform& AllocationTransform::operator= (const AllocationTransform & rhs) { *m_impl = *rhs.m_impl; return *this; } TransformDirection AllocationTransform::getDirection() const { return getImpl()->dir_; } void AllocationTransform::setDirection(TransformDirection dir) { getImpl()->dir_ = dir; } Allocation AllocationTransform::getAllocation() const { return getImpl()->allocation_; } void AllocationTransform::setAllocation(Allocation allocation) { getImpl()->allocation_ = allocation; } int AllocationTransform::getNumVars() const { return static_cast(getImpl()->vars_.size()); } void AllocationTransform::getVars(float * vars) const { if(!getImpl()->vars_.empty()) { memcpy(vars, &getImpl()->vars_[0], getImpl()->vars_.size()*sizeof(float)); } } void AllocationTransform::setVars(int numvars, const float * vars) { getImpl()->vars_.resize(numvars); if(!getImpl()->vars_.empty()) { memcpy(&getImpl()->vars_[0], vars, numvars*sizeof(float)); } } std::ostream& operator<< (std::ostream& os, const AllocationTransform& t) { Allocation allocation(t.getAllocation()); int numVars(t.getNumVars()); std::vector vars(numVars); t.getVars(&vars[0]); os << ""; return os; } /////////////////////////////////////////////////////////////////////////// void BuildAllocationOps(OpRcPtrVec & ops, const Config& /*config*/, const AllocationTransform& allocationTransform, TransformDirection dir) { TransformDirection combinedDir = CombineTransformDirections(dir, allocationTransform.getDirection()); AllocationData data; data.allocation = allocationTransform.getAllocation(); data.vars.resize(allocationTransform.getNumVars()); if(!data.vars.empty()) { allocationTransform.getVars(&data.vars[0]); } CreateAllocationOps(ops, data, combinedDir); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/MatrixTransform.cpp0000644000175000017500000002730413223553423021657 0ustar mfvmfv/* 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 #include #include "OpBuilders.h" #include "MatrixOps.h" #include "MathUtils.h" OCIO_NAMESPACE_ENTER { MatrixTransformRcPtr MatrixTransform::Create() { return MatrixTransformRcPtr(new MatrixTransform(), &deleter); } void MatrixTransform::deleter(MatrixTransform* t) { delete t; } class MatrixTransform::Impl { public: TransformDirection dir_; float matrix_[16]; float offset_[4]; Impl() : dir_(TRANSFORM_DIR_FORWARD) { Identity(matrix_, offset_); } ~Impl() { } Impl& operator= (const Impl & rhs) { dir_ = rhs.dir_; memcpy(matrix_, rhs.matrix_, 16*sizeof(float)); memcpy(offset_, rhs.offset_, 4*sizeof(float)); return *this; } }; /////////////////////////////////////////////////////////////////////////// MatrixTransform::MatrixTransform() : m_impl(new MatrixTransform::Impl) { } TransformRcPtr MatrixTransform::createEditableCopy() const { MatrixTransformRcPtr transform = MatrixTransform::Create(); *(transform->m_impl) = *m_impl; return transform; } MatrixTransform::~MatrixTransform() { delete m_impl; m_impl = NULL; } MatrixTransform& MatrixTransform::operator= (const MatrixTransform & rhs) { *m_impl = *rhs.m_impl; return *this; } TransformDirection MatrixTransform::getDirection() const { return getImpl()->dir_; } void MatrixTransform::setDirection(TransformDirection dir) { getImpl()->dir_ = dir; } bool MatrixTransform::equals(const MatrixTransform & other) const { const float abserror = 1e-9f; for(int i=0; i<16; ++i) { if(!equalWithAbsError(getImpl()->matrix_[i], other.getImpl()->matrix_[i], abserror)) { return false; } } for(int i=0; i<4; ++i) { if(!equalWithAbsError(getImpl()->offset_[i], other.getImpl()->offset_[i], abserror)) { return false; } } return true; } void MatrixTransform::getValue(float * m44, float * offset4) const { if(m44) memcpy(m44, getImpl()->matrix_, 16*sizeof(float)); if(offset4) memcpy(offset4, getImpl()->offset_, 4*sizeof(float)); } void MatrixTransform::setValue(const float * m44, const float * offset4) { if(m44) memcpy(getImpl()->matrix_, m44, 16*sizeof(float)); if(offset4) memcpy(getImpl()->offset_, offset4, 4*sizeof(float)); } void MatrixTransform::setMatrix(const float * m44) { if(m44) memcpy(getImpl()->matrix_, m44, 16*sizeof(float)); } void MatrixTransform::getMatrix(float * m44) const { if(m44) memcpy(m44, getImpl()->matrix_, 16*sizeof(float)); } void MatrixTransform::setOffset(const float * offset4) { if(offset4) memcpy(getImpl()->offset_, offset4, 4*sizeof(float)); } void MatrixTransform::getOffset(float * offset4) const { if(offset4) memcpy(offset4, getImpl()->offset_, 4*sizeof(float)); } /* Fit is canonically formulated as: out = newmin + ((value-oldmin)/(oldmax-oldmin)*(newmax-newmin)) I.e., subtract the old offset, descale into the [0,1] range, scale into the new range, and add the new offset We algebraiclly manipulate the terms into y = mx + b form as: m = (newmax-newmin)/(oldmax-oldmin) b = (newmin*oldmax - newmax*oldmin) / (oldmax-oldmin) */ void MatrixTransform::Fit(float * m44, float * offset4, const float * oldmin4, const float * oldmax4, const float * newmin4, const float * newmax4) { if(!oldmin4 || !oldmax4) return; if(!newmin4 || !newmax4) return; if(m44) memset(m44, 0, 16*sizeof(float)); if(offset4) memset(offset4, 0, 4*sizeof(float)); for(int i=0; i<4; ++i) { float denom = oldmax4[i] - oldmin4[i]; if(IsScalarEqualToZero(denom)) { std::ostringstream os; os << "Cannot create Fit operator. "; os << "Max value equals min value '"; os << oldmax4[i] << "' in channel index "; os << i << "."; throw Exception(os.str().c_str()); } if(m44) m44[5*i] = (newmax4[i]-newmin4[i]) / denom; if(offset4) offset4[i] = (newmin4[i]*oldmax4[i] - newmax4[i]*oldmin4[i]) / denom; } } void MatrixTransform::Identity(float * m44, float * offset4) { if(m44) { memset(m44, 0, 16*sizeof(float)); m44[0] = 1.0f; m44[5] = 1.0f; m44[10] = 1.0f; m44[15] = 1.0f; } if(offset4) { offset4[0] = 0.0f; offset4[1] = 0.0f; offset4[2] = 0.0f; offset4[3] = 0.0f; } } void MatrixTransform::Sat(float * m44, float * offset4, float sat, const float * lumaCoef3) { if(!lumaCoef3) return; if(m44) { m44[0] = (1 - sat) * lumaCoef3[0] + sat; m44[1] = (1 - sat) * lumaCoef3[1]; m44[2] = (1 - sat) * lumaCoef3[2]; m44[3] = 0.0f; m44[4] = (1 - sat) * lumaCoef3[0]; m44[5] = (1 - sat) * lumaCoef3[1] + sat; m44[6] = (1 - sat) * lumaCoef3[2]; m44[7] = 0.0f; m44[8] = (1 - sat) * lumaCoef3[0]; m44[9] = (1 - sat) * lumaCoef3[1]; m44[10] = (1 - sat) * lumaCoef3[2] + sat; m44[11] = 0.0f; m44[12] = 0.0f; m44[13] = 0.0f; m44[14] = 0.0f; m44[15] = 1.0f; } if(offset4) { offset4[0] = 0.0f; offset4[1] = 0.0f; offset4[2] = 0.0f; offset4[3] = 0.0f; } } void MatrixTransform::Scale(float * m44, float * offset4, const float * scale4) { if(!scale4) return; if(m44) { memset(m44, 0, 16*sizeof(float)); m44[0] = scale4[0]; m44[5] = scale4[1]; m44[10] = scale4[2]; m44[15] = scale4[3]; } if(offset4) { offset4[0] = 0.0f; offset4[1] = 0.0f; offset4[2] = 0.0f; offset4[3] = 0.0f; } } void MatrixTransform::View(float * m44, float * offset4, int * channelHot4, const float * lumaCoef3) { if(!channelHot4 || !lumaCoef3) return; if(offset4) { offset4[0] = 0.0f; offset4[1] = 0.0f; offset4[2] = 0.0f; offset4[3] = 0.0f; } if(m44) { memset(m44, 0, 16*sizeof(float)); // All channels are hot, return identity if(channelHot4[0] && channelHot4[1] && channelHot4[2] && channelHot4[3]) { Identity(m44, 0x0); } // If not all the channels are hot, but alpha is, // just show it. else if(channelHot4[3]) { for(int i=0; i<4; ++i) { m44[4*i+3] = 1.0f; } } // Blend rgb as specified, place it in all 3 output // channels (to make a grayscale final image) else { float values[3] = { 0.0f, 0.0f, 0.0f }; for(int i = 0; i < 3; ++i) { values[i] += lumaCoef3[i] * (channelHot4[i] ? 1.0f : 0.0f); } float sum = values[0] + values[1] + values[2]; if(!IsScalarEqualToZero(sum)) { values[0] /= sum; values[1] /= sum; values[2] /= sum; } // Copy rgb into rgb rows for(int row=0; row<3; ++row) { for(int i=0; i<3; i++) { m44[4*row+i] = values[i]; } } // Preserve alpha m44[15] = 1.0f; } } } std::ostream& operator<< (std::ostream& os, const MatrixTransform& t) { float matrix[16], offset[4]; t.getMatrix(matrix); t.getOffset(offset); os << ""; return os; } TransformDirection dir_; float matrix_[16]; float offset_[4]; /////////////////////////////////////////////////////////////////////////// void BuildMatrixOps(OpRcPtrVec & ops, const Config& /*config*/, const MatrixTransform & transform, TransformDirection dir) { TransformDirection combinedDir = CombineTransformDirections(dir, transform.getDirection()); float matrix[16]; float offset[4]; transform.getValue(matrix, offset); CreateMatrixOffsetOp(ops, matrix, offset, combinedDir); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/MatrixOps.cpp0000644000175000017500000006460413223553423020451 0ustar mfvmfv/* 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 #include "GpuShaderUtils.h" #include "HashUtils.h" #include "MatrixOps.h" #include "MathUtils.h" #include #include OCIO_NAMESPACE_ENTER { namespace { void ApplyScale(float* rgbaBuffer, long numPixels, const float* scale4) { for(long pixelIndex=0; pixelIndex MatrixOffsetOpRcPtr; MatrixOffsetOp::MatrixOffsetOp(const float * m44, const float * offset4, TransformDirection direction): Op(), m_isNoOp(false), m_direction(direction), m_m44IsIdentity(false), m_offset4IsIdentity(false) { if(m_direction == TRANSFORM_DIR_UNKNOWN) { throw Exception("Cannot apply MatrixOffsetOp op, unspecified transform direction."); } memcpy(m_m44, m44, 16*sizeof(float)); memcpy(m_offset4, offset4, 4*sizeof(float)); memset(m_m44_inv, 0, 16*sizeof(float)); // This Op will be a NoOp if and old if both the offset and matrix // are identity. This hold true no matter what the direction is, // so we can compute this ahead of time. m_isNoOp = (IsVecEqualToZero(m_offset4, 4) && IsM44Identity(m_m44)); } OpRcPtr MatrixOffsetOp::clone() const { OpRcPtr op = OpRcPtr(new MatrixOffsetOp(m_m44, m_offset4, m_direction)); return op; } MatrixOffsetOp::~MatrixOffsetOp() { } std::string MatrixOffsetOp::getInfo() const { return ""; } std::string MatrixOffsetOp::getCacheID() const { return m_cacheID; } bool MatrixOffsetOp::isNoOp() const { return m_isNoOp; } bool MatrixOffsetOp::isSameType(const OpRcPtr & op) const { MatrixOffsetOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; return true; } bool MatrixOffsetOp::isInverse(const OpRcPtr & op) const { MatrixOffsetOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; if(GetInverseTransformDirection(m_direction) != typedRcPtr->m_direction) return false; float error = std::numeric_limits::min(); if(!VecsEqualWithRelError(m_m44, 16, typedRcPtr->m_m44, 16, error)) return false; if(!VecsEqualWithRelError(m_offset4, 4,typedRcPtr->m_offset4, 4, error)) return false; return true; } bool MatrixOffsetOp::canCombineWith(const OpRcPtr & op) const { return isSameType(op); } void MatrixOffsetOp::combineWith(OpRcPtrVec & ops, const OpRcPtr & secondOp) const { MatrixOffsetOpRcPtr typedRcPtr = DynamicPtrCast(secondOp); if(!typedRcPtr) { std::ostringstream os; os << "MatrixOffsetOp can only be combined with other "; os << "MatrixOffsetOps. secondOp:" << secondOp->getInfo(); throw Exception(os.str().c_str()); } float mout[16]; float vout[4]; if(m_direction == TRANSFORM_DIR_FORWARD && typedRcPtr->m_direction == TRANSFORM_DIR_FORWARD) { GetMxbCombine(mout, vout, m_m44, m_offset4, typedRcPtr->m_m44, typedRcPtr->m_offset4); } else if(m_direction == TRANSFORM_DIR_FORWARD && typedRcPtr->m_direction == TRANSFORM_DIR_INVERSE) { float minv2[16]; float vinv2[4]; if(!GetMxbInverse(minv2, vinv2, typedRcPtr->m_m44, typedRcPtr->m_offset4)) { std::ostringstream os; os << "Cannot invert second MatrixOffsetOp op. "; os << "Matrix inverse does not exist for ("; for(int i=0; i<16; ++i) { os << typedRcPtr->m_m44[i] << " "; } os << ")."; throw Exception(os.str().c_str()); } GetMxbCombine(mout, vout, m_m44, m_offset4, minv2, vinv2); } else if(m_direction == TRANSFORM_DIR_INVERSE && typedRcPtr->m_direction == TRANSFORM_DIR_FORWARD) { float minv1[16]; float vinv1[4]; if(!GetMxbInverse(minv1, vinv1, m_m44, m_offset4)) { std::ostringstream os; os << "Cannot invert primary MatrixOffsetOp op. "; os << "Matrix inverse does not exist for ("; for(int i=0; i<16; ++i) { os << m_m44[i] << " "; } os << ")."; throw Exception(os.str().c_str()); } GetMxbCombine(mout, vout, minv1, vinv1, typedRcPtr->m_m44, typedRcPtr->m_offset4); } else if(m_direction == TRANSFORM_DIR_INVERSE && typedRcPtr->m_direction == TRANSFORM_DIR_INVERSE) { float minv1[16]; float vinv1[4]; float minv2[16]; float vinv2[4]; if(!GetMxbInverse(minv1, vinv1, m_m44, m_offset4)) { std::ostringstream os; os << "Cannot invert primary MatrixOffsetOp op. "; os << "Matrix inverse does not exist for ("; for(int i=0; i<16; ++i) { os << m_m44[i] << " "; } os << ")."; throw Exception(os.str().c_str()); } if(!GetMxbInverse(minv2, vinv2, typedRcPtr->m_m44, typedRcPtr->m_offset4)) { std::ostringstream os; os << "Cannot invert second MatrixOffsetOp op. "; os << "Matrix inverse does not exist for ("; for(int i=0; i<16; ++i) { os << typedRcPtr->m_m44[i] << " "; } os << ")."; throw Exception(os.str().c_str()); } GetMxbCombine(mout, vout, minv1, vinv1, minv2, vinv2); } else { std::ostringstream os; os << "MatrixOffsetOp cannot combine ops with unspecified "; os << "directions. First op: " << m_direction << " "; os << "secondOp:" << typedRcPtr->m_direction; throw Exception(os.str().c_str()); } CreateMatrixOffsetOp(ops, mout, vout, TRANSFORM_DIR_FORWARD); } bool MatrixOffsetOp::hasChannelCrosstalk() const { return (!m_m44IsDiagonal); } void MatrixOffsetOp::finalize() { m_offset4IsIdentity = IsVecEqualToZero(m_offset4, 4); m_m44IsIdentity = IsM44Identity(m_m44); m_m44IsDiagonal = IsM44Diagonal(m_m44); if(m_direction == TRANSFORM_DIR_INVERSE) { if(!GetM44Inverse(m_m44_inv, m_m44)) { std::ostringstream os; os << "Cannot apply MatrixOffsetOp op. "; os << "Matrix inverse does not exist for m44 ("; for(int i=0; i<16; ++i) os << m_m44[i] << " "; os << ")."; throw Exception(os.str().c_str()); } } // Create the cacheID md5_state_t state; md5_byte_t digest[16]; md5_init(&state); md5_append(&state, (const md5_byte_t *)m_m44, (int)(16*sizeof(float))); md5_append(&state, (const md5_byte_t *)m_offset4, (int)(4*sizeof(float))); md5_finish(&state, digest); std::ostringstream cacheIDStream; cacheIDStream << ""; m_cacheID = cacheIDStream.str(); } void MatrixOffsetOp::apply(float* rgbaBuffer, long numPixels) const { if(m_direction == TRANSFORM_DIR_FORWARD) { if(!m_m44IsIdentity) { if(m_m44IsDiagonal) { float scale[4]; GetM44Diagonal(scale, m_m44); ApplyScale(rgbaBuffer, numPixels, scale); } else { ApplyMatrix(rgbaBuffer, numPixels, m_m44); } } if(!m_offset4IsIdentity) { ApplyOffset(rgbaBuffer, numPixels, m_offset4); } } else if(m_direction == TRANSFORM_DIR_INVERSE) { if(!m_offset4IsIdentity) { float offset_inv[] = { -m_offset4[0], -m_offset4[1], -m_offset4[2], -m_offset4[3] }; ApplyOffset(rgbaBuffer, numPixels, offset_inv); } if(!m_m44IsIdentity) { if(m_m44IsDiagonal) { float scale[4]; GetM44Diagonal(scale, m_m44_inv); ApplyScale(rgbaBuffer, numPixels, scale); } else { ApplyMatrix(rgbaBuffer, numPixels, m_m44_inv); } } } } // Op::process bool MatrixOffsetOp::supportsGpuShader() const { return true; } void MatrixOffsetOp::writeGpuShader(std::ostream & shader, const std::string & pixelName, const GpuShaderDesc & shaderDesc) const { GpuLanguage lang = shaderDesc.getLanguage(); // TODO: This should not act upon alpha, // since we dont apply it on the CPU? if(m_direction == TRANSFORM_DIR_FORWARD) { if(!m_m44IsIdentity) { if(m_m44IsDiagonal) { shader << pixelName << " = "; float scale[4]; GetM44Diagonal(scale, m_m44); Write_half4(shader, scale, lang); shader << " * " << pixelName << ";\n"; } else { shader << pixelName << " = "; Write_mtx_x_vec(shader, GpuTextHalf4x4(m_m44, lang), pixelName, lang); shader << ";\n"; } } if(!m_offset4IsIdentity) { shader << pixelName << " = "; Write_half4(shader, m_offset4, lang); shader << " + " << pixelName << ";\n"; } } else if(m_direction == TRANSFORM_DIR_INVERSE) { if(!m_offset4IsIdentity) { float offset_inv[] = { -m_offset4[0], -m_offset4[1], -m_offset4[2], -m_offset4[3] }; shader << pixelName << " = "; Write_half4(shader, offset_inv, lang); shader << " + " << pixelName << ";\n"; } if(!m_m44IsIdentity) { if(m_m44IsDiagonal) { shader << pixelName << " = "; float scale[4]; GetM44Diagonal(scale, m_m44_inv); Write_half4(shader, scale, lang); shader << " * " << pixelName << ";\n"; } else { shader << pixelName << " = "; Write_mtx_x_vec(shader, GpuTextHalf4x4(m_m44_inv, lang), pixelName, lang); shader << ";\n"; } } } } } // Anon namespace /////////////////////////////////////////////////////////////////////////// void CreateScaleOp(OpRcPtrVec & ops, const float * scale4, TransformDirection direction) { float offset4[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; CreateScaleOffsetOp(ops, scale4, offset4, direction); } void CreateMatrixOp(OpRcPtrVec & ops, const float * m44, TransformDirection direction) { float offset4[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; CreateMatrixOffsetOp(ops, m44, offset4, direction); } void CreateOffsetOp(OpRcPtrVec & ops, const float * offset4, TransformDirection direction) { float scale4[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; CreateScaleOffsetOp(ops, scale4, offset4, direction); } void CreateScaleOffsetOp(OpRcPtrVec & ops, const float * scale4, const float * offset4, TransformDirection direction) { float m44[16]; memset(m44, 0, 16*sizeof(float)); m44[0] = scale4[0]; m44[5] = scale4[1]; m44[10] = scale4[2]; m44[15] = scale4[3]; CreateMatrixOffsetOp(ops, m44, offset4, direction); } void CreateSaturationOp(OpRcPtrVec & ops, float sat, const float * lumaCoef3, TransformDirection direction) { float matrix[16]; float offset[4]; MatrixTransform::Sat(matrix, offset, sat, lumaCoef3); CreateMatrixOffsetOp(ops, matrix, offset, direction); } void CreateMatrixOffsetOp(OpRcPtrVec & ops, const float * m44, const float * offset4, TransformDirection direction) { bool mtxIsIdentity = IsM44Identity(m44); bool offsetIsIdentity = IsVecEqualToZero(offset4, 4); if(mtxIsIdentity && offsetIsIdentity) return; ops.push_back( MatrixOffsetOpRcPtr(new MatrixOffsetOp(m44, offset4, direction)) ); } void CreateFitOp(OpRcPtrVec & ops, const float * oldmin4, const float * oldmax4, const float * newmin4, const float * newmax4, TransformDirection direction) { float matrix[16]; float offset[4]; MatrixTransform::Fit(matrix, offset, oldmin4, oldmax4, newmin4, newmax4); CreateMatrixOffsetOp(ops, matrix, offset, direction); } } OCIO_NAMESPACE_EXIT //////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" OCIO_NAMESPACE_USING OIIO_ADD_TEST(MatrixOps, Combining) { float m1[16] = { 1.1f, 0.2f, 0.3f, 0.4f, 0.5f, 1.6f, 0.7f, 0.8f, 0.2f, 0.1f, 1.1f, 0.2f, 0.3f, 0.4f, 0.5f, 1.6f }; float v1[4] = { -0.5f, -0.25f, 0.25f, 0.0f }; float m2[16] = { 1.1f, -0.1f, -0.1f, 0.0f, 0.1f, 0.9f, -0.2f, 0.0f, 0.05f, 0.0f, 1.1f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }; float v2[4] = { -0.2f, -0.1f, -0.1f, -0.2f }; const float source[] = { 0.1f, 0.2f, 0.3f, 0.4f, -0.1f, -0.2f, 50.0f, 123.4f, 1.0f, 1.0f, 1.0f, 1.0f }; float error = 1e-4f; { OpRcPtrVec ops; CreateMatrixOffsetOp(ops, m1, v1, TRANSFORM_DIR_FORWARD); CreateMatrixOffsetOp(ops, m2, v2, TRANSFORM_DIR_FORWARD); OIIO_CHECK_EQUAL(ops.size(), 2); ops[0]->finalize(); ops[1]->finalize(); OpRcPtrVec combined; ops[0]->combineWith(combined, ops[1]); OIIO_CHECK_EQUAL(combined.size(), 1); combined[0]->finalize(); for(int test=0; test<3; ++test) { float tmp[4]; memcpy(tmp, &source[4*test], 4*sizeof(float)); ops[0]->apply(tmp, 1); ops[1]->apply(tmp, 1); float tmp2[4]; memcpy(tmp2, &source[4*test], 4*sizeof(float)); combined[0]->apply(tmp2, 1); for(unsigned int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(tmp2[i], tmp[i], error); } } } { OpRcPtrVec ops; CreateMatrixOffsetOp(ops, m1, v1, TRANSFORM_DIR_FORWARD); CreateMatrixOffsetOp(ops, m2, v2, TRANSFORM_DIR_INVERSE); OIIO_CHECK_EQUAL(ops.size(), 2); ops[0]->finalize(); ops[1]->finalize(); OpRcPtrVec combined; ops[0]->combineWith(combined, ops[1]); OIIO_CHECK_EQUAL(combined.size(), 1); combined[0]->finalize(); for(int test=0; test<3; ++test) { float tmp[4]; memcpy(tmp, &source[4*test], 4*sizeof(float)); ops[0]->apply(tmp, 1); ops[1]->apply(tmp, 1); float tmp2[4]; memcpy(tmp2, &source[4*test], 4*sizeof(float)); combined[0]->apply(tmp2, 1); for(unsigned int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(tmp2[i], tmp[i], error); } } } { OpRcPtrVec ops; CreateMatrixOffsetOp(ops, m1, v1, TRANSFORM_DIR_INVERSE); CreateMatrixOffsetOp(ops, m2, v2, TRANSFORM_DIR_FORWARD); OIIO_CHECK_EQUAL(ops.size(), 2); ops[0]->finalize(); ops[1]->finalize(); OpRcPtrVec combined; ops[0]->combineWith(combined, ops[1]); OIIO_CHECK_EQUAL(combined.size(), 1); combined[0]->finalize(); for(int test=0; test<3; ++test) { float tmp[4]; memcpy(tmp, &source[4*test], 4*sizeof(float)); ops[0]->apply(tmp, 1); ops[1]->apply(tmp, 1); float tmp2[4]; memcpy(tmp2, &source[4*test], 4*sizeof(float)); combined[0]->apply(tmp2, 1); for(unsigned int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(tmp2[i], tmp[i], error); } } } { OpRcPtrVec ops; CreateMatrixOffsetOp(ops, m1, v1, TRANSFORM_DIR_INVERSE); CreateMatrixOffsetOp(ops, m2, v2, TRANSFORM_DIR_INVERSE); OIIO_CHECK_EQUAL(ops.size(), 2); ops[0]->finalize(); ops[1]->finalize(); OpRcPtrVec combined; ops[0]->combineWith(combined, ops[1]); OIIO_CHECK_EQUAL(combined.size(), 1); combined[0]->finalize(); for(int test=0; test<3; ++test) { float tmp[4]; memcpy(tmp, &source[4*test], 4*sizeof(float)); ops[0]->apply(tmp, 1); ops[1]->apply(tmp, 1); float tmp2[4]; memcpy(tmp2, &source[4*test], 4*sizeof(float)); combined[0]->apply(tmp2, 1); for(unsigned int i=0; i<4; ++i) { OIIO_CHECK_CLOSE(tmp2[i], tmp[i], error); } } } } #endif opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatSpi3D.cpp0000644000175000017500000001647513223553423021421 0ustar mfvmfv/* 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 #include "FileTransform.h" #include "Lut3DOp.h" #include "pystring/pystring.h" #include #include /* SPILUT 1.0 3 3 32 32 32 0 0 0 0.0132509 0.0158522 0.0156622 0 0 1 0.0136178 0.018843 0.033921 0 0 2 0.0136487 0.0240918 0.0563014 0 0 3 0.015706 0.0303061 0.0774135 ... entries can be in any order ... after the expected number of entries is found, file can contain anything */ OCIO_NAMESPACE_ENTER { //////////////////////////////////////////////////////////////// namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile() { lut = Lut3D::Create(); }; ~LocalCachedFile() {}; Lut3DRcPtr lut; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "spi3d"; info.extension = "spi3d"; info.capabilities = FORMAT_CAPABILITY_READ; formatInfoVec.push_back(info); } CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { const int MAX_LINE_SIZE = 4096; char lineBuffer[MAX_LINE_SIZE]; Lut3DRcPtr lut3d = Lut3D::Create(); // Read header information istream.getline(lineBuffer, MAX_LINE_SIZE); if(!pystring::startswith(pystring::lower(lineBuffer), "spilut")) { std::ostringstream os; os << "Lut does not appear to be valid spilut format. "; os << "Expected 'SPILUT'. Found, '" << lineBuffer << "'."; throw Exception(os.str().c_str()); } // TODO: Assert 2nd line is 3 3 istream.getline(lineBuffer, MAX_LINE_SIZE); // Get LUT Size // TODO: Error handling int rSize, gSize, bSize; istream.getline(lineBuffer, MAX_LINE_SIZE); sscanf(lineBuffer, "%d %d %d", &rSize, &gSize, &bSize); lut3d->size[0] = rSize; lut3d->size[1] = gSize; lut3d->size[2] = bSize; lut3d->lut.resize(rSize * gSize * bSize * 3); // Parse table int index = 0; int rIndex, gIndex, bIndex; float redValue, greenValue, blueValue; int entriesRemaining = rSize * gSize * bSize; while (istream.good() && entriesRemaining > 0) { istream.getline(lineBuffer, MAX_LINE_SIZE); if (sscanf(lineBuffer, "%d %d %d %f %f %f", &rIndex, &gIndex, &bIndex, &redValue, &greenValue, &blueValue) == 6) { index = GetLut3DIndex_B(rIndex, gIndex, bIndex, rSize, gSize, bSize); if(index < 0 || index >= (int) lut3d->lut.size()) { std::ostringstream os; os << "Cannot load .spi3d lut, data is invalid. "; os << "A lut entry is specified ("; os << rIndex << " " << gIndex << " " << bIndex; os << " that falls outside of the cube."; throw Exception(os.str().c_str()); } lut3d->lut[index+0] = redValue; lut3d->lut[index+1] = greenValue; lut3d->lut[index+2] = blueValue; entriesRemaining--; } } // Have we fully populated the table? if (entriesRemaining>0) throw Exception("Not enough entries found."); LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile()); cachedFile->lut = lut3d; return cachedFile; } void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops, const Config& /*config*/, const ConstContextRcPtr & /*context*/, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { LocalCachedFileRcPtr cachedFile = DynamicPtrCast(untypedCachedFile); if(!cachedFile) // This should never happen. { std::ostringstream os; os << "Cannot build Spi3D Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); CreateLut3DOp(ops, cachedFile->lut, fileTransform.getInterpolation(), newDir); } } FileFormat * CreateFileFormatSpi3D() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/Context.cpp0000644000175000017500000003444613223553423020150 0ustar mfvmfv/* 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 #include #include #include #include #include "HashUtils.h" #include "Mutex.h" #include "PathUtils.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { namespace { typedef std::map< std::string, std::string> StringMap; void GetAbsoluteSearchPaths(std::vector & searchpaths, const std::string & pathString, const std::string & configRootDir, const EnvMap & map); } class Context::Impl { public: std::string searchPath_; std::string workingDir_; EnvironmentMode envmode_; EnvMap envMap_; mutable std::string cacheID_; mutable StringMap resultsCache_; mutable Mutex resultsCacheMutex_; Impl() : envmode_(ENV_ENVIRONMENT_LOAD_PREDEFINED) { } ~Impl() { } Impl& operator= (const Impl & rhs) { AutoMutex lock1(resultsCacheMutex_); AutoMutex lock2(rhs.resultsCacheMutex_); searchPath_ = rhs.searchPath_; workingDir_ = rhs.workingDir_; envMap_ = rhs.envMap_; resultsCache_ = rhs.resultsCache_; cacheID_ = rhs.cacheID_; return *this; } }; /////////////////////////////////////////////////////////////////////////// ContextRcPtr Context::Create() { return ContextRcPtr(new Context(), &deleter); } void Context::deleter(Context* c) { delete c; } /////////////////////////////////////////////////////////////////////////// Context::Context() : m_impl(new Context::Impl) { } Context::~Context() { delete m_impl; m_impl = NULL; } ContextRcPtr Context::createEditableCopy() const { ContextRcPtr context = Context::Create(); *context->m_impl = *getImpl(); return context; } const char * Context::getCacheID() const { AutoMutex lock(getImpl()->resultsCacheMutex_); if(getImpl()->cacheID_.empty()) { std::ostringstream cacheid; cacheid << "Search Path " << getImpl()->searchPath_ << " "; cacheid << "Working Dir " << getImpl()->workingDir_ << " "; cacheid << "Environment Mode " << getImpl()->envmode_ << " "; for (EnvMap::const_iterator iter = getImpl()->envMap_.begin(), end = getImpl()->envMap_.end(); iter != end; ++iter) { cacheid << iter->first << "=" << iter->second << " "; } std::string fullstr = cacheid.str(); getImpl()->cacheID_ = CacheIDHash(fullstr.c_str(), (int)fullstr.size()); } return getImpl()->cacheID_.c_str(); } void Context::setSearchPath(const char * path) { AutoMutex lock(getImpl()->resultsCacheMutex_); getImpl()->searchPath_ = path; getImpl()->resultsCache_.clear(); getImpl()->cacheID_ = ""; } const char * Context::getSearchPath() const { return getImpl()->searchPath_.c_str(); } void Context::setWorkingDir(const char * dirname) { AutoMutex lock(getImpl()->resultsCacheMutex_); getImpl()->workingDir_ = dirname; getImpl()->resultsCache_.clear(); getImpl()->cacheID_ = ""; } const char * Context::getWorkingDir() const { return getImpl()->workingDir_.c_str(); } void Context::setEnvironmentMode(EnvironmentMode mode) { AutoMutex lock(getImpl()->resultsCacheMutex_); getImpl()->envmode_ = mode; getImpl()->resultsCache_.clear(); getImpl()->cacheID_ = ""; } EnvironmentMode Context::getEnvironmentMode() const { return getImpl()->envmode_; } void Context::loadEnvironment() { bool update = (getImpl()->envmode_ == ENV_ENVIRONMENT_LOAD_ALL) ? false : true; LoadEnvironment(getImpl()->envMap_, update); AutoMutex lock(getImpl()->resultsCacheMutex_); getImpl()->resultsCache_.clear(); getImpl()->cacheID_ = ""; } void Context::setStringVar(const char * name, const char * value) { if(!name) return; AutoMutex lock(getImpl()->resultsCacheMutex_); // Set the value if specified if(value) { getImpl()->envMap_[name] = value; } // If a null value is specified, erase it else { EnvMap::iterator iter = getImpl()->envMap_.find(name); if(iter != getImpl()->envMap_.end()) { getImpl()->envMap_.erase(iter); } } getImpl()->resultsCache_.clear(); getImpl()->cacheID_ = ""; } const char * Context::getStringVar(const char * name) const { if(!name) return ""; EnvMap::const_iterator iter = getImpl()->envMap_.find(name); if(iter != getImpl()->envMap_.end()) { return iter->second.c_str(); } return ""; } int Context::getNumStringVars() const { return static_cast(getImpl()->envMap_.size()); } const char * Context::getStringVarNameByIndex(int index) const { if(index < 0 || index >= static_cast(getImpl()->envMap_.size())) return ""; EnvMap::const_iterator iter = getImpl()->envMap_.begin(); for(int count = 0; countfirst.c_str(); } void Context::clearStringVars() { getImpl()->envMap_.clear(); } const char * Context::resolveStringVar(const char * val) const { AutoMutex lock(getImpl()->resultsCacheMutex_); if(!val || !*val) { return ""; } StringMap::const_iterator iter = getImpl()->resultsCache_.find(val); if(iter != getImpl()->resultsCache_.end()) { return iter->second.c_str(); } std::string resolvedval = EnvExpand(val, getImpl()->envMap_); getImpl()->resultsCache_[val] = resolvedval; return getImpl()->resultsCache_[val].c_str(); } const char * Context::resolveFileLocation(const char * filename) const { AutoMutex lock(getImpl()->resultsCacheMutex_); if(!filename || !*filename) { return ""; } StringMap::const_iterator iter = getImpl()->resultsCache_.find(filename); if(iter != getImpl()->resultsCache_.end()) { return iter->second.c_str(); } // Attempt to load an absolute file reference { std::string expandedfullpath = EnvExpand(filename, getImpl()->envMap_); if(pystring::os::path::isabs(expandedfullpath)) { if(FileExists(expandedfullpath)) { getImpl()->resultsCache_[filename] = expandedfullpath; return getImpl()->resultsCache_[filename].c_str(); } std::ostringstream errortext; errortext << "The specified absolute file reference "; errortext << "'" << expandedfullpath << "' could not be located. "; throw Exception(errortext.str().c_str()); } } // Load a relative file reference // Prep the search path vector // TODO: Cache this prepped vector? std::vector searchpaths; GetAbsoluteSearchPaths(searchpaths, getImpl()->searchPath_, getImpl()->workingDir_, getImpl()->envMap_); // Loop over each path, and try to find the file std::ostringstream errortext; errortext << "The specified file reference "; errortext << " '" << filename << "' could not be located. "; errortext << "The following attempts were made: "; for (unsigned int i = 0; i < searchpaths.size(); ++i) { // Make an attempt to find the lut in one of the search paths std::string fullpath = pystring::os::path::join(searchpaths[i], filename); std::string expandedfullpath = EnvExpand(fullpath, getImpl()->envMap_); if(FileExists(expandedfullpath)) { getImpl()->resultsCache_[filename] = expandedfullpath; return getImpl()->resultsCache_[filename].c_str(); } if(i!=0) errortext << " : "; errortext << expandedfullpath; } throw ExceptionMissingFile(errortext.str().c_str()); } std::ostream& operator<< (std::ostream& os, const Context& context) { os << ""; return os; } namespace { void GetAbsoluteSearchPaths(std::vector & searchpaths, const std::string & pathString, const std::string & workingDir, const EnvMap & map) { if(pathString.empty()) { searchpaths.push_back(workingDir); return; } std::vector parts; pystring::split(pathString, parts, ":"); for (unsigned int i = 0; i < parts.size(); ++i) { // Expand variables incase the expansion adds slashes std::string expanded = EnvExpand(parts[i], map); // Remove trailing "/", and spaces std::string dirname = pystring::rstrip(pystring::strip(expanded), "/"); if(!pystring::os::path::isabs(dirname)) { dirname = pystring::os::path::join(workingDir, dirname); } searchpaths.push_back(pystring::os::path::normpath(dirname)); } } } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" #include #ifdef OCIO_SOURCE_DIR #define _STR(x) #x #define STR(x) _STR(x) #ifdef WINDOWS // FIXME: On Windows remove the 'C:' from the absolute path as the ':' is // used for the search path delimiter. The selected character // is problematic on Windows. static const std::string ociodir(&std::string(STR(OCIO_SOURCE_DIR)).c_str()[2]); // Method to avoid using boost filesystem library to compare paths std::string sanatizepath(const char* path) { std::string s(path); std::replace(s.begin(), s.end(), '\\', '/'); return s; } #else static const std::string ociodir(STR(OCIO_SOURCE_DIR)); std::string sanatizepath(const char* path) { return std::string(path); } #endif static const std::string contextpath(ociodir+std::string("/src/core/Context.cpp")); OIIO_ADD_TEST(Context, ABSPath) { OCIO::ContextRcPtr con = OCIO::Context::Create(); con->setSearchPath(ociodir.c_str()); con->setStringVar("non_abs", "src/core/Context.cpp"); con->setStringVar("is_abs", contextpath.c_str()); OIIO_CHECK_NO_THROW(con->resolveFileLocation("${non_abs}")); OIIO_CHECK_ASSERT(strcmp(sanatizepath(con->resolveFileLocation("${non_abs}")).c_str(), contextpath.c_str()) == 0); OIIO_CHECK_NO_THROW(con->resolveFileLocation("${is_abs}")); OIIO_CHECK_ASSERT(strcmp(con->resolveFileLocation("${is_abs}"), contextpath.c_str()) == 0); } OIIO_ADD_TEST(Context, VarSearchPath) { OCIO::ContextRcPtr context = OCIO::Context::Create(); context->setStringVar("SOURCE_DIR", ociodir.c_str()); context->setSearchPath("${SOURCE_DIR}/src/core"); OIIO_CHECK_NO_THROW(context->resolveFileLocation("Context.cpp")); OIIO_CHECK_ASSERT(strcmp(sanatizepath(context->resolveFileLocation("Context.cpp")).c_str(), contextpath.c_str()) == 0); } #endif // OCIO_SOURCE_DIR #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatVF.cpp0000644000175000017500000002654313223553423021007 0ustar mfvmfv/* 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 #include #include #include #include #include "FileTransform.h" #include "Lut3DOp.h" #include "MatrixOps.h" #include "ParseUtils.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile () : useMatrix(false) { lut3D = Lut3D::Create(); memset(m44, 0, 16*sizeof(float)); }; ~LocalCachedFile() {}; Lut3DRcPtr lut3D; float m44[16]; bool useMatrix; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "nukevf"; info.extension = "vf"; info.capabilities = FORMAT_CAPABILITY_READ; formatInfoVec.push_back(info); } CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { // this shouldn't happen if(!istream) { throw Exception ("File stream empty when trying to read .vf lut"); } // Validate the file type std::string line; if(!nextline(istream, line) || !pystring::startswith(pystring::lower(line), "#inventor")) { throw Exception("Lut doesn't seem to be a .vf lut. Expecting '#Inventor V2.1 ascii'."); } // Parse the file std::vector raw3d; int size3d[] = { 0, 0, 0 }; std::vector global_transform; { std::vector parts; std::vector tmpfloats; bool in3d = false; while(nextline(istream, line)) { // Strip, lowercase, and split the line pystring::split(pystring::lower(pystring::strip(line)), parts); if(parts.empty()) continue; if(pystring::startswith(parts[0],"#")) continue; if(!in3d) { if(parts[0] == "grid_size") { if(parts.size() != 4 || !StringToInt( &size3d[0], parts[1].c_str()) || !StringToInt( &size3d[1], parts[2].c_str()) || !StringToInt( &size3d[2], parts[3].c_str())) { throw Exception("Malformed grid_size tag in .vf lut."); } raw3d.reserve(3*size3d[0]*size3d[1]*size3d[2]); } else if(parts[0] == "global_transform") { if(parts.size() != 17) { throw Exception("Malformed global_transform tag. 16 floats expected."); } parts.erase(parts.begin()); // Drop the 1st entry. (the tag) if(!StringVecToFloatVec(global_transform, parts) || global_transform.size() != 16) { throw Exception("Malformed global_transform tag. Could not convert to float array."); } } // TODO: element_size (aka scale3) // TODO: world_origin (aka translate3) else if(parts[0] == "data") { in3d = true; } } else // (in3d) { if(StringVecToFloatVec(tmpfloats, parts) && (tmpfloats.size() == 3)) { raw3d.push_back(tmpfloats[0]); raw3d.push_back(tmpfloats[1]); raw3d.push_back(tmpfloats[2]); } } } } // Interpret the parsed data, validate lut sizes if(size3d[0]*size3d[1]*size3d[2] != static_cast(raw3d.size()/3)) { std::ostringstream os; os << "Parse error in .vf lut. "; os << "Incorrect number of lut3d entries. "; os << "Found " << raw3d.size()/3 << ", expected " << size3d[0]*size3d[1]*size3d[2] << "."; throw Exception(os.str().c_str()); } if(size3d[0]*size3d[1]*size3d[2] == 0) { std::ostringstream os; os << "Parse error in .vf lut. "; os << "No 3D Lut entries found."; throw Exception(os.str().c_str()); } LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile()); // Setup the global matrix. // (Nuke pre-scales this by the 3dlut size, so we must undo that here) if(global_transform.size() == 16) { for(int i=0; i<4; ++i) { global_transform[4*i+0] *= static_cast(size3d[0]); global_transform[4*i+1] *= static_cast(size3d[1]); global_transform[4*i+2] *= static_cast(size3d[2]); } memcpy(cachedFile->m44, &global_transform[0], 16*sizeof(float)); cachedFile->useMatrix = true; } // Reformat 3D data cachedFile->lut3D->size[0] = size3d[0]; cachedFile->lut3D->size[1] = size3d[1]; cachedFile->lut3D->size[2] = size3d[2]; cachedFile->lut3D->lut.reserve(raw3d.size()); for(int rIndex=0; rIndexlut3D->lut.push_back(static_cast(raw3d[i+0])); cachedFile->lut3D->lut.push_back(static_cast(raw3d[i+1])); cachedFile->lut3D->lut.push_back(static_cast(raw3d[i+2])); } } } return cachedFile; } void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops, const Config& /*config*/, const ConstContextRcPtr & /*context*/, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { LocalCachedFileRcPtr cachedFile = DynamicPtrCast(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build .vf Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_UNKNOWN) { std::ostringstream os; os << "Cannot build file format transform,"; os << " unspecified transform direction."; throw Exception(os.str().c_str()); } if(newDir == TRANSFORM_DIR_FORWARD) { if(cachedFile->useMatrix) { CreateMatrixOp(ops, cachedFile->m44, newDir); } CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } else if(newDir == TRANSFORM_DIR_INVERSE) { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); if(cachedFile->useMatrix) { CreateMatrixOp(ops, cachedFile->m44, newDir); } } } } FileFormat * CreateFileFormatVF() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// // TODO: Unit test opencolorio-1.1.0~dfsg0.orig/src/core/NoOps.h0000644000175000017500000000504713223553423017222 0ustar mfvmfv/* 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_OCIO_GPUALLOCATIONNOOP_H #define INCLUDED_OCIO_GPUALLOCATIONNOOP_H #include #include "Op.h" #include OCIO_NAMESPACE_ENTER { void CreateGpuAllocationNoOp(OpRcPtrVec & ops, const AllocationData & allocationData); // Partition an opvec into 3 segments for GPU Processing // // gpuLatticeOps need not support analytical gpu shader generation // the pre and post ops must support analytical generation. // // Additional ops will optinally be inserted to take into account // allocation transformations void PartitionGPUOps(OpRcPtrVec & gpuPreOps, OpRcPtrVec & gpuLatticeOps, OpRcPtrVec & gpuPostOps, const OpRcPtrVec & ops); void CreateFileNoOp(OpRcPtrVec & ops, const std::string & fname); void CreateLookNoOp(OpRcPtrVec & ops, const std::string & lookName); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/LogOps.h0000644000175000017500000000421413223553423017362 0ustar mfvmfv/* 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_OCIO_LOGOPS_H #define INCLUDED_OCIO_LOGOPS_H #include #include "Op.h" #include OCIO_NAMESPACE_ENTER { // output = k * log(mx+b, base) + kb // This does not affect alpha // In the forward direction this is lin->log // All input vectors are size 3 (including base) void CreateLogOp(OpRcPtrVec & ops, const float * k, const float * m, const float * b, const float * base, const float * kb, TransformDirection direction); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/GpuShaderDesc.cpp0000644000175000017500000000747513223553423021207 0ustar mfvmfv/* 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 #include #include "Mutex.h" OCIO_NAMESPACE_ENTER { class GpuShaderDesc::Impl { public: GpuLanguage language_; std::string functionName_; int lut3DEdgeLen_; mutable std::string cacheID_; mutable Mutex cacheIDMutex_; Impl() : language_(GPU_LANGUAGE_UNKNOWN), lut3DEdgeLen_(0) { } ~Impl() { } Impl& operator= (const Impl & rhs) { language_ = rhs.language_; functionName_ = rhs.functionName_; lut3DEdgeLen_ = rhs.lut3DEdgeLen_; cacheID_ = rhs.cacheID_; return *this; } }; GpuShaderDesc::GpuShaderDesc() : m_impl(new GpuShaderDesc::Impl) { } GpuShaderDesc::~GpuShaderDesc() { delete m_impl; m_impl = NULL; } void GpuShaderDesc::setLanguage(GpuLanguage lang) { AutoMutex lock(getImpl()->cacheIDMutex_); getImpl()->language_ = lang; getImpl()->cacheID_ = ""; } GpuLanguage GpuShaderDesc::getLanguage() const { return getImpl()->language_; } void GpuShaderDesc::setFunctionName(const char * name) { AutoMutex lock(getImpl()->cacheIDMutex_); getImpl()->functionName_ = name; getImpl()->cacheID_ = ""; } const char * GpuShaderDesc::getFunctionName() const { return getImpl()->functionName_.c_str(); } void GpuShaderDesc::setLut3DEdgeLen(int len) { AutoMutex lock(getImpl()->cacheIDMutex_); getImpl()->lut3DEdgeLen_ = len; getImpl()->cacheID_ = ""; } int GpuShaderDesc::getLut3DEdgeLen() const { return getImpl()->lut3DEdgeLen_; } const char * GpuShaderDesc::getCacheID() const { AutoMutex lock(getImpl()->cacheIDMutex_); if(getImpl()->cacheID_.empty()) { std::ostringstream os; os << GpuLanguageToString(getImpl()->language_) << " "; os << getImpl()->functionName_ << " "; os << getImpl()->lut3DEdgeLen_; getImpl()->cacheID_ = os.str(); } return getImpl()->cacheID_.c_str(); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/PathUtils.h0000644000175000017500000000655013223553423020101 0ustar mfvmfv/* 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_OCIO_PATHUTILS_H #define INCLUDED_OCIO_PATHUTILS_H #include #include OCIO_NAMESPACE_ENTER { namespace pystring { namespace os { namespace path { // This is not currently included in pystring, but we need it // So let's define it locally for now std::string abspath(const std::string & path); } } } // The EnvMap is ordered by the length of the keys (long -> short). This // is so that recursive string expansion will deal with similar prefixed // keys as expected. // ie. '$TEST_$TESTING_$TE' will expand in this order '2 1 3' template struct EnvMapKey : std::binary_function { bool operator() (const T &x, const T &y) const { // If the lengths are unequal, sort by length if(x.length() != y.length()) { return (x.length() > y.length()); } // Otherwise, use the standard string sort comparison else { return (x > EnvMap; // Get map of current env key = value, or update the existing entries void LoadEnvironment(EnvMap & map, bool update = false); // Expand a string with $VAR, ${VAR} or %VAR% with the keys passed // in the EnvMap. std::string EnvExpand(const std::string & str, const EnvMap & map); // Check if a file exists bool FileExists(const std::string & filename); // Get a fast hash for a file, without reading all the contents. // Currently, this checks the mtime and the inode number. std::string GetFastFileHash(const std::string & filename); void ClearPathCaches(); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/Baker.cpp0000644000175000017500000001750513223553423017545 0ustar mfvmfv/* 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 #include #include #include "FileTransform.h" #include "MathUtils.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { BakerRcPtr Baker::Create() { return BakerRcPtr(new Baker(), &deleter); } void Baker::deleter(Baker* c) { delete c; } class Baker::Impl { public: ConfigRcPtr config_; std::string formatName_; std::string type_; std::string metadata_; std::string inputSpace_; std::string shaperSpace_; std::string looks_; std::string targetSpace_; int shapersize_; int cubesize_; Impl() : shapersize_(-1), cubesize_(-1) { } ~Impl() { } Impl& operator= (const Impl & rhs) { config_ = rhs.config_; formatName_ = rhs.formatName_; inputSpace_ = rhs.inputSpace_; shaperSpace_ = rhs.shaperSpace_; looks_ = rhs.looks_; targetSpace_ = rhs.targetSpace_; shapersize_ = rhs.shapersize_; cubesize_ = rhs.cubesize_; return *this; } }; Baker::Baker() : m_impl(new Baker::Impl) { } Baker::~Baker() { delete m_impl; m_impl = NULL; } BakerRcPtr Baker::createEditableCopy() const { BakerRcPtr oven = Baker::Create(); *oven->m_impl = *m_impl; return oven; } void Baker::setConfig(const ConstConfigRcPtr & config) { getImpl()->config_ = config->createEditableCopy(); } ConstConfigRcPtr Baker::getConfig() const { return getImpl()->config_; } int Baker::getNumFormats() { return FormatRegistry::GetInstance().getNumFormats(FORMAT_CAPABILITY_WRITE); } const char * Baker::getFormatNameByIndex(int index) { return FormatRegistry::GetInstance().getFormatNameByIndex(FORMAT_CAPABILITY_WRITE, index); } const char * Baker::getFormatExtensionByIndex(int index) { return FormatRegistry::GetInstance().getFormatExtensionByIndex(FORMAT_CAPABILITY_WRITE, index); } void Baker::setFormat(const char * formatName) { getImpl()->formatName_ = formatName; } const char * Baker::getFormat() const { return getImpl()->formatName_.c_str(); } void Baker::setType(const char * type) { getImpl()->type_ = type; } const char * Baker::getType() const { return getImpl()->type_.c_str(); } void Baker::setMetadata(const char * metadata) { getImpl()->metadata_ = metadata; } const char * Baker::getMetadata() const { return getImpl()->metadata_.c_str(); } void Baker::setInputSpace(const char * inputSpace) { getImpl()->inputSpace_ = inputSpace; } const char * Baker::getInputSpace() const { return getImpl()->inputSpace_.c_str(); } void Baker::setShaperSpace(const char * shaperSpace) { getImpl()->shaperSpace_ = shaperSpace; } const char * Baker::getShaperSpace() const { return getImpl()->shaperSpace_.c_str(); } void Baker::setLooks(const char * looks) { getImpl()->looks_ = looks; } const char * Baker::getLooks() const { return getImpl()->looks_.c_str(); } void Baker::setTargetSpace(const char * targetSpace) { getImpl()->targetSpace_ = targetSpace; } const char * Baker::getTargetSpace() const { return getImpl()->targetSpace_.c_str(); } void Baker::setShaperSize(int shapersize) { getImpl()->shapersize_ = shapersize; } int Baker::getShaperSize() const { return getImpl()->shapersize_; } void Baker::setCubeSize(int cubesize) { getImpl()->cubesize_ = cubesize; } int Baker::getCubeSize() const { return getImpl()->cubesize_; } void Baker::bake(std::ostream & os) const { FileFormat* fmt = FormatRegistry::GetInstance().getFileFormatByName(getImpl()->formatName_); if(!fmt) { std::ostringstream err; err << "The format named '" << getImpl()->formatName_; err << "' could not be found. "; throw Exception(err.str().c_str()); } try { fmt->Write(*this, getImpl()->formatName_, os); } catch(std::exception & e) { std::ostringstream err; err << "Error baking " << getImpl()->formatName_ << ":"; err << e.what(); throw Exception(err.str().c_str()); } // // TODO: // // - throw exception when we don't have inputSpace and targetSpace // at least set // - check limits of shaper and target, throw exception if we can't // write that much data in x format // - check that the shaper is 1D transform only, throw excpetion // - check the file format supports shapers, 1D and 3D // - add some checks to make sure we are monotonic // - deal with the case of writing out non cube formats (1D only) // - do a compare between ocio transform and output lut transform // throw error if we going beyond tolerance // } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" /* OIIO_ADD_TEST(Baker_Unit_Tests, test_listlutwriters) { std::vector current_writers; current_writers.push_back("cinespace"); current_writers.push_back("houdini"); OCIO::BakerRcPtr baker = OCIO::Baker::Create(); OIIO_CHECK_EQUAL(baker->getNumFormats(), (int)current_writers.size()); std::vector test; for(int i = 0; i < baker->getNumFormats(); ++i) test.push_back(baker->getFormatNameByIndex(i)); for(unsigned int i = 0; i < current_writers.size(); ++i) OIIO_CHECK_EQUAL(current_writers[i], test[i]); } */ #endif // OCIO_BUILD_TESTS opencolorio-1.1.0~dfsg0.orig/src/core/NoOps.cpp0000644000175000017500000005260213223553423017554 0ustar mfvmfv/* 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 #include #include "AllocationOp.h" #include "NoOps.h" #include "OpBuilders.h" #include "Op.h" OCIO_NAMESPACE_ENTER { namespace { class AllocationNoOp : public Op { public: AllocationNoOp(const AllocationData & allocationData): m_allocationData(allocationData) {} virtual ~AllocationNoOp() {} virtual OpRcPtr clone() const; virtual std::string getInfo() const { return ""; } virtual std::string getCacheID() const { return ""; } virtual bool isNoOp() const { return true; } virtual bool isSameType(const OpRcPtr & op) const; virtual bool isInverse(const OpRcPtr & op) const; virtual bool hasChannelCrosstalk() const { return false; } virtual void finalize() { } virtual void apply(float* /*rgbaBuffer*/, long /*numPixels*/) const { } virtual bool supportsGpuShader() const { return true; } virtual void writeGpuShader(std::ostream & /*shader*/, const std::string & /*pixelName*/, const GpuShaderDesc & /*shaderDesc*/) const { } void getGpuAllocation(AllocationData & allocation) const; private: AllocationData m_allocationData; }; typedef OCIO_SHARED_PTR AllocationNoOpRcPtr; OpRcPtr AllocationNoOp::clone() const { OpRcPtr op = OpRcPtr(new AllocationNoOp(m_allocationData)); return op; } bool AllocationNoOp::isSameType(const OpRcPtr & op) const { AllocationNoOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; return true; } bool AllocationNoOp::isInverse(const OpRcPtr & op) const { if(!isSameType(op)) return false; return true; } void AllocationNoOp::getGpuAllocation(AllocationData & allocation) const { allocation = m_allocationData; } // Return whether the op defines an Allocation bool DefinesGpuAllocation(const OpRcPtr & op) { AllocationNoOpRcPtr allocationNoOpRcPtr = DynamicPtrCast(op); if(allocationNoOpRcPtr) return true; return false; } } void CreateGpuAllocationNoOp(OpRcPtrVec & ops, const AllocationData & allocationData) { ops.push_back( AllocationNoOpRcPtr(new AllocationNoOp(allocationData)) ); } namespace { // Find the minimal index range in the opVec that does not support // shader text generation. The endIndex *is* inclusive. // // I.e., if the entire opVec does not support GPUShaders, the // result will be startIndex = 0, endIndex = opVec.size() - 1 // // If the entire opVec supports GPU generation, both the // startIndex and endIndex will equal -1 void GetGpuUnsupportedIndexRange(int * startIndex, int * endIndex, const OpRcPtrVec & opVec) { int start = -1; int end = -1; for(unsigned int i=0; isupportsGpuShader()) { if(start<0) { start = i; end = i; } else end = i; } } // Now that we've found a startIndex, walk back until we find // one that defines a GpuAllocation. (we can only upload to // the gpu at a location are tagged with an allocation) while(start>0) { if(DefinesGpuAllocation(opVec[start])) break; --start; } if(startIndex) *startIndex = start; if(endIndex) *endIndex = end; } bool GetGpuAllocation(AllocationData & allocation, const OpRcPtr & op) { AllocationNoOpRcPtr allocationNoOpRcPtr = DynamicPtrCast(op); if(!allocationNoOpRcPtr) { return false; } allocationNoOpRcPtr->getGpuAllocation(allocation); return true; } } void PartitionGPUOps(OpRcPtrVec & gpuPreOps, OpRcPtrVec & gpuLatticeOps, OpRcPtrVec & gpuPostOps, const OpRcPtrVec & ops) { // // Partition the original, raw opvec into 3 segments for GPU Processing // // gpuLatticeOps need not support analytical gpu shader generation // the pre and post ops must support analytical generation. // Additional ops will be inserted to take into account allocations // transformations. // This is used to bound our analytical shader text generation // start index and end index are inclusive. int gpuLut3DOpStartIndex = 0; int gpuLut3DOpEndIndex = 0; GetGpuUnsupportedIndexRange(&gpuLut3DOpStartIndex, &gpuLut3DOpEndIndex, ops); // Write the entire shader using only shader text (3d lut is unused) if(gpuLut3DOpStartIndex == -1 && gpuLut3DOpEndIndex == -1) { for(unsigned int i=0; iclone() ); } } // Analytical -> 3dlut -> analytical else { // Handle analytical shader block before start index. for(int i=0; iclone() ); } // Get the GPU Allocation at the cross-over point // Create 2 symmetrically canceling allocation ops, // where the shader text moves to a nicely allocated LDR // (low dynamic range color space), and the lattice processing // does the inverse (making the overall operation a no-op // color-wise AllocationData allocation; if(gpuLut3DOpStartIndex<0 || gpuLut3DOpStartIndex>=(int)ops.size()) { std::ostringstream error; error << "Invalid GpuUnsupportedIndexRange: "; error << "gpuLut3DOpStartIndex: " << gpuLut3DOpStartIndex << " "; error << "gpuLut3DOpEndIndex: " << gpuLut3DOpEndIndex << " "; error << "cpuOps.size: " << ops.size(); throw Exception(error.str().c_str()); } // If the specified location defines an allocation, use it. // It's possible that this index wont define an allocation. // (For example in the case of getProcessor(FileTransform) if(GetGpuAllocation(allocation, ops[gpuLut3DOpStartIndex])) { CreateAllocationOps(gpuPreOps, allocation, TRANSFORM_DIR_FORWARD); CreateAllocationOps(gpuLatticeOps, allocation, TRANSFORM_DIR_INVERSE); } // Handle cpu lattice processing for(int i=gpuLut3DOpStartIndex; i<=gpuLut3DOpEndIndex; ++i) { gpuLatticeOps.push_back( ops[i]->clone() ); } // And then handle the gpu post processing for(int i=gpuLut3DOpEndIndex+1; i<(int)ops.size(); ++i) { gpuPostOps.push_back( ops[i]->clone() ); } } } void AssertPartitionIntegrity(OpRcPtrVec & gpuPreOps, OpRcPtrVec & gpuLatticeOps, OpRcPtrVec & gpuPostOps) { // All gpu pre ops must support analytical gpu shader generation for(unsigned int i=0; isupportsGpuShader()) { throw Exception("Patition failed check. gpuPreOps"); } } // If there are any lattice ops, at lease one must NOT support GPU // shaders (otherwise this block isnt necessary!) if(gpuLatticeOps.size()>0) { bool requireslattice = false; for(unsigned int i=0; isupportsGpuShader()) requireslattice = true; } if(!requireslattice) { throw Exception("Patition failed check. gpuLatticeOps"); } } // All gpu post ops must support analytical gpu shader generation for(unsigned int i=0; isupportsGpuShader()) { throw Exception("Patition failed check. gpuPostOps"); } } } //////////////////////////////////////////////////////////////////////////// namespace { class FileNoOp : public Op { public: FileNoOp(const std::string & fileReference): m_fileReference(fileReference) {} virtual ~FileNoOp() {} virtual OpRcPtr clone() const; virtual std::string getInfo() const { return ""; } virtual std::string getCacheID() const { return ""; } virtual bool isNoOp() const { return true; } virtual bool isSameType(const OpRcPtr & op) const; virtual bool isInverse(const OpRcPtr & op) const; virtual bool hasChannelCrosstalk() const { return false; } virtual void dumpMetadata(ProcessorMetadataRcPtr & metadata) const; virtual void finalize() {} virtual void apply(float* /*rgbaBuffer*/, long /*numPixels*/) const {} virtual bool supportsGpuShader() const { return true; } virtual void writeGpuShader(std::ostream & /*shader*/, const std::string & /*pixelName*/, const GpuShaderDesc & /*shaderDesc*/) const { } private: std::string m_fileReference; }; typedef OCIO_SHARED_PTR FileNoOpRcPtr; OpRcPtr FileNoOp::clone() const { OpRcPtr op = OpRcPtr(new FileNoOp(m_fileReference)); return op; } bool FileNoOp::isSameType(const OpRcPtr & op) const { FileNoOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; return true; } bool FileNoOp::isInverse(const OpRcPtr & op) const { return isSameType(op); } void FileNoOp::dumpMetadata(ProcessorMetadataRcPtr & metadata) const { metadata->addFile(m_fileReference.c_str()); } } void CreateFileNoOp(OpRcPtrVec & ops, const std::string & fileReference) { ops.push_back( FileNoOpRcPtr(new FileNoOp(fileReference)) ); } //////////////////////////////////////////////////////////////////////////// namespace { class LookNoOp : public Op { public: LookNoOp(const std::string & look): m_look(look) {} virtual ~LookNoOp() {} virtual OpRcPtr clone() const; virtual std::string getInfo() const { return ""; } virtual std::string getCacheID() const { return ""; } virtual bool isNoOp() const { return true; } virtual bool isSameType(const OpRcPtr & op) const; virtual bool isInverse(const OpRcPtr & op) const; virtual bool hasChannelCrosstalk() const { return false; } virtual void dumpMetadata(ProcessorMetadataRcPtr & metadata) const; virtual void finalize() {} virtual void apply(float* /*rgbaBuffer*/, long /*numPixels*/) const {} virtual bool supportsGpuShader() const { return true; } virtual void writeGpuShader(std::ostream & /*shader*/, const std::string & /*pixelName*/, const GpuShaderDesc & /*shaderDesc*/) const { } private: std::string m_look; }; typedef OCIO_SHARED_PTR LookNoOpRcPtr; OpRcPtr LookNoOp::clone() const { OpRcPtr op = OpRcPtr(new LookNoOp(m_look)); return op; } bool LookNoOp::isSameType(const OpRcPtr & op) const { LookNoOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; return true; } bool LookNoOp::isInverse(const OpRcPtr & op) const { return isSameType(op); } void LookNoOp::dumpMetadata(ProcessorMetadataRcPtr & metadata) const { metadata->addLook(m_look.c_str()); } } void CreateLookNoOp(OpRcPtrVec & ops, const std::string & look) { ops.push_back( LookNoOpRcPtr(new LookNoOp(look)) ); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST OCIO_NAMESPACE_USING #include "UnitTest.h" #include "Lut1DOp.h" #include "MatrixOps.h" void CreateGenericAllocationOp(OpRcPtrVec & ops) { AllocationData srcAllocation; srcAllocation.allocation = ALLOCATION_LG2; srcAllocation.vars.push_back(-8.0f); srcAllocation.vars.push_back(8.0f); CreateGpuAllocationNoOp(ops, srcAllocation); } void CreateGenericScaleOp(OpRcPtrVec & ops) { float scale4[4] = { 1.04f, 1.05f, 1.06f, 1.0f }; CreateScaleOp(ops, scale4, TRANSFORM_DIR_FORWARD); } void CreateGenericLutOp(OpRcPtrVec & ops) { // Make a lut that squares the input Lut1DRcPtr lut = Lut1D::Create(); { lut->from_min[0] = 0.0f; lut->from_min[1] = 0.0f; lut->from_min[2] = 0.0f; lut->from_max[0] = 1.0f; lut->from_max[1] = 1.0f; lut->from_max[2] = 1.0f; int size = 256; for(int i=0; iluts[c].push_back(x2); } } } CreateLut1DOp(ops, lut, INTERP_LINEAR, TRANSFORM_DIR_FORWARD); } OIIO_ADD_TEST(NoOps, PartitionGPUOps) { { OpRcPtrVec ops; OpRcPtrVec gpuPreOps, gpuLatticeOps, gpuPostOps; PartitionGPUOps(gpuPreOps, gpuLatticeOps, gpuPostOps, ops); OIIO_CHECK_EQUAL(gpuPreOps.size(), 0); OIIO_CHECK_EQUAL(gpuLatticeOps.size(), 0); OIIO_CHECK_EQUAL(gpuPostOps.size(), 0); OIIO_CHECK_NO_THROW( AssertPartitionIntegrity(gpuPreOps, gpuLatticeOps, gpuPostOps) ); } { OpRcPtrVec ops; CreateGenericAllocationOp(ops); OpRcPtrVec gpuPreOps, gpuLatticeOps, gpuPostOps; PartitionGPUOps(gpuPreOps, gpuLatticeOps, gpuPostOps, ops); OIIO_CHECK_EQUAL(gpuPreOps.size(), 1); OIIO_CHECK_EQUAL(gpuLatticeOps.size(), 0); OIIO_CHECK_EQUAL(gpuPostOps.size(), 0); OIIO_CHECK_NO_THROW( AssertPartitionIntegrity(gpuPreOps, gpuLatticeOps, gpuPostOps) ); } { OpRcPtrVec ops; CreateGenericAllocationOp(ops); CreateGenericScaleOp(ops); OpRcPtrVec gpuPreOps, gpuLatticeOps, gpuPostOps; PartitionGPUOps(gpuPreOps, gpuLatticeOps, gpuPostOps, ops); OIIO_CHECK_EQUAL(gpuPreOps.size(), 2); OIIO_CHECK_EQUAL(gpuLatticeOps.size(), 0); OIIO_CHECK_EQUAL(gpuPostOps.size(), 0); OIIO_CHECK_NO_THROW( AssertPartitionIntegrity(gpuPreOps, gpuLatticeOps, gpuPostOps) ); } { OpRcPtrVec ops; CreateGenericAllocationOp(ops); CreateGenericLutOp(ops); CreateGenericScaleOp(ops); OpRcPtrVec gpuPreOps, gpuLatticeOps, gpuPostOps; PartitionGPUOps(gpuPreOps, gpuLatticeOps, gpuPostOps, ops); OIIO_CHECK_EQUAL(gpuPreOps.size(), 2); OIIO_CHECK_EQUAL(gpuLatticeOps.size(), 4); OIIO_CHECK_EQUAL(gpuPostOps.size(), 1); OIIO_CHECK_NO_THROW( AssertPartitionIntegrity(gpuPreOps, gpuLatticeOps, gpuPostOps) ); } { OpRcPtrVec ops; CreateGenericLutOp(ops); OpRcPtrVec gpuPreOps, gpuLatticeOps, gpuPostOps; PartitionGPUOps(gpuPreOps, gpuLatticeOps, gpuPostOps, ops); OIIO_CHECK_EQUAL(gpuPreOps.size(), 0); OIIO_CHECK_EQUAL(gpuLatticeOps.size(), 1); OIIO_CHECK_EQUAL(gpuPostOps.size(), 0); OIIO_CHECK_NO_THROW( AssertPartitionIntegrity(gpuPreOps, gpuLatticeOps, gpuPostOps) ); } { OpRcPtrVec ops; CreateGenericLutOp(ops); CreateGenericScaleOp(ops); CreateGenericAllocationOp(ops); CreateGenericLutOp(ops); CreateGenericScaleOp(ops); CreateGenericAllocationOp(ops); OpRcPtrVec gpuPreOps, gpuLatticeOps, gpuPostOps; PartitionGPUOps(gpuPreOps, gpuLatticeOps, gpuPostOps, ops); OIIO_CHECK_EQUAL(gpuPreOps.size(), 0); OIIO_CHECK_EQUAL(gpuLatticeOps.size(), 4); OIIO_CHECK_EQUAL(gpuPostOps.size(), 2); OIIO_CHECK_NO_THROW( AssertPartitionIntegrity(gpuPreOps, gpuLatticeOps, gpuPostOps) ); } { OpRcPtrVec ops; CreateGenericAllocationOp(ops); CreateGenericScaleOp(ops); CreateGenericLutOp(ops); CreateGenericScaleOp(ops); CreateGenericAllocationOp(ops); CreateGenericLutOp(ops); CreateGenericScaleOp(ops); CreateGenericAllocationOp(ops); OpRcPtrVec gpuPreOps, gpuLatticeOps, gpuPostOps; PartitionGPUOps(gpuPreOps, gpuLatticeOps, gpuPostOps, ops); OIIO_CHECK_EQUAL(gpuPreOps.size(), 2); OIIO_CHECK_EQUAL(gpuLatticeOps.size(), 8); OIIO_CHECK_EQUAL(gpuPostOps.size(), 2); OIIO_CHECK_NO_THROW( AssertPartitionIntegrity(gpuPreOps, gpuLatticeOps, gpuPostOps) ); /* std::cerr << "gpuPreOps" << std::endl; std::cerr << SerializeOpVec(gpuPreOps, 4) << std::endl; std::cerr << "gpuLatticeOps" << std::endl; std::cerr << SerializeOpVec(gpuLatticeOps, 4) << std::endl; std::cerr << "gpuPostOps" << std::endl; std::cerr << SerializeOpVec(gpuPostOps, 4) << std::endl; */ } } // PartitionGPUOps #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/GpuShaderUtils.cpp0000644000175000017500000001362713223553423021425 0ustar mfvmfv/* 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 #include "GpuShaderUtils.h" #include "MathUtils.h" #include #include OCIO_NAMESPACE_ENTER { void Write_half4x4(std::ostream & os, const float * m44, GpuLanguage lang) { if(lang == GPU_LANGUAGE_CG) { os << "half4x4("; for(int i=0; i<16; i++) { if(i!=0) os << ", "; os << ClampToNormHalf(m44[i]); } os << ")"; } else if(lang == GPU_LANGUAGE_GLSL_1_0 || lang == GPU_LANGUAGE_GLSL_1_3) { os << "mat4("; for(int i=0; i<16; i++) { if(i!=0) os << ", "; os << m44[i]; // Clamping to half is not necessary } os << ")"; } else { throw Exception("Unsupported shader language."); } } void Write_half4(std::ostream & os, const float * v4, GpuLanguage lang) { if(lang == GPU_LANGUAGE_CG) { os << "half4("; for(int i=0; i<4; i++) { if(i!=0) os << ", "; os << ClampToNormHalf(v4[i]); } os << ")"; } else if(lang == GPU_LANGUAGE_GLSL_1_0 || lang == GPU_LANGUAGE_GLSL_1_3) { os << "vec4("; for(int i=0; i<4; i++) { if(i!=0) os << ", "; os << v4[i]; // Clamping to half is not necessary } os << ")"; } else { throw Exception("Unsupported shader language."); } } void Write_half3(std::ostream & os, const float * v3, GpuLanguage lang) { if(lang == GPU_LANGUAGE_CG) { os << "half3("; for(int i=0; i<3; i++) { if(i!=0) os << ", "; os << ClampToNormHalf(v3[i]); } os << ")"; } else if(lang == GPU_LANGUAGE_GLSL_1_0 || lang == GPU_LANGUAGE_GLSL_1_3) { os << "vec3("; for(int i=0; i<3; i++) { if(i!=0) os << ", "; os << v3[i]; // Clamping to half is not necessary } os << ")"; } else { throw Exception("Unsupported shader language."); } } std::string GpuTextHalf4x4(const float * m44, GpuLanguage lang) { std::ostringstream os; Write_half4x4(os, m44, lang); return os.str(); } std::string GpuTextHalf4(const float * v4, GpuLanguage lang) { std::ostringstream os; Write_half4(os, v4, lang); return os.str(); } std::string GpuTextHalf3(const float * v3, GpuLanguage lang) { std::ostringstream os; Write_half3(os, v3, lang); return os.str(); } // Note that Cg and GLSL have opposite ordering for vec/mtx multiplication void Write_mtx_x_vec(std::ostream & os, const std::string & mtx, const std::string & vec, GpuLanguage lang) { if(lang == GPU_LANGUAGE_CG) { os << "mul( " << mtx << ", " << vec << ")"; } else if(lang == GPU_LANGUAGE_GLSL_1_0 || lang == GPU_LANGUAGE_GLSL_1_3) { os << vec << " * " << mtx; } else { throw Exception("Unsupported shader language."); } } void Write_sampleLut3D_rgb(std::ostream & os, const std::string& variableName, const std::string& lutName, int lut3DEdgeLen, GpuLanguage lang) { float m = ((float) lut3DEdgeLen-1.0f) / (float) lut3DEdgeLen; float b = 1.0f / (2.0f * (float) lut3DEdgeLen); if(lang == GPU_LANGUAGE_CG) { os << "tex3D("; os << lutName << ", "; os << m << " * " << variableName << ".rgb + " << b << ").rgb;" << std::endl; } else if(lang == GPU_LANGUAGE_GLSL_1_0 || lang == GPU_LANGUAGE_GLSL_1_3) { os << "texture3D("; os << lutName << ", "; os << m << " * " << variableName << ".rgb + " << b << ").rgb;" << std::endl; } else { throw Exception("Unsupported shader language."); } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/Processor.cpp0000644000175000017500000004560413223553423020501 0ustar mfvmfv/* 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 #include "AllocationOp.h" #include "GpuShaderUtils.h" #include "HashUtils.h" #include "Logging.h" #include "Lut3DOp.h" #include "NoOps.h" #include "OpBuilders.h" #include "Processor.h" #include "ScanlineHelper.h" #include #include #include OCIO_NAMESPACE_ENTER { ////////////////////////////////////////////////////////////////////////// class ProcessorMetadata::Impl { public: StringSet files; StringVec looks; Impl() { } ~Impl() { } }; ProcessorMetadataRcPtr ProcessorMetadata::Create() { return ProcessorMetadataRcPtr(new ProcessorMetadata(), &deleter); } ProcessorMetadata::ProcessorMetadata() : m_impl(new ProcessorMetadata::Impl) { } ProcessorMetadata::~ProcessorMetadata() { delete m_impl; m_impl = NULL; } void ProcessorMetadata::deleter(ProcessorMetadata* c) { delete c; } int ProcessorMetadata::getNumFiles() const { return static_cast(getImpl()->files.size()); } const char * ProcessorMetadata::getFile(int index) const { if(index < 0 || index >= (static_cast(getImpl()->files.size()))) { return ""; } StringSet::const_iterator iter = getImpl()->files.begin(); std::advance( iter, index ); return iter->c_str(); } void ProcessorMetadata::addFile(const char * fname) { getImpl()->files.insert(fname); } int ProcessorMetadata::getNumLooks() const { return static_cast(getImpl()->looks.size()); } const char * ProcessorMetadata::getLook(int index) const { if(index < 0 || index >= (static_cast(getImpl()->looks.size()))) { return ""; } return getImpl()->looks[index].c_str(); } void ProcessorMetadata::addLook(const char * look) { getImpl()->looks.push_back(look); } ////////////////////////////////////////////////////////////////////////// ProcessorRcPtr Processor::Create() { return ProcessorRcPtr(new Processor(), &deleter); } void Processor::deleter(Processor* c) { delete c; } Processor::Processor() : m_impl(new Processor::Impl) { } Processor::~Processor() { delete m_impl; m_impl = NULL; } bool Processor::isNoOp() const { return getImpl()->isNoOp(); } bool Processor::hasChannelCrosstalk() const { return getImpl()->hasChannelCrosstalk(); } ConstProcessorMetadataRcPtr Processor::getMetadata() const { return getImpl()->getMetadata(); } void Processor::apply(ImageDesc& img) const { getImpl()->apply(img); } void Processor::applyRGB(float * pixel) const { getImpl()->applyRGB(pixel); } void Processor::applyRGBA(float * pixel) const { getImpl()->applyRGBA(pixel); } const char * Processor::getCpuCacheID() const { return getImpl()->getCpuCacheID(); } const char * Processor::getGpuShaderText(const GpuShaderDesc & shaderDesc) const { return getImpl()->getGpuShaderText(shaderDesc); } const char * Processor::getGpuShaderTextCacheID(const GpuShaderDesc & shaderDesc) const { return getImpl()->getGpuShaderTextCacheID(shaderDesc); } void Processor::getGpuLut3D(float* lut3d, const GpuShaderDesc & shaderDesc) const { return getImpl()->getGpuLut3D(lut3d, shaderDesc); } const char * Processor::getGpuLut3DCacheID(const GpuShaderDesc & shaderDesc) const { return getImpl()->getGpuLut3DCacheID(shaderDesc); } ////////////////////////////////////////////////////////////////////////// namespace { void WriteShaderHeader(std::ostream & shader, const std::string & pixelName, const GpuShaderDesc & shaderDesc) { if(!shader) return; std::string lut3dName = "lut3d"; shader << "\n// Generated by OpenColorIO\n\n"; GpuLanguage lang = shaderDesc.getLanguage(); std::string fcnName = shaderDesc.getFunctionName(); if(lang == GPU_LANGUAGE_CG) { shader << "half4 " << fcnName << "(in half4 inPixel," << "\n"; shader << " const uniform sampler3D " << lut3dName << ") \n"; } else if(lang == GPU_LANGUAGE_GLSL_1_0) { shader << "vec4 " << fcnName << "(vec4 inPixel, \n"; shader << " sampler3D " << lut3dName << ") \n"; } else if(lang == GPU_LANGUAGE_GLSL_1_3) { shader << "vec4 " << fcnName << "(in vec4 inPixel, \n"; shader << " const sampler3D " << lut3dName << ") \n"; } else throw Exception("Unsupported shader language."); shader << "{" << "\n"; if(lang == GPU_LANGUAGE_CG) { shader << "half4 " << pixelName << " = inPixel; \n"; } else if(lang == GPU_LANGUAGE_GLSL_1_0 || lang == GPU_LANGUAGE_GLSL_1_3) { shader << "vec4 " << pixelName << " = inPixel; \n"; } else throw Exception("Unsupported shader language."); } void WriteShaderFooter(std::ostream & shader, const std::string & pixelName, const GpuShaderDesc & /*shaderDesc*/) { shader << "return " << pixelName << ";\n"; shader << "}" << "\n\n"; } } ////////////////////////////////////////////////////////////////////////// Processor::Impl::Impl(): m_metadata(ProcessorMetadata::Create()) { } Processor::Impl::~Impl() { } bool Processor::Impl::isNoOp() const { return IsOpVecNoOp(m_cpuOps); } bool Processor::Impl::hasChannelCrosstalk() const { for(OpRcPtrVec::size_type i=0, size = m_cpuOps.size(); ihasChannelCrosstalk()) return true; } return false; } ConstProcessorMetadataRcPtr Processor::Impl::getMetadata() const { return m_metadata; } void Processor::Impl::apply(ImageDesc& img) const { if(m_cpuOps.empty()) return; ScanlineHelper scanlineHelper(img); float * rgbaBuffer = 0; long numPixels = 0; while(true) { scanlineHelper.prepRGBAScanline(&rgbaBuffer, &numPixels); if(numPixels == 0) break; if(!rgbaBuffer) throw Exception("Cannot apply transform; null image."); for(OpRcPtrVec::size_type i=0, size = m_cpuOps.size(); iapply(rgbaBuffer, numPixels); } scanlineHelper.finishRGBAScanline(); } } void Processor::Impl::applyRGB(float * pixel) const { if(m_cpuOps.empty()) return; // We need to allocate a temp array as the pixel must be 4 floats in size // (otherwise, sse loads will potentially fail) float rgbaBuffer[4] = { pixel[0], pixel[1], pixel[2], 0.0f }; for(OpRcPtrVec::size_type i=0, size = m_cpuOps.size(); iapply(rgbaBuffer, 1); } pixel[0] = rgbaBuffer[0]; pixel[1] = rgbaBuffer[1]; pixel[2] = rgbaBuffer[2]; } void Processor::Impl::applyRGBA(float * pixel) const { for(OpRcPtrVec::size_type i=0, size = m_cpuOps.size(); iapply(pixel, 1); } } const char * Processor::Impl::getCpuCacheID() const { AutoMutex lock(m_resultsCacheMutex); if(!m_cpuCacheID.empty()) return m_cpuCacheID.c_str(); if(m_cpuOps.empty()) { m_cpuCacheID = ""; } else { std::ostringstream cacheid; for(OpRcPtrVec::size_type i=0, size = m_cpuOps.size(); igetCacheID() << " "; } std::string fullstr = cacheid.str(); m_cpuCacheID = CacheIDHash(fullstr.c_str(), (int)fullstr.size()); } return m_cpuCacheID.c_str(); } /////////////////////////////////////////////////////////////////////////// const char * Processor::Impl::getGpuShaderText(const GpuShaderDesc & shaderDesc) const { AutoMutex lock(m_resultsCacheMutex); if(m_lastShaderDesc != shaderDesc.getCacheID()) { m_lastShaderDesc = shaderDesc.getCacheID(); m_shader = ""; m_shaderCacheID = ""; m_lut3D.clear(); m_lut3DCacheID = ""; } if(m_shader.empty()) { std::ostringstream shader; calcGpuShaderText(shader, shaderDesc); m_shader = shader.str(); if(IsDebugLoggingEnabled()) { LogDebug("GPU Shader"); LogDebug(m_shader); } } return m_shader.c_str(); } const char * Processor::Impl::getGpuShaderTextCacheID(const GpuShaderDesc & shaderDesc) const { AutoMutex lock(m_resultsCacheMutex); if(m_lastShaderDesc != shaderDesc.getCacheID()) { m_lastShaderDesc = shaderDesc.getCacheID(); m_shader = ""; m_shaderCacheID = ""; m_lut3D.clear(); m_lut3DCacheID = ""; } if(m_shader.empty()) { std::ostringstream shader; calcGpuShaderText(shader, shaderDesc); m_shader = shader.str(); } if(m_shaderCacheID.empty()) { m_shaderCacheID = CacheIDHash(m_shader.c_str(), (int)m_shader.size()); } return m_shaderCacheID.c_str(); } const char * Processor::Impl::getGpuLut3DCacheID(const GpuShaderDesc & shaderDesc) const { AutoMutex lock(m_resultsCacheMutex); if(m_lastShaderDesc != shaderDesc.getCacheID()) { m_lastShaderDesc = shaderDesc.getCacheID(); m_shader = ""; m_shaderCacheID = ""; m_lut3D.clear(); m_lut3DCacheID = ""; } if(m_lut3DCacheID.empty()) { if(m_gpuOpsCpuLatticeProcess.empty()) { m_lut3DCacheID = ""; } else { std::ostringstream cacheid; for(OpRcPtrVec::size_type i=0, size = m_gpuOpsCpuLatticeProcess.size(); igetCacheID() << " "; } // Also, add a hash of the shader description cacheid << shaderDesc.getCacheID(); std::string fullstr = cacheid.str(); m_lut3DCacheID = CacheIDHash(fullstr.c_str(), (int)fullstr.size()); } } return m_lut3DCacheID.c_str(); } void Processor::Impl::getGpuLut3D(float* lut3d, const GpuShaderDesc & shaderDesc) const { if(!lut3d) return; AutoMutex lock(m_resultsCacheMutex); if(m_lastShaderDesc != shaderDesc.getCacheID()) { m_lastShaderDesc = shaderDesc.getCacheID(); m_shader = ""; m_shaderCacheID = ""; m_lut3D.clear(); m_lut3DCacheID = ""; } int lut3DEdgeLen = shaderDesc.getLut3DEdgeLen(); int lut3DNumPixels = lut3DEdgeLen*lut3DEdgeLen*lut3DEdgeLen; // Can we write the entire shader using only shader text? // If so, the lut3D is not needed so clear it. // This is preferable to identity, as it lets people notice if // it's accidentally being used. if(m_gpuOpsCpuLatticeProcess.empty()) { memset(lut3d, 0, sizeof(float) * 3 * lut3DNumPixels); return; } if(m_lut3D.empty()) { // Allocate 3dlut image, RGBA m_lut3D.resize(lut3DNumPixels*4); GenerateIdentityLut3D(&m_lut3D[0], lut3DEdgeLen, 4, LUT3DORDER_FAST_RED); // Apply the lattice ops to it for(int i=0; i<(int)m_gpuOpsCpuLatticeProcess.size(); ++i) { m_gpuOpsCpuLatticeProcess[i]->apply(&m_lut3D[0], lut3DNumPixels); } // Convert the RGBA image to an RGB image, in place. // Of course, this only works because we're doing it from left to right // so old pixels are read before they're written over // TODO: is this bad for memory access patterns? // see if this is faster with a 2nd temp float array for(int i=1; idumpMetadata(m_metadata); } // GPU Process setup // // Partition the original, raw opvec into 3 segments for GPU Processing // // Interior index range does not support the gpu shader. // This is used to bound our analytical shader text generation // start index and end index are inclusive. PartitionGPUOps(m_gpuOpsHwPreProcess, m_gpuOpsCpuLatticeProcess, m_gpuOpsHwPostProcess, m_cpuOps); LogDebug("GPU Ops: Pre-3DLUT"); FinalizeOpVec(m_gpuOpsHwPreProcess); LogDebug("GPU Ops: 3DLUT"); FinalizeOpVec(m_gpuOpsCpuLatticeProcess); LogDebug("GPU Ops: Post-3DLUT"); FinalizeOpVec(m_gpuOpsHwPostProcess); LogDebug("CPU Ops"); FinalizeOpVec(m_cpuOps); } void Processor::Impl::calcGpuShaderText(std::ostream & shader, const GpuShaderDesc & shaderDesc) const { std::string pixelName = "out_pixel"; std::string lut3dName = "lut3d"; WriteShaderHeader(shader, pixelName, shaderDesc); for(unsigned int i=0; iwriteGpuShader(shader, pixelName, shaderDesc); } if(!m_gpuOpsCpuLatticeProcess.empty()) { // Sample the 3D LUT. int lut3DEdgeLen = shaderDesc.getLut3DEdgeLen(); shader << pixelName << ".rgb = "; Write_sampleLut3D_rgb(shader, pixelName, lut3dName, lut3DEdgeLen, shaderDesc.getLanguage()); } #ifdef __APPLE__ else { // Force a no-op sampling of the 3d lut on OSX to work around a segfault. int lut3DEdgeLen = shaderDesc.getLut3DEdgeLen(); shader << "// OSX segfault work-around: Force a no-op sampling of the 3d lut.\n"; Write_sampleLut3D_rgb(shader, pixelName, lut3dName, lut3DEdgeLen, shaderDesc.getLanguage()); } #endif // __APPLE__ for(unsigned int i=0; iwriteGpuShader(shader, pixelName, shaderDesc); } WriteShaderFooter(shader, pixelName, shaderDesc); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/UnitTest.cpp0000644000175000017500000000352413223553423020274 0ustar mfvmfv/* 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_OCIO_UNITTEST_H #define INCLUDED_OCIO_UNITTEST_H #ifdef OCIO_UNIT_TEST #ifndef WIN32 #pragma GCC visibility push(default) #endif #include // OIIO unit tests header OIIO_TEST_APP(OpenColorIO_Core_Unit_Tests) #ifndef WIN32 #pragma GCC visibility pop #endif #endif // OCIO_UNIT_TEST #endif // INCLUDED_OCIO_UNITTEST_H opencolorio-1.1.0~dfsg0.orig/src/core/ParseUtils.h0000644000175000017500000000672013223553423020256 0ustar mfvmfv/* 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_OCIO_PARSEUTILS_H #define INCLUDED_OCIO_PARSEUTILS_H #include #include "PrivateTypes.h" #include #include #include OCIO_NAMESPACE_ENTER { std::string FloatToString(float fval); std::string FloatVecToString(const float * fval, unsigned int size); std::string DoubleToString(double value); bool StringToFloat(float * fval, const char * str); bool StringToInt(int * ival, const char * str, bool failIfLeftoverChars=false); bool StringVecToFloatVec(std::vector & floatArray, const std::vector & lineParts); bool StringVecToIntVec(std::vector & intArray, const std::vector & lineParts); ////////////////////////////////////////////////////////////////////////// // read the next non empty line, and store it in 'line' // return 'true' on success bool nextline(std::istream &istream, std::string &line); bool StrEqualsCaseIgnore(const std::string & a, const std::string & b); // If a ',' is in the string, split on it // If a ':' is in the string, split on it // Otherwise, assume a single string. // Also, strip whitespace from all parts. void SplitStringEnvStyle(std::vector & outputvec, const char * str); // Join on ',' std::string JoinStringEnvStyle(const std::vector & outputvec); // Ordering and capitalization from vec1 is preserved std::vector IntersectStringVecsCaseIgnore(const std::vector & vec1, const std::vector & vec2); // Find the index of the specified string, ignoring case. // return -1 if not found. int FindInStringVecCaseIgnore(const std::vector & vec, const std::string & str); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/OpOptimizers.cpp0000644000175000017500000002751713223553423021171 0ustar mfvmfv/* 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 #include "Logging.h" #include "Op.h" #include #include #include OCIO_NAMESPACE_ENTER { namespace { const int MAX_OPTIMIZATION_PASSES = 8; int RemoveNoOps(OpRcPtrVec & opVec) { int count = 0; OpRcPtrVec::iterator iter = opVec.begin(); while(iter != opVec.end()) { if((*iter)->isNoOp()) { iter = opVec.erase(iter); ++count; } else { ++iter; } } return count; } int RemoveInverseOps(OpRcPtrVec & opVec) { int count = 0; int firstindex = 0; // this must be a signed int while(firstindex < static_cast(opVec.size()-1)) { const OpRcPtr & first = opVec[firstindex]; const OpRcPtr & second = opVec[firstindex+1]; // The common case of inverse ops is to have a deep nesting: // ..., A, B, B', A', ... // // Consider the above, when firstindex reaches B: // // | // ..., A, B, B', A', ... // // We will remove B and B'. // Firstindex remains pointing at the original location: // // | // ..., A, A', ... // // We then decrement firstindex by 1, // to backstep and reconsider the A, A' case: // // | <-- firstindex decremented // ..., A, A', ... // if(first->isSameType(second) && first->isInverse(second)) { opVec.erase(opVec.begin() + firstindex, opVec.begin() + firstindex + 2); ++count; firstindex = std::max(0, firstindex-1); } else { ++firstindex; } } return count; } int CombineOps(OpRcPtrVec & opVec) { int count = 0; int firstindex = 0; // this must be a signed int OpRcPtrVec tmpops; while(firstindex < static_cast(opVec.size()-1)) { const OpRcPtr & first = opVec[firstindex]; const OpRcPtr & second = opVec[firstindex+1]; if(first->canCombineWith(second)) { tmpops.clear(); first->combineWith(tmpops, second); // tmpops may have any number of ops in it. (0, 1, 2, ...) // (size 0 would occur potentially iff the combination // results in a no-op) // // No matter the number, we need to swap them in for the // original ops // Erase the initial two ops we've combined opVec.erase(opVec.begin() + firstindex, opVec.begin() + firstindex + 2); // Insert the new ops (which may be empty) at // this location std::copy(tmpops.begin(), tmpops.end(), std::inserter(opVec, opVec.begin() + firstindex)); // Decrement firstindex by 1, // to backstep and reconsider the A, A' case. // See RemoveInverseOps for the full discussion of // why this is appropriate firstindex = std::max(0, firstindex-1); // We've done something so increment the count! ++count; } else { ++firstindex; } } return count; } } void OptimizeOpVec(OpRcPtrVec & ops) { if(ops.empty()) return; if(IsDebugLoggingEnabled()) { LogDebug("Optimizing Op Vec..."); LogDebug(SerializeOpVec(ops, 4)); } OpRcPtrVec::size_type originalSize = ops.size(); int total_noops = 0; int total_inverseops = 0; int total_combines = 0; int passes = 0; while(passes<=MAX_OPTIMIZATION_PASSES) { int noops = RemoveNoOps(ops); int inverseops = RemoveInverseOps(ops); int combines = CombineOps(ops); if(noops == 0 && inverseops==0 && combines==0) { // No optimization progress was made, so stop trying. break; } total_noops += noops; total_inverseops += inverseops; total_combines += combines; ++passes; } OpRcPtrVec::size_type finalSize = ops.size(); if(passes == MAX_OPTIMIZATION_PASSES) { std::ostringstream os; os << "The max number of passes, " << passes << ", "; os << "was reached during optimization. This is likely a sign "; os << "that either the complexity of the color transform is "; os << "very high, or that some internal optimizers are in conflict "; os << "(undo-ing / redo-ing the other's results)."; LogDebug(os.str().c_str()); } if(IsDebugLoggingEnabled()) { std::ostringstream os; os << "Optimized "; os << originalSize << "->" << finalSize << ", "; os << passes << " passes, "; os << total_noops << " noops removed, "; os << total_inverseops << " inverse ops removed\n"; os << total_combines << " ops combines\n"; os << SerializeOpVec(ops, 4); LogDebug(os.str()); } } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" #include "ExponentOps.h" #include "LogOps.h" #include "Lut1DOp.h" #include "Lut3DOp.h" #include "MatrixOps.h" OIIO_ADD_TEST(OpOptimizers, RemoveInverseOps) { OCIO::OpRcPtrVec ops; float exp[4] = { 1.2f, 1.3f, 1.4f, 1.5f }; float k[3] = { 0.18f, 0.18f, 0.18f }; float m[3] = { 2.0f, 2.0f, 2.0f }; float b[3] = { 0.1f, 0.1f, 0.1f }; float base[3] = { 10.0f, 10.0f, 10.0f }; float kb[3] = { 1.0f, 1.0f, 1.0f }; OCIO::CreateExponentOp(ops, exp, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateLogOp(ops, k, m, b, base, kb, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateLogOp(ops, k, m, b, base, kb, OCIO::TRANSFORM_DIR_INVERSE); OCIO::CreateExponentOp(ops, exp, OCIO::TRANSFORM_DIR_INVERSE); OIIO_CHECK_EQUAL(ops.size(), 4); OCIO::RemoveInverseOps(ops); OIIO_CHECK_EQUAL(ops.size(), 0); ops.clear(); OCIO::CreateExponentOp(ops, exp, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateExponentOp(ops, exp, OCIO::TRANSFORM_DIR_INVERSE); OCIO::CreateLogOp(ops, k, m, b, base, kb, OCIO::TRANSFORM_DIR_INVERSE); OCIO::CreateLogOp(ops, k, m, b, base, kb, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateExponentOp(ops, exp, OCIO::TRANSFORM_DIR_FORWARD); OIIO_CHECK_EQUAL(ops.size(), 5); OCIO::RemoveInverseOps(ops); OIIO_CHECK_EQUAL(ops.size(), 1); } OIIO_ADD_TEST(OpOptimizers, CombineOps) { float m1[4] = { 2.0f, 2.0f, 2.0f, 1.0f }; float m2[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; float m3[4] = { 0.6f, 0.6f, 0.6f, 1.0f }; float m4[4] = { 0.7f, 0.7f, 0.7f, 1.0f }; float exp[4] = { 1.2f, 1.3f, 1.4f, 1.5f }; { OCIO::OpRcPtrVec ops; OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_FORWARD); OIIO_CHECK_EQUAL(ops.size(), 1); OCIO::CombineOps(ops); OIIO_CHECK_EQUAL(ops.size(), 1); } { OCIO::OpRcPtrVec ops; OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateScaleOp(ops, m3, OCIO::TRANSFORM_DIR_FORWARD); OIIO_CHECK_EQUAL(ops.size(), 2); OCIO::CombineOps(ops); OIIO_CHECK_EQUAL(ops.size(), 1); } { OCIO::OpRcPtrVec ops; OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateScaleOp(ops, m3, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateScaleOp(ops, m4, OCIO::TRANSFORM_DIR_FORWARD); OIIO_CHECK_EQUAL(ops.size(), 3); OCIO::CombineOps(ops); OIIO_CHECK_EQUAL(ops.size(), 1); } { OCIO::OpRcPtrVec ops; OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateScaleOp(ops, m2, OCIO::TRANSFORM_DIR_FORWARD); OIIO_CHECK_EQUAL(ops.size(), 2); OCIO::CombineOps(ops); OIIO_CHECK_EQUAL(ops.size(), 0); } { OCIO::OpRcPtrVec ops; OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_INVERSE); OIIO_CHECK_EQUAL(ops.size(), 2); OCIO::CombineOps(ops); OIIO_CHECK_EQUAL(ops.size(), 0); } { OCIO::OpRcPtrVec ops; OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_FORWARD); OIIO_CHECK_EQUAL(ops.size(), 5); OCIO::CombineOps(ops); OIIO_CHECK_EQUAL(ops.size(), 1); } { OCIO::OpRcPtrVec ops; OCIO::CreateExponentOp(ops, exp, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateScaleOp(ops, m1, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateScaleOp(ops, m2, OCIO::TRANSFORM_DIR_FORWARD); OCIO::CreateExponentOp(ops, exp, OCIO::TRANSFORM_DIR_INVERSE); OIIO_CHECK_EQUAL(ops.size(), 4); OCIO::CombineOps(ops); OIIO_CHECK_EQUAL(ops.size(), 0); } } #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/SSE.h0000644000175000017500000000314413223553423016612 0ustar mfvmfv/* 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_OCIO_SSE_H #define INCLUDED_OCIO_SSE_H #ifdef USE_SSE #include #endif #endif opencolorio-1.1.0~dfsg0.orig/src/core/Logging.cpp0000644000175000017500000001216313223553423020102 0ustar mfvmfv/* 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 #include #include #include #include "Logging.h" #include "Mutex.h" #include "pystring/pystring.h" #include "Platform.h" OCIO_NAMESPACE_ENTER { namespace { const char * OCIO_LOGGING_LEVEL_ENVVAR = "OCIO_LOGGING_LEVEL"; const LoggingLevel OCIO_DEFAULT_LOGGING_LEVEL = LOGGING_LEVEL_INFO; Mutex g_logmutex; LoggingLevel g_logginglevel = LOGGING_LEVEL_UNKNOWN; bool g_initialized = false; bool g_loggingOverride = false; // You must manually acquire the logging mutex before calling this. // This will set g_logginglevel, g_initialized, g_loggingOverride void InitLogging() { if(g_initialized) return; g_initialized = true; std::string levelstr; Platform::getenv(OCIO_LOGGING_LEVEL_ENVVAR, levelstr); if(!levelstr.empty()) { g_loggingOverride = true; g_logginglevel = LoggingLevelFromString(levelstr.c_str()); if(g_logginglevel == LOGGING_LEVEL_UNKNOWN) { std::cerr << "[OpenColorIO Warning]: Invalid $OCIO_LOGGING_LEVEL specified. "; std::cerr << "Options: none (0), warning (1), info (2), debug (3)" << std::endl; g_logginglevel = OCIO_DEFAULT_LOGGING_LEVEL; } } else { g_logginglevel = OCIO_DEFAULT_LOGGING_LEVEL; } } } LoggingLevel GetLoggingLevel() { AutoMutex lock(g_logmutex); InitLogging(); return g_logginglevel; } void SetLoggingLevel(LoggingLevel level) { AutoMutex lock(g_logmutex); InitLogging(); // Calls to SetLoggingLevel are ignored if OCIO_LOGGING_LEVEL_ENVVAR // is specified. This is to allow users to optionally debug OCIO at // runtime even in applications that disable logging. if(!g_loggingOverride) { g_logginglevel = level; } } void LogWarning(const std::string & text) { AutoMutex lock(g_logmutex); InitLogging(); if(g_logginglevel parts; pystring::split( pystring::rstrip(text), parts, "\n"); for(unsigned int i=0; i parts; pystring::split( pystring::rstrip(text), parts, "\n"); for(unsigned int i=0; i parts; pystring::split( pystring::rstrip(text), parts, "\n"); for(unsigned int i=0; i=LOGGING_LEVEL_DEBUG); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/LogTransform.cpp0000644000175000017500000001067513223553423021137 0ustar mfvmfv/* 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 #include #include #include #include "LogOps.h" #include "OpBuilders.h" OCIO_NAMESPACE_ENTER { LogTransformRcPtr LogTransform::Create() { return LogTransformRcPtr(new LogTransform(), &deleter); } void LogTransform::deleter(LogTransform* t) { delete t; } class LogTransform::Impl { public: TransformDirection dir_; float base_; Impl() : dir_(TRANSFORM_DIR_FORWARD), base_(2.0) { } ~Impl() { } Impl& operator= (const Impl & rhs) { dir_ = rhs.dir_; base_ = rhs.base_; return *this; } }; /////////////////////////////////////////////////////////////////////////// LogTransform::LogTransform() : m_impl(new LogTransform::Impl) { } TransformRcPtr LogTransform::createEditableCopy() const { LogTransformRcPtr transform = LogTransform::Create(); *(transform->m_impl) = *m_impl; return transform; } LogTransform::~LogTransform() { delete m_impl; m_impl = NULL; } LogTransform& LogTransform::operator= (const LogTransform & rhs) { *m_impl = *rhs.m_impl; return *this; } TransformDirection LogTransform::getDirection() const { return getImpl()->dir_; } void LogTransform::setDirection(TransformDirection dir) { getImpl()->dir_ = dir; } float LogTransform::getBase() const { return getImpl()->base_; } void LogTransform::setBase(float val) { getImpl()->base_ = val; } std::ostream& operator<< (std::ostream& os, const LogTransform& t) { os << ""; return os; } /////////////////////////////////////////////////////////////////////////// void BuildLogOps(OpRcPtrVec & ops, const Config& /*config*/, const LogTransform& transform, TransformDirection dir) { TransformDirection combinedDir = CombineTransformDirections(dir, transform.getDirection()); float basescalar = transform.getBase(); float base[3] = { basescalar, basescalar, basescalar }; float k[3] = { 1.0f, 1.0f, 1.0f }; float m[3] = { 1.0f, 1.0f, 1.0f }; float b[3] = { 0.0f, 0.0f, 0.0f }; float kb[3] = { 0.0f, 0.0f, 0.0f }; // output = k * log(mx+b, base) + kb CreateLogOp(ops, k, m, b, base, kb, combinedDir); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/ImagePacking.cpp0000644000175000017500000004020013223553423021024 0ustar mfvmfv/* 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 #include #include #include #include #include #include "ImagePacking.h" OCIO_NAMESPACE_ENTER { namespace { // GENERIC CASE, SLOW BUT ALWAYS WORKS void PackRGBAFromImageDesc_Generic(const GenericImageDesc& srcImg, float* outputBuffer, int* numPixelsCopied, int outputBufferSize, long imagePixelStartIndex) { assert(outputBuffer); assert(numPixelsCopied); long imgWidth = srcImg.width; long imgHeight = srcImg.height; long imgPixels = imgWidth * imgHeight; if(imagePixelStartIndex<0 || imagePixelStartIndex>=imgPixels) { *numPixelsCopied = 0; return; } ptrdiff_t xStrideBytes = srcImg.xStrideBytes; ptrdiff_t yStrideBytes = srcImg.yStrideBytes; long yIndex = imagePixelStartIndex / imgWidth; long xIndex = imagePixelStartIndex % imgWidth; // Figure out our initial ptr positions char* rRow = reinterpret_cast(srcImg.rData) + yStrideBytes * yIndex; char* gRow = reinterpret_cast(srcImg.gData) + yStrideBytes * yIndex; char* bRow = reinterpret_cast(srcImg.bData) + yStrideBytes * yIndex; char* aRow = NULL; float* rPtr = reinterpret_cast(rRow + xStrideBytes*xIndex); float* gPtr = reinterpret_cast(gRow + xStrideBytes*xIndex); float* bPtr = reinterpret_cast(bRow + xStrideBytes*xIndex); float* aPtr = NULL; if(srcImg.aData) { aRow = reinterpret_cast(srcImg.aData) + yStrideBytes * yIndex; aPtr = reinterpret_cast(aRow + xStrideBytes*xIndex); } if(aPtr) { int pixelsCopied = 0; while(pixelsCopied < outputBufferSize) { outputBuffer[4*pixelsCopied] = *rPtr; outputBuffer[4*pixelsCopied+1] = *gPtr; outputBuffer[4*pixelsCopied+2] = *bPtr; outputBuffer[4*pixelsCopied+3] = *aPtr; pixelsCopied++; xIndex++; // Jump to the next scanline if(xIndex == imgWidth) { yIndex += 1; if(yIndex == imgHeight) { *numPixelsCopied = pixelsCopied; return; } xIndex = 0; rRow += yStrideBytes; gRow += yStrideBytes; bRow += yStrideBytes; aRow += yStrideBytes; rPtr = reinterpret_cast(rRow); gPtr = reinterpret_cast(gRow); bPtr = reinterpret_cast(bRow); aPtr = reinterpret_cast(aRow); } // Jump to the next pixel else { rPtr = reinterpret_cast( reinterpret_cast(rPtr) + xStrideBytes); gPtr = reinterpret_cast( reinterpret_cast(gPtr) + xStrideBytes); bPtr = reinterpret_cast( reinterpret_cast(bPtr) + xStrideBytes); aPtr = reinterpret_cast( reinterpret_cast(aPtr) + xStrideBytes); } } *numPixelsCopied = pixelsCopied; } else { int pixelsCopied = 0; while(pixelsCopied < outputBufferSize) { outputBuffer[4*pixelsCopied] = *rPtr; outputBuffer[4*pixelsCopied+1] = *gPtr; outputBuffer[4*pixelsCopied+2] = *bPtr; outputBuffer[4*pixelsCopied+3] = 0.0; pixelsCopied++; xIndex++; // Jump to the next scanline if(xIndex == imgWidth) { yIndex += 1; if(yIndex == imgHeight) { *numPixelsCopied = pixelsCopied; return; } xIndex = 0; rRow += yStrideBytes; gRow += yStrideBytes; bRow += yStrideBytes; rPtr = reinterpret_cast(rRow); gPtr = reinterpret_cast(gRow); bPtr = reinterpret_cast(bRow); } // Jump to the next pixel else { rPtr = reinterpret_cast( reinterpret_cast(rPtr) + xStrideBytes); gPtr = reinterpret_cast( reinterpret_cast(gPtr) + xStrideBytes); bPtr = reinterpret_cast( reinterpret_cast(bPtr) + xStrideBytes); } } *numPixelsCopied = pixelsCopied; } } void UnpackRGBAToImageDesc_Generic(GenericImageDesc& dstImg, float* inputBuffer, int numPixelsToUnpack, long imagePixelStartIndex) { assert(inputBuffer); long imgWidth = dstImg.width; long imgHeight = dstImg.height; long imgPixels = imgWidth * imgHeight; if(imagePixelStartIndex<0 || imagePixelStartIndex>=imgPixels) { return; } ptrdiff_t xStrideBytes = dstImg.xStrideBytes; ptrdiff_t yStrideBytes = dstImg.yStrideBytes; long yIndex = imagePixelStartIndex / imgWidth; long xIndex = imagePixelStartIndex % imgWidth; // Figure out our initial ptr positions char* rRow = reinterpret_cast(dstImg.rData) + yStrideBytes * yIndex; char* gRow = reinterpret_cast(dstImg.gData) + yStrideBytes * yIndex; char* bRow = reinterpret_cast(dstImg.bData) + yStrideBytes * yIndex; char* aRow = NULL; float* rPtr = reinterpret_cast(rRow + xStrideBytes*xIndex); float* gPtr = reinterpret_cast(gRow + xStrideBytes*xIndex); float* bPtr = reinterpret_cast(bRow + xStrideBytes*xIndex); float* aPtr = NULL; if(dstImg.aData) { aRow = reinterpret_cast(dstImg.aData) + yStrideBytes * yIndex; aPtr = reinterpret_cast(aRow + xStrideBytes*xIndex); } if(aPtr) { int pixelsCopied = 0; while(pixelsCopied < numPixelsToUnpack) { *rPtr = inputBuffer[4*pixelsCopied]; *gPtr = inputBuffer[4*pixelsCopied+1]; *bPtr = inputBuffer[4*pixelsCopied+2]; *aPtr = inputBuffer[4*pixelsCopied+3]; pixelsCopied++; xIndex++; // Jump to the next scanline if(xIndex == imgWidth) { yIndex += 1; if(yIndex == imgHeight) { return; } xIndex = 0; rRow += yStrideBytes; gRow += yStrideBytes; bRow += yStrideBytes; aRow += yStrideBytes; rPtr = reinterpret_cast(rRow); gPtr = reinterpret_cast(gRow); bPtr = reinterpret_cast(bRow); aPtr = reinterpret_cast(aRow); } // Jump to the next pixel else { rPtr = reinterpret_cast( reinterpret_cast(rPtr) + xStrideBytes); gPtr = reinterpret_cast( reinterpret_cast(gPtr) + xStrideBytes); bPtr = reinterpret_cast( reinterpret_cast(bPtr) + xStrideBytes); aPtr = reinterpret_cast( reinterpret_cast(aPtr) + xStrideBytes); } } } else { int pixelsCopied = 0; while(pixelsCopied < numPixelsToUnpack) { *rPtr = inputBuffer[4*pixelsCopied]; *gPtr = inputBuffer[4*pixelsCopied+1]; *bPtr = inputBuffer[4*pixelsCopied+2]; pixelsCopied++; xIndex++; // Jump to the next scanline if(xIndex == imgWidth) { yIndex += 1; if(yIndex == imgHeight) { return; } xIndex = 0; rRow += yStrideBytes; gRow += yStrideBytes; bRow += yStrideBytes; rPtr = reinterpret_cast(rRow); gPtr = reinterpret_cast(gRow); bPtr = reinterpret_cast(bRow); } // Jump to the next pixel else { rPtr = reinterpret_cast( reinterpret_cast(rPtr) + xStrideBytes); gPtr = reinterpret_cast( reinterpret_cast(gPtr) + xStrideBytes); bPtr = reinterpret_cast( reinterpret_cast(bPtr) + xStrideBytes); } } } } } /* namespace { void PackRGBAFromImageDesc_RGBAMemcpy(const GenericImageDesc& srcImg, float* outputBuffer, int* numPixelsCopied, int outputBufferSize, int imagePixelStartIndex) { assert(outputBuffer); assert(numPixelsCopied); long imgWidth = srcImg.getWidth(); long imgHeight = srcImg.getHeight(); long imgPixels = srcImg.getNumPixels(); if(imagePixelStartIndex<0 || imagePixelStartIndex>=imgPixels) { *numPixelsCopied = 0; return; } ptrdiff_t xStrideBytes = srcImg.getXStrideBytes(); ptrdiff_t yStrideBytes = srcImg.getYStrideBytes(); int yIndex = imagePixelStartIndex / imgWidth; int xIndex = imagePixelStartIndex % imgWidth; // Figure out our initial ptr positions char* imgRow = reinterpret_cast(srcImg.getRData()) + yStrideBytes * yIndex; char* imgPtr = imgRow + xStrideBytes*xIndex; int totalPixelsCopied = 0; int pixelsRemainingToCopy = outputBufferSize; while(pixelsRemainingToCopy>0 && yIndex < imgHeight) { int imgScanlinePixels = imgWidth - xIndex; int numPixels = std::min(imgScanlinePixels, pixelsRemainingToCopy); memcpy(outputBuffer+totalPixelsCopied, imgPtr, numPixels); yIndex += 1; xIndex = 0; imgRow += yStrideBytes; imgPtr = imgRow; totalPixelsCopied += numPixels; pixelsRemainingToCopy -= numPixels; } if(numPixelsCopied) *numPixelsCopied = totalPixelsCopied; } } */ //////////////////////////////////////////////////////////////////////////// // TODO: Add optimized codepaths to image packing / unpacking void PackRGBAFromImageDesc(const GenericImageDesc& srcImg, float* outputBuffer, int* numPixelsCopied, int outputBufferSize, long imagePixelStartIndex) { PackRGBAFromImageDesc_Generic(srcImg, outputBuffer, numPixelsCopied, outputBufferSize, imagePixelStartIndex); } void UnpackRGBAToImageDesc(GenericImageDesc& dstImg, float* inputBuffer, int numPixelsToUnpack, long imagePixelStartIndex) { UnpackRGBAToImageDesc_Generic(dstImg, inputBuffer, numPixelsToUnpack, imagePixelStartIndex); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/ExponentOps.h0000644000175000017500000000371713223553423020450 0ustar mfvmfv/* 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_OCIO_EXPONENTOP_H #define INCLUDED_OCIO_EXPONENTOP_H #include #include "Op.h" #include OCIO_NAMESPACE_ENTER { // If the exponent is 1.0, this will return without clamping // Otherwise, will be clamped between [0.0, inf] void CreateExponentOp(OpRcPtrVec & ops, const float * exponent4, TransformDirection direction); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatTruelight.cpp0000644000175000017500000006022413223553423022435 0ustar mfvmfv/* 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 #include #include #include #include #include #include "FileTransform.h" #include "Lut1DOp.h" #include "Lut3DOp.h" #include "ParseUtils.h" #include "pystring/pystring.h" // This implements the spec for: // Per http://www.filmlight.ltd.uk/resources/documents/truelight/white-papers_tl.php // FL-TL-TN-0388-TLCubeFormat2.0.pdf // // Known deficiency in implementation: // 1D shaper luts (InputLUT) using integer encodings (vs float) are not supported. // How to we determine if the input is integer? MaxVal? Or do we look for a decimal-point? // How about scientific notation? (which is explicitly allowed?) /* The input LUT is used to interpolate a higher precision LUT matched to the particular image format. For integer formats, the range 0-1 is mapped onto the integer range. Floating point values outside the 0-1 range are allowed but may be truncated for integer formats. */ OCIO_NAMESPACE_ENTER { namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile () : has1D(false), has3D(false) { lut1D = Lut1D::Create(); lut3D = Lut3D::Create(); }; ~LocalCachedFile() {}; bool has1D; bool has3D; Lut1DRcPtr lut1D; Lut3DRcPtr lut3D; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void Write(const Baker & baker, const std::string & formatName, std::ostream & ostream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "truelight"; info.extension = "cub"; info.capabilities = (FORMAT_CAPABILITY_READ | FORMAT_CAPABILITY_WRITE); formatInfoVec.push_back(info); } CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { // this shouldn't happen if(!istream) { throw Exception ("File stream empty when trying to read Truelight .cub lut"); } // Validate the file type std::string line; if(!nextline(istream, line) || !pystring::startswith(pystring::lower(line), "# truelight cube")) { throw Exception("Lut doesn't seem to be a Truelight .cub lut."); } // Parse the file std::vector raw1d; std::vector raw3d; int size3d[] = { 0, 0, 0 }; int size1d = 0; { std::vector parts; std::vector tmpfloats; bool in1d = false; bool in3d = false; while(nextline(istream, line)) { // Strip, lowercase, and split the line pystring::split(pystring::lower(pystring::strip(line)), parts); if(parts.empty()) continue; // Parse header metadata (which starts with #) if(pystring::startswith(parts[0],"#")) { if(parts.size() < 2) continue; if(parts[1] == "width") { if(parts.size() != 5 || !StringToInt( &size3d[0], parts[2].c_str()) || !StringToInt( &size3d[1], parts[3].c_str()) || !StringToInt( &size3d[2], parts[4].c_str())) { throw Exception("Malformed width tag in Truelight .cub lut."); } raw3d.reserve(3*size3d[0]*size3d[1]*size3d[2]); } else if(parts[1] == "lutlength") { if(parts.size() != 3 || !StringToInt( &size1d, parts[2].c_str())) { throw Exception("Malformed lutlength tag in Truelight .cub lut."); } raw1d.reserve(3*size1d); } else if(parts[1] == "inputlut") { in1d = true; in3d = false; } else if(parts[1] == "cube") { in3d = true; in1d = false; } else if(parts[1] == "end") { in3d = false; in1d = false; // If we hit the end tag, don't bother searching further in the file. break; } } if(in1d || in3d) { if(StringVecToFloatVec(tmpfloats, parts) && (tmpfloats.size() == 3)) { if(in1d) { raw1d.push_back(tmpfloats[0]); raw1d.push_back(tmpfloats[1]); raw1d.push_back(tmpfloats[2]); } else if(in3d) { raw3d.push_back(tmpfloats[0]); raw3d.push_back(tmpfloats[1]); raw3d.push_back(tmpfloats[2]); } } } } } // Interpret the parsed data, validate lut sizes if(size1d != static_cast(raw1d.size()/3)) { std::ostringstream os; os << "Parse error in Truelight .cub lut. "; os << "Incorrect number of lut1d entries. "; os << "Found " << raw1d.size()/3 << ", expected " << size1d << "."; throw Exception(os.str().c_str()); } if(size3d[0]*size3d[1]*size3d[2] != static_cast(raw3d.size()/3)) { std::ostringstream os; os << "Parse error in Truelight .cub lut. "; os << "Incorrect number of lut3d entries. "; os << "Found " << raw3d.size()/3 << ", expected " << size3d[0]*size3d[1]*size3d[2] << "."; throw Exception(os.str().c_str()); } LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile()); cachedFile->has1D = (size1d>0); cachedFile->has3D = (size3d[0]*size3d[1]*size3d[2]>0); // Reformat 1D data if(cachedFile->has1D) { for(int channel=0; channel<3; ++channel) { // Determine the scale factor for the 1d lut. Example: // The inputlut feeding a 6x6x6 3dlut should be scaled from 0.0-5.0. // Beware: Nuke Truelight Writer (at least 6.3 and before) is busted // and does this scaling incorrectly. float descale = 1.0f; if(cachedFile->has3D) { descale = 1.0f / static_cast(size3d[channel]-1); } cachedFile->lut1D->luts[channel].resize(size1d); for(int i=0; ilut1D->luts[channel][i] = raw1d[3*i+channel] * descale; } } // 1e-5 rel error is a good threshold when float numbers near 0 // are written out with 6 decimal places of precision. This is // a bit aggressive, I.e., changes in the 6th decimal place will // be considered roundoff error, but changes in the 5th decimal // will be considered lut 'intent'. // 1.0 // 1.000005 equal to 1.0 // 1.000007 equal to 1.0 // 1.000010 not equal // 0.0 // 0.000001 not equal cachedFile->lut1D->maxerror = 1e-5f; cachedFile->lut1D->errortype = ERROR_RELATIVE; } // Reformat 3D data if(cachedFile->has3D) { cachedFile->lut3D->size[0] = size3d[0]; cachedFile->lut3D->size[1] = size3d[1]; cachedFile->lut3D->size[2] = size3d[2]; cachedFile->lut3D->lut = raw3d; } return cachedFile; } void LocalFileFormat::Write(const Baker & baker, const std::string & /*formatName*/, std::ostream & ostream) const { const int DEFAULT_CUBE_SIZE = 32; const int DEFAULT_SHAPER_SIZE = 1024; ConstConfigRcPtr config = baker.getConfig(); int cubeSize = baker.getCubeSize(); if (cubeSize==-1) cubeSize = DEFAULT_CUBE_SIZE; cubeSize = std::max(2, cubeSize); // smallest cube is 2x2x2 std::vector cubeData; cubeData.resize(cubeSize*cubeSize*cubeSize*3); GenerateIdentityLut3D(&cubeData[0], cubeSize, 3, LUT3DORDER_FAST_RED); PackedImageDesc cubeImg(&cubeData[0], cubeSize*cubeSize*cubeSize, 1, 3); // Apply processor to lut data ConstProcessorRcPtr inputToTarget; inputToTarget = config->getProcessor(baker.getInputSpace(), baker.getTargetSpace()); inputToTarget->apply(cubeImg); int shaperSize = baker.getShaperSize(); if (shaperSize==-1) shaperSize = DEFAULT_SHAPER_SIZE; shaperSize = std::max(2, shaperSize); // smallest shaper is 2x2x2 // Write the header ostream << "# Truelight Cube v2.0\n"; ostream << "# lutLength " << shaperSize << "\n"; ostream << "# iDims 3\n"; ostream << "# oDims 3\n"; ostream << "# width " << cubeSize << " " << cubeSize << " " << cubeSize << "\n"; ostream << "\n"; // Write the shaper lut // (We are just going to use a unity lut) ostream << "# InputLUT\n"; ostream << std::setprecision(6) << std::fixed; float v = 0.0f; for (int i=0; i < shaperSize-1; i++) { v = ((float)i / (float)(shaperSize-1)) * (float)(cubeSize-1); ostream << v << " " << v << " " << v << "\n"; } v = (float) (cubeSize-1); ostream << v << " " << v << " " << v << "\n"; // ensure that the last value is spot on ostream << "\n"; // Write the cube ostream << "# Cube\n"; for (int i=0; i(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build Truelight .cub Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_UNKNOWN) { std::ostringstream os; os << "Cannot build file format transform,"; os << " unspecified transform direction."; throw Exception(os.str().c_str()); } // TODO: INTERP_LINEAR should not be hard-coded. // Instead query 'highest' interpolation? // (right now, it's linear). If cubic is added, consider // using it if(newDir == TRANSFORM_DIR_FORWARD) { if(cachedFile->has1D) { CreateLut1DOp(ops, cachedFile->lut1D, INTERP_LINEAR, newDir); } CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } else if(newDir == TRANSFORM_DIR_INVERSE) { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); if(cachedFile->has1D) { CreateLut1DOp(ops, cachedFile->lut1D, INTERP_LINEAR, newDir); } } } } FileFormat * CreateFileFormatTruelight() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" OIIO_ADD_TEST(FileFormatTruelight, ShaperAndLut3D) { // This lowers the red channel by 0.5, other channels are unaffected. const char * luttext = "# Truelight Cube v2.0\n" "# iDims 3\n" "# oDims 3\n" "# width 3 3 3\n" "# lutLength 5\n" "# InputLUT\n" " 0.000000 0.000000 0.000000\n" " 0.500000 0.500000 0.500000\n" " 1.000000 1.000000 1.000000\n" " 1.500000 1.500000 1.500000\n" " 2.000000 2.000000 2.000000\n" "\n" "# Cube\n" " 0.000000 0.000000 0.000000\n" " 0.250000 0.000000 0.000000\n" " 0.500000 0.000000 0.000000\n" " 0.000000 0.500000 0.000000\n" " 0.250000 0.500000 0.000000\n" " 0.500000 0.500000 0.000000\n" " 0.000000 1.000000 0.000000\n" " 0.250000 1.000000 0.000000\n" " 0.500000 1.000000 0.000000\n" " 0.000000 0.000000 0.500000\n" " 0.250000 0.000000 0.500000\n" " 0.500000 0.000000 0.500000\n" " 0.000000 0.500000 0.500000\n" " 0.250000 0.500000 0.500000\n" " 0.500000 0.500000 0.500000\n" " 0.000000 1.000000 0.500000\n" " 0.250000 1.000000 0.500000\n" " 0.500000 1.000000 0.500000\n" " 0.000000 0.000000 1.000000\n" " 0.250000 0.000000 1.000000\n" " 0.500000 0.000000 1.000000\n" " 0.000000 0.500000 1.000000\n" " 0.250000 0.500000 1.000000\n" " 0.500000 0.500000 1.000000\n" " 0.000000 1.000000 1.000000\n" " 0.250000 1.000000 1.000000\n" " 0.500000 1.000000 1.000000\n" "\n" "# end\n" "\n" "# Truelight profile\n" "title{madeup on some display}\n" "print{someprint}\n" "display{some}\n" "cubeFile{madeup.cube}\n" "\n" " # This last line confirms 'end' tag is obeyed\n" " 1.23456 1.23456 1.23456\n"; std::istringstream lutIStream; lutIStream.str(luttext); // Read file OCIO::LocalFileFormat tester; OCIO::CachedFileRcPtr cachedFile; OIIO_CHECK_NO_THROW(cachedFile = tester.Read(lutIStream)); OCIO::LocalCachedFileRcPtr lut = OCIO::DynamicPtrCast(cachedFile); OIIO_CHECK_ASSERT(lut->has1D); OIIO_CHECK_ASSERT(lut->has3D); float data[4*3] = { 0.1f, 0.2f, 0.3f, 0.0f, 1.0f, 0.5f, 0.123456f, 0.0f, -1.0f, 1.5f, 0.5f, 0.0f }; float result[4*3] = { 0.05f, 0.2f, 0.3f, 0.0f, 0.50f, 0.5f, 0.123456f, 0.0f, 0.0f, 1.5f, 0.5f, 0.0f }; OCIO::OpRcPtrVec ops; if(lut->has1D) { CreateLut1DOp(ops, lut->lut1D, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_FORWARD); } if(lut->has3D) { CreateLut3DOp(ops, lut->lut3D, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_FORWARD); } FinalizeOpVec(ops); // Apply the result for(OCIO::OpRcPtrVec::size_type i = 0, size = ops.size(); i < size; ++i) { ops[i]->apply(data, 3); } for(int i=0; i<3; ++i) { OIIO_CHECK_CLOSE( data[i], result[i], 1.0e-6 ); } } OIIO_ADD_TEST(FileFormatTruelight, Shaper) { const char * luttext = "# Truelight Cube v2.0\n" "# lutLength 11\n" "# iDims 3\n" "\n" "\n" "# InputLUT\n" " 0.000 0.000 -0.000\n" " 0.200 0.010 -0.100\n" " 0.400 0.040 -0.200\n" " 0.600 0.090 -0.300\n" " 0.800 0.160 -0.400\n" " 1.000 0.250 -0.500\n" " 1.200 0.360 -0.600\n" " 1.400 0.490 -0.700\n" " 1.600 0.640 -0.800\n" " 1.800 0.820 -0.900\n" " 2.000 1.000 -1.000\n" "\n\n\n" "# end\n"; std::istringstream lutIStream; lutIStream.str(luttext); // Read file OCIO::LocalFileFormat tester; OCIO::CachedFileRcPtr cachedFile; OIIO_CHECK_NO_THROW(cachedFile = tester.Read(lutIStream)); OCIO::LocalCachedFileRcPtr lut = OCIO::DynamicPtrCast(cachedFile); OIIO_CHECK_ASSERT(lut->has1D); OIIO_CHECK_ASSERT(!lut->has3D); float data[4*3] = { 0.1f, 0.2f, 0.3f, 0.0f, 1.0f, 0.5f, 0.123456f, 0.0f, -1.0f, 1.5f, 0.5f, 0.0f }; float result[4*3] = { 0.2f, 0.04f, -0.3f, 0.0f, 2.0f, 0.25f, -0.123456f, 0.0f, 0.0f, 1.0f, -0.5f, 0.0f }; OCIO::OpRcPtrVec ops; if(lut->has1D) { CreateLut1DOp(ops, lut->lut1D, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_FORWARD); } if(lut->has3D) { CreateLut3DOp(ops, lut->lut3D, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_FORWARD); } FinalizeOpVec(ops); // Apply the result for(OCIO::OpRcPtrVec::size_type i = 0, size = ops.size(); i < size; ++i) { ops[i]->apply(data, 3); } for(int i=0; i<3; ++i) { OIIO_CHECK_CLOSE( data[i], result[i], 1.0e-6 ); } } OIIO_ADD_TEST(FileFormatTruelight, Lut3D) { // This lowers the red channel by 0.5, other channels are unaffected. const char * luttext = "# Truelight Cube v2.0\n" "# iDims 3\n" "# oDims 3\n" "# width 3 3 3\n" "\n\n\n" "# Cube\n" " 0.000000 0.000000 0.000000\n" " 0.250000 0.000000 0.000000\n" " 0.500000 0.000000 0.000000\n" " 0.000000 0.500000 0.000000\n" " 0.250000 0.500000 0.000000\n" " 0.500000 0.500000 0.000000\n" " 0.000000 1.000000 0.000000\n" " 0.250000 1.000000 0.000000\n" " 0.500000 1.000000 0.000000\n" " 0.000000 0.000000 0.500000\n" " 0.250000 0.000000 0.500000\n" " 0.500000 0.000000 0.500000\n" " 0.000000 0.500000 0.500000\n" " 0.250000 0.500000 0.500000\n" " 0.500000 0.500000 0.500000\n" " 0.000000 1.000000 0.500000\n" " 0.250000 1.000000 0.500000\n" " 0.500000 1.000000 0.500000\n" " 0.000000 0.000000 1.000000\n" " 0.250000 0.000000 1.000000\n" " 0.500000 0.000000 1.000000\n" " 0.000000 0.500000 1.000000\n" " 0.250000 0.500000 1.000000\n" " 0.500000 0.500000 1.000000\n" " 0.000000 1.000000 1.000000\n" " 0.250000 1.000000 1.000000\n" " 0.500000 1.000000 1.000000\n" "\n" "# end\n"; std::istringstream lutIStream; lutIStream.str(luttext); // Read file OCIO::LocalFileFormat tester; OCIO::CachedFileRcPtr cachedFile; OIIO_CHECK_NO_THROW(cachedFile = tester.Read(lutIStream)); OCIO::LocalCachedFileRcPtr lut = OCIO::DynamicPtrCast(cachedFile); OIIO_CHECK_ASSERT(!lut->has1D); OIIO_CHECK_ASSERT(lut->has3D); float data[4*3] = { 0.1f, 0.2f, 0.3f, 0.0f, 1.0f, 0.5f, 0.123456f, 0.0f, -1.0f, 1.5f, 0.5f, 0.0f }; float result[4*3] = { 0.05f, 0.2f, 0.3f, 0.0f, 0.50f, 0.5f, 0.123456f, 0.0f, 0.0f, 1.5f, 0.5f, 0.0f }; OCIO::OpRcPtrVec ops; if(lut->has1D) { CreateLut1DOp(ops, lut->lut1D, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_FORWARD); } if(lut->has3D) { CreateLut3DOp(ops, lut->lut3D, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_FORWARD); } FinalizeOpVec(ops); // Apply the result for(OCIO::OpRcPtrVec::size_type i = 0, size = ops.size(); i < size; ++i) { ops[i]->apply(data, 3); } for(int i=0; i<3; ++i) { OIIO_CHECK_CLOSE( data[i], result[i], 1.0e-6 ); } } #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/AllocationOp.cpp0000644000175000017500000001066613223553423021106 0ustar mfvmfv/* 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 "AllocationOp.h" #include "LogOps.h" #include "MatrixOps.h" #include "Op.h" #include OCIO_NAMESPACE_ENTER { void CreateAllocationOps(OpRcPtrVec & ops, const AllocationData & data, TransformDirection dir) { if(data.allocation == ALLOCATION_UNIFORM) { float oldmin[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float oldmax[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; float newmin[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float newmax[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; if(data.vars.size() >= 2) { for(int i=0; i<3; ++i) { oldmin[i] = data.vars[0]; oldmax[i] = data.vars[1]; } } CreateFitOp(ops, oldmin, oldmax, newmin, newmax, dir); } else if(data.allocation == ALLOCATION_LG2) { float oldmin[4] = { -10.0f, -10.0f, -10.0f, 0.0f }; float oldmax[4] = { 6.0f, 6.0f, 6.0f, 1.0f }; float newmin[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float newmax[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; if(data.vars.size() >= 2) { for(int i=0; i<3; ++i) { oldmin[i] = data.vars[0]; oldmax[i] = data.vars[1]; } } // Log Settings // output = k * log(mx+b, base) + kb float k[3] = { 1.0f, 1.0f, 1.0f }; float m[3] = { 1.0f, 1.0f, 1.0f }; float b[3] = { 0.0f, 0.0f, 0.0f }; float base[3] = { 2.0f, 2.0f, 2.0f }; float kb[3] = { 0.0f, 0.0f, 0.0f }; if(data.vars.size() >= 3) { for(int i=0; i<3; ++i) { b[i] = data.vars[2]; } } if(dir == TRANSFORM_DIR_FORWARD) { CreateLogOp(ops, k, m, b, base, kb, dir); CreateFitOp(ops, oldmin, oldmax, newmin, newmax, dir); } else if(dir == TRANSFORM_DIR_INVERSE) { CreateFitOp(ops, oldmin, oldmax, newmin, newmax, dir); CreateLogOp(ops, k, m, b, base, kb, dir); } else { throw Exception("Cannot BuildAllocationOps, unspecified transform direction."); } } else { throw Exception("Unsupported Allocation Type."); } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/OCIOYaml.h0000644000175000017500000000357013223553423017537 0ustar mfvmfv/* 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 #ifndef INCLUDED_OCIO_YAML_H #define INCLUDED_OCIO_YAML_H OCIO_NAMESPACE_ENTER { class OCIOYaml { public: void open(std::istream& istream, ConfigRcPtr& c, const char* filename = NULL) const; void write(std::ostream& ostream, const Config* c) const; }; } OCIO_NAMESPACE_EXIT #endif // INCLUDED_OCIO_YAML_H opencolorio-1.1.0~dfsg0.orig/src/core/Lut1DOp.cpp0000644000175000017500000010602013223553423017740 0ustar mfvmfv/* 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 #include "HashUtils.h" #include "Lut1DOp.h" #include "MathUtils.h" #include "SSE.h" #include #include #include #include OCIO_NAMESPACE_ENTER { Lut1D::Lut1D() : maxerror(std::numeric_limits::min()), errortype(ERROR_RELATIVE) { for(int i=0; i<3; ++i) { from_min[i] = 0.0f; from_max[i] = 1.0f; } } Lut1DRcPtr Lut1D::Create() { return Lut1DRcPtr(new Lut1D()); } namespace { bool IsLut1DNoOp(const Lut1D & lut, float maxerror, ErrorType errortype) { // If tolerance not positive, skip the check. if(!(maxerror > 0.0)) return false; for(int channel = 0; channel<3; ++channel) { if(lut.luts[channel].size() == 0) continue; float inorm = 1.0f / (static_cast(lut.luts[channel].size()) - 1.0f); float m = lut.from_max[channel] - lut.from_min[channel]; float b = lut.from_min[channel]; for(unsigned int i=0; i(i) * inorm; float identval = m*x+b; float lutval = lut.luts[channel][i]; if(errortype == ERROR_ABSOLUTE) { if(!equalWithAbsError(identval, lutval, maxerror)) { return false; } } else if(errortype == ERROR_RELATIVE) { if(!equalWithRelError(identval, lutval, maxerror)) { return false; } } else { throw Exception("Unknown error type."); } } } return true; } } std::string Lut1D::getCacheID() const { AutoMutex lock(m_mutex); if(luts[0].empty() || luts[1].empty() || luts[2].empty()) throw Exception("Cannot compute cacheID of invalid Lut1D"); if(!m_cacheID.empty()) return m_cacheID; finalize(); return m_cacheID; } bool Lut1D::isNoOp() const { AutoMutex lock(m_mutex); if(luts[0].empty() || luts[1].empty() || luts[2].empty()) throw Exception("Cannot compute noOp of invalid Lut1D"); if(!m_cacheID.empty()) return m_isNoOp; finalize(); return m_isNoOp; } void Lut1D::unfinalize() { AutoMutex lock(m_mutex); m_cacheID = ""; m_isNoOp = false; } void Lut1D::finalize() const { m_isNoOp = IsLut1DNoOp(*this, maxerror, errortype); if(m_isNoOp) { m_cacheID = ""; } else { md5_state_t state; md5_byte_t digest[16]; md5_init(&state); md5_append(&state, (const md5_byte_t *)from_min, (int)(3*sizeof(float))); md5_append(&state, (const md5_byte_t *)from_max, (int)(3*sizeof(float))); for(int i=0; i<3; ++i) { md5_append( &state, (const md5_byte_t *)&(luts[i][0]), (int) (luts[i].size()*sizeof(float)) ); } md5_finish(&state, digest); m_cacheID = GetPrintableHash(digest); } } namespace { // Note: This function assumes that minVal is less than maxVal inline int clamp(float k, float minVal, float maxVal) { return static_cast(roundf(std::max(std::min(k, maxVal), minVal))); } /////////////////////////////////////////////////////////////////////// // Nearest Forward inline float lookupNearest_1D(float index, float maxIndex, const float * simple_lut) { return simple_lut[clamp(index, 0.0f, maxIndex)]; } void Lut1D_Nearest(float* rgbaBuffer, long numPixels, const Lut1D & lut) { float maxIndex[3]; float mInv[3]; float b[3]; float mInv_x_maxIndex[3]; const float* startPos[3]; for(int i=0; i<3; ++i) { maxIndex[i] = (float) (lut.luts[i].size() - 1); mInv[i] = 1.0f / (lut.from_max[i] - lut.from_min[i]); b[i] = lut.from_min[i]; mInv_x_maxIndex[i] = (float) (mInv[i] * maxIndex[i]); startPos[i] = &(lut.luts[i][0]); } for(long pixelIndex=0; pixelIndex *lowbound) { delta = (v - *lowbound) / (*highbound - *lowbound); } return std::max(((float)(lowbound - start) + delta) * invMaxIndex, 0.0f); } void Lut1D_LinearInverse(float* rgbaBuffer, long numPixels, const Lut1D & lut) { float m[3]; float b[3]; const float* startPos[3]; const float* endPos[3]; float invMaxIndex[3]; for(int i=0; i<3; ++i) { m[i] = (lut.from_max[i] - lut.from_min[i]); b[i] = lut.from_min[i]; startPos[i] = &(lut.luts[i][0]); endPos[i] = startPos[i] + lut.luts[i].size(); invMaxIndex[i] = 1.0f / (float) (lut.luts[i].size() - 1); } for(long pixelIndex=0; pixelIndex Lut1DOpRcPtr; Lut1DOp::Lut1DOp(const Lut1DRcPtr & lut, Interpolation interpolation, TransformDirection direction): Op(), m_lut(lut), m_interpolation(interpolation), m_direction(direction) { } OpRcPtr Lut1DOp::clone() const { OpRcPtr op = OpRcPtr(new Lut1DOp(m_lut, m_interpolation, m_direction)); return op; } Lut1DOp::~Lut1DOp() { } std::string Lut1DOp::getInfo() const { return ""; } std::string Lut1DOp::getCacheID() const { return m_cacheID; } // TODO: compute real value for isNoOp bool Lut1DOp::isNoOp() const { return false; } bool Lut1DOp::isSameType(const OpRcPtr & op) const { Lut1DOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; return true; } bool Lut1DOp::isInverse(const OpRcPtr & op) const { Lut1DOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; if(GetInverseTransformDirection(m_direction) != typedRcPtr->m_direction) return false; return (m_lut->getCacheID() == typedRcPtr->m_lut->getCacheID()); } bool Lut1DOp::hasChannelCrosstalk() const { return false; } void Lut1DOp::finalize() { if(m_direction == TRANSFORM_DIR_UNKNOWN) { throw Exception("Cannot apply lut1d op, unspecified transform direction."); } // Validate the requested interpolation type switch(m_interpolation) { // These are the allowed values. case INTERP_NEAREST: case INTERP_LINEAR: break; case INTERP_BEST: m_interpolation = INTERP_LINEAR; break; case INTERP_UNKNOWN: throw Exception("Cannot apply Lut1DOp, unspecified interpolation."); break; case INTERP_TETRAHEDRAL: throw Exception("Cannot apply Lut1DOp, tetrahedral interpolation is not allowed for 1d luts."); break; default: throw Exception("Cannot apply Lut1DOp, invalid interpolation specified."); } if(m_lut->luts[0].empty() || m_lut->luts[1].empty() || m_lut->luts[2].empty()) { throw Exception("Cannot apply lut1d op, no lut data provided."); } // Create the cacheID std::ostringstream cacheIDStream; cacheIDStream << "getCacheID() << " "; cacheIDStream << InterpolationToString(m_interpolation) << " "; cacheIDStream << TransformDirectionToString(m_direction) << " "; cacheIDStream << ">"; m_cacheID = cacheIDStream.str(); } void Lut1DOp::apply(float* rgbaBuffer, long numPixels) const { if(m_direction == TRANSFORM_DIR_FORWARD) { if(m_interpolation == INTERP_NEAREST) { #ifdef USE_SSE Lut1D_Nearest_SSE(rgbaBuffer, numPixels, *m_lut); #else Lut1D_Nearest(rgbaBuffer, numPixels, *m_lut); #endif } else if(m_interpolation == INTERP_LINEAR) { Lut1D_Linear(rgbaBuffer, numPixels, *m_lut); } } else if(m_direction == TRANSFORM_DIR_INVERSE) { if(m_interpolation == INTERP_NEAREST) { Lut1D_NearestInverse(rgbaBuffer, numPixels, *m_lut); } else if(m_interpolation == INTERP_LINEAR) { Lut1D_LinearInverse(rgbaBuffer, numPixels, *m_lut); } } } bool Lut1DOp::supportsGpuShader() const { return false; } void Lut1DOp::writeGpuShader(std::ostream & /*shader*/, const std::string & /*pixelName*/, const GpuShaderDesc & /*shaderDesc*/) const { throw Exception("Lut1DOp does not support analytical shader generation."); } } void CreateLut1DOp(OpRcPtrVec & ops, const Lut1DRcPtr & lut, Interpolation interpolation, TransformDirection direction) { if(lut->isNoOp()) return; // TODO: Detect if lut1d can be exactly approximated as y = mx + b // If so, return a mtx instead. ops.push_back( OpRcPtr(new Lut1DOp(lut, interpolation, direction)) ); } void GenerateIdentityLut1D(float* img, int numElements, int numChannels) { if(!img) return; int numChannelsToFill = std::min(3, numChannels); float scale = 1.0f / ((float) numElements - 1.0f); for(int i=0; i namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" OIIO_ADD_TEST(Lut1DOp, NoOp) { // Make an identity lut OCIO::Lut1DRcPtr lut = OCIO::Lut1D::Create(); lut->from_min[0] = 0.0f; lut->from_min[1] = 0.0f; lut->from_min[2] = 0.0f; lut->from_max[0] = 1.0f; lut->from_max[1] = 1.0f; lut->from_max[2] = 1.0f; int size = 256; for(int i=0; iluts[c].push_back(x); } } lut->maxerror = 1e-5f; lut->errortype = OCIO::ERROR_RELATIVE; OIIO_CHECK_EQUAL(lut->isNoOp(), true); lut->unfinalize(); lut->maxerror = 1e-5f; lut->errortype = OCIO::ERROR_ABSOLUTE; OIIO_CHECK_EQUAL(lut->isNoOp(), true); // Edit the lut // These should NOT be identity lut->unfinalize(); lut->luts[0][125] += 1e-3f; lut->maxerror = 1e-5f; lut->errortype = OCIO::ERROR_RELATIVE; OIIO_CHECK_EQUAL(lut->isNoOp(), false); lut->unfinalize(); lut->maxerror = 1e-5f; lut->errortype = OCIO::ERROR_ABSOLUTE; OIIO_CHECK_EQUAL(lut->isNoOp(), false); } OIIO_ADD_TEST(Lut1DOp, FiniteValue) { // Make a lut that squares the input OCIO::Lut1DRcPtr lut = OCIO::Lut1D::Create(); lut->from_min[0] = 0.0f; lut->from_min[1] = 0.0f; lut->from_min[2] = 0.0f; lut->from_max[0] = 1.0f; lut->from_max[1] = 1.0f; lut->from_max[2] = 1.0f; int size = 256; for(int i=0; iluts[c].push_back(x2); } } lut->maxerror = 1e-5f; lut->errortype = OCIO::ERROR_RELATIVE; OIIO_CHECK_EQUAL(lut->isNoOp(), false); float inputBuffer_linearforward[4] = { 0.5f, 0.6f, 0.7f, 0.5f }; float outputBuffer_linearforward[4] = { 0.25f, 0.36f, 0.49f, 0.5f }; OCIO::Lut1D_Linear(inputBuffer_linearforward, 1, *lut); for(int i=0; i <4; ++i) { OIIO_CHECK_CLOSE(inputBuffer_linearforward[i], outputBuffer_linearforward[i], 1e-5f); } float inputBuffer_nearestforward[4] = { 0.5f, 0.6f, 0.7f, 0.5f }; float outputBuffer_nearestforward[4] = { 0.25f, 0.36f, 0.49f, 0.5f }; OCIO::Lut1D_Nearest(inputBuffer_nearestforward, 1, *lut); for(int i=0; i <4; ++i) { OIIO_CHECK_CLOSE(inputBuffer_nearestforward[i], outputBuffer_nearestforward[i], 1e-2f); } float inputBuffer_linearinverse[4] = { 0.5f, 0.6f, 0.7f, 0.5f }; float outputBuffer_linearinverse[4] = { 0.25f, 0.36f, 0.49f, 0.5f }; OCIO::Lut1D_LinearInverse(outputBuffer_linearinverse, 1, *lut); for(int i=0; i <4; ++i) { OIIO_CHECK_CLOSE(inputBuffer_linearinverse[i], outputBuffer_linearinverse[i], 1e-5f); } float inputBuffer_nearestinverse[4] = { 0.5f, 0.6f, 0.7f, 0.5f }; float outputBuffer_nearestinverse[4] = { 0.25f, 0.36f, 0.49f, 0.5f }; OCIO::Lut1D_NearestInverse(outputBuffer_nearestinverse, 1, *lut); for(int i=0; i <4; ++i) { OIIO_CHECK_CLOSE(inputBuffer_nearestinverse[i], outputBuffer_nearestinverse[i], 1e-2f); } } OIIO_ADD_TEST(Lut1DOp, ExtrapolationErrors) { OCIO::Lut1DRcPtr lut = OCIO::Lut1D::Create(); lut->from_min[0] = 0.0f; lut->from_min[2] = 0.0f; lut->from_min[2] = 0.0f; lut->from_max[0] = 1.0f; lut->from_max[1] = 1.0f; lut->from_max[2] = 1.0f; // Simple y=x+0.1 LUT for(int c=0; c<3; ++c) { lut->luts[c].push_back(0.1f); lut->luts[c].push_back(0.6f); lut->luts[c].push_back(1.1f); } lut->maxerror = 1e-5f; lut->errortype = OCIO::ERROR_RELATIVE; OIIO_CHECK_EQUAL(lut->isNoOp(), false); const int PIXELS = 5; float inputBuffer_linearforward[PIXELS*4] = { -0.1f, -0.2f, -10.0f, 0.0f, 0.5f, 1.0f, 1.1f, 0.0f, 10.1f, 55.0f, 2.3f, 0.0f, 9.1f, 1.0e6f, 1.0e9f, 0.0f, 4.0e9f, 9.5e7f, 0.5f, 0.0f }; float outputBuffer_linearforward[PIXELS*4] = { 0.1f, 0.1f, 0.1f, 0.0f, 0.6f, 1.1f, 1.1f, 0.0f, 1.1f, 1.1f, 1.1f, 0.0f, 1.1f, 1.1f, 1.1f, 0.0f, 1.1f, 1.1f, 0.6f, 0.0f }; OCIO::Lut1D_Linear(inputBuffer_linearforward, PIXELS, *lut); for(size_t i=0; i from_min[0] = 0.0f; lut_a->from_min[1] = 0.0f; lut_a->from_min[2] = 0.0f; lut_a->from_max[0] = 1.0f; lut_a->from_max[1] = 1.0f; lut_a->from_max[2] = 1.0f; int size = 256; for(int i=0; iluts[c].push_back(x2); } } lut_a->maxerror = 1e-5f; lut_a->errortype = OCIO::ERROR_RELATIVE; } // Make another lut OCIO::Lut1DRcPtr lut_b = OCIO::Lut1D::Create(); { lut_b->from_min[0] = 0.5f; lut_b->from_min[1] = 0.6f; lut_b->from_min[2] = 0.7f; lut_b->from_max[0] = 1.0f; lut_b->from_max[1] = 1.0f; lut_b->from_max[2] = 1.0f; int size = 256; for(int i=0; iluts[c].push_back(x2); } } lut_b->maxerror = 1e-5f; lut_b->errortype = OCIO::ERROR_RELATIVE; } OCIO::OpRcPtrVec ops; CreateLut1DOp(ops, lut_a, OCIO::INTERP_NEAREST, OCIO::TRANSFORM_DIR_FORWARD); CreateLut1DOp(ops, lut_a, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_INVERSE); CreateLut1DOp(ops, lut_b, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_FORWARD); CreateLut1DOp(ops, lut_b, OCIO::INTERP_LINEAR, OCIO::TRANSFORM_DIR_INVERSE); OIIO_CHECK_EQUAL(ops.size(), 4); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[1])); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[2])); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[3]->clone())); OIIO_CHECK_EQUAL( ops[0]->isInverse(ops[1]), true); OIIO_CHECK_EQUAL( ops[0]->isInverse(ops[2]), false); OIIO_CHECK_EQUAL( ops[0]->isInverse(ops[2]), false); OIIO_CHECK_EQUAL( ops[0]->isInverse(ops[3]), false); OIIO_CHECK_EQUAL( ops[2]->isInverse(ops[3]), true); } #ifdef USE_SSE OIIO_ADD_TEST(Lut1DOp, SSE) { // Make a lut that squares the input OCIO::Lut1DRcPtr lut = OCIO::Lut1D::Create(); lut->from_min[0] = 0.0f; lut->from_min[1] = 0.0f; lut->from_min[2] = 0.0f; lut->from_max[0] = 1.0f; lut->from_max[1] = 1.0f; lut->from_max[2] = 1.0f; int size = 256; for(int i=0; iluts[c].push_back(x2); } } lut->maxerror = 1e-5f; lut->errortype = OCIO::ERROR_RELATIVE; OIIO_CHECK_EQUAL(lut->isNoOp(), false); int NUM_TEST_PIXELS = 1024; std::vector testValues(NUM_TEST_PIXELS*4); std::vector outputBuffer_cpu(NUM_TEST_PIXELS*4); std::vector outputBuffer_sse(NUM_TEST_PIXELS*4); float val = -1.0f; float delta = 0.00123456789f; for(int i=0; i::signaling_NaN(); testValues[1] = std::numeric_limits::quiet_NaN(); testValues[2] = -std::numeric_limits::signaling_NaN(); testValues[3] = -std::numeric_limits::signaling_NaN(); testValues[4] = std::numeric_limits::infinity(); testValues[5] = -std::numeric_limits::infinity(); testValues[6] = 0.0f; memcpy(&outputBuffer_cpu[0], &testValues[0], testValues.size()*sizeof(float)); memcpy(&outputBuffer_sse[0], &testValues[0], testValues.size()*sizeof(float)); OCIO::Lut1D_Nearest(&outputBuffer_cpu[0], NUM_TEST_PIXELS, lut); OCIO::Lut1D_Nearest_SSE(&outputBuffer_sse[0], NUM_TEST_PIXELS, lut); for(int i=0; ifrom_min[0] = 0.0f; lut->from_min[1] = 0.0f; lut->from_min[2] = 0.0f; lut->from_max[0] = 1.0f; lut->from_max[1] = 1.0f; lut->from_max[2] = 1.0f; int size = 256; for(int i=0; iluts[c].push_back(x2); } } lut->maxerror = 1e-5f; lut->errortype = OCIO::ERROR_RELATIVE; OIIO_CHECK_EQUAL(lut->isNoOp(), false); const float reference[4] = { std::numeric_limits::signaling_NaN(), std::numeric_limits::quiet_NaN(), std::numeric_limits::infinity(), -std::numeric_limits::infinity() }; /* float output[4] = { std::numeric_limits::signaling_NaN(), std::numeric_limits::quiet_NaN(), 1.0f, -std::numeric_limits::infinity() }; */ float color[4]; memcpy(color, reference, 4*sizeof(float)); OCIO::Lut1D_Linear(color, 1, *lut); /* for(int i=0; i<4; ++i) { if(isnan(color[i])) { std::cerr << color[i] << " " << output[i] << std::endl; OIIO_CHECK_EQUAL(isnan(color[i]), isnan(output[i])); } else { OIIO_CHECK_EQUAL(color[i], output[i]); } } */ memcpy(color, reference, 4*sizeof(float)); OCIO::Lut1D_Nearest(color, 1, *lut); /* for(int i=0; i <4; ++i) { if(isnan(color[i])) { OIIO_CHECK_EQUAL(isnan(color[i]), isnan(output[i])); } else { OIIO_CHECK_EQUAL(color[i], output[i]); } } */ memcpy(color, reference, 4*sizeof(float)); OCIO::Lut1D_LinearInverse(color, 1, *lut); /* for(int i=0; i <4; ++i) { if(isnan(color[i])) { OIIO_CHECK_EQUAL(isnan(color[i]), isnan(output[i])); } else { OIIO_CHECK_EQUAL(color[i], output[i]); } } */ memcpy(color, reference, 4*sizeof(float)); OCIO::Lut1D_NearestInverse(color, 1, *lut); /* for(int i=0; i <4; ++i) { if(isnan(color[i])) { OIIO_CHECK_EQUAL(isnan(color[i]), isnan(output[i])); } else { OIIO_CHECK_EQUAL(color[i], output[i]); } } */ } #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/LookTransform.cpp0000644000175000017500000003155513223553423021322 0ustar mfvmfv/* 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 #include #include #include "LookParse.h" #include "NoOps.h" #include "OpBuilders.h" #include "ParseUtils.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { LookTransformRcPtr LookTransform::Create() { return LookTransformRcPtr(new LookTransform(), &deleter); } void LookTransform::deleter(LookTransform* t) { delete t; } class LookTransform::Impl { public: TransformDirection dir_; std::string src_; std::string dst_; std::string looks_; Impl() : dir_(TRANSFORM_DIR_FORWARD) { } ~Impl() { } Impl& operator= (const Impl & rhs) { dir_ = rhs.dir_; src_ = rhs.src_; dst_ = rhs.dst_; looks_ = rhs.looks_; return *this; } }; /////////////////////////////////////////////////////////////////////////// LookTransform::LookTransform() : m_impl(new LookTransform::Impl) { } TransformRcPtr LookTransform::createEditableCopy() const { LookTransformRcPtr transform = LookTransform::Create(); *(transform->m_impl) = *m_impl; return transform; } LookTransform::~LookTransform() { delete m_impl; m_impl = NULL; } LookTransform& LookTransform::operator= (const LookTransform & rhs) { *m_impl = *rhs.m_impl; return *this; } TransformDirection LookTransform::getDirection() const { return getImpl()->dir_; } void LookTransform::setDirection(TransformDirection dir) { getImpl()->dir_ = dir; } const char * LookTransform::getSrc() const { return getImpl()->src_.c_str(); } void LookTransform::setSrc(const char * src) { getImpl()->src_ = src; } const char * LookTransform::getDst() const { return getImpl()->dst_.c_str(); } void LookTransform::setDst(const char * dst) { getImpl()->dst_ = dst; } void LookTransform::setLooks(const char * looks) { getImpl()->looks_ = looks; } const char * LookTransform::getLooks() const { return getImpl()->looks_.c_str(); } std::ostream& operator<< (std::ostream& os, const LookTransform& t) { os << ""; return os; } //////////////////////////////////////////////////////////////////////////// namespace { void RunLookTokens(OpRcPtrVec & ops, ConstColorSpaceRcPtr & currentColorSpace, bool skipColorSpaceConversions, const Config& config, const ConstContextRcPtr & context, const LookParseResult::Tokens & lookTokens) { if(lookTokens.empty()) return; for(unsigned int i=0; igetTransform()) { BuildOps(tmpOps, config, context, look->getTransform(), TRANSFORM_DIR_FORWARD); } else if(look->getInverseTransform()) { BuildOps(tmpOps, config, context, look->getInverseTransform(), TRANSFORM_DIR_INVERSE); } } else if(lookTokens[i].dir == TRANSFORM_DIR_INVERSE) { CreateLookNoOp(tmpOps, std::string("-") + lookName); if(look->getInverseTransform()) { BuildOps(tmpOps, config, context, look->getInverseTransform(), TRANSFORM_DIR_FORWARD); } else if(look->getTransform()) { BuildOps(tmpOps, config, context, look->getTransform(), TRANSFORM_DIR_INVERSE); } } else { std::ostringstream os; os << "BuildLookOps error. "; os << "The specified look, '" << lookTokens[i].name; os << "' has an ill-defined transform direction."; throw Exception(os.str().c_str()); } if(!IsOpVecNoOp(tmpOps)) { if(!skipColorSpaceConversions) { ConstColorSpaceRcPtr processColorSpace = config.getColorSpace(look->getProcessSpace()); if(!processColorSpace) { std::ostringstream os; os << "RunLookTokens error. "; os << "The specified look, '" << lookTokens[i].name; os << "', requires processing in the ColorSpace, '"; os << look->getProcessSpace() << "' which is not defined."; throw Exception(os.str().c_str()); } BuildColorSpaceOps(ops, config, context, currentColorSpace, processColorSpace); currentColorSpace = processColorSpace; } std::copy(tmpOps.begin(), tmpOps.end(), std::back_inserter(ops)); } } } } // anon namespace //////////////////////////////////////////////////////////////////////////// void BuildLookOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, const LookTransform & lookTransform, TransformDirection dir) { ConstColorSpaceRcPtr src, dst; src = config.getColorSpace( lookTransform.getSrc() ); dst = config.getColorSpace( lookTransform.getDst() ); if(!src) { std::ostringstream os; os << "BuildLookOps error."; os << "The specified lookTransform specifies a src colorspace, '"; os << lookTransform.getSrc() << "', which is not defined."; throw Exception(os.str().c_str()); } if(!dst) { std::ostringstream os; os << "BuildLookOps error."; os << "The specified lookTransform specifies a dst colorspace, '"; os << lookTransform.getDst() << "', which is not defined."; throw Exception(os.str().c_str()); } LookParseResult looks; looks.parse(lookTransform.getLooks()); // We must handle the inverse src/dst colorspace transformation explicitly. if(dir == TRANSFORM_DIR_INVERSE) { std::swap(src, dst); looks.reverse(); } else if(dir == TRANSFORM_DIR_UNKNOWN) { std::ostringstream os; os << "BuildLookOps error. A valid transform direction must be specified."; throw Exception(os.str().c_str()); } ConstColorSpaceRcPtr currentColorSpace = src; BuildLookOps(ops, currentColorSpace, false, config, context, looks); BuildColorSpaceOps(ops, config, context, currentColorSpace, dst); } void BuildLookOps(OpRcPtrVec & ops, ConstColorSpaceRcPtr & currentColorSpace, bool skipColorSpaceConversions, const Config& config, const ConstContextRcPtr & context, const LookParseResult & looks) { const LookParseResult::Options & options = looks.getOptions(); if(options.empty()) { // Do nothing } else if(options.size() == 1) { // As an optimization, if we only have a single look option, // just push back onto the final location RunLookTokens(ops, currentColorSpace, skipColorSpaceConversions, config, context, options[0]); } else { // If we have multiple look options, try each one in order, // and if we can create the ops without a missing file exception, // push back it's results and return bool success = false; std::ostringstream os; OpRcPtrVec tmpOps; ConstColorSpaceRcPtr cs; for(unsigned int i=0; i #include #include #include #include #include "FileTransform.h" #include "Lut1DOp.h" #include "Lut3DOp.h" #include "ParseUtils.h" #include "pystring/pystring.h" /* Iridas .look format An XML format containing , a series of layers describing the operations and their parameters (irrelevant to us in this context). This series of shaders is baked into the section. # anything in here is useless to us "8" # Size of 3D LUT " 0000008000000080000000802CF52E3D2DF52E3D2DF52E3D2CF5AE3D2DF5AE3D # ...cut... 5A216A3F5A216A3FAD10753FAD10753FAD10753F0000803F0000803F0000803F" The LUT data contains a 3D LUT, as a hex-encoded series of 32-bit floats, with little-endian bit-ordering. LUT value ordering is LUT3DORDER_FAST_RED (red index incrementing fastest, then green, then blue) The LUT data is parsed by removing all whitespace and quotes. Taking 8 characters at a time and intepreting as little-endian float, as follows: Given the string "0000003F0000803FAD10753F": >>> import binascii, struct >>> struct.unpack(">> struct.unpack(">> struct.unpack("=48 && character<=57) // [0-9] { ival = static_cast(character-48); return true; } else if(character>=65 && character<=70) // [A-F] { ival = static_cast(10+character-65); return true; } else if(character>=97 && character<=102) // [a-f] { ival = static_cast(10+character-97); return true; } ival = 0; return false; } // convert array of 8 hex ascii to f32 // The input hexascii is required to be a little-endian representation // as used in the iridas file format // "AD10753F" -> 0.9572857022285461f on ALL architectures bool hexasciitofloat(float& fval, const char * ascii) { // Convert all ASCII numbers to their numerical representations char asciinums[8]; for(unsigned int i=0; i<8; ++i) { if(!hexasciitoint(asciinums[i], ascii[i])) { return false; } } unsigned char * fvalbytes = reinterpret_cast(&fval); #if OCIO_LITTLE_ENDIAN // Since incoming values are little endian, and we're on little endian // preserve the byte order fvalbytes[0] = (unsigned char) (asciinums[1] | (asciinums[0] << 4)); fvalbytes[1] = (unsigned char) (asciinums[3] | (asciinums[2] << 4)); fvalbytes[2] = (unsigned char) (asciinums[5] | (asciinums[4] << 4)); fvalbytes[3] = (unsigned char) (asciinums[7] | (asciinums[6] << 4)); #else // Since incoming values are little endian, and we're on big endian // flip the byte order fvalbytes[3] = (unsigned char) (asciinums[1] | (asciinums[0] << 4)); fvalbytes[2] = (unsigned char) (asciinums[3] | (asciinums[2] << 4)); fvalbytes[1] = (unsigned char) (asciinums[5] | (asciinums[4] << 4)); fvalbytes[0] = (unsigned char) (asciinums[7] | (asciinums[6] << 4)); #endif return true; } } namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile () { lut3D = Lut3D::Create(); }; ~LocalCachedFile() {}; Lut3DRcPtr lut3D; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; typedef OCIO_SHARED_PTR TiXmlDocumentRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "iridas_look"; info.extension = "look"; info.capabilities = FORMAT_CAPABILITY_READ; formatInfoVec.push_back(info); } CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { // Get root element from XML file TiXmlDocumentRcPtr doc; TiXmlElement* rootElement; { std::ostringstream rawdata; rawdata << istream.rdbuf(); doc = TiXmlDocumentRcPtr(new TiXmlDocument()); doc->Parse(rawdata.str().c_str()); if(doc->Error()) { std::ostringstream os; os << "XML Parse Error. "; os << doc->ErrorDesc() << " (line "; os << doc->ErrorRow() << ", character "; os << doc->ErrorCol() << ")"; throw Exception(os.str().c_str()); } // Check for blank file rootElement = doc->RootElement(); if(!rootElement) { std::ostringstream os; os << "Error loading xml. Null root element."; throw Exception(os.str().c_str()); } } // Check root element is if(std::string(rootElement->Value()) != "look") { std::ostringstream os; os << "Error loading .look LUT. "; os << "Root element is type '" << rootElement->Value() << "', "; os << "expected 'look'."; throw Exception(os.str().c_str()); } // Fail to load file if it contains a section if(rootElement->FirstChild("mask") && rootElement->FirstChild("mask")->FirstChild()) { // If root element contains "mask" child, and it is // not empty, throw exception std::ostringstream os; os << "Cannot load .look LUT containing mask"; throw Exception(os.str().c_str()); } // Get section // TODO: There is a LUT1D section in some .look files, // which we could use if available. Need to check // assumption that it is only written for 1D transforms, // and it matches the desired output TiXmlNode* lutsection = rootElement->FirstChild("LUT"); if(!lutsection) { std::ostringstream os; os << "Error loading .look LUT. "; os << "Could not find required 'LUT' section."; throw Exception(os.str().c_str()); } // Get 3D LUT size int size_3d = -1; { // Get size from '123' TiXmlNode* elemsize = lutsection->FirstChild("size"); if(!elemsize) { std::ostringstream os; os << "Error loading .look LUT. "; os << "LUT section did not contain 'size'."; throw Exception(os.str().c_str()); } std::string size_raw = std::string(elemsize->ToElement()->GetText()); std::string size_clean = pystring::strip(size_raw, "'\" "); // strip quotes and space char* endptr = 0; size_3d = static_cast(strtol(size_clean.c_str(), &endptr, 10)); if(*endptr) { // strtol didn't consume entire string, there was // remaining data, thus did not contain a single interger std::ostringstream os; os << "Invalid LUT size value: '" << size_raw; os << "'. Expected quoted integer."; throw Exception(os.str().c_str()); } } // Grab raw 3D data std::vector raw; { TiXmlNode* dataelem = lutsection->FirstChild("data"); if(!dataelem) { std::ostringstream os; os << "Error loading .look LUT. "; os << "LUT section did not contain 'data'."; throw Exception(os.str().c_str()); } raw.reserve(3*(size_3d*size_3d*size_3d)); std::string what = dataelem->ToElement()->GetText(); // Remove spaces, quotes and newlines what = pystring::replace(what, " ", ""); what = pystring::replace(what, "\"", ""); what = pystring::replace(what, "'", ""); what = pystring::replace(what, "\n", ""); if(what.size() % 8 != 0) { std::ostringstream os; os << "Error loading .look LUT. "; os << "Number of characters in 'data' must be multiple of 8. "; os << what.size() << " elements found."; throw Exception(os.str().c_str()); } const char * ascii = what.c_str(); float fval = 0.0f; for(unsigned int i=0; i(raw.size())) { std::ostringstream os; os << "Parse error in Iridas .look lut. "; os << "Incorrect number of lut3d entries. "; os << "Found " << raw.size() << " values, expected " << (size_3d*size_3d*size_3d)*3 << "."; throw Exception(os.str().c_str()); } // Reformat 3D data cachedFile->lut3D->size[0] = size_3d; cachedFile->lut3D->size[1] = size_3d; cachedFile->lut3D->size[2] = size_3d; cachedFile->lut3D->lut = raw; return cachedFile; } void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops, const Config& /*config*/, const ConstContextRcPtr & /*context*/, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { LocalCachedFileRcPtr cachedFile = DynamicPtrCast(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build Iridas .look Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_UNKNOWN) { std::ostringstream os; os << "Cannot build file format transform,"; os << " unspecified transform direction."; throw Exception(os.str().c_str()); } CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } } FileFormat * CreateFileFormatIridasLook() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST #include "UnitTest.h" OCIO_NAMESPACE_USING OIIO_ADD_TEST(FileFormatIridasLook, hexasciitoint) { { char ival = 0; bool success = hexasciitoint(ival, 'a'); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 10); } { char ival = 0; bool success = hexasciitoint(ival, 'A'); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 10); } { char ival = 0; bool success = hexasciitoint(ival, 'f'); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 15); } { char ival = 0; bool success = hexasciitoint(ival, 'F'); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 15); } { char ival = 0; bool success = hexasciitoint(ival, '0'); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 0); } { char ival = 0; bool success = hexasciitoint(ival, '0'); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 0); } { char ival = 0; bool success = hexasciitoint(ival, '9'); OIIO_CHECK_EQUAL(success, true); OIIO_CHECK_EQUAL(ival, 9); } { char ival = 0; bool success = hexasciitoint(ival, '\n'); OIIO_CHECK_EQUAL(success, false); } { char ival = 0; bool success = hexasciitoint(ival, 'j'); OIIO_CHECK_EQUAL(success, false); } { char ival = 0; bool success = hexasciitoint(ival, 'x'); OIIO_CHECK_EQUAL(success, false); } } OIIO_ADD_TEST(FileFormatIridasLook, hexasciitofloat) { //>>> import binascii, struct //>> struct.unpack("" << "\n"; strebuf << "" << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " \"1\"" << "\n"; strebuf << " " << "\n"; strebuf << " \"1\"" << "\n"; strebuf << " " << "\n"; strebuf << " \"1\"" << "\n"; strebuf << " \"0\"" << "\n"; strebuf << " \"0\"" << "\n"; strebuf << " \"0\"" << "\n"; strebuf << " \"0\"" << "\n"; strebuf << " \"0\"" << "\n"; strebuf << " \"0\"" << "\n"; strebuf << " \"0\"" << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " \"8\"" << "\n"; strebuf << " \"" << "\n"; strebuf << " 0000008000000080000000802CF52E3D2DF52E3D2DF52E3D2CF5AE3D2DF5AE3D" << "\n"; strebuf << " 2DF5AE3DE237033EE237033EE237033E2CF52E3E2DF52E3E2DF52E3E78B25A3E" << "\n"; strebuf << " 78B25A3E78B25A3EE037833EE137833EE137833E8616993E8716993E8716993E" << "\n"; strebuf << " 4BBDAB3D4BBDAB3D4BBDAB3DF09B013EF09B013EF09B013E3C592D3E3C592D3E" << "\n"; strebuf << " 3C592D3E8716593E8716593E8716593EE969823EE969823EE969823E8E48983E" << "\n"; strebuf << " 8E48983E8E48983E3227AE3E3327AE3E3327AE3ED805C43ED905C43ED905C43E" << "\n"; strebuf << " 4BBD2B3E4BBD2B3E4BBD2B3E967A573E967A573E967A573EF09B813EF09B813E" << "\n"; strebuf << " F09B813E967A973E967A973E967A973E3C59AD3E3C59AD3E3C59AD3EE137C33E" << "\n"; strebuf << " E137C33EE137C33E8616D93E8616D93E8616D93E2CF5EE3E2CF5EE3E2CF5EE3E" << "\n"; strebuf << " F9CD803EF9CD803EF9CD803E9EAC963E9EAC963E9EAC963E448BAC3E448BAC3E" << "\n"; strebuf << " 448BAC3EEA69C23EEA69C23EEA69C23E8F48D83E8F48D83E8F48D83E3527EE3E" << "\n"; strebuf << " 3527EE3E3527EE3EED02023FED02023FED02023F40F20C3F40F20C3F40F20C3F" << "\n"; strebuf << " 4BBDAB3E4BBDAB3E4BBDAB3EF09BC13EF09BC13EF09BC13E967AD73E967AD73E" << "\n"; strebuf << " 967AD73E3C59ED3E3C59ED3E3C59ED3EF09B013FF09B013FF09B013F438B0C3F" << "\n"; strebuf << " 438B0C3F438B0C3F967A173F967A173F967A173FE969223FE969223FE969223F" << "\n"; strebuf << " 9EACD63E9EACD63E9EACD63E428BEC3E438BEC3E438BEC3EF434013FF434013F" << "\n"; strebuf << " F434013F47240C3F47240C3F47240C3F9A13173F9A13173F9A13173FED02223F" << "\n"; strebuf << " ED02223FED02223F3FF22C3F3FF22C3F3FF22C3F92E1373F92E1373F92E1373F" << "\n"; strebuf << " F8CD003FF8CD003FF8CD003F49BD0B3F4ABD0B3F4ABD0B3F9DAC163F9DAC163F" << "\n"; strebuf << " 9DAC163FF09B213FF09B213FF09B213F438B2C3F438B2C3F438B2C3F967A373F" << "\n"; strebuf << " 967A373F967A373FE869423FE869423FE869423F3B594D3F3B594D3F3B594D3F" << "\n"; strebuf << " A245163FA245163FA245163FF334213FF434213FF434213F47242C3F47242C3F" << "\n"; strebuf << " 47242C3F9A13373F9A13373F9A13373FED02423FED02423FED02423F40F24C3F" << "\n"; strebuf << " 40F24C3F40F24C3F92E1573F92E1573F92E1573FE5D0623FE5D0623FE5D0623F" << "\n"; strebuf << " 9E69853C9E69853C9869853CFCA9713DFCA9713DFCA9713D944FD03D944FD03D" << "\n"; strebuf << " 944FD03D14E5133E15E5133E15E5133E60A23F3E60A23F3E60A23F3EAA5F6B3E" << "\n"; strebuf << " AB5F6B3EAB5F6B3E7A8E8B3E7A8E8B3E7A8E8B3E206DA13E206DA13E206DA13E" << "\n"; strebuf << " B217CD3DB217CD3DB217CD3D2449123E2449123E2449123E6F063E3E6F063E3E" << "\n"; strebuf << " 6F063E3EBAC3693EBAC3693EBAC3693E82C08A3E82C08A3E82C08A3E289FA03E" << "\n"; strebuf << " 289FA03E289FA03ECC7DB63ECC7DB63ECC7DB63E725CCC3E715CCC3E715CCC3E" << "\n"; strebuf << " 7E6A3C3E7E6A3C3E7E6A3C3ECA27683ECA27683ECA27683E8AF2893E8AF2893E" << "\n"; strebuf << " 8AF2893E30D19F3E30D19F3E30D19F3ED5AFB53ED5AFB53ED5AFB53E7B8ECB3E" << "\n"; strebuf << " 7B8ECB3E7A8ECB3E1F6DE13E1F6DE13E1E6DE13EC44BF73EC54BF73EC44BF73E" << "\n"; strebuf << " 9224893E9224893E9224893E38039F3E38039F3E38039F3EDEE1B43EDEE1B43E" << "\n"; strebuf << " DEE1B43E83C0CA3E83C0CA3E82C0CA3E299FE03E299FE03E289FE03ECE7DF63E" << "\n"; strebuf << " CE7DF63ECD7DF63E392E063F392E063F382E063F8C1D113F8C1D113F8B1D113F" << "\n"; strebuf << " E413B43EE413B43EE413B43E89F2C93E8AF2C93E89F2C93E30D1DF3E30D1DF3E" << "\n"; strebuf << " 2FD1DF3ED5AFF53ED5AFF53ED4AFF53E3DC7053F3DC7053F3CC7053F90B6103F" << "\n"; strebuf << " 90B6103F8FB6103FE2A51B3FE2A51B3FE1A51B3F3595263F3595263F3495263F" << "\n"; strebuf << " 3703DF3E3703DF3E3603DF3EDCE1F43EDDE1F43EDCE1F43E4160053F4160053F" << "\n"; strebuf << " 4060053F944F103F944F103F934F103FE73E1B3FE73E1B3FE63E1B3F392E263F" << "\n"; strebuf << " 392E263F382E263F8C1D313F8C1D313F8B1D313FDF0C3C3FDF0C3C3FDE0C3C3F" << "\n"; strebuf << " 44F9043F44F9043F43F9043F96E80F3F97E80F3F96E80F3FEAD71A3FEAD71A3F" << "\n"; strebuf << " E9D71A3F3DC7253F3DC7253F3CC7253F90B6303F90B6303F8FB6303FE2A53B3F" << "\n"; strebuf << " E2A53B3FE1A53B3F3595463F3595463F3495463F8884513F8884513F8784513F" << "\n"; strebuf << " EE701A3FEE701A3FED701A3F4060253F4160253F4060253F944F303F944F303F" << "\n"; strebuf << " 934F303FE73E3B3FE73E3B3FE63E3B3F3A2E463F3A2E463F392E463F8C1D513F" << "\n"; strebuf << " 8C1D513F8B1D513FDF0C5C3FDF0C5C3FDE0C5C3F32FC663F32FC663F31FC663F" << "\n"; strebuf << " 9E69053D9E69053D9869053D652F9A3D652F9A3D642F9A3DFCA9F13DFCA9F13D" << "\n"; strebuf << " FCA9F13D4892243E4992243E4992243E944F503E944F503E944F503EDE0C7C3E" << "\n"; strebuf << " DF0C7C3EDF0C7C3E14E5933E14E5933E14E5933EBAC3A93EBAC3A93EBAC3A93E" << "\n"; strebuf << " 1A72EE3D1A72EE3D1A72EE3D58F6223E58F6223E58F6223EA3B34E3EA3B34E3E" << "\n"; strebuf << " A3B34E3EEE707A3EEE707A3EEE707A3E1C17933E1C17933E1C17933EC2F5A83E" << "\n"; strebuf << " C2F5A83EC2F5A83E66D4BE3E66D4BE3E66D4BE3E0CB3D43E0BB3D43E0CB3D43E" << "\n"; strebuf << " B2174D3EB2174D3EB2174D3EFDD4783EFDD4783EFDD4783E2449923E2449923E" << "\n"; strebuf << " 2449923ECA27A83ECA27A83ECA27A83E6F06BE3E6F06BE3E6F06BE3E15E5D33E" << "\n"; strebuf << " 15E5D33E15E5D33EB9C3E93EB9C3E93EB9C3E93E5EA2FF3E5FA2FF3E5FA2FF3E" << "\n"; strebuf << " 2C7B913E2C7B913E2C7B913ED259A73ED259A73ED259A73E7838BD3E7838BD3E" << "\n"; strebuf << " 7838BD3E1D17D33E1D17D33E1D17D33EC3F5E83EC3F5E83EC3F5E83E68D4FE3E" << "\n"; strebuf << " 68D4FE3E68D4FE3E86590A3F86590A3F86590A3FD948153FD948153FD948153F" << "\n"; strebuf << " 7E6ABC3E7E6ABC3E7E6ABC3E2349D23E2449D23E2449D23ECA27E83ECA27E83E" << "\n"; strebuf << " CA27E83E6F06FE3E6F06FE3E6F06FE3E8AF2093F8AF2093F8AF2093FDDE1143F" << "\n"; strebuf << " DDE1143FDDE1143F2FD11F3F2FD11F3F2FD11F3F82C02A3F82C02A3F82C02A3F" << "\n"; strebuf << " D159E73ED159E73ED159E73E7638FD3E7738FD3E7738FD3E8E8B093F8E8B093F" << "\n"; strebuf << " 8E8B093FE17A143FE17A143FE17A143F346A1F3F346A1F3F346A1F3F86592A3F" << "\n"; strebuf << " 86592A3F86592A3FD948353FD948353FD948353F2C38403F2C38403F2C38403F" << "\n"; strebuf << " 9124093F9124093F9124093FE313143FE413143FE413143F37031F3F37031F3F" << "\n"; strebuf << " 37031F3F8AF2293F8AF2293F8AF2293FDDE1343FDDE1343FDDE1343F2FD13F3F" << "\n"; strebuf << " 2FD13F3F2FD13F3F82C04A3F82C04A3F81C04A3FD5AF553FD5AF553FD4AF553F" << "\n"; strebuf << " 3B9C1E3F3B9C1E3F3B9C1E3F8D8B293F8E8B293F8E8B293FE17A343FE17A343F" << "\n"; strebuf << " E17A343F346A3F3F346A3F3F346A3F3F87594A3F87594A3F86594A3FD948553F" << "\n"; strebuf << " D948553FD848553F2C38603F2C38603F2B38603F7F276B3F7F276B3F7E276B3F" << "\n"; strebuf << " 6E1E483D6E1E483D681E483DCD89BB3DCD89BB3DCC89BB3D3282093E3282093E" << "\n"; strebuf << " 3282093E7C3F353E7D3F353E7C3F353EC8FC603EC8FC603EC8FC603E095D863E" << "\n"; strebuf << " 095D863E095D863EAE3B9C3EAE3B9C3EAE3B9C3E541AB23E541AB23E541AB23E" << "\n"; strebuf << " 41E6073E41E6073E40E6073E8CA3333E8CA3333E8CA3333ED7605F3ED7605F3E" << "\n"; strebuf << " D7605F3E118F853E118F853E118F853EB66D9B3EB66D9B3EB66D9B3E5B4CB13E" << "\n"; strebuf << " 5B4CB13E5B4CB13E002BC73E002BC73E002BC73EA609DD3EA509DD3EA609DD3E" << "\n"; strebuf << " E6C45D3EE6C45D3EE6C45D3E18C1843E18C1843E18C1843EBE9F9A3EBE9F9A3E" << "\n"; strebuf << " BE9F9A3E647EB03E647EB03E647EB03E095DC63E095DC63E095DC63EAE3BDC3E" << "\n"; strebuf << " AE3BDC3EAE3BDC3E531AF23E531AF23E531AF23E7CFC033F7CFC033F7CFC033F" << "\n"; strebuf << " C6D1993EC6D1993EC6D1993E6CB0AF3E6CB0AF3E6CB0AF3E128FC53E128FC53E" << "\n"; strebuf << " 128FC53EB76DDB3EB76DDB3EB76DDB3E5D4CF13E5D4CF13E5D4CF13E8195033F" << "\n"; strebuf << " 8195033F8195033FD3840E3FD3840E3FD3840E3F2674193F2674193F2674193F" << "\n"; strebuf << " 18C1C43E18C1C43E18C1C43EBD9FDA3EBE9FDA3EBE9FDA3E647EF03E647EF03E" << "\n"; strebuf << " 647EF03E842E033F842E033F842E033FD71D0E3FD71D0E3FD71D0E3F2A0D193F" << "\n"; strebuf << " 2A0D193F2A0D193F7CFC233F7CFC233F7CFC233FCFEB2E3FCFEB2E3FCFEB2E3F" << "\n"; strebuf << " 6BB0EF3E6BB0EF3E6BB0EF3E87C7023F88C7023F88C7023FDBB60D3FDBB60D3F" << "\n"; strebuf << " DBB60D3F2EA6183F2EA6183F2EA6183F8195233F8195233F8195233FD3842E3F" << "\n"; strebuf << " D3842E3FD3842E3F2674393F2674393F2674393F7963443F7963443F7963443F" << "\n"; strebuf << " DE4F0D3FDE4F0D3FDE4F0D3F303F183F313F183F313F183F842E233F842E233F" << "\n"; strebuf << " 842E233FD71D2E3FD71D2E3FD71D2E3F2A0D393F2A0D393F2A0D393F7CFC433F" << "\n"; strebuf << " 7CFC433F7CFC433FCFEB4E3FCFEB4E3FCFEB4E3F22DB593F22DB593F22DB593F" << "\n"; strebuf << " 88C7223F88C7223F88C7223FDAB62D3FDBB62D3FDBB62D3F2EA6383F2EA6383F" << "\n"; strebuf << " 2EA6383F8195433F8195433F8195433FD4844E3FD4844E3FD4844E3F2674593F" << "\n"; strebuf << " 2674593F2674593F7963643F7963643F7963643FCC526F3FCC526F3FCC526F3F" << "\n"; strebuf << " 9E69853D9E69853D9869853D34E4DC3D34E4DC3D34E4DC3D652F1A3E652F1A3E" << "\n"; strebuf << " 642F1A3EB1EC453EB1EC453EB0EC453EFCA9713EFCA9713EFCA9713EA3B38E3E" << "\n"; strebuf << " A3B38E3EA3B38E3E4892A43E4892A43E4892A43EEE70BA3EEE70BA3EEE70BA3E" << "\n"; strebuf << " 7493183E7493183E7493183EBF50443EBF50443EBE50443E0A0E703E0A0E703E" << "\n"; strebuf << " 0A0E703EABE58D3EABE58D3EABE58D3E50C4A33E50C4A33E50C4A33EF5A2B93E" << "\n"; strebuf << " F5A2B93EF5A2B93E9A81CF3E9981CF3E9A81CF3E4060E53E3F60E53E4060E53E" << "\n"; strebuf << " 1A726E3E1A726E3E1A726E3EB2178D3EB2178D3EB2178D3E58F6A23E58F6A23E" << "\n"; strebuf << " 58F6A23EFED4B83EFED4B83EFED4B83EA3B3CE3EA3B3CE3EA3B3CE3E4892E43E" << "\n"; strebuf << " 4892E43E4892E43EED70FA3EED70FA3EED70FA3EC927083FC927083FC927083F" << "\n"; strebuf << " 6028A23E6028A23E6028A23E0607B83E0607B83E0607B83EABE5CD3EABE5CD3E" << "\n"; strebuf << " ABE5CD3E51C4E33E51C4E33E51C4E33EF7A2F93EF7A2F93EF7A2F93ECEC0073F" << "\n"; strebuf << " CEC0073FCEC0073F20B0123F20B0123F20B0123F739F1D3F739F1D3F739F1D3F" << "\n"; strebuf << " B217CD3EB217CD3EB217CD3E57F6E23E58F6E23E58F6E23EFDD4F83EFDD4F83E" << "\n"; strebuf << " FDD4F83ED159073FD159073FD159073F2449123F2449123F2449123F77381D3F" << "\n"; strebuf << " 77381D3F77381D3FC927283FC927283FC927283F1C17333F1C17333F1C17333F" << "\n"; strebuf << " 0507F83E0507F83E0507F83ED4F2063FD5F2063FD5F2063F28E2113F28E2113F" << "\n"; strebuf << " 28E2113F7BD11C3F7BD11C3F7BD11C3FCEC0273FCEC0273FCEC0273F20B0323F" << "\n"; strebuf << " 20B0323F20B0323F739F3D3F739F3D3F739F3D3FC68E483FC68E483FC68E483F" << "\n"; strebuf << " 2B7B113F2B7B113F2B7B113F7D6A1C3F7E6A1C3F7E6A1C3FD159273FD159273F" << "\n"; strebuf << " D159273F2449323F2449323F2449323F77383D3F77383D3F77383D3FC927483F" << "\n"; strebuf << " C927483FC927483F1C17533F1C17533F1C17533F6F065E3F6F065E3F6F065E3F" << "\n"; strebuf << " D5F2263FD5F2263FD5F2263F27E2313F28E2313F28E2313F7BD13C3F7BD13C3F" << "\n"; strebuf << " 7BD13C3FCEC0473FCEC0473FCEC0473F21B0523F21B0523F21B0523F739F5D3F" << "\n"; strebuf << " 739F5D3F739F5D3FC68E683FC68E683FC68E683F197E733F197E733F197E733F" << "\n"; strebuf << " 06C4A63D06C4A63D00C4A63D9C3EFE3D9C3EFE3D983EFE3D99DC2A3E99DC2A3E" << "\n"; strebuf << " 98DC2A3EE599563EE599563EE499563E982B813E982B813E982B813E3D0A973E" << "\n"; strebuf << " 3D0A973E3D0A973EE2E8AC3EE2E8AC3EE2E8AC3E88C7C23E88C7C23E88C7C23E" << "\n"; strebuf << " A840293EA840293EA840293EF3FD543EF3FD543EF0FD543E9F5D803E9F5D803E" << "\n"; strebuf << " 9F5D803E453C963E453C963E453C963EEA1AAC3EEA1AAC3EEA1AAC3E8FF9C13E" << "\n"; strebuf << " 8FF9C13E8FF9C13E34D8D73E33D8D73E34D8D73EDAB6ED3ED9B6ED3EDAB6ED3E" << "\n"; strebuf << " 4E1F7F3E4E1F7F3E4E1F7F3E4C6E953E4C6E953E4C6E953EF24CAB3EF24CAB3E" << "\n"; strebuf << " F24CAB3E982BC13E982BC13E982BC13E3D0AD73E3D0AD73E3D0AD73EE2E8EC3E" << "\n"; strebuf << " E2E8EC3EE2E8EC3EC363013FC363013FC363013F16530C3F16530C3F16530C3F" << "\n"; strebuf << " FA7EAA3EFA7EAA3EFA7EAA3EA05DC03EA05DC03EA05DC03E453CD63E453CD63E" << "\n"; strebuf << " 453CD63EEB1AEC3EEB1AEC3EEB1AEC3EC8FC003FC8FC003FC8FC003F1BEC0B3F" << "\n"; strebuf << " 1BEC0B3F1BEC0B3F6DDB163F6DDB163F6DDB163FC0CA213FC0CA213FC0CA213F" << "\n"; strebuf << " 4C6ED53E4C6ED53E4C6ED53EF14CEB3EF24CEB3EF24CEB3ECB95003FCB95003F" << "\n"; strebuf << " CB95003F1E850B3F1E850B3F1E850B3F7174163F7174163F7174163FC463213F" << "\n"; strebuf << " C463213FC463213F16532C3F16532C3F16532C3F6942373F6942373F6942373F" << "\n"; strebuf << " CF2E003FCF2E003FCF2E003F211E0B3F221E0B3F221E0B3F750D163F750D163F" << "\n"; strebuf << " 750D163FC8FC203FC8FC203FC8FC203F1BEC2B3F1BEC2B3F1BEC2B3F6DDB363F" << "\n"; strebuf << " 6DDB363F6DDB363FC0CA413FC0CA413FC0CA413F13BA4C3F13BA4C3F13BA4C3F" << "\n"; strebuf << " 78A6153F78A6153F78A6153FCA95203FCB95203FCB95203F1E852B3F1E852B3F" << "\n"; strebuf << " 1E852B3F7174363F7174363F7174363FC463413FC463413FC463413F16534C3F" << "\n"; strebuf << " 16534C3F16534C3F6942573F6942573F6942573FBC31623FBC31623FBC31623F" << "\n"; strebuf << " 221E2B3F221E2B3F221E2B3F740D363F750D363F750D363FC8FC403FC8FC403F" << "\n"; strebuf << " C8FC403F1BEC4B3F1BEC4B3F1BEC4B3F6EDB563F6EDB563F6EDB563FC0CA613F" << "\n"; strebuf << " C0CA613FC0CA613F13BA6C3F13BA6C3F13BA6C3F66A9773F66A9773F66A9773F" << "\n"; strebuf << " 6D1EC83D6D1EC83D681EC83D81CC0F3E81CC0F3E80CC0F3ECD893B3ECD893B3E" << "\n"; strebuf << " CC893B3E1847673E1847673E1847673E3182893E3182893E3082893ED7609F3E" << "\n"; strebuf << " D7609F3ED6609F3E7C3FB53E7C3FB53E7C3FB53E221ECB3E221ECB3E221ECB3E" << "\n"; strebuf << " DCED393EDCED393EDCED393E26AB653E26AB653E24AB653E39B4883E39B4883E" << "\n"; strebuf << " 38B4883EDE929E3EDE929E3EDE929E3E8371B43E8371B43E8271B43E2950CA3E" << "\n"; strebuf << " 2850CA3E2950CA3ECE2EE03ECD2EE03ECE2EE03E740DF63E730DF63E740DF63E" << "\n"; strebuf << " 40E6873E40E6873E40E6873EE6C49D3EE6C49D3EE6C49D3E8CA3B33E8CA3B33E" << "\n"; strebuf << " 8CA3B33E3182C93E3182C93E3182C93ED660DF3ED660DF3ED660DF3E7C3FF53E" << "\n"; strebuf << " 7C3FF53E7C3FF53E108F053F108F053F108F053F637E103F637E103F637E103F" << "\n"; strebuf << " 94D5B23E94D5B23E94D5B23E39B4C83E39B4C83E39B4C83EDF92DE3EDF92DE3E" << "\n"; strebuf << " DF92DE3E8571F43E8571F43E8571F43E1528053F1528053F1528053F6817103F" << "\n"; strebuf << " 6817103F6817103FBA061B3FBA061B3FBA061B3F0DF6253F0DF6253F0DF6253F" << "\n"; strebuf << " E6C4DD3EE6C4DD3EE6C4DD3E8AA3F33E8BA3F33E8BA3F33E18C1043F18C1043F" << "\n"; strebuf << " 18C1043F6BB00F3F6BB00F3F6BB00F3FBE9F1A3FBE9F1A3FBE9F1A3F118F253F" << "\n"; strebuf << " 118F253F118F253F637E303F637E303F637E303FB66D3B3FB66D3B3FB66D3B3F" << "\n"; strebuf << " 1C5A043F1C5A043F1C5A043F6E490F3F6F490F3F6F490F3FC2381A3FC2381A3F" << "\n"; strebuf << " C2381A3F1528253F1528253F1528253F6717303F6717303F6717303FBA063B3F" << "\n"; strebuf << " BA063B3FBA063B3F0DF6453F0DF6453F0DF6453F60E5503F60E5503F60E5503F" << "\n"; strebuf << " C5D1193FC5D1193FC5D1193F17C1243F18C1243F18C1243F6BB02F3F6BB02F3F" << "\n"; strebuf << " 6BB02F3FBE9F3A3FBE9F3A3FBE9F3A3F108F453F108F453F108F453F637E503F" << "\n"; strebuf << " 637E503F637E503FB66D5B3FB66D5B3FB66D5B3F095D663F095D663F095D663F" << "\n"; strebuf << " 6F492F3F6F492F3F6F492F3FC1383A3FC2383A3FC2383A3F1528453F1528453F" << "\n"; strebuf << " 1528453F6817503F6817503F6817503FBA065B3FBA065B3FBA065B3F0DF6653F" << "\n"; strebuf << " 0DF6653F0DF6653F60E5703F60E5703F60E5703FB3D47B3FB3D47B3FB3D47B3F" << "\n"; strebuf << " D578E93DD578E93DD078E93DB579203EB579203EB479203E01374C3E01374C3E" << "\n"; strebuf << " 00374C3E4CF4773E4CF4773E4CF4773ECBD8913ECBD8913ECAD8913E71B7A73E" << "\n"; strebuf << " 71B7A73E70B7A73E1696BD3E1696BD3E1696BD3EBC74D33EBC74D33EBC74D33E" << "\n"; strebuf << " 109B4A3E109B4A3E109B4A3E5A58763E5A58763E5858763ED30A913ED30A913E" << "\n"; strebuf << " D20A913E78E9A63E78E9A63E78E9A63E1DC8BC3E1DC8BC3E1CC8BC3EC3A6D23E" << "\n"; strebuf << " C2A6D23EC2A6D23E6885E83E6785E83E6885E83E0E64FE3E0D64FE3E0E64FE3E" << "\n"; strebuf << " DA3C903EDA3C903EDA3C903E801BA63E801BA63E801BA63E26FABB3E26FABB3E" << "\n"; strebuf << " 26FABB3ECBD8D13ECBD8D13ECAD8D13E70B7E73E70B7E73E70B7E73E1696FD3E" << "\n"; strebuf << " 1696FD3E1696FD3E5DBA093F5DBA093F5DBA093FB0A9143FB0A9143FB0A9143F" << "\n"; strebuf << " 2E2CBB3E2E2CBB3E2E2CBB3ED20AD13ED30AD13ED20AD13E79E9E63E79E9E63E" << "\n"; strebuf << " 78E9E63E1FC8FC3E1FC8FC3E1EC8FC3E6253093F6253093F6253093FB542143F" << "\n"; strebuf << " B542143FB542143F07321F3F07321F3F07321F3F5A212A3F5A212A3F5A212A3F" << "\n"; strebuf << " 801BE63E801BE63E801BE63E24FAFB3E25FAFB3E24FAFB3E65EC083F65EC083F" << "\n"; strebuf << " 65EC083FB8DB133FB8DB133FB8DB133F0BCB1E3F0BCB1E3F0BCB1E3F5EBA293F" << "\n"; strebuf << " 5EBA293F5EBA293FB0A9343FB0A9343FB0A9343F03993F3F03993F3F03993F3F" << "\n"; strebuf << " 6985083F6985083F6985083FBB74133FBC74133FBC74133F0F641E3F0F641E3F" << "\n"; strebuf << " 0F641E3F6253293F6253293F6253293FB442343FB442343FB442343F07323F3F" << "\n"; strebuf << " 07323F3F07323F3F5A214A3F5A214A3F5A214A3FAD10553FAD10553FAD10553F" << "\n"; strebuf << " 12FD1D3F12FD1D3F12FD1D3F64EC283F65EC283F65EC283FB8DB333FB8DB333F" << "\n"; strebuf << " B8DB333F0BCB3E3F0BCB3E3F0BCB3E3F5DBA493F5DBA493F5DBA493FB0A9543F" << "\n"; strebuf << " B0A9543FB0A9543F03995F3F03995F3F03995F3F56886A3F56886A3F56886A3F" << "\n"; strebuf << " BC74333FBC74333FBC74333F0E643E3F0F643E3F0F643E3F6153493F6253493F" << "\n"; strebuf << " 6253493FB542543FB542543FB542543F07325F3F07325F3F07325F3F5A216A3F" << "\n"; strebuf << " 5A216A3F5A216A3FAD10753FAD10753FAD10753F0000803F0000803F0000803F\"" << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << "" << "\n"; std::istringstream simple1D; simple1D.str(strebuf.str()); // Read file LocalFileFormat tester; CachedFileRcPtr cachedFile = tester.Read(simple1D); LocalCachedFileRcPtr looklut = DynamicPtrCast(cachedFile); // Check LUT size is correct OIIO_CHECK_EQUAL(looklut->lut3D->size[0], 8); OIIO_CHECK_EQUAL(looklut->lut3D->size[1], 8); OIIO_CHECK_EQUAL(looklut->lut3D->size[2], 8); // Check LUT values OIIO_CHECK_EQUAL(looklut->lut3D->lut.size(), 8*8*8*3); double cube[8 * 8 * 8 * 3] = { -0.00000, -0.00000, -0.00000, 0.04271, 0.04271, 0.04271, 0.08543, 0.08543, 0.08543, 0.12814, 0.12814, 0.12814, 0.17086, 0.17086, 0.17086, 0.21357, 0.21357, 0.21357, 0.25629, 0.25629, 0.25629, 0.29900, 0.29900, 0.29900, 0.08386, 0.08386, 0.08386, 0.12657, 0.12657, 0.12657, 0.16929, 0.16929, 0.16929, 0.21200, 0.21200, 0.21200, 0.25471, 0.25471, 0.25471, 0.29743, 0.29743, 0.29743, 0.34014, 0.34014, 0.34014, 0.38286, 0.38286, 0.38286, 0.16771, 0.16771, 0.16771, 0.21043, 0.21043, 0.21043, 0.25314, 0.25314, 0.25314, 0.29586, 0.29586, 0.29586, 0.33857, 0.33857, 0.33857, 0.38129, 0.38129, 0.38129, 0.42400, 0.42400, 0.42400, 0.46671, 0.46671, 0.46671, 0.25157, 0.25157, 0.25157, 0.29429, 0.29429, 0.29429, 0.33700, 0.33700, 0.33700, 0.37971, 0.37971, 0.37971, 0.42243, 0.42243, 0.42243, 0.46514, 0.46514, 0.46514, 0.50786, 0.50786, 0.50786, 0.55057, 0.55057, 0.55057, 0.33543, 0.33543, 0.33543, 0.37814, 0.37814, 0.37814, 0.42086, 0.42086, 0.42086, 0.46357, 0.46357, 0.46357, 0.50629, 0.50629, 0.50629, 0.54900, 0.54900, 0.54900, 0.59171, 0.59171, 0.59171, 0.63443, 0.63443, 0.63443, 0.41929, 0.41929, 0.41929, 0.46200, 0.46200, 0.46200, 0.50471, 0.50471, 0.50471, 0.54743, 0.54743, 0.54743, 0.59014, 0.59014, 0.59014, 0.63286, 0.63286, 0.63286, 0.67557, 0.67557, 0.67557, 0.71829, 0.71829, 0.71829, 0.50314, 0.50314, 0.50314, 0.54586, 0.54586, 0.54586, 0.58857, 0.58857, 0.58857, 0.63129, 0.63129, 0.63129, 0.67400, 0.67400, 0.67400, 0.71671, 0.71671, 0.71671, 0.75943, 0.75943, 0.75943, 0.80214, 0.80214, 0.80214, 0.58700, 0.58700, 0.58700, 0.62971, 0.62971, 0.62971, 0.67243, 0.67243, 0.67243, 0.71514, 0.71514, 0.71514, 0.75786, 0.75786, 0.75786, 0.80057, 0.80057, 0.80057, 0.84329, 0.84329, 0.84329, 0.88600, 0.88600, 0.88600, 0.01629, 0.01629, 0.01629, 0.05900, 0.05900, 0.05900, 0.10171, 0.10171, 0.10171, 0.14443, 0.14443, 0.14443, 0.18714, 0.18714, 0.18714, 0.22986, 0.22986, 0.22986, 0.27257, 0.27257, 0.27257, 0.31529, 0.31529, 0.31529, 0.10014, 0.10014, 0.10014, 0.14286, 0.14286, 0.14286, 0.18557, 0.18557, 0.18557, 0.22829, 0.22829, 0.22829, 0.27100, 0.27100, 0.27100, 0.31371, 0.31371, 0.31371, 0.35643, 0.35643, 0.35643, 0.39914, 0.39914, 0.39914, 0.18400, 0.18400, 0.18400, 0.22671, 0.22671, 0.22671, 0.26943, 0.26943, 0.26943, 0.31214, 0.31214, 0.31214, 0.35486, 0.35486, 0.35486, 0.39757, 0.39757, 0.39757, 0.44029, 0.44029, 0.44029, 0.48300, 0.48300, 0.48300, 0.26786, 0.26786, 0.26786, 0.31057, 0.31057, 0.31057, 0.35329, 0.35329, 0.35329, 0.39600, 0.39600, 0.39600, 0.43871, 0.43871, 0.43871, 0.48143, 0.48143, 0.48143, 0.52414, 0.52414, 0.52414, 0.56686, 0.56686, 0.56686, 0.35171, 0.35171, 0.35171, 0.39443, 0.39443, 0.39443, 0.43714, 0.43714, 0.43714, 0.47986, 0.47986, 0.47986, 0.52257, 0.52257, 0.52257, 0.56529, 0.56529, 0.56529, 0.60800, 0.60800, 0.60800, 0.65071, 0.65071, 0.65071, 0.43557, 0.43557, 0.43557, 0.47829, 0.47829, 0.47829, 0.52100, 0.52100, 0.52100, 0.56371, 0.56371, 0.56371, 0.60643, 0.60643, 0.60643, 0.64914, 0.64914, 0.64914, 0.69186, 0.69186, 0.69186, 0.73457, 0.73457, 0.73457, 0.51943, 0.51943, 0.51943, 0.56214, 0.56214, 0.56214, 0.60486, 0.60486, 0.60486, 0.64757, 0.64757, 0.64757, 0.69029, 0.69029, 0.69029, 0.73300, 0.73300, 0.73300, 0.77571, 0.77571, 0.77571, 0.81843, 0.81843, 0.81843, 0.60329, 0.60329, 0.60329, 0.64600, 0.64600, 0.64600, 0.68871, 0.68871, 0.68871, 0.73143, 0.73143, 0.73143, 0.77414, 0.77414, 0.77414, 0.81686, 0.81686, 0.81686, 0.85957, 0.85957, 0.85957, 0.90229, 0.90229, 0.90229, 0.03257, 0.03257, 0.03257, 0.07529, 0.07529, 0.07529, 0.11800, 0.11800, 0.11800, 0.16071, 0.16071, 0.16071, 0.20343, 0.20343, 0.20343, 0.24614, 0.24614, 0.24614, 0.28886, 0.28886, 0.28886, 0.33157, 0.33157, 0.33157, 0.11643, 0.11643, 0.11643, 0.15914, 0.15914, 0.15914, 0.20186, 0.20186, 0.20186, 0.24457, 0.24457, 0.24457, 0.28729, 0.28729, 0.28729, 0.33000, 0.33000, 0.33000, 0.37271, 0.37271, 0.37271, 0.41543, 0.41543, 0.41543, 0.20029, 0.20029, 0.20029, 0.24300, 0.24300, 0.24300, 0.28571, 0.28571, 0.28571, 0.32843, 0.32843, 0.32843, 0.37114, 0.37114, 0.37114, 0.41386, 0.41386, 0.41386, 0.45657, 0.45657, 0.45657, 0.49929, 0.49929, 0.49929, 0.28414, 0.28414, 0.28414, 0.32686, 0.32686, 0.32686, 0.36957, 0.36957, 0.36957, 0.41229, 0.41229, 0.41229, 0.45500, 0.45500, 0.45500, 0.49771, 0.49771, 0.49771, 0.54043, 0.54043, 0.54043, 0.58314, 0.58314, 0.58314, 0.36800, 0.36800, 0.36800, 0.41071, 0.41071, 0.41071, 0.45343, 0.45343, 0.45343, 0.49614, 0.49614, 0.49614, 0.53886, 0.53886, 0.53886, 0.58157, 0.58157, 0.58157, 0.62429, 0.62429, 0.62429, 0.66700, 0.66700, 0.66700, 0.45186, 0.45186, 0.45186, 0.49457, 0.49457, 0.49457, 0.53729, 0.53729, 0.53729, 0.58000, 0.58000, 0.58000, 0.62271, 0.62271, 0.62271, 0.66543, 0.66543, 0.66543, 0.70814, 0.70814, 0.70814, 0.75086, 0.75086, 0.75086, 0.53571, 0.53571, 0.53571, 0.57843, 0.57843, 0.57843, 0.62114, 0.62114, 0.62114, 0.66386, 0.66386, 0.66386, 0.70657, 0.70657, 0.70657, 0.74929, 0.74929, 0.74929, 0.79200, 0.79200, 0.79200, 0.83471, 0.83471, 0.83471, 0.61957, 0.61957, 0.61957, 0.66229, 0.66229, 0.66229, 0.70500, 0.70500, 0.70500, 0.74771, 0.74771, 0.74771, 0.79043, 0.79043, 0.79043, 0.83314, 0.83314, 0.83314, 0.87586, 0.87586, 0.87586, 0.91857, 0.91857, 0.91857, 0.04886, 0.04886, 0.04886, 0.09157, 0.09157, 0.09157, 0.13429, 0.13429, 0.13429, 0.17700, 0.17700, 0.17700, 0.21971, 0.21971, 0.21971, 0.26243, 0.26243, 0.26243, 0.30514, 0.30514, 0.30514, 0.34786, 0.34786, 0.34786, 0.13271, 0.13271, 0.13271, 0.17543, 0.17543, 0.17543, 0.21814, 0.21814, 0.21814, 0.26086, 0.26086, 0.26086, 0.30357, 0.30357, 0.30357, 0.34629, 0.34629, 0.34629, 0.38900, 0.38900, 0.38900, 0.43171, 0.43171, 0.43171, 0.21657, 0.21657, 0.21657, 0.25929, 0.25929, 0.25929, 0.30200, 0.30200, 0.30200, 0.34471, 0.34471, 0.34471, 0.38743, 0.38743, 0.38743, 0.43014, 0.43014, 0.43014, 0.47286, 0.47286, 0.47286, 0.51557, 0.51557, 0.51557, 0.30043, 0.30043, 0.30043, 0.34314, 0.34314, 0.34314, 0.38586, 0.38586, 0.38586, 0.42857, 0.42857, 0.42857, 0.47129, 0.47129, 0.47129, 0.51400, 0.51400, 0.51400, 0.55671, 0.55671, 0.55671, 0.59943, 0.59943, 0.59943, 0.38429, 0.38429, 0.38429, 0.42700, 0.42700, 0.42700, 0.46971, 0.46971, 0.46971, 0.51243, 0.51243, 0.51243, 0.55514, 0.55514, 0.55514, 0.59786, 0.59786, 0.59786, 0.64057, 0.64057, 0.64057, 0.68329, 0.68329, 0.68329, 0.46814, 0.46814, 0.46814, 0.51086, 0.51086, 0.51086, 0.55357, 0.55357, 0.55357, 0.59629, 0.59629, 0.59629, 0.63900, 0.63900, 0.63900, 0.68171, 0.68171, 0.68171, 0.72443, 0.72443, 0.72443, 0.76714, 0.76714, 0.76714, 0.55200, 0.55200, 0.55200, 0.59471, 0.59471, 0.59471, 0.63743, 0.63743, 0.63743, 0.68014, 0.68014, 0.68014, 0.72286, 0.72286, 0.72286, 0.76557, 0.76557, 0.76557, 0.80829, 0.80829, 0.80829, 0.85100, 0.85100, 0.85100, 0.63586, 0.63586, 0.63586, 0.67857, 0.67857, 0.67857, 0.72129, 0.72129, 0.72129, 0.76400, 0.76400, 0.76400, 0.80671, 0.80671, 0.80671, 0.84943, 0.84943, 0.84943, 0.89214, 0.89214, 0.89214, 0.93486, 0.93486, 0.93486, 0.06514, 0.06514, 0.06514, 0.10786, 0.10786, 0.10786, 0.15057, 0.15057, 0.15057, 0.19329, 0.19329, 0.19329, 0.23600, 0.23600, 0.23600, 0.27871, 0.27871, 0.27871, 0.32143, 0.32143, 0.32143, 0.36414, 0.36414, 0.36414, 0.14900, 0.14900, 0.14900, 0.19171, 0.19171, 0.19171, 0.23443, 0.23443, 0.23443, 0.27714, 0.27714, 0.27714, 0.31986, 0.31986, 0.31986, 0.36257, 0.36257, 0.36257, 0.40529, 0.40529, 0.40529, 0.44800, 0.44800, 0.44800, 0.23286, 0.23286, 0.23286, 0.27557, 0.27557, 0.27557, 0.31829, 0.31829, 0.31829, 0.36100, 0.36100, 0.36100, 0.40371, 0.40371, 0.40371, 0.44643, 0.44643, 0.44643, 0.48914, 0.48914, 0.48914, 0.53186, 0.53186, 0.53186, 0.31671, 0.31671, 0.31671, 0.35943, 0.35943, 0.35943, 0.40214, 0.40214, 0.40214, 0.44486, 0.44486, 0.44486, 0.48757, 0.48757, 0.48757, 0.53029, 0.53029, 0.53029, 0.57300, 0.57300, 0.57300, 0.61571, 0.61571, 0.61571, 0.40057, 0.40057, 0.40057, 0.44329, 0.44329, 0.44329, 0.48600, 0.48600, 0.48600, 0.52871, 0.52871, 0.52871, 0.57143, 0.57143, 0.57143, 0.61414, 0.61414, 0.61414, 0.65686, 0.65686, 0.65686, 0.69957, 0.69957, 0.69957, 0.48443, 0.48443, 0.48443, 0.52714, 0.52714, 0.52714, 0.56986, 0.56986, 0.56986, 0.61257, 0.61257, 0.61257, 0.65529, 0.65529, 0.65529, 0.69800, 0.69800, 0.69800, 0.74071, 0.74071, 0.74071, 0.78343, 0.78343, 0.78343, 0.56829, 0.56829, 0.56829, 0.61100, 0.61100, 0.61100, 0.65371, 0.65371, 0.65371, 0.69643, 0.69643, 0.69643, 0.73914, 0.73914, 0.73914, 0.78186, 0.78186, 0.78186, 0.82457, 0.82457, 0.82457, 0.86729, 0.86729, 0.86729, 0.65214, 0.65214, 0.65214, 0.69486, 0.69486, 0.69486, 0.73757, 0.73757, 0.73757, 0.78029, 0.78029, 0.78029, 0.82300, 0.82300, 0.82300, 0.86571, 0.86571, 0.86571, 0.90843, 0.90843, 0.90843, 0.95114, 0.95114, 0.95114, 0.08143, 0.08143, 0.08143, 0.12414, 0.12414, 0.12414, 0.16686, 0.16686, 0.16686, 0.20957, 0.20957, 0.20957, 0.25229, 0.25229, 0.25229, 0.29500, 0.29500, 0.29500, 0.33771, 0.33771, 0.33771, 0.38043, 0.38043, 0.38043, 0.16529, 0.16529, 0.16529, 0.20800, 0.20800, 0.20800, 0.25071, 0.25071, 0.25071, 0.29343, 0.29343, 0.29343, 0.33614, 0.33614, 0.33614, 0.37886, 0.37886, 0.37886, 0.42157, 0.42157, 0.42157, 0.46429, 0.46429, 0.46429, 0.24914, 0.24914, 0.24914, 0.29186, 0.29186, 0.29186, 0.33457, 0.33457, 0.33457, 0.37729, 0.37729, 0.37729, 0.42000, 0.42000, 0.42000, 0.46271, 0.46271, 0.46271, 0.50543, 0.50543, 0.50543, 0.54814, 0.54814, 0.54814, 0.33300, 0.33300, 0.33300, 0.37571, 0.37571, 0.37571, 0.41843, 0.41843, 0.41843, 0.46114, 0.46114, 0.46114, 0.50386, 0.50386, 0.50386, 0.54657, 0.54657, 0.54657, 0.58929, 0.58929, 0.58929, 0.63200, 0.63200, 0.63200, 0.41686, 0.41686, 0.41686, 0.45957, 0.45957, 0.45957, 0.50229, 0.50229, 0.50229, 0.54500, 0.54500, 0.54500, 0.58771, 0.58771, 0.58771, 0.63043, 0.63043, 0.63043, 0.67314, 0.67314, 0.67314, 0.71586, 0.71586, 0.71586, 0.50071, 0.50071, 0.50071, 0.54343, 0.54343, 0.54343, 0.58614, 0.58614, 0.58614, 0.62886, 0.62886, 0.62886, 0.67157, 0.67157, 0.67157, 0.71429, 0.71429, 0.71429, 0.75700, 0.75700, 0.75700, 0.79971, 0.79971, 0.79971, 0.58457, 0.58457, 0.58457, 0.62729, 0.62729, 0.62729, 0.67000, 0.67000, 0.67000, 0.71271, 0.71271, 0.71271, 0.75543, 0.75543, 0.75543, 0.79814, 0.79814, 0.79814, 0.84086, 0.84086, 0.84086, 0.88357, 0.88357, 0.88357, 0.66843, 0.66843, 0.66843, 0.71114, 0.71114, 0.71114, 0.75386, 0.75386, 0.75386, 0.79657, 0.79657, 0.79657, 0.83929, 0.83929, 0.83929, 0.88200, 0.88200, 0.88200, 0.92471, 0.92471, 0.92471, 0.96743, 0.96743, 0.96743, 0.09771, 0.09771, 0.09771, 0.14043, 0.14043, 0.14043, 0.18314, 0.18314, 0.18314, 0.22586, 0.22586, 0.22586, 0.26857, 0.26857, 0.26857, 0.31129, 0.31129, 0.31129, 0.35400, 0.35400, 0.35400, 0.39671, 0.39671, 0.39671, 0.18157, 0.18157, 0.18157, 0.22429, 0.22429, 0.22429, 0.26700, 0.26700, 0.26700, 0.30971, 0.30971, 0.30971, 0.35243, 0.35243, 0.35243, 0.39514, 0.39514, 0.39514, 0.43786, 0.43786, 0.43786, 0.48057, 0.48057, 0.48057, 0.26543, 0.26543, 0.26543, 0.30814, 0.30814, 0.30814, 0.35086, 0.35086, 0.35086, 0.39357, 0.39357, 0.39357, 0.43629, 0.43629, 0.43629, 0.47900, 0.47900, 0.47900, 0.52171, 0.52171, 0.52171, 0.56443, 0.56443, 0.56443, 0.34929, 0.34929, 0.34929, 0.39200, 0.39200, 0.39200, 0.43471, 0.43471, 0.43471, 0.47743, 0.47743, 0.47743, 0.52014, 0.52014, 0.52014, 0.56286, 0.56286, 0.56286, 0.60557, 0.60557, 0.60557, 0.64829, 0.64829, 0.64829, 0.43314, 0.43314, 0.43314, 0.47586, 0.47586, 0.47586, 0.51857, 0.51857, 0.51857, 0.56129, 0.56129, 0.56129, 0.60400, 0.60400, 0.60400, 0.64671, 0.64671, 0.64671, 0.68943, 0.68943, 0.68943, 0.73214, 0.73214, 0.73214, 0.51700, 0.51700, 0.51700, 0.55971, 0.55971, 0.55971, 0.60243, 0.60243, 0.60243, 0.64514, 0.64514, 0.64514, 0.68786, 0.68786, 0.68786, 0.73057, 0.73057, 0.73057, 0.77329, 0.77329, 0.77329, 0.81600, 0.81600, 0.81600, 0.60086, 0.60086, 0.60086, 0.64357, 0.64357, 0.64357, 0.68629, 0.68629, 0.68629, 0.72900, 0.72900, 0.72900, 0.77171, 0.77171, 0.77171, 0.81443, 0.81443, 0.81443, 0.85714, 0.85714, 0.85714, 0.89986, 0.89986, 0.89986, 0.68471, 0.68471, 0.68471, 0.72743, 0.72743, 0.72743, 0.77014, 0.77014, 0.77014, 0.81286, 0.81286, 0.81286, 0.85557, 0.85557, 0.85557, 0.89829, 0.89829, 0.89829, 0.94100, 0.94100, 0.94100, 0.98371, 0.98371, 0.98371, 0.11400, 0.11400, 0.11400, 0.15671, 0.15671, 0.15671, 0.19943, 0.19943, 0.19943, 0.24214, 0.24214, 0.24214, 0.28486, 0.28486, 0.28486, 0.32757, 0.32757, 0.32757, 0.37029, 0.37029, 0.37029, 0.41300, 0.41300, 0.41300, 0.19786, 0.19786, 0.19786, 0.24057, 0.24057, 0.24057, 0.28329, 0.28329, 0.28329, 0.32600, 0.32600, 0.32600, 0.36871, 0.36871, 0.36871, 0.41143, 0.41143, 0.41143, 0.45414, 0.45414, 0.45414, 0.49686, 0.49686, 0.49686, 0.28171, 0.28171, 0.28171, 0.32443, 0.32443, 0.32443, 0.36714, 0.36714, 0.36714, 0.40986, 0.40986, 0.40986, 0.45257, 0.45257, 0.45257, 0.49529, 0.49529, 0.49529, 0.53800, 0.53800, 0.53800, 0.58071, 0.58071, 0.58071, 0.36557, 0.36557, 0.36557, 0.40829, 0.40829, 0.40829, 0.45100, 0.45100, 0.45100, 0.49371, 0.49371, 0.49371, 0.53643, 0.53643, 0.53643, 0.57914, 0.57914, 0.57914, 0.62186, 0.62186, 0.62186, 0.66457, 0.66457, 0.66457, 0.44943, 0.44943, 0.44943, 0.49214, 0.49214, 0.49214, 0.53486, 0.53486, 0.53486, 0.57757, 0.57757, 0.57757, 0.62029, 0.62029, 0.62029, 0.66300, 0.66300, 0.66300, 0.70571, 0.70571, 0.70571, 0.74843, 0.74843, 0.74843, 0.53329, 0.53329, 0.53329, 0.57600, 0.57600, 0.57600, 0.61871, 0.61871, 0.61871, 0.66143, 0.66143, 0.66143, 0.70414, 0.70414, 0.70414, 0.74686, 0.74686, 0.74686, 0.78957, 0.78957, 0.78957, 0.83229, 0.83229, 0.83229, 0.61714, 0.61714, 0.61714, 0.65986, 0.65986, 0.65986, 0.70257, 0.70257, 0.70257, 0.74529, 0.74529, 0.74529, 0.78800, 0.78800, 0.78800, 0.83071, 0.83071, 0.83071, 0.87343, 0.87343, 0.87343, 0.91614, 0.91614, 0.91614, 0.70100, 0.70100, 0.70100, 0.74371, 0.74371, 0.74371, 0.78643, 0.78643, 0.78643, 0.82914, 0.82914, 0.82914, 0.87186, 0.87186, 0.87186, 0.91457, 0.91457, 0.91457, 0.95729, 0.95729, 0.95729, 1.00000, 1.00000, 1.00000 }; // check cube data for(unsigned int i = 0; i < looklut->lut3D->lut.size(); ++i) { OIIO_CHECK_CLOSE(cube[i], looklut->lut3D->lut[i], 1e-4); } } OIIO_ADD_TEST(FileFormatIridasLook, fail_on_mask) { std::ostringstream strebuf; strebuf << "" << "\n"; strebuf << "" << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " \"2\"" << "\n"; strebuf << " \"1\"" << "\n"; strebuf << " " << "\n"; strebuf << " \"1\"" << "\n"; strebuf << " " << "\n"; strebuf << " \"N1\"" << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " \"1\"" << "\n"; strebuf << " " << "\n"; strebuf << " \"0.49967\"" << "\n"; strebuf << " \"0.28739\"" << "\n"; strebuf << " \"0.49179\"" << "\n"; strebuf << " \"0.22243\"" << "\n"; strebuf << " \"0.34531\"" << "\n"; strebuf << " \"0.39388\"" << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " \"Untitled00_00_00_00\"" << "\n"; strebuf << " \"0\"" << "\n"; strebuf << " \"1024\"" << "\n"; strebuf << " \"778\"" << "\n"; strebuf << " " << "\n"; strebuf << " \"1\"" << "\n"; strebuf << " " << "\n"; strebuf << " \"catmull-rom,value:317.5,583.5@0\"" << "\n"; strebuf << " \"catmull-rom,value:0,0@0\"" << "\n"; strebuf << " \"catmull-rom,value:0,0@0\"" << "\n"; strebuf << " \"catmull-rom,value:1@0\"" << "\n"; strebuf << " \"catmull-rom,value:0.5@0\"" << "\n"; strebuf << " linear,value:0@0" << "\n"; strebuf << " \"catmull-rom,value:317.5,583.5@0\"" << "\n"; strebuf << " \"catmull-rom,value:0,0@0\"" << "\n"; strebuf << " \"catmull-rom,value:0,0@0\"" << "\n"; strebuf << " \"linear,value:0@0\"" << "\n"; strebuf << " \"linear,value:0@0\"" << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << " \"8\"" << "\n"; strebuf << " \"" << "\n"; strebuf << " 000000000000000000000000878B933D000000000000000057BC563E00000000" << "\n"; strebuf << " ...truncated, should never be parsed due to mask section\"" << "\n"; strebuf << " " << "\n"; strebuf << " " << "\n"; strebuf << "" << "\n"; std::istringstream infile; infile.str(strebuf.str()); // Read file LocalFileFormat tester; try { CachedFileRcPtr cachedFile = tester.Read(infile); OIIO_CHECK_ASSERT(false); // Fail test if previous line doesn't throw Exception } catch(Exception& e) { // Check exception message is correct error (not something // like "cannot parse LUT data") std::string expected_error = "Cannot load .look LUT containing mask"; OIIO_CHECK_EQUAL(e.what(), expected_error); } } #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/TruelightOp.h0000644000175000017500000000355113223553423020430 0ustar mfvmfv/* 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_OCIO_TRUELIGHTOP_H #define INCLUDED_OCIO_TRUELIGHTOP_H #include #include "Op.h" OCIO_NAMESPACE_ENTER { void CreateTruelightOps(OpRcPtrVec & ops, const TruelightTransform & data, TransformDirection dir); } OCIO_NAMESPACE_EXIT #endif // INCLUDED_OCIO_TRUELIGHTOP_H opencolorio-1.1.0~dfsg0.orig/src/core/PrivateTypes.h0000644000175000017500000000425713223553423020625 0ustar mfvmfv/* 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_OCIO_PRIVATE_TYPES_H #define INCLUDED_OCIO_PRIVATE_TYPES_H #include #include #include #include OCIO_NAMESPACE_ENTER { // Stl types of OCIO classes typedef std::map StringMap; typedef std::map StringBoolMap; typedef std::vector StringVec; typedef std::set StringSet; typedef std::vector ConstTransformVec; typedef std::vector ColorSpaceVec; typedef std::vector LookVec; typedef std::vector TransformDirectionVec; } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/TruelightTransform.cpp0000644000175000017500000002632013223553423022357 0ustar mfvmfv/* 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 #include #include "OpBuilders.h" #include "TruelightOp.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { TruelightTransformRcPtr TruelightTransform::Create() { return TruelightTransformRcPtr(new TruelightTransform(), &deleter); } void TruelightTransform::deleter(TruelightTransform* t) { delete t; } class TruelightTransform::Impl { public: TransformDirection dir_; std::string configroot_; std::string profile_; std::string camera_; std::string inputdisplay_; std::string recorder_; std::string print_; std::string lamp_; std::string outputcamera_; std::string display_; std::string cubeinput_; Impl() : dir_(TRANSFORM_DIR_FORWARD) { } ~Impl() { } Impl& operator= (const Impl & rhs) { dir_ = rhs.dir_; configroot_ = rhs.configroot_; profile_ = rhs.profile_; camera_ = rhs.camera_; inputdisplay_ = rhs.inputdisplay_; recorder_ = rhs.recorder_; print_ = rhs.print_; lamp_ = rhs.lamp_; outputcamera_ = rhs.outputcamera_; display_ = rhs.display_; cubeinput_ = rhs.cubeinput_; return *this; } }; /////////////////////////////////////////////////////////////////////////// TruelightTransform::TruelightTransform() : m_impl(new TruelightTransform::Impl) { getImpl()->configroot_ = "/usr/fl/truelight"; getImpl()->profile_ = ""; getImpl()->camera_ = ""; getImpl()->inputdisplay_ = ""; getImpl()->recorder_ = ""; getImpl()->print_ = ""; getImpl()->lamp_ = ""; getImpl()->outputcamera_ = ""; getImpl()->display_ = ""; getImpl()->cubeinput_ = "log"; } TransformRcPtr TruelightTransform::createEditableCopy() const { TruelightTransformRcPtr transform = TruelightTransform::Create(); *(transform->m_impl) = *m_impl; return transform; } TruelightTransform::~TruelightTransform() { delete m_impl; m_impl = NULL; } TruelightTransform& TruelightTransform::operator= (const TruelightTransform & rhs) { *m_impl = *rhs.m_impl; return *this; } TransformDirection TruelightTransform::getDirection() const { return getImpl()->dir_; } void TruelightTransform::setDirection(TransformDirection dir) { getImpl()->dir_ = dir; } void TruelightTransform::setConfigRoot(const char * configroot) { getImpl()->configroot_ = configroot; } const char * TruelightTransform::getConfigRoot() const { return getImpl()->configroot_.c_str(); } void TruelightTransform::setProfile(const char * profile) { getImpl()->profile_ = profile; } const char * TruelightTransform::getProfile() const { return getImpl()->profile_.c_str(); } void TruelightTransform::setCamera(const char * camera) { getImpl()->camera_ = camera; } const char * TruelightTransform::getCamera() const { return getImpl()->camera_.c_str(); } void TruelightTransform::setInputDisplay(const char * display) { getImpl()->inputdisplay_ = display; } const char * TruelightTransform::getInputDisplay() const { return getImpl()->inputdisplay_.c_str(); } void TruelightTransform::setRecorder(const char * recorder) { getImpl()->recorder_ = recorder; } const char * TruelightTransform::getRecorder() const { return getImpl()->recorder_.c_str(); } void TruelightTransform::setPrint(const char * print) { getImpl()->print_ = print; } const char * TruelightTransform::getPrint() const { return getImpl()->print_.c_str(); } void TruelightTransform::setLamp(const char * lamp) { getImpl()->lamp_ = lamp; } const char * TruelightTransform::getLamp() const { return getImpl()->lamp_.c_str(); } void TruelightTransform::setOutputCamera(const char * camera) { getImpl()->outputcamera_ = camera; } const char * TruelightTransform::getOutputCamera() const { return getImpl()->outputcamera_.c_str(); } void TruelightTransform::setDisplay(const char * display) { getImpl()->display_ = display; } const char * TruelightTransform::getDisplay() const { return getImpl()->display_.c_str(); } void TruelightTransform::setCubeInput(const char * cubeinput) { getImpl()->cubeinput_ = pystring::lower(cubeinput); } const char * TruelightTransform::getCubeInput() const { return getImpl()->cubeinput_.c_str(); } std::ostream& operator<< (std::ostream& os, const TruelightTransform& t) { os << ""; return os; } /////////////////////////////////////////////////////////////////////////// void BuildTruelightOps(OpRcPtrVec & ops, const Config& /*config*/, const TruelightTransform & transform, TransformDirection dir) { TransformDirection combinedDir = CombineTransformDirections(dir, transform.getDirection()); CreateTruelightOps(ops, transform, combinedDir); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" OIIO_ADD_TEST(TruelightTransform, simpletest) { OCIO::ConfigRcPtr config = OCIO::Config::Create(); { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("log"); cs->setFamily("log"); config->addColorSpace(cs); config->setRole(OCIO::ROLE_COMPOSITING_LOG, cs->getName()); } { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("sRGB"); cs->setFamily("srgb"); OCIO::TruelightTransformRcPtr transform1 = OCIO::TruelightTransform::Create(); transform1->setConfigRoot("/usr/fl/truelight"); transform1->setPrint("internal-LowContrast"); //transform1->setInputDisplay("DCIrgb"); transform1->setDisplay("sRGB"); transform1->setCubeInput("log"); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_FROM_REFERENCE); config->addColorSpace(cs); } // check the transform round trip OCIO::ConstProcessorRcPtr tosrgb; OCIO::ConstProcessorRcPtr tolog; #ifdef OCIO_TRUELIGHT_SUPPORT OIIO_CHECK_NO_THROW(tosrgb = config->getProcessor("log", "sRGB")); OIIO_CHECK_NO_THROW(tolog = config->getProcessor("sRGB", "log")); #else OIIO_CHECK_THROW(tosrgb = config->getProcessor("log", "sRGB"), OCIO::Exception); OIIO_CHECK_THROW(tolog = config->getProcessor("sRGB", "log"), OCIO::Exception); #endif #ifdef OCIO_TRUELIGHT_SUPPORT float input[3] = {0.5f, 0.5f, 0.5f}; float output[3] = {0.500098f, 0.500317f, 0.501134f}; OIIO_CHECK_NO_THROW(tosrgb->applyRGB(input)); OIIO_CHECK_NO_THROW(tolog->applyRGB(input)); OIIO_CHECK_CLOSE(input[0], output[0], 1e-4); OIIO_CHECK_CLOSE(input[1], output[1], 1e-4); OIIO_CHECK_CLOSE(input[2], output[2], 1e-4); #endif std::ostringstream os; OIIO_CHECK_NO_THROW(config->serialize(os)); std::string referenceconfig = "ocio_profile_version: 1\n" "\n" "search_path: \"\"\n" "strictparsing: true\n" "luma: [0.2126, 0.7152, 0.0722]\n" "\n" "roles:\n" " compositing_log: log\n" "\n" "displays:\n" " {}\n" "\n" "active_displays: []\n" "active_views: []\n" "\n" "colorspaces:\n" " - !\n" " name: log\n" " family: log\n" " equalitygroup: \"\"\n" " bitdepth: unknown\n" " isdata: false\n" " allocation: uniform\n" "\n" " - !\n" " name: sRGB\n" " family: srgb\n" " equalitygroup: \"\"\n" " bitdepth: unknown\n" " isdata: false\n" " allocation: uniform\n" " from_reference: ! {config_root: /usr/fl/truelight, print: internal-LowContrast, display: sRGB, cube_input: log}\n"; std::vector osvec; OCIO::pystring::splitlines(os.str(), osvec); std::vector referenceconfigvec; OCIO::pystring::splitlines(referenceconfig, referenceconfigvec); OIIO_CHECK_EQUAL(osvec.size(), referenceconfigvec.size()); for(unsigned int i = 0; i < referenceconfigvec.size(); ++i) OIIO_CHECK_EQUAL(osvec[i], referenceconfigvec[i]); std::istringstream is; is.str(referenceconfig); OCIO::ConstConfigRcPtr rtconfig; OIIO_CHECK_NO_THROW(rtconfig = OCIO::Config::CreateFromStream(is)); } #endif // OCIO_BUILD_TESTS opencolorio-1.1.0~dfsg0.orig/src/core/HashUtils.h0000644000175000017500000000360213223553423020063 0ustar mfvmfv/* 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_OCIO_HASHUTILS_H #define INCLUDED_OCIO_HASHUTILS_H #include #include "md5/md5.h" #include OCIO_NAMESPACE_ENTER { std::string CacheIDHash(const char * array, int size); // TODO: get rid of md5.h include, make this a generic byte array std::string GetPrintableHash(const md5_byte_t * digest); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/GpuShaderUtils.h0000644000175000017500000000500313223553423021057 0ustar mfvmfv/* 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_OCIO_GPUSHADERUTILS_H #define INCLUDED_OCIO_GPUSHADERUTILS_H #include #include OCIO_NAMESPACE_ENTER { std::string GpuTextHalf4x4(const float * m44, GpuLanguage lang); std::string GpuTextHalf4(const float * v4, GpuLanguage lang); std::string GpuTextHalf3(const float * v3, GpuLanguage lang); void Write_mtx_x_vec(std::ostream & os, const std::string & mtx, const std::string & vec, GpuLanguage lang); void Write_half4x4(std::ostream & os, const float * m44, GpuLanguage lang); void Write_half4(std::ostream & os, const float * v4, GpuLanguage lang); void Write_half3(std::ostream & os, const float * v3, GpuLanguage lang); // returns vec3 void Write_sampleLut3D_rgb(std::ostream & os, const std::string & variableName, const std::string & lutName, int lut3DEdgeLen, GpuLanguage lang); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/pystring/0000755000175000017500000000000013223553423017664 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/core/pystring/pystring.h0000644000175000017500000005602313223553423021722 0ustar mfvmfv/////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2008-2010, Sony Pictures Imageworks Inc // 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 the organization 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_OCIO_PYSTRING_H #define INCLUDED_OCIO_PYSTRING_H #include #include #include OCIO_NAMESPACE_ENTER { // Version 1.1.2 // https://github.com/imageworks/pystring/tarball/v1.1.2 namespace pystring { ////////////////////////////////////////////////////////////////////////////////////////////// /// @mainpage pystring /// /// This is a set of functions matching the interface and behaviors of python string methods /// (as of python 2.3) using std::string. /// /// Overlapping functionality ( such as index and slice/substr ) of std::string is included /// to match python interfaces. /// ////////////////////////////////////////////////////////////////////////////////////////////// /// @defgroup functions pystring /// @{ #define MAX_32BIT_INT 2147483647 ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with only its first character capitalized. /// std::string capitalize( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return centered in a string of length width. Padding is done using spaces. /// std::string center( const std::string & str, int width ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the number of occurrences of substring sub in string S[start:end]. Optional /// arguments start and end are interpreted as in slice notation. /// int count( const std::string & str, const std::string & substr, int start = 0, int end = MAX_32BIT_INT); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return True if the string ends with the specified suffix, otherwise return False. With /// optional start, test beginning at that position. With optional end, stop comparing at that position. /// bool endswith( const std::string & str, const std::string & suffix, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string where all tab characters are expanded using spaces. If tabsize /// is not given, a tab size of 8 characters is assumed. /// std::string expandtabs( const std::string & str, int tabsize = 8); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the lowest index in the string where substring sub is found, such that sub is /// contained in the range [start, end). Optional arguments start and end are interpreted as /// in slice notation. Return -1 if sub is not found. /// int find( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Synonym of find right now. Python version throws exceptions. This one currently doesn't /// int index( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all characters in the string are alphanumeric and there is at least one /// character, false otherwise. /// bool isalnum( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all characters in the string are alphabetic and there is at least one /// character, false otherwise /// bool isalpha( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all characters in the string are digits and there is at least one /// character, false otherwise. /// bool isdigit( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all cased characters in the string are lowercase and there is at least one /// cased character, false otherwise. /// bool islower( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if there are only whitespace characters in the string and there is at least /// one character, false otherwise. /// bool isspace( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if the string is a titlecased string and there is at least one character, /// i.e. uppercase characters may only follow uncased characters and lowercase characters only /// cased ones. Return false otherwise. /// bool istitle( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all cased characters in the string are uppercase and there is at least one /// cased character, false otherwise. /// bool isupper( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a string which is the concatenation of the strings in the sequence seq. /// The separator between elements is the str argument /// std::string join( const std::string & str, const std::vector< std::string > & seq ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the string left justified in a string of length width. Padding is done using /// spaces. The original string is returned if width is less than str.size(). /// std::string ljust( const std::string & str, int width ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string converted to lowercase. /// std::string lower( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with leading characters removed. If chars is omitted or None, /// whitespace characters are removed. If given and not "", chars must be a string; the /// characters in the string will be stripped from the beginning of the string this method /// is called on (argument "str" ). /// std::string lstrip( const std::string & str, const std::string & chars = "" ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string, concatenated N times, together. /// Corresponds to the __mul__ operator. /// std::string mul( const std::string & str, int n); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the string around first occurance of sep. /// Three strings will always placed into result. If sep is found, the strings will /// be the text before sep, sep itself, and the remaining text. If sep is /// not found, the original string will be returned with two empty strings. /// void partition( const std::string & str, const std::string & sep, std::vector< std::string > & result ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with all occurrences of substring old replaced by new. If /// the optional argument count is given, only the first count occurrences are replaced. /// std::string replace( const std::string & str, const std::string & oldstr, const std::string & newstr, int count = -1); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the highest index in the string where substring sub is found, such that sub is /// contained within s[start,end]. Optional arguments start and end are interpreted as in /// slice notation. Return -1 on failure. /// int rfind( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Currently a synonym of rfind. The python version raises exceptions. This one currently /// does not /// int rindex( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the string right justified in a string of length width. Padding is done using /// spaces. The original string is returned if width is less than str.size(). /// std::string rjust( const std::string & str, int width); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the string around last occurance of sep. /// Three strings will always placed into result. If sep is found, the strings will /// be the text before sep, sep itself, and the remaining text. If sep is /// not found, the original string will be returned with two empty strings. /// void rpartition( const std::string & str, const std::string & sep, std::vector< std::string > & result ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with trailing characters removed. If chars is "", whitespace /// characters are removed. If not "", the characters in the string will be stripped from the /// end of the string this method is called on. /// std::string rstrip( const std::string & str, const std::string & chars = "" ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Fills the "result" list with the words in the string, using sep as the delimiter string. /// If maxsplit is > -1, at most maxsplit splits are done. If sep is "", /// any whitespace string is a separator. /// void split( const std::string & str, std::vector< std::string > & result, const std::string & sep = "", int maxsplit = -1); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Fills the "result" list with the words in the string, using sep as the delimiter string. /// Does a number of splits starting at the end of the string, the result still has the /// split strings in their original order. /// If maxsplit is > -1, at most maxsplit splits are done. If sep is "", /// any whitespace string is a separator. /// void rsplit( const std::string & str, std::vector< std::string > & result, const std::string & sep = "", int maxsplit = -1); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a list of the lines in the string, breaking at line boundaries. Line breaks /// are not included in the resulting list unless keepends is given and true. /// void splitlines( const std::string & str, std::vector< std::string > & result, bool keepends = false ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return True if string starts with the prefix, otherwise return False. With optional start, /// test string beginning at that position. With optional end, stop comparing string at that /// position /// bool startswith( const std::string & str, const std::string & prefix, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with leading and trailing characters removed. If chars is "", /// whitespace characters are removed. If given not "", the characters in the string will be /// stripped from the both ends of the string this method is called on. /// std::string strip( const std::string & str, const std::string & chars = "" ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with uppercase characters converted to lowercase and vice versa. /// std::string swapcase( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a titlecased version of the string: words start with uppercase characters, /// all remaining cased characters are lowercase. /// std::string title( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string where all characters occurring in the optional argument /// deletechars are removed, and the remaining characters have been mapped through the given /// translation table, which must be a string of length 256. /// std::string translate( const std::string & str, const std::string & table, const std::string & deletechars = ""); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string converted to uppercase. /// std::string upper( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the numeric string left filled with zeros in a string of length width. The original /// string is returned if width is less than str.size(). /// std::string zfill( const std::string & str, int width ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief function matching python's slice functionality. /// std::string slice( const std::string & str, int start = 0, int end = MAX_32BIT_INT); /// /// @ } /// namespace os { namespace path { // All of the function below have three versions. // Example: // join(...) // join_nt(...) // join_posix(...) // // The regular function dispatches to the other versions - based on the OS // at compile time - to match the result you'd get from the python // interepreter on the same operating system // // Should you want to 'lock off' to a particular version of the string // manipulation across *all* operating systems, use the version with the // _OS you are interested in. I.e., you can use posix style path joining, // even on Windows, with join_posix. // // The naming, (nt, posix) matches the cpython source implementation. ////////////////////////////////////////////////////////////////////////////////////////////// /// @defgroup functions pystring::os::path /// @{ ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the base name of pathname path. This is the second half of the pair returned /// by split(path). Note that the result of this function is different from the Unix basename /// program; where basename for '/foo/bar/' returns 'bar', the basename() function returns an /// empty string (''). std::string basename(const std::string & path); std::string basename_nt(const std::string & path); std::string basename_posix(const std::string & path); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the directory name of pathname path. This is the first half of the pair /// returned by split(path). std::string dirname(const std::string & path); std::string dirname_nt(const std::string & path); std::string dirname_posix(const std::string & path); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return True if path is an absolute pathname. On Unix, that means it begins with a /// slash, on Windows that it begins with a (back)slash after chopping off a potential drive /// letter. bool isabs(const std::string & path); bool isabs_nt(const std::string & path); bool isabs_posix(const std::string & s); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a normalized absolutized version of the pathname path. /// /// NOTE: This differs from the interface of the python equivalent in that it requires you /// to pass in the current working directory as an argument. std::string abspath(const std::string & path, const std::string & cwd); std::string abspath_nt(const std::string & path, const std::string & cwd); std::string abspath_posix(const std::string & path, const std::string & cwd); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Join one or more path components intelligently. If any component is an absolute /// path, all previous components (on Windows, including the previous drive letter, if there /// was one) are thrown away, and joining continues. The return value is the concatenation of /// path1, and optionally path2, etc., with exactly one directory separator (os.sep) inserted /// between components, unless path2 is empty. Note that on Windows, since there is a current /// directory for each drive, os.path.join("c:", "foo") represents a path relative to the /// current directory on drive C: (c:foo), not c:\foo. /// This dispatches based on the compilation OS std::string join(const std::string & path1, const std::string & path2); std::string join_nt(const std::string & path1, const std::string & path2); std::string join_posix(const std::string & path1, const std::string & path2); std::string join(const std::vector< std::string > & paths); std::string join_nt(const std::vector< std::string > & paths); std::string join_posix(const std::vector< std::string > & paths); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Normalize a pathname. This collapses redundant separators and up-level references /// so that A//B, A/B/, A/./B and A/foo/../B all become A/B. It does not normalize the case /// (use normcase() for that). On Windows, it converts forward slashes to backward slashes. /// It should be understood that this may change the meaning of the path if it contains /// symbolic links! std::string normpath(const std::string & path); std::string normpath_nt(const std::string & path); std::string normpath_posix(const std::string & path); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the pathname path into a pair, (head, tail) where tail is the last pathname /// component and head is everything leading up to that. The tail part will never contain a /// slash; if path ends in a slash, tail will be empty. If there is no slash in path, head /// will be empty. If path is empty, both head and tail are empty. Trailing slashes are /// stripped from head unless it is the root (one or more slashes only). In all cases, /// join(head, tail) returns a path to the same location as path (but the strings may /// differ). void split(std::string & head, std::string & tail, const std::string & path); void split_nt(std::string & head, std::string & tail, const std::string & path); void split_posix(std::string & head, std::string & tail, const std::string & path); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the pathname path into a pair (drive, tail) where drive is either a drive /// specification or the empty string. On systems which do not use drive specifications, /// drive will always be the empty string. In all cases, drive + tail will be the same as /// path. void splitdrive(std::string & drivespec, std::string & pathspec, const std::string & path); void splitdrive_nt(std::string & drivespec, std::string & pathspec, const std::string & p); void splitdrive_posix(std::string & drivespec, std::string & pathspec, const std::string & path); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the pathname path into a pair (root, ext) such that root + ext == path, and /// ext is empty or begins with a period and contains at most one period. Leading periods on /// the basename are ignored; splitext('.cshrc') returns ('.cshrc', ''). void splitext(std::string & root, std::string & ext, const std::string & path); void splitext_nt(std::string & root, std::string & ext, const std::string & path); void splitext_posix(std::string & root, std::string & ext, const std::string & path); /// /// @ } /// } // namespace path } // namespace os } // namespace pystring } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/pystring/pystring.cpp0000644000175000017500000011124313223553423022251 0ustar mfvmfv/////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2008-2010, Sony Pictures Imageworks Inc // 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 the organization 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 #include "pystring.h" #include #include #include #include #include OCIO_NAMESPACE_ENTER { namespace pystring { #if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) || defined(_MSC_VER) #ifndef WINDOWS #define WINDOWS #endif #endif // This definition codes from configure.in in the python src. // Strictly speaking this limits us to str sizes of 2**31. // Should we wish to handle this limit, we could use an architecture // specific #defines and read from ssize_t (unistd.h) if the header exists. // But in the meantime, the use of int assures maximum arch compatibility. // This must also equal the size used in the end = MAX_32BIT_INT default arg. typedef int Py_ssize_t; /* helper macro to fixup start/end slice values */ #define ADJUST_INDICES(start, end, len) \ if (end > len) \ end = len; \ else if (end < 0) { \ end += len; \ if (end < 0) \ end = 0; \ } \ if (start < 0) { \ start += len; \ if (start < 0) \ start = 0; \ } namespace { ////////////////////////////////////////////////////////////////////////////////////////////// /// why doesn't the std::reverse work? /// void reverse_strings( std::vector< std::string > & result) { for (std::vector< std::string >::size_type i = 0; i < result.size() / 2; i++ ) { std::swap(result[i], result[result.size() - 1 - i]); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void split_whitespace( const std::string & str, std::vector< std::string > & result, int maxsplit ) { std::string::size_type i, j, len = str.size(); for (i = j = 0; i < len; ) { while ( i < len && ::isspace( str[i] ) ) i++; j = i; while ( i < len && ! ::isspace( str[i]) ) i++; if (j < i) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( j, i - j )); while ( i < len && ::isspace( str[i])) i++; j = i; } } if (j < len) { result.push_back( str.substr( j, len - j )); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void rsplit_whitespace( const std::string & str, std::vector< std::string > & result, int maxsplit ) { std::string::size_type len = str.size(); std::string::size_type i, j; for (i = j = len; i > 0; ) { while ( i > 0 && ::isspace( str[i - 1] ) ) i--; j = i; while ( i > 0 && ! ::isspace( str[i - 1]) ) i--; if (j > i) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( i, j - i )); while ( i > 0 && ::isspace( str[i - 1])) i--; j = i; } } if (j > 0) { result.push_back( str.substr( 0, j )); } //std::reverse( result, result.begin(), result.end() ); reverse_strings( result ); } } //anonymous namespace ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void split( const std::string & str, std::vector< std::string > & result, const std::string & sep, int maxsplit ) { result.clear(); if ( maxsplit < 0 ) maxsplit = MAX_32BIT_INT;//result.max_size(); if ( sep.size() == 0 ) { split_whitespace( str, result, maxsplit ); return; } std::string::size_type i,j, len = str.size(), n = sep.size(); i = j = 0; while ( i+n <= len ) { if ( str[i] == sep[0] && str.substr( i, n ) == sep ) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( j, i - j ) ); i = j = i + n; } else { i++; } } result.push_back( str.substr( j, len-j ) ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void rsplit( const std::string & str, std::vector< std::string > & result, const std::string & sep, int maxsplit ) { if ( maxsplit < 0 ) { split( str, result, sep, 0 ); return; } result.clear(); if ( sep.size() == 0 ) { rsplit_whitespace( str, result, maxsplit ); return; } std::string::size_type i,j, len = str.size(), n = sep.size(); i = j = len; while ( i > n ) { if ( str[i - 1] == sep[n - 1] && str.substr( i - n, n ) == sep ) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( i, j - i ) ); i = j = i - n; } else { i--; } } result.push_back( str.substr( 0, j ) ); reverse_strings( result ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// #define LEFTSTRIP 0 #define RIGHTSTRIP 1 #define BOTHSTRIP 2 ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string do_strip( const std::string & str, int striptype, const std::string & chars ) { Py_ssize_t len = (Py_ssize_t) str.size(), i, j, charslen = (Py_ssize_t) chars.size(); if ( charslen == 0 ) { i = 0; if ( striptype != RIGHTSTRIP ) { while ( i < len && ::isspace( str[i] ) ) { i++; } } j = len; if ( striptype != LEFTSTRIP ) { do { j--; } while (j >= i && ::isspace(str[j])); j++; } } else { const char * sep = chars.c_str(); i = 0; if ( striptype != RIGHTSTRIP ) { while ( i < len && memchr(sep, str[i], charslen) ) { i++; } } j = len; if (striptype != LEFTSTRIP) { do { j--; } while (j >= i && memchr(sep, str[j], charslen) ); j++; } } if ( i == 0 && j == len ) { return str; } else { return str.substr( i, j - i ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void partition( const std::string & str, const std::string & sep, std::vector< std::string > & result ) { result.resize(3); int index = find( str, sep ); if ( index < 0 ) { result[0] = str; result[1] = ""; result[2] = ""; } else { result[0] = str.substr( 0, index ); result[1] = sep; result[2] = str.substr( index + sep.size(), str.size() ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void rpartition( const std::string & str, const std::string & sep, std::vector< std::string > & result ) { result.resize(3); int index = rfind( str, sep ); if ( index < 0 ) { result[0] = ""; result[1] = ""; result[2] = str; } else { result[0] = str.substr( 0, index ); result[1] = sep; result[2] = str.substr( index + sep.size(), str.size() ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string strip( const std::string & str, const std::string & chars ) { return do_strip( str, BOTHSTRIP, chars ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string lstrip( const std::string & str, const std::string & chars ) { return do_strip( str, LEFTSTRIP, chars ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string rstrip( const std::string & str, const std::string & chars ) { return do_strip( str, RIGHTSTRIP, chars ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string join( const std::string & str, const std::vector< std::string > & seq ) { std::vector< std::string >::size_type seqlen = seq.size(), i; if ( seqlen == 0 ) return ""; if ( seqlen == 1 ) return seq[0]; std::string result( seq[0] ); for ( i = 1; i < seqlen; ++i ) { result += str + seq[i]; } return result; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// namespace { /* Matches the end (direction >= 0) or start (direction < 0) of self * against substr, using the start and end arguments. Returns * -1 on error, 0 if not found and 1 if found. */ int _string_tailmatch(const std::string & self, const std::string & substr, Py_ssize_t start, Py_ssize_t end, int direction) { Py_ssize_t len = (Py_ssize_t) self.size(); Py_ssize_t slen = (Py_ssize_t) substr.size(); const char* sub = substr.c_str(); const char* str = self.c_str(); ADJUST_INDICES(start, end, len); if (direction < 0) { // startswith if (start+slen > len) return 0; } else { // endswith if (end-start < slen || start > len) return 0; if (end-slen > start) start = end - slen; } if (end-start >= slen) return (!std::memcmp(str+start, sub, slen)); return 0; } } bool endswith( const std::string & str, const std::string & suffix, int start, int end ) { int result = _string_tailmatch(str, suffix, (Py_ssize_t) start, (Py_ssize_t) end, +1); //if (result == -1) // TODO: Error condition return result == 1; } bool startswith( const std::string & str, const std::string & prefix, int start, int end ) { int result = _string_tailmatch(str, prefix, (Py_ssize_t) start, (Py_ssize_t) end, -1); //if (result == -1) // TODO: Error condition return result == 1; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isalnum( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::isalnum( str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::isalnum( str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isalpha( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::isalpha( (int) str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::isalpha( (int) str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isdigit( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::isdigit( str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::isdigit( str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool islower( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::islower( str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::islower( str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isspace( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::isspace( str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::isspace( str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool istitle( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if ( len == 1 ) { return ::isupper( str[0] ) != 0; } bool cased = false, previous_is_cased = false; for ( i = 0; i < len; ++i ) { if ( ::isupper( str[i] ) ) { if ( previous_is_cased ) { return false; } previous_is_cased = true; cased = true; } else if ( ::islower( str[i] ) ) { if (!previous_is_cased) { return false; } previous_is_cased = true; cased = true; } else { previous_is_cased = false; } } return cased; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isupper( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::isupper( str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::isupper( str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string capitalize( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; if ( len > 0) { if (::islower(s[0])) s[0] = (char) ::toupper( s[0] ); } for ( i = 1; i < len; ++i ) { if (::isupper(s[i])) s[i] = (char) ::tolower( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string lower( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; for ( i = 0; i < len; ++i ) { if ( ::isupper( s[i] ) ) s[i] = (char) ::tolower( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string upper( const std::string & str ) { std::string s( str ) ; std::string::size_type len = s.size(), i; for ( i = 0; i < len; ++i ) { if ( ::islower( s[i] ) ) s[i] = (char) ::toupper( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string swapcase( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; for ( i = 0; i < len; ++i ) { if ( ::islower( s[i] ) ) s[i] = (char) ::toupper( s[i] ); else if (::isupper( s[i] ) ) s[i] = (char) ::tolower( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string title( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; bool previous_is_cased = false; for ( i = 0; i < len; ++i ) { int c = s[i]; if ( ::islower(c) ) { if ( !previous_is_cased ) { s[i] = (char) ::toupper(c); } previous_is_cased = true; } else if ( ::isupper(c) ) { if ( previous_is_cased ) { s[i] = (char) ::tolower(c); } previous_is_cased = true; } else { previous_is_cased = false; } } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string translate( const std::string & str, const std::string & table, const std::string & deletechars ) { std::string s; std::string::size_type len = str.size(), dellen = deletechars.size(); if ( table.size() != 256 ) { // TODO : raise exception instead return str; } //if nothing is deleted, use faster code if ( dellen == 0 ) { s = str; for ( std::string::size_type i = 0; i < len; ++i ) { s[i] = table[ s[i] ]; } return s; } int trans_table[256]; for ( int i = 0; i < 256; i++) { trans_table[i] = table[i]; } for ( std::string::size_type i = 0; i < dellen; i++) { trans_table[(int) deletechars[i] ] = -1; } for ( std::string::size_type i = 0; i < len; ++i ) { if ( trans_table[ (int) str[i] ] != -1 ) { s += table[ str[i] ]; } } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string zfill( const std::string & str, int width ) { int len = (int)str.size(); if ( len >= width ) { return str; } std::string s( str ); int fill = width - len; s = std::string( fill, '0' ) + s; if ( s[fill] == '+' || s[fill] == '-' ) { s[0] = s[fill]; s[fill] = '0'; } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string ljust( const std::string & str, int width ) { std::string::size_type len = str.size(); if ( (( int ) len ) >= width ) return str; return str + std::string( width - len, ' ' ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string rjust( const std::string & str, int width ) { std::string::size_type len = str.size(); if ( (( int ) len ) >= width ) return str; return std::string( width - len, ' ' ) + str; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string center( const std::string & str, int width ) { int len = (int) str.size(); int marg, left; if ( len >= width ) return str; marg = width - len; left = marg / 2 + (marg & width & 1); return std::string( left, ' ' ) + str + std::string( marg - left, ' ' ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string slice( const std::string & str, int start, int end ) { ADJUST_INDICES(start, end, (int) str.size()); if ( start >= end ) return ""; return str.substr( start, end - start ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int find( const std::string & str, const std::string & sub, int start, int end ) { ADJUST_INDICES(start, end, (int) str.size()); std::string::size_type result = str.find( sub, start ); // If we cannot find the string, or if the end-point of our found substring is past // the allowed end limit, return that it can't be found. if( result == std::string::npos || (result + sub.size() > (std::string::size_type)end) ) { return -1; } return (int) result; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int index( const std::string & str, const std::string & sub, int start, int end ) { return find( str, sub, start, end ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int rfind( const std::string & str, const std::string & sub, int start, int end ) { ADJUST_INDICES(start, end, (int) str.size()); std::string::size_type result = str.rfind( sub, end ); if( result == std::string::npos || result < (std::string::size_type)start || (result + sub.size() > (std::string::size_type)end)) return -1; return (int)result; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int rindex( const std::string & str, const std::string & sub, int start, int end ) { return rfind( str, sub, start, end ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string expandtabs( const std::string & str, int tabsize ) { std::string s( str ); std::string::size_type len = str.size(), i = 0; int offset = 0; int j = 0; for ( i = 0; i < len; ++i ) { if ( str[i] == '\t' ) { if ( tabsize > 0 ) { int fillsize = tabsize - (j % tabsize); j += fillsize; s.replace( i + offset, 1, std::string( fillsize, ' ' )); offset += fillsize - 1; } else { s.replace( i + offset, 1, "" ); offset -= 1; } } else { j++; if (str[i] == '\n' || str[i] == '\r') { j = 0; } } } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int count( const std::string & str, const std::string & substr, int start, int end ) { int nummatches = 0; int cursor = start; while ( 1 ) { cursor = find( str, substr, cursor, end ); if ( cursor < 0 ) break; cursor += (int) substr.size(); nummatches += 1; } return nummatches; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string replace( const std::string & str, const std::string & oldstr, const std::string & newstr, int count ) { int sofar = 0; int cursor = 0; std::string s( str ); std::string::size_type oldlen = oldstr.size(), newlen = newstr.size(); while ( ( cursor = find( s, oldstr, cursor ) ) != -1 ) { if ( count > -1 && sofar >= count ) { break; } s.replace( cursor, oldlen, newstr ); cursor += (int) newlen; ++sofar; } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void splitlines( const std::string & str, std::vector< std::string > & result, bool keepends ) { result.clear(); std::string::size_type len = str.size(), i, j, eol; for (i = j = 0; i < len; ) { while (i < len && str[i] != '\n' && str[i] != '\r') i++; eol = i; if (i < len) { if (str[i] == '\r' && i + 1 < len && str[i+1] == '\n') { i += 2; } else { i++; } if (keepends) eol = i; } result.push_back( str.substr( j, eol - j ) ); j = i; } if (j < len) { result.push_back( str.substr( j, len - j ) ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string mul( const std::string & str, int n ) { // Early exits if (n <= 0) return ""; if (n == 1) return str; std::ostringstream os; for(int i=0; i & paths) { if(paths.empty()) return ""; if(paths.size() == 1) return paths[0]; std::string path = paths[0]; for(unsigned int i=1; i3) || ((path.size()==3) && !pystring::endswith(path, "/") && !pystring::endswith(path, "\\"))) { b_nts = true; } } if(b_nts) { path = b; } else { // Join, and ensure there's a separator. // assert len(path) > 0 if( pystring::endswith(path, "/") || pystring::endswith(path, "\\")) { if(pystring::startswith(b,"/") || pystring::startswith(b,"\\")) { path += pystring::slice(b, 1); } else { path += b; } } else if(pystring::endswith(path, ":")) { path += b; } else if(!b.empty()) { if(pystring::startswith(b,"/") || pystring::startswith(b,"\\")) { path += b; } else { path += "\\" + b; } } else { // path is not empty and does not end with a backslash, // but b is empty; since, e.g., split('a/') produces // ('a', ''), it's best if join() adds a backslash in // this case. path += "\\"; } } } return path; } // Join two or more pathname components, inserting "\\" as needed. std::string join_nt(const std::string & a, const std::string & b) { std::vector< std::string > paths(2); paths[0] = a; paths[1] = b; return join_nt(paths); } // Join pathnames. // If any component is an absolute path, all previous path components // will be discarded. // Ignore the previous parts if a part is absolute. // Insert a '/' unless the first part is empty or already ends in '/'. std::string join_posix(const std::vector< std::string > & paths) { if(paths.empty()) return ""; if(paths.size() == 1) return paths[0]; std::string path = paths[0]; for(unsigned int i=1; i paths(2); paths[0] = a; paths[1] = b; return join_posix(paths); } std::string join(const std::string & path1, const std::string & path2) { #ifdef WINDOWS return join_nt(path1, path2); #else return join_posix(path1, path2); #endif } std::string join(const std::vector< std::string > & paths) { #ifdef WINDOWS return join_nt(paths); #else return join_posix(paths); #endif } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// // Split a pathname. // Return (head, tail) where tail is everything after the final slash. // Either part may be empty void split_nt(std::string & head, std::string & tail, const std::string & path) { std::string d, p; splitdrive_nt(d, p, path); // set i to index beyond p's last slash int i = (int)p.size(); while(i>0 && (p[i-1] != '\\') && (p[i-1] != '/')) { i = i - 1; } head = pystring::slice(p,0,i); tail = pystring::slice(p,i); // now tail has no slashes // remove trailing slashes from head, unless it's all slashes std::string head2 = head; while(!head2.empty() && ((pystring::slice(head2,-1) == "/") || (pystring::slice(head2,-1) == "\\"))) { head2 = pystring::slice(head,0,-1); } if(!head2.empty()) head = head2; head = d + head; } // Split a path in head (everything up to the last '/') and tail (the // rest). If the path ends in '/', tail will be empty. If there is no // '/' in the path, head will be empty. // Trailing '/'es are stripped from head unless it is the root. void split_posix(std::string & head, std::string & tail, const std::string & p) { int i = pystring::rfind(p, "/") + 1; head = pystring::slice(p,0,i); tail = pystring::slice(p,i); if(!head.empty() && (head != pystring::mul("/", (int) head.size()))) { head = pystring::rstrip(head, "/"); } } void split(std::string & head, std::string & tail, const std::string & path) { #ifdef WINDOWS return split_nt(head, tail, path); #else return split_posix(head, tail, path); #endif } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string basename_nt(const std::string & path) { std::string head, tail; split_nt(head, tail, path); return tail; } std::string basename_posix(const std::string & path) { std::string head, tail; split_posix(head, tail, path); return tail; } std::string basename(const std::string & path) { #ifdef WINDOWS return basename_nt(path); #else return basename_posix(path); #endif } std::string dirname_nt(const std::string & path) { std::string head, tail; split_nt(head, tail, path); return head; } std::string dirname_posix(const std::string & path) { std::string head, tail; split_posix(head, tail, path); return head; } std::string dirname(const std::string & path) { #ifdef WINDOWS return dirname_nt(path); #else return dirname_posix(path); #endif } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// // Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B. std::string normpath_nt(const std::string & p) { std::string path = p; path = pystring::replace(path, "/","\\"); std::string prefix; splitdrive_nt(prefix, path, path); // We need to be careful here. If the prefix is empty, and the path starts // with a backslash, it could either be an absolute path on the current // drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It // is therefore imperative NOT to collapse multiple backslashes blindly in // that case. // The code below preserves multiple backslashes when there is no drive // letter. This means that the invalid filename \\\a\b is preserved // unchanged, where a\\\b is normalised to a\b. It's not clear that there // is any better behaviour for such edge cases. if(prefix.empty()) { // No drive letter - preserve initial backslashes while(pystring::slice(path,0,1) == "\\") { prefix = prefix + "\\"; path = pystring::slice(path,1); } } else { // We have a drive letter - collapse initial backslashes if(pystring::startswith(path, "\\")) { prefix = prefix + "\\"; path = pystring::lstrip(path, "\\"); } } std::vector comps; pystring::split(path, comps, "\\"); int i = 0; while(i<(int)comps.size()) { if(comps[i].empty() || comps[i] == ".") { comps.erase(comps.begin()+i); } else if(comps[i] == "..") { if(i>0 && comps[i-1] != "..") { comps.erase(comps.begin()+i-1, comps.begin()+i+1); i -= 1; } else if(i == 0 && pystring::endswith(prefix, "\\")) { comps.erase(comps.begin()+i); } else { i += 1; } } else { i += 1; } } // If the path is now empty, substitute '.' if(prefix.empty() && comps.empty()) { comps.push_back("."); } return prefix + pystring::join("\\", comps); } // Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B. // It should be understood that this may change the meaning of the path // if it contains symbolic links! // Normalize path, eliminating double slashes, etc. std::string normpath_posix(const std::string & p) { if(p.empty()) return "."; std::string path = p; int initial_slashes = pystring::startswith(path,"/") ? 1 : 0; // POSIX allows one or two initial slashes, but treats three or more // as single slash. if (initial_slashes && pystring::startswith(path,"//") && !pystring::startswith(path,"///")) initial_slashes = 2; std::vector comps, new_comps; pystring::split(path, comps, "/"); for(unsigned int i=0; i 0) path = pystring::mul("/",initial_slashes) + path; if(path.empty()) return "."; return path; } std::string normpath(const std::string & path) { #ifdef WINDOWS return normpath_nt(path); #else return normpath_posix(path); #endif } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// // Split the extension from a pathname. // Extension is everything from the last dot to the end, ignoring // leading dots. Returns "(root, ext)"; ext may be empty. // It is always true that root + ext == p void splitext_generic(std::string & root, std::string & ext, const std::string & p, const std::string & sep, const std::string & altsep, const std::string & extsep) { int sepIndex = pystring::rfind(p, sep); if(!altsep.empty()) { int altsepIndex = pystring::rfind(p, altsep); sepIndex = std::max(sepIndex, altsepIndex); } int dotIndex = pystring::rfind(p, extsep); if(dotIndex > sepIndex) { // Skip all leading dots int filenameIndex = sepIndex + 1; while(filenameIndex < dotIndex) { if(pystring::slice(p,filenameIndex) != extsep) { root = pystring::slice(p, 0, dotIndex); ext = pystring::slice(p, dotIndex); return; } filenameIndex += 1; } } root = p; ext = ""; } void splitext_nt(std::string & root, std::string & ext, const std::string & path) { return splitext_generic(root, ext, path, "\\", "/", "."); } void splitext_posix(std::string & root, std::string & ext, const std::string & path) { return splitext_generic(root, ext, path, "/", "", "."); } void splitext(std::string & root, std::string & ext, const std::string & path) { #ifdef WINDOWS return splitext_nt(root, ext, path); #else return splitext_posix(root, ext, path); #endif } } // namespace path } // namespace os }//namespace pystring } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/LogOps.cpp0000644000175000017500000004412413223553423017721 0ustar mfvmfv/* 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 #include #include #include #include #include "GpuShaderUtils.h" #include "LogOps.h" #include "MathUtils.h" OCIO_NAMESPACE_ENTER { namespace { const float FLTMIN = std::numeric_limits::min(); const int FLOAT_DECIMALS = 7; // k * log(mx+b, base) + kb // the caller is responsible for base != 1.0 // TODO: pull the precomputation into the caller? void ApplyLinToLog(float* rgbaBuffer, long numPixels, const float * k, const float * m, const float * b, const float * base, const float * kb) { // We account for the change of base by rolling the multiplier // in with 'k' float knew[3] = { k[0] / logf(base[0]), k[1] / logf(base[1]), k[2] / logf(base[2]) }; for(long pixelIndex=0; pixelIndex LogOpRcPtr; LogOp::LogOp(const float * k, const float * m, const float * b, const float * base, const float * kb, TransformDirection direction): Op(), m_direction(direction) { if(m_direction == TRANSFORM_DIR_UNKNOWN) { throw Exception("Cannot apply LogOp op, unspecified transform direction."); } memcpy(m_k, k, sizeof(float)*3); memcpy(m_m, m, sizeof(float)*3); memcpy(m_b, b, sizeof(float)*3); memcpy(m_base, base, sizeof(float)*3); memcpy(m_kb, kb, sizeof(float)*3); } OpRcPtr LogOp::clone() const { OpRcPtr op = OpRcPtr(new LogOp(m_k, m_m, m_b, m_base, m_kb, m_direction)); return op; } LogOp::~LogOp() { } std::string LogOp::getInfo() const { return ""; } std::string LogOp::getCacheID() const { return m_cacheID; } bool LogOp::isNoOp() const { return false; } bool LogOp::isSameType(const OpRcPtr & op) const { LogOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; return true; } bool LogOp::isInverse(const OpRcPtr & op) const { LogOpRcPtr typedRcPtr = DynamicPtrCast(op); if(!typedRcPtr) return false; if(GetInverseTransformDirection(m_direction) != typedRcPtr->m_direction) return false; float error = std::numeric_limits::min(); if(!VecsEqualWithRelError(m_k, 3, typedRcPtr->m_k, 3, error)) return false; if(!VecsEqualWithRelError(m_m, 3, typedRcPtr->m_m, 3, error)) return false; if(!VecsEqualWithRelError(m_b, 3, typedRcPtr->m_b, 3, error)) return false; if(!VecsEqualWithRelError(m_base, 3, typedRcPtr->m_base, 3, error)) return false; if(!VecsEqualWithRelError(m_kb, 3, typedRcPtr->m_kb, 3, error)) return false; return true; } bool LogOp::hasChannelCrosstalk() const { return false; } void LogOp::finalize() { if(m_direction == TRANSFORM_DIR_FORWARD) { if(VecContainsOne(m_base, 3)) throw Exception("LogOp Exception, base cannot be 1."); } else if(m_direction == TRANSFORM_DIR_INVERSE) { if(VecContainsZero(m_m, 3)) throw Exception("LogOp Exception, m (slope) cannot be 0."); if(VecContainsZero(m_k, 3)) throw Exception("LogOp Exception, k (multiplier) cannot be 0."); } std::ostringstream cacheIDStream; cacheIDStream << ""; m_cacheID = cacheIDStream.str(); } void LogOp::apply(float* rgbaBuffer, long numPixels) const { if(m_direction == TRANSFORM_DIR_FORWARD) { ApplyLinToLog(rgbaBuffer, numPixels, m_k, m_m, m_b, m_base, m_kb); } else if(m_direction == TRANSFORM_DIR_INVERSE) { ApplyLogToLin(rgbaBuffer, numPixels, m_k, m_m, m_b, m_base, m_kb); } } // Op::process bool LogOp::supportsGpuShader() const { return true; } void LogOp::writeGpuShader(std::ostream & shader, const std::string & pixelName, const GpuShaderDesc & shaderDesc) const { GpuLanguage lang = shaderDesc.getLanguage(); if(m_direction == TRANSFORM_DIR_FORWARD) { // Lin To Log // k * log(mx+b, base) + kb // We account for the change of base by rolling the multiplier // in with 'k' float knew[3] = { m_k[0] / logf(m_base[0]), m_k[1] / logf(m_base[1]), m_k[2] / logf(m_base[2]) }; float clampMin[3] = { FLTMIN, FLTMIN, FLTMIN }; // TODO: Switch to f32 for internal Cg processing? if(lang == GPU_LANGUAGE_CG) { clampMin[0] = static_cast(GetHalfNormMin()); clampMin[1] = static_cast(GetHalfNormMin()); clampMin[2] = static_cast(GetHalfNormMin()); } // Decompose into 2 steps // 1) clamp(mx+b) // 2) knew * log(x) + kb shader << pixelName << ".rgb = "; shader << "max(" << GpuTextHalf3(clampMin,lang) << ", "; shader << GpuTextHalf3(m_m,lang) << " * "; shader << pixelName << ".rgb + "; shader << GpuTextHalf3(m_b,lang) << ");\n"; shader << pixelName << ".rgb = "; shader << GpuTextHalf3(knew,lang) << " * "; shader << "log(" << pixelName << ".rgb) + "; shader << GpuTextHalf3(m_kb,lang) << ";\n"; } else if(m_direction == TRANSFORM_DIR_INVERSE) { float kinv[3] = { 1.0f / m_k[0], 1.0f / m_k[1], 1.0f / m_k[2] }; float minv[3] = { 1.0f / m_m[0], 1.0f / m_m[1], 1.0f / m_m[2] }; // Decompose into 3 steps // 1) kinv * ( x - kb) // 2) pow(base, x) // 3) minv * (x - b) shader << pixelName << ".rgb = "; shader << GpuTextHalf3(kinv,lang) << " * ("; shader << pixelName << ".rgb - "; shader << GpuTextHalf3(m_kb,lang) << ");\n"; shader << pixelName << ".rgb = pow("; shader << GpuTextHalf3(m_base,lang) << ", "; shader << pixelName << ".rgb);\n"; shader << pixelName << ".rgb = "; shader << GpuTextHalf3(minv,lang) << " * ("; shader << pixelName << ".rgb - "; shader << GpuTextHalf3(m_b,lang) << ");\n"; } } } // Anon namespace /////////////////////////////////////////////////////////////////////////// void CreateLogOp(OpRcPtrVec & ops, const float * k, const float * m, const float * b, const float * base, const float * kb, TransformDirection direction) { ops.push_back( LogOpRcPtr(new LogOp(k, m, b, base, kb, direction)) ); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" OIIO_ADD_TEST(LogOps, LinToLog) { float k[3] = { 0.18f, 0.18f, 0.18f }; float m[3] = { 2.0f, 2.0f, 2.0f }; float b[3] = { 0.1f, 0.1f, 0.1f }; float base[3] = { 10.0f, 10.0f, 10.0f }; float kb[3] = { 1.0f, 1.0f, 1.0f }; float data[8] = { 0.01f, 0.1f, 1.0f, 1.0f, 10.0f, 100.0f, 1000.0f, 1.0f, }; float result[8] = { 0.8342526242885725f, 0.90588182584953925f, 1.057999473052105462f, 1.0f, 1.23457529033568797f, 1.41422447595451795f, 1.59418930777214063f, 1.0f }; OCIO::OpRcPtrVec ops; CreateLogOp(ops, k, m, b, base, kb, OCIO::TRANSFORM_DIR_FORWARD); FinalizeOpVec(ops); // Apply the result for(OCIO::OpRcPtrVec::size_type i = 0, size = ops.size(); i < size; ++i) { ops[i]->apply(data, 2); } for(int i=0; i<8; ++i) { OIIO_CHECK_CLOSE( data[i], result[i], 1.0e-3 ); } } OIIO_ADD_TEST(LogOps, LogToLin) { float k[3] = { 0.18f, 0.18f, 0.18f }; float m[3] = { 2.0f, 2.0f, 2.0f }; float b[3] = { 0.1f, 0.1f, 0.1f }; float base[3] = { 10.0f, 10.0f, 10.0f }; float kb[3] = { 1.0f, 1.0f, 1.0f }; float data[8] = { 0.8342526242885725f, 0.90588182584953925f, 1.057999473052105462f, 1.0f, 1.23457529033568797f, 1.41422447595451795f, 1.59418930777214063f, 1.0f }; float result[8] = { 0.01f, 0.1f, 1.0f, 1.0f, 10.0f, 100.0f, 1000.0f, 1.0f, }; OCIO::OpRcPtrVec ops; CreateLogOp(ops, k, m, b, base, kb, OCIO::TRANSFORM_DIR_INVERSE); FinalizeOpVec(ops); // Apply the result for(OCIO::OpRcPtrVec::size_type i = 0, size = ops.size(); i < size; ++i) { ops[i]->apply(data, 2); } for(int i=0; i<8; ++i) { OIIO_CHECK_CLOSE( data[i], result[i], 1.0e-3 ); } } OIIO_ADD_TEST(LogOps, Inverse) { float k[3] = { 0.18f, 0.5f, 0.3f }; float m[3] = { 2.0f, 4.0f, 8.0f }; float b[3] = { 0.1f, 0.1f, 0.1f }; float base[3] = { 10.0f, 5.0f, 2.0f }; float kb[3] = { 1.0f, 1.0f, 1.0f }; OCIO::OpRcPtrVec ops; CreateLogOp(ops, k, m, b, base, kb, OCIO::TRANSFORM_DIR_FORWARD); CreateLogOp(ops, k, m, b, base, kb, OCIO::TRANSFORM_DIR_INVERSE); base[0] += 1e-5f; CreateLogOp(ops, k, m, b, base, kb, OCIO::TRANSFORM_DIR_INVERSE); CreateLogOp(ops, k, m, b, base, kb, OCIO::TRANSFORM_DIR_FORWARD); OIIO_CHECK_EQUAL(ops.size(), 4); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[1])); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[2])); OIIO_CHECK_ASSERT(ops[0]->isSameType(ops[3]->clone())); OIIO_CHECK_EQUAL(ops[0]->isInverse(ops[0]), false); OIIO_CHECK_EQUAL(ops[0]->isInverse(ops[1]), true); OIIO_CHECK_EQUAL(ops[0]->isInverse(ops[2]), false); OIIO_CHECK_EQUAL(ops[0]->isInverse(ops[3]), false); OIIO_CHECK_EQUAL(ops[1]->isInverse(ops[0]), true); OIIO_CHECK_EQUAL(ops[1]->isInverse(ops[2]), false); OIIO_CHECK_EQUAL(ops[1]->isInverse(ops[3]), false); OIIO_CHECK_EQUAL(ops[2]->isInverse(ops[2]), false); OIIO_CHECK_EQUAL(ops[2]->isInverse(ops[3]), true); OIIO_CHECK_EQUAL(ops[3]->isInverse(ops[3]), false); float result[12] = { 0.01f, 0.1f, 1.0f, 1.0f, 1.0f, 10.0f, 100.0f, 1.0f, 1000.0f, 1.0f, 0.5f, 1.0f }; float data[12]; for(int i=0; i<12; ++i) { data[i] = result[i]; } ops[0]->apply(data, 3); // Note: Skip testing alpha channels. OIIO_CHECK_NE( data[0], result[0] ); OIIO_CHECK_NE( data[1], result[1] ); OIIO_CHECK_NE( data[2], result[2] ); OIIO_CHECK_NE( data[4], result[4] ); OIIO_CHECK_NE( data[5], result[5] ); OIIO_CHECK_NE( data[6], result[6] ); OIIO_CHECK_NE( data[8], result[8] ); OIIO_CHECK_NE( data[9], result[9] ); OIIO_CHECK_NE( data[10], result[10] ); ops[1]->apply(data, 3); for(int i=0; i<12; ++i) { OIIO_CHECK_CLOSE( data[i], result[i], 1.0e-3 ); } } #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/ImageDesc.cpp0000644000175000017500000003043113223553423020333 0ustar mfvmfv/* 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 #include #include #include "ImagePacking.h" OCIO_NAMESPACE_ENTER { std::ostream& operator<< (std::ostream& os, const ImageDesc& img) { if(const PackedImageDesc * packedImg = dynamic_cast(&img)) { os << ""; } else if(const PlanarImageDesc * planarImg = dynamic_cast(&img)) { os << ""; } else { os << ""; } return os; } ImageDesc::~ImageDesc() { } GenericImageDesc::GenericImageDesc(): width(0), height(0), xStrideBytes(0), yStrideBytes(0), rData(NULL), gData(NULL), bData(NULL), aData(NULL) { }; /////////////////////////////////////////////////////////////////////////// GenericImageDesc::~GenericImageDesc() { }; void GenericImageDesc::init(const ImageDesc& img) { if(const PackedImageDesc * packedImg = dynamic_cast(&img)) { width = packedImg->getWidth(); height = packedImg->getHeight(); long numChannels = packedImg->getNumChannels(); ptrdiff_t chanStrideBytes = packedImg->getChanStrideBytes(); xStrideBytes = packedImg->getXStrideBytes(); yStrideBytes = packedImg->getYStrideBytes(); // AutoStrides will already be resolved by here, in the constructor of the ImageDesc if(chanStrideBytes == AutoStride || xStrideBytes == AutoStride || yStrideBytes == AutoStride) { throw Exception("Malformed PackedImageDesc: Unresolved AutoStride."); } rData = packedImg->getData(); gData = reinterpret_cast( reinterpret_cast(rData) + chanStrideBytes ); bData = reinterpret_cast( reinterpret_cast(rData) + 2*chanStrideBytes ); if(numChannels >= 4) { aData = reinterpret_cast( reinterpret_cast(rData) + 3*chanStrideBytes ); } if(rData == NULL) { std::ostringstream os; os << "PackedImageDesc Error: A null image ptr was specified."; throw Exception(os.str().c_str()); } if(width <= 0 || height <= 0) { std::ostringstream os; os << "PackedImageDesc Error: Image dimensions must be positive for both x,y. '"; os << width << "x" << height << "' is not allowed."; throw Exception(os.str().c_str()); } if(numChannels < 3) { std::ostringstream os; os << "PackedImageDesc Error: Image numChannels must be three (or more) (rgb+). '"; os << numChannels << "' is not allowed."; throw Exception(os.str().c_str()); } } else if(const PlanarImageDesc * planarImg = dynamic_cast(&img)) { width = planarImg->getWidth(); height = planarImg->getHeight(); xStrideBytes = sizeof(float); yStrideBytes = planarImg->getYStrideBytes(); // AutoStrides will already be resolved by here, in the constructor of the ImageDesc if(yStrideBytes == AutoStride) { throw Exception("Malformed PlanarImageDesc: Unresolved AutoStride."); } rData = planarImg->getRData(); gData = planarImg->getGData(); bData = planarImg->getBData(); aData = planarImg->getAData(); if(width <= 0 || height <= 0) { std::ostringstream os; os << "PlanarImageDesc Error: Image dimensions must be positive for both x,y. '"; os << width << "x" << height << "' is not allowed."; throw Exception(os.str().c_str()); } if(rData == NULL || gData == NULL || bData == NULL) { std::ostringstream os; os << "PlanarImageDesc Error: Valid ptrs must be passed for all 3 image rgb color channels."; throw Exception(os.str().c_str()); } } else { throw Exception("Unknown ImageDesc type."); } } bool GenericImageDesc::isPackedRGBA() const { char* rPtr = reinterpret_cast(rData); char* gPtr = reinterpret_cast(gData); char* bPtr = reinterpret_cast(bData); char* aPtr = reinterpret_cast(aData); if(gPtr-rPtr != sizeof(float)) return false; if(bPtr-gPtr != sizeof(float)) return false; if(aPtr && (aPtr-bPtr != sizeof(float))) return false; // Confirm xStrideBytes is a pure float-sized packing // (I.e., it will divide evenly) if(xStrideBytes <= 0) return false; div_t result = div((int) xStrideBytes, (int)sizeof(float)); if(result.rem != 0) return false; int implicitChannels = result.quot; if(implicitChannels != 4) return false; return true; } /////////////////////////////////////////////////////////////////////////// class PackedImageDesc::Impl { public: float * data_; long width_; long height_; long numChannels_; ptrdiff_t chanStrideBytes_; ptrdiff_t xStrideBytes_; ptrdiff_t yStrideBytes_; Impl() : data_(NULL), width_(0), height_(0), numChannels_(0), chanStrideBytes_(0), xStrideBytes_(0), yStrideBytes_(0) { } ~Impl() { } }; PackedImageDesc::PackedImageDesc(float * data, long width, long height, long numChannels, ptrdiff_t chanStrideBytes, ptrdiff_t xStrideBytes, ptrdiff_t yStrideBytes) : m_impl(new PackedImageDesc::Impl) { getImpl()->data_ = data; getImpl()->width_ = width; getImpl()->height_ = height; getImpl()->numChannels_ = numChannels; getImpl()->chanStrideBytes_ = (chanStrideBytes == AutoStride) ? sizeof(float) : chanStrideBytes; getImpl()->xStrideBytes_ = (xStrideBytes == AutoStride) ? sizeof(float)*numChannels : xStrideBytes; getImpl()->yStrideBytes_ = (yStrideBytes == AutoStride) ? sizeof(float)*width*numChannels : yStrideBytes; } PackedImageDesc::~PackedImageDesc() { delete m_impl; m_impl = NULL; } float * PackedImageDesc::getData() const { return getImpl()->data_; } long PackedImageDesc::getWidth() const { return getImpl()->width_; } long PackedImageDesc::getHeight() const { return getImpl()->height_; } long PackedImageDesc::getNumChannels() const { return getImpl()->numChannels_; } ptrdiff_t PackedImageDesc::getChanStrideBytes() const { return getImpl()->chanStrideBytes_; } ptrdiff_t PackedImageDesc::getXStrideBytes() const { return getImpl()->xStrideBytes_; } ptrdiff_t PackedImageDesc::getYStrideBytes() const { return getImpl()->yStrideBytes_; } /////////////////////////////////////////////////////////////////////////// class PlanarImageDesc::Impl { public: float * rData_; float * gData_; float * bData_; float * aData_; long width_; long height_; ptrdiff_t yStrideBytes_; Impl() : rData_(NULL), gData_(NULL), bData_(NULL), aData_(NULL), width_(0), height_(0), yStrideBytes_(0) { } ~Impl() { } }; PlanarImageDesc::PlanarImageDesc(float * rData, float * gData, float * bData, float * aData, long width, long height, ptrdiff_t yStrideBytes) : m_impl(new PlanarImageDesc::Impl()) { getImpl()->rData_ = rData; getImpl()->gData_ = gData; getImpl()->bData_ = bData; getImpl()->aData_ = aData; getImpl()->width_ = width; getImpl()->height_ = height; getImpl()->yStrideBytes_ = (yStrideBytes == AutoStride) ? sizeof(float)*width : yStrideBytes; } PlanarImageDesc::~PlanarImageDesc() { delete m_impl; m_impl = NULL; } float* PlanarImageDesc::getRData() const { return getImpl()->rData_; } float* PlanarImageDesc::getGData() const { return getImpl()->gData_; } float* PlanarImageDesc::getBData() const { return getImpl()->bData_; } float* PlanarImageDesc::getAData() const { return getImpl()->aData_; } long PlanarImageDesc::getWidth() const { return getImpl()->width_; } long PlanarImageDesc::getHeight() const { return getImpl()->height_; } ptrdiff_t PlanarImageDesc::getYStrideBytes() const { return getImpl()->yStrideBytes_; } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/LookParse.cpp0000644000175000017500000002366613223553423020425 0ustar mfvmfv/* 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 #include #include "LookParse.h" #include "ParseUtils.h" #include "pystring/pystring.h" #include OCIO_NAMESPACE_ENTER { void LookParseResult::Token::parse(const std::string & str) { // Assert no commas, colons, or | in str. if(pystring::startswith(str, "+")) { name = pystring::lstrip(str, "+"); dir = TRANSFORM_DIR_FORWARD; } // TODO: Handle -- else if(pystring::startswith(str, "-")) { name = pystring::lstrip(str, "-"); dir = TRANSFORM_DIR_INVERSE; } else { name = str; dir = TRANSFORM_DIR_FORWARD; } } void LookParseResult::Token::serialize(std::ostream & os) const { if(dir==TRANSFORM_DIR_FORWARD) { os << name; } else if(dir==TRANSFORM_DIR_INVERSE) { os << "-" << name; } else { os << "?" << name; } } void LookParseResult::serialize(std::ostream & os, const Tokens & tokens) { for(unsigned int i=0; i options; pystring::split(strippedlooks, options, "|"); std::vector vec; for(unsigned int optionsindex=0; optionsindex #include "Platform.h" OCIO_NAMESPACE_ENTER { namespace Platform { // Unlike the ::getenv(), the method does not use any static buffer // for the Windows platform only. *nix platforms are still using // the ::getenv method, but reducing the static vairable usage. // void getenv (const char* name, std::string& value) { #ifdef WINDOWS // To remove the security compilation warning, the _dupenv_s method // must be used (instead of the getenv). The improvement is that // the buffer length is now under control to mitigate buffer overflow attacks. // char * val; size_t len = 0; // At least _dupenv_s validates the memory size by returning ENOMEM // in case of allocation size issue. const errno_t err = ::_dupenv_s(&val, &len, name); if(err!=0 || len==0 || !val || !*val) { if(val) free(val); value.resize(0); } else { value.resize(len+1); ::snprintf(&value[0], len, "%s", val); if(val) free(val); } #else const char* val = ::getenv(name); value = (val && *val) ? val : ""; #endif } }//namespace platform } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" OIIO_ADD_TEST(Platform, getenv) { { std::string env; OCIO::Platform::getenv("NotExistingEnvVariable", env); OIIO_CHECK_ASSERT(env.empty()); } { std::string env; OCIO::Platform::getenv("PATH", env); OIIO_CHECK_ASSERT(!env.empty()); } { std::string env; OCIO::Platform::getenv("PATH", env); OCIO::Platform::getenv("NotExistingEnvVariable", env); OIIO_CHECK_ASSERT(env.empty()); } { std::string env; OCIO::Platform::getenv("NotExistingEnvVariable", env); OCIO::Platform::getenv("PATH", env); OIIO_CHECK_ASSERT(!env.empty()); } } OIIO_ADD_TEST(Platform, putenv) { { ::putenv("MY_DUMMY_ENV=SomeValue"); std::string env; OCIO::Platform::getenv("MY_DUMMY_ENV", env); OIIO_CHECK_ASSERT(!env.empty()); OIIO_CHECK_ASSERT(0==strcmp("SomeValue", env.c_str())); } } #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/UnitTest.h0000644000175000017500000000345113223553423017740 0ustar mfvmfv/* 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_OCIO_UNITTEST_H #define INCLUDED_OCIO_UNITTEST_H #ifdef OCIO_UNIT_TEST #ifndef WIN32 #pragma GCC visibility push(default) #endif #include // OIIO unit tests header #ifndef WIN32 #pragma GCC visibility pop #endif #endif // OCIO_UNIT_TEST #endif // INCLUDED_OCIO_UNITTEST_H opencolorio-1.1.0~dfsg0.orig/src/core/Display.cpp0000644000175000017500000001136713223553423020126 0ustar mfvmfv/* 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 #include #include "Display.h" #include "ParseUtils.h" OCIO_NAMESPACE_ENTER { DisplayMap::iterator find_display(DisplayMap & displays, const std::string & display) { for(DisplayMap::iterator iter = displays.begin(); iter != displays.end(); ++iter) { if(StrEqualsCaseIgnore(display, iter->first)) return iter; } return displays.end(); } DisplayMap::const_iterator find_display_const(const DisplayMap & displays, const std::string & display) { for(DisplayMap::const_iterator iter = displays.begin(); iter != displays.end(); ++iter) { if(StrEqualsCaseIgnore(display, iter->first)) return iter; } return displays.end(); } int find_view(const ViewVec & vec, const std::string & name) { for(unsigned int i=0; isecond; int index = find_view(views, view); if(index<0) { views.push_back( View(view, colorspace, looks) ); } else { views[index].colorspace = colorspace; views[index].looks = looks; } } } void ComputeDisplays(StringVec & displayCache, const DisplayMap & displays, const StringVec & activeDisplays, const StringVec & activeDisplaysEnvOverride) { displayCache.clear(); StringVec displayMasterList; for(DisplayMap::const_iterator iter = displays.begin(); iter != displays.end(); ++iter) { displayMasterList.push_back(iter->first); } // Apply the env override if it's not empty. if(!activeDisplaysEnvOverride.empty()) { displayCache = IntersectStringVecsCaseIgnore(displayMasterList, activeDisplaysEnvOverride); if(!displayCache.empty()) return; } // Otherwise, aApply the active displays if it's not empty. else if(!activeDisplays.empty()) { displayCache = IntersectStringVecsCaseIgnore(displayMasterList, activeDisplays); if(!displayCache.empty()) return; } displayCache = displayMasterList; } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" OIIO_ADD_TEST(Display, Basic) { } #endif // OCIO_UNIT_TESTopencolorio-1.1.0~dfsg0.orig/src/core/ScanlineHelper.cpp0000644000175000017500000001045113223553423021406 0ustar mfvmfv/* 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 #include "ScanlineHelper.h" #include #include #include OCIO_NAMESPACE_ENTER { namespace { const int PIXELS_PER_LINE = 4096; } //////////////////////////////////////////////////////////////////////////// ScanlineHelper::ScanlineHelper(ImageDesc& img): m_buffer(0), m_imagePixelIndex(0), m_numPixelsCopied(0), m_yIndex(0), m_inPlaceMode(false) { m_img.init(img); if(m_img.isPackedRGBA()) { m_inPlaceMode = true; } else { // TODO: Re-use memory from thread-safe memory pool, rather // than doing a new allocation each time. m_buffer = (float*)malloc(sizeof(float)*PIXELS_PER_LINE*4); } } ScanlineHelper::~ScanlineHelper() { free(m_buffer); } // Copy from the src image to our scanline, in our preferred // pixel layout. void ScanlineHelper::prepRGBAScanline(float** buffer, long* numPixels) { if(m_inPlaceMode) { // TODO: what if scanline is too short, or too long? if(m_yIndex >= m_img.height) { *numPixels = 0; return; } char* rowPtr = reinterpret_cast(m_img.rData); rowPtr += m_img.yStrideBytes*m_yIndex; *buffer = reinterpret_cast(rowPtr); *numPixels = m_img.width; } else { PackRGBAFromImageDesc(m_img, m_buffer, &m_numPixelsCopied, PIXELS_PER_LINE, m_imagePixelIndex); *buffer = m_buffer; *numPixels = m_numPixelsCopied; } } // Write back the result of our work, from the scanline to our // destination image. void ScanlineHelper::finishRGBAScanline() { if(m_inPlaceMode) { m_yIndex += 1; } else { UnpackRGBAToImageDesc(m_img, m_buffer, m_numPixelsCopied, m_imagePixelIndex); m_imagePixelIndex += m_numPixelsCopied; } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/FileTransform.cpp0000644000175000017500000005233513223553423021274 0ustar mfvmfv/* 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 #include "FileTransform.h" #include "Logging.h" #include "Mutex.h" #include "NoOps.h" #include "PathUtils.h" #include "pystring/pystring.h" #include #include #include OCIO_NAMESPACE_ENTER { FileTransformRcPtr FileTransform::Create() { return FileTransformRcPtr(new FileTransform(), &deleter); } void FileTransform::deleter(FileTransform* t) { delete t; } class FileTransform::Impl { public: TransformDirection dir_; std::string src_; std::string cccid_; Interpolation interp_; Impl() : dir_(TRANSFORM_DIR_FORWARD), interp_(INTERP_UNKNOWN) { } ~Impl() { } Impl& operator= (const Impl & rhs) { dir_ = rhs.dir_; src_ = rhs.src_; cccid_ = rhs.cccid_; interp_ = rhs.interp_; return *this; } }; /////////////////////////////////////////////////////////////////////////// FileTransform::FileTransform() : m_impl(new FileTransform::Impl) { } TransformRcPtr FileTransform::createEditableCopy() const { FileTransformRcPtr transform = FileTransform::Create(); *(transform->m_impl) = *m_impl; return transform; } FileTransform::~FileTransform() { delete m_impl; m_impl = NULL; } FileTransform& FileTransform::operator= (const FileTransform & rhs) { *m_impl = *rhs.m_impl; return *this; } TransformDirection FileTransform::getDirection() const { return getImpl()->dir_; } void FileTransform::setDirection(TransformDirection dir) { getImpl()->dir_ = dir; } const char * FileTransform::getSrc() const { return getImpl()->src_.c_str(); } void FileTransform::setSrc(const char * src) { getImpl()->src_ = src; } const char * FileTransform::getCCCId() const { return getImpl()->cccid_.c_str(); } void FileTransform::setCCCId(const char * cccid) { getImpl()->cccid_ = cccid; } Interpolation FileTransform::getInterpolation() const { return getImpl()->interp_; } void FileTransform::setInterpolation(Interpolation interp) { getImpl()->interp_ = interp; } int FileTransform::getNumFormats() { return FormatRegistry::GetInstance().getNumFormats(FORMAT_CAPABILITY_READ); } const char * FileTransform::getFormatNameByIndex(int index) { return FormatRegistry::GetInstance().getFormatNameByIndex(FORMAT_CAPABILITY_READ, index); } const char * FileTransform::getFormatExtensionByIndex(int index) { return FormatRegistry::GetInstance().getFormatExtensionByIndex(FORMAT_CAPABILITY_READ, index); } std::ostream& operator<< (std::ostream& os, const FileTransform& t) { os << ""; return os; } /////////////////////////////////////////////////////////////////////////// // NOTE: You must be mindful when editing this function. // to be resiliant to the static initialization order 'fiasco' // // See // http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14 // http://stackoverflow.com/questions/335369/finding-c-static-initialization-order-problems // for more info. namespace { FormatRegistry* g_formatRegistry = NULL; Mutex g_formatRegistryLock; } FormatRegistry & FormatRegistry::GetInstance() { AutoMutex lock(g_formatRegistryLock); if(!g_formatRegistry) { g_formatRegistry = new FormatRegistry(); } return *g_formatRegistry; } FormatRegistry::FormatRegistry() { registerFileFormat(CreateFileFormat3DL()); registerFileFormat(CreateFileFormatCCC()); registerFileFormat(CreateFileFormatCDL()); registerFileFormat(CreateFileFormatCC()); registerFileFormat(CreateFileFormatCSP()); registerFileFormat(CreateFileFormatHDL()); registerFileFormat(CreateFileFormatIridasItx()); registerFileFormat(CreateFileFormatIridasCube()); registerFileFormat(CreateFileFormatIridasLook()); registerFileFormat(CreateFileFormatPandora()); registerFileFormat(CreateFileFormatSpi1D()); registerFileFormat(CreateFileFormatSpi3D()); registerFileFormat(CreateFileFormatSpiMtx()); registerFileFormat(CreateFileFormatTruelight()); registerFileFormat(CreateFileFormatVF()); } FormatRegistry::~FormatRegistry() { } FileFormat* FormatRegistry::getFileFormatByName(const std::string & name) const { FileFormatMap::const_iterator iter = m_formatsByName.find( pystring::lower(name)); if(iter != m_formatsByName.end()) return iter->second; return NULL; } FileFormat* FormatRegistry::getFileFormatForExtension(const std::string & extension) const { FileFormatMap::const_iterator iter = m_formatsByExtension.find( pystring::lower(extension)); if(iter != m_formatsByExtension.end()) return iter->second; return NULL; } void FormatRegistry::registerFileFormat(FileFormat* format) { FormatInfoVec formatInfoVec; format->GetFormatInfo(formatInfoVec); if(formatInfoVec.empty()) { std::ostringstream os; os << "FileFormat Registry error. "; os << "A file format did not provide the required format info."; throw Exception(os.str().c_str()); } for(unsigned int i=0; i(m_rawFormats.size()); } FileFormat* FormatRegistry::getRawFormatByIndex(int index) const { if(index<0 || index>=getNumRawFormats()) { return NULL; } return m_rawFormats[index]; } int FormatRegistry::getNumFormats(int capability) const { if(capability == FORMAT_CAPABILITY_READ) { return static_cast(m_readFormatNames.size()); } else if(capability == FORMAT_CAPABILITY_WRITE) { return static_cast(m_writeFormatNames.size()); } return 0; } const char * FormatRegistry::getFormatNameByIndex(int capability, int index) const { if(capability == FORMAT_CAPABILITY_READ) { if(index<0 || index>=static_cast(m_readFormatNames.size())) { return ""; } return m_readFormatNames[index].c_str(); } else if(capability == FORMAT_CAPABILITY_WRITE) { if(index<0 || index>=static_cast(m_readFormatNames.size())) { return ""; } return m_writeFormatNames[index].c_str(); } return ""; } const char * FormatRegistry::getFormatExtensionByIndex(int capability, int index) const { if(capability == FORMAT_CAPABILITY_READ) { if(index<0 || index>=static_cast(m_readFormatExtensions.size())) { return ""; } return m_readFormatExtensions[index].c_str(); } else if(capability == FORMAT_CAPABILITY_WRITE) { if(index<0 || index>=static_cast(m_writeFormatExtensions.size())) { return ""; } return m_writeFormatExtensions[index].c_str(); } return ""; } /////////////////////////////////////////////////////////////////////////// FileFormat::~FileFormat() { } std::string FileFormat::getName() const { FormatInfoVec infoVec; GetFormatInfo(infoVec); if(infoVec.size()>0) { return infoVec[0].name; } return "Unknown Format"; } void FileFormat::Write(const Baker & /*baker*/, const std::string & formatName, std::ostream & /*ostream*/) const { std::ostringstream os; os << "Format " << formatName << " does not support writing."; throw Exception(os.str().c_str()); } namespace { void LoadFileUncached(FileFormat * & returnFormat, CachedFileRcPtr & returnCachedFile, const std::string & filepath) { returnFormat = NULL; { std::ostringstream os; os << "Opening " << filepath; LogDebug(os.str()); } // Open the filePath std::ifstream filestream; filestream.open(filepath.c_str(), std::ios_base::in); if (!filestream.good()) { std::ostringstream os; os << "The specified FileTransform srcfile, '"; os << filepath <<"', could not be opened. "; os << "Please confirm the file exists with appropriate read"; os << " permissions."; throw Exception(os.str().c_str()); } // Try the initial format. std::string primaryErrorText; std::string root, extension; pystring::os::path::splitext(root, extension, filepath); extension = pystring::replace(extension,".","",1); // remove the leading '.' FormatRegistry & formatRegistry = FormatRegistry::GetInstance(); FileFormat * primaryFormat = formatRegistry.getFileFormatForExtension(extension); if(primaryFormat) { try { CachedFileRcPtr cachedFile = primaryFormat->Read(filestream); if(IsDebugLoggingEnabled()) { std::ostringstream os; os << " Loaded primary format "; os << primaryFormat->getName(); LogDebug(os.str()); } returnFormat = primaryFormat; returnCachedFile = cachedFile; return; } catch(std::exception & e) { primaryErrorText = e.what(); if(IsDebugLoggingEnabled()) { std::ostringstream os; os << " Failed primary format "; os << primaryFormat->getName(); os << ": " << e.what(); LogDebug(os.str()); } } } filestream.clear(); filestream.seekg( std::ifstream::beg ); // If this fails, try all other formats CachedFileRcPtr cachedFile; FileFormat * altFormat = NULL; for(int findex = 0; findexRead(filestream); if(IsDebugLoggingEnabled()) { std::ostringstream os; os << " Loaded alt format "; os << altFormat->getName(); LogDebug(os.str()); } returnFormat = altFormat; returnCachedFile = cachedFile; return; } catch(std::exception & e) { if(IsDebugLoggingEnabled()) { std::ostringstream os; os << " Failed alt format "; os << altFormat->getName(); os << ": " << e.what(); LogDebug(os.str()); } } filestream.clear(); filestream.seekg( std::ifstream::beg ); } // No formats succeeded. Error out with a sensible message. if(primaryFormat) { std::ostringstream os; os << "The specified transform file '"; os << filepath <<"' could not be loaded. "; os << primaryErrorText; throw Exception(os.str().c_str()); } else { std::ostringstream os; os << "The specified transform file '"; os << filepath <<"' does not appear to be a valid, known LUT file format."; throw Exception(os.str().c_str()); } } // We mutex both the main map and each item individually, so that // the potentially slow file access wont block other lookups to already // existing items. (Loads of the *same* file will mutually block though) struct FileCacheResult { Mutex mutex; FileFormat * format; bool ready; bool error; CachedFileRcPtr cachedFile; std::string exceptionText; FileCacheResult(): format(NULL), ready(false), error(false) {} }; typedef OCIO_SHARED_PTR FileCacheResultPtr; typedef std::map FileCacheMap; FileCacheMap g_fileCache; Mutex g_fileCacheLock; void GetCachedFileAndFormat( FileFormat * & format, CachedFileRcPtr & cachedFile, const std::string & filepath) { // Load the file cache ptr from the global map FileCacheResultPtr result; { AutoMutex lock(g_fileCacheLock); FileCacheMap::iterator iter = g_fileCache.find(filepath); if(iter != g_fileCache.end()) { result = iter->second; } else { result = FileCacheResultPtr(new FileCacheResult); g_fileCache[filepath] = result; } } // If this file has already been loaded, return // the result immediately AutoMutex lock(result->mutex); if(!result->ready) { result->ready = true; result->error = false; try { LoadFileUncached(result->format, result->cachedFile, filepath); } catch(std::exception & e) { result->error = true; result->exceptionText = e.what(); } catch(...) { result->error = true; std::ostringstream os; os << "An unknown error occurred in LoadFileUncached, "; os << filepath; result->exceptionText = os.str(); } } if(result->error) { throw Exception(result->exceptionText.c_str()); } else { format = result->format; cachedFile = result->cachedFile; } } } // namespace void ClearFileTransformCaches() { AutoMutex lock(g_fileCacheLock); g_fileCache.clear(); } void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, const FileTransform& fileTransform, TransformDirection dir) { std::string src = fileTransform.getSrc(); if(src.empty()) { std::ostringstream os; os << "The transform file has not been specified."; throw Exception(os.str().c_str()); } std::string filepath = context->resolveFileLocation(src.c_str()); CreateFileNoOp(ops, filepath); FileFormat* format = NULL; CachedFileRcPtr cachedFile; GetCachedFileAndFormat(format, cachedFile, filepath); if(!format) { std::ostringstream os; os << "The specified file load "; os << filepath << " appeared to succeed, but no format "; os << "was returned."; throw Exception(os.str().c_str()); } if(!cachedFile.get()) { std::ostringstream os; os << "The specified file load "; os << filepath << " appeared to succeed, but no cachedFile "; os << "was returned."; throw Exception(os.str().c_str()); } format->BuildFileOps(ops, config, context, cachedFile, fileTransform, dir); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/OpBuilders.h0000644000175000017500000001215313223553423020230 0ustar mfvmfv/* 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_OCIO_OPBUILDERS_H #define INCLUDED_OCIO_OPBUILDERS_H #include #include "Op.h" #include "LookParse.h" #include "PrivateTypes.h" OCIO_NAMESPACE_ENTER { void BuildOps(OpRcPtrVec & ops, const Config & config, const ConstContextRcPtr & context, const ConstTransformRcPtr & transform, TransformDirection dir); //////////////////////////////////////////////////////////////////////// void BuildAllocationOps(OpRcPtrVec & ops, const Config & config, const AllocationTransform & transform, TransformDirection dir); void BuildCDLOps(OpRcPtrVec & ops, const Config & config, const CDLTransform & transform, TransformDirection dir); void BuildColorSpaceOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, const ColorSpaceTransform & transform, TransformDirection dir); void BuildColorSpaceOps(OpRcPtrVec & ops, const Config & config, const ConstContextRcPtr & context, const ConstColorSpaceRcPtr & srcColorSpace, const ConstColorSpaceRcPtr & dstColorSpace); void BuildDisplayOps(OpRcPtrVec & ops, const Config & config, const ConstContextRcPtr & context, const DisplayTransform & transform, TransformDirection dir); void BuildExponentOps(OpRcPtrVec & ops, const Config& config, const ExponentTransform & transform, TransformDirection dir); void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, const FileTransform & transform, TransformDirection dir); void BuildGroupOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, const GroupTransform & transform, TransformDirection dir); void BuildLogOps(OpRcPtrVec & ops, const Config& config, const LogTransform& transform, TransformDirection dir); void BuildLookOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, const LookTransform & lookTransform, TransformDirection dir); void BuildLookOps(OpRcPtrVec & ops, ConstColorSpaceRcPtr & currentColorSpace, bool skipColorSpaceConversions, const Config& config, const ConstContextRcPtr & context, const LookParseResult & looks); void BuildMatrixOps(OpRcPtrVec & ops, const Config& config, const MatrixTransform & transform, TransformDirection dir); void BuildTruelightOps(OpRcPtrVec & ops, const Config & config, const TruelightTransform & transform, TransformDirection dir); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/Config.cpp0000644000175000017500000020464713223553423017733 0ustar mfvmfv/* 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 #include #include #include #include #include #include #include #include "HashUtils.h" #include "Logging.h" #include "LookParse.h" #include "Display.h" #include "MathUtils.h" #include "Mutex.h" #include "OpBuilders.h" #include "PathUtils.h" #include "ParseUtils.h" #include "Processor.h" #include "PrivateTypes.h" #include "pystring/pystring.h" #include "OCIOYaml.h" #include "Platform.h" OCIO_NAMESPACE_ENTER { namespace { const char * OCIO_CONFIG_ENVVAR = "OCIO"; const char * OCIO_ACTIVE_DISPLAYS_ENVVAR = "OCIO_ACTIVE_DISPLAYS"; const char * OCIO_ACTIVE_VIEWS_ENVVAR = "OCIO_ACTIVE_VIEWS"; enum Sanity { SANITY_UNKNOWN = 0, SANITY_SANE, SANITY_INSANE }; // These are the 709 primaries specified by the ASC. const float DEFAULT_LUMA_COEFF_R = 0.2126f; const float DEFAULT_LUMA_COEFF_G = 0.7152f; const float DEFAULT_LUMA_COEFF_B = 0.0722f; const char * INTERNAL_RAW_PROFILE = "ocio_profile_version: 1\n" "strictparsing: false\n" "roles:\n" " default: raw\n" "displays:\n" " sRGB:\n" " - ! {name: Raw, colorspace: raw}\n" "colorspaces:\n" " - !\n" " name: raw\n" " family: raw\n" " equalitygroup:\n" " bitdepth: 32f\n" " isdata: true\n" " allocation: uniform\n" " description: 'A raw color space. Conversions to and from this space are no-ops.'\n"; } /////////////////////////////////////////////////////////////////////////// const char * GetVersion() { return OCIO_VERSION; } int GetVersionHex() { return OCIO_VERSION_HEX; } namespace { ConstConfigRcPtr g_currentConfig; Mutex g_currentConfigLock; } ConstConfigRcPtr GetCurrentConfig() { AutoMutex lock(g_currentConfigLock); if(!g_currentConfig) { g_currentConfig = Config::CreateFromEnv(); } return g_currentConfig; } void SetCurrentConfig(const ConstConfigRcPtr & config) { AutoMutex lock(g_currentConfigLock); g_currentConfig = config->createEditableCopy(); } namespace { // Environment const char* LookupEnvironment(const StringMap & env, const std::string & name) { StringMap::const_iterator iter = env.find(name); if(iter == env.end()) return ""; return iter->second.c_str(); } // Roles // (lower case role name: colorspace name) const char* LookupRole(const StringMap & roles, const std::string & rolename) { StringMap::const_iterator iter = roles.find(pystring::lower(rolename)); if(iter == roles.end()) return ""; return iter->second.c_str(); } void GetFileReferences(std::set & files, const ConstTransformRcPtr & transform) { if(!transform) return; if(ConstGroupTransformRcPtr groupTransform = \ DynamicPtrCast(transform)) { for(int i=0; isize(); ++i) { GetFileReferences(files, groupTransform->getTransform(i)); } } else if(ConstFileTransformRcPtr fileTransform = \ DynamicPtrCast(transform)) { files.insert(fileTransform->getSrc()); } } void GetColorSpaceReferences(std::set & colorSpaceNames, const ConstTransformRcPtr & transform) { if(!transform) return; if(ConstGroupTransformRcPtr groupTransform = \ DynamicPtrCast(transform)) { for(int i=0; isize(); ++i) { GetColorSpaceReferences(colorSpaceNames, groupTransform->getTransform(i)); } } else if(ConstColorSpaceTransformRcPtr colorSpaceTransform = \ DynamicPtrCast(transform)) { colorSpaceNames.insert(colorSpaceTransform->getSrc()); colorSpaceNames.insert(colorSpaceTransform->getDst()); } else if(ConstDisplayTransformRcPtr displayTransform = \ DynamicPtrCast(transform)) { colorSpaceNames.insert(displayTransform->getInputColorSpaceName()); } else if(ConstLookTransformRcPtr lookTransform = \ DynamicPtrCast(transform)) { colorSpaceNames.insert(colorSpaceTransform->getSrc()); colorSpaceNames.insert(colorSpaceTransform->getDst()); } } bool FindColorSpaceIndex(int * index, const ColorSpaceVec & colorspaces, const std::string & csname) { if(csname.empty()) return false; std::string csnamelower = pystring::lower(csname); for(unsigned int i = 0; i < colorspaces.size(); ++i) { if(csnamelower == pystring::lower(colorspaces[i]->getName())) { if(index) *index = i; return true; } } return false; } } // namespace class Config::Impl { public: StringMap env_; ContextRcPtr context_; std::string description_; ColorSpaceVec colorspaces_; StringMap roles_; LookVec looksList_; DisplayMap displays_; StringVec activeDisplays_; StringVec activeDisplaysEnvOverride_; StringVec activeViews_; StringVec activeViewsEnvOverride_; mutable std::string activeDisplaysStr_; mutable std::string activeViewsStr_; mutable StringVec displayCache_; // Misc std::vector defaultLumaCoefs_; bool strictParsing_; mutable Sanity sanity_; mutable std::string sanitytext_; mutable Mutex cacheidMutex_; mutable StringMap cacheids_; mutable std::string cacheidnocontext_; OCIOYaml io_; Impl() : context_(Context::Create()), strictParsing_(true), sanity_(SANITY_UNKNOWN) { std::string activeDisplays; Platform::getenv(OCIO_ACTIVE_DISPLAYS_ENVVAR, activeDisplays); SplitStringEnvStyle(activeDisplaysEnvOverride_, activeDisplays.c_str()); std::string activeViews; Platform::getenv(OCIO_ACTIVE_VIEWS_ENVVAR, activeViews); SplitStringEnvStyle(activeViewsEnvOverride_, activeViews.c_str()); defaultLumaCoefs_.resize(3); defaultLumaCoefs_[0] = DEFAULT_LUMA_COEFF_R; defaultLumaCoefs_[1] = DEFAULT_LUMA_COEFF_G; defaultLumaCoefs_[2] = DEFAULT_LUMA_COEFF_B; } ~Impl() { } Impl& operator= (const Impl & rhs) { if(this!=&rhs) { env_ = rhs.env_; context_ = rhs.context_->createEditableCopy(); description_ = rhs.description_; // Deep copy the colorspaces colorspaces_.clear(); colorspaces_.reserve(rhs.colorspaces_.size()); for(unsigned int i=0; icreateEditableCopy()); } // Deep copy the looks looksList_.clear(); looksList_.reserve(rhs.looksList_.size()); for(unsigned int i=0; icreateEditableCopy()); } // Assignment operator will suffice for these roles_ = rhs.roles_; displays_ = rhs.displays_; activeDisplays_ = rhs.activeDisplays_; activeViews_ = rhs.activeViews_; activeViewsEnvOverride_ = rhs.activeViewsEnvOverride_; activeDisplaysEnvOverride_ = rhs.activeDisplaysEnvOverride_; activeDisplaysStr_ = rhs.activeDisplaysStr_; displayCache_ = rhs.displayCache_; defaultLumaCoefs_ = rhs.defaultLumaCoefs_; strictParsing_ = rhs.strictParsing_; sanity_ = rhs.sanity_; sanitytext_ = rhs.sanitytext_; cacheids_ = rhs.cacheids_; cacheidnocontext_ = cacheidnocontext_; } return *this; } // Any time you modify the state of the config, you must call this // to reset internal cache states. You also should do this in a // thread safe manner by acquiring the cacheidMutex_; void resetCacheIDs(); // Get all internal transforms (to generate cacheIDs, validation, etc). // This currently crawls colorspaces + looks void getAllIntenalTransforms(ConstTransformVec & transformVec) const; }; /////////////////////////////////////////////////////////////////////////// ConfigRcPtr Config::Create() { return ConfigRcPtr(new Config(), &deleter); } void Config::deleter(Config* c) { delete c; } ConstConfigRcPtr Config::CreateFromEnv() { std::string file; Platform::getenv(OCIO_CONFIG_ENVVAR, file); if(!file.empty()) return CreateFromFile(file.c_str()); std::ostringstream os; os << "Color management disabled. "; os << "(Specify the $OCIO environment variable to enable.)"; LogInfo(os.str()); std::istringstream istream; istream.str(INTERNAL_RAW_PROFILE); ConfigRcPtr config = Config::Create(); config->getImpl()->io_.open(istream, config); return config; } ConstConfigRcPtr Config::CreateFromFile(const char * filename) { std::ifstream istream(filename); if(istream.fail()) { std::ostringstream os; os << "Error could not read '" << filename; os << "' OCIO profile."; throw Exception (os.str().c_str()); } ConfigRcPtr config = Config::Create(); config->getImpl()->io_.open(istream, config, filename); return config; } ConstConfigRcPtr Config::CreateFromStream(std::istream & istream) { ConfigRcPtr config = Config::Create(); config->getImpl()->io_.open(istream, config); return config; } /////////////////////////////////////////////////////////////////////////// Config::Config() : m_impl(new Config::Impl) { } Config::~Config() { delete m_impl; m_impl = NULL; } ConfigRcPtr Config::createEditableCopy() const { ConfigRcPtr config = Config::Create(); *config->m_impl = *m_impl; return config; } void Config::sanityCheck() const { if(getImpl()->sanity_ == SANITY_SANE) return; if(getImpl()->sanity_ == SANITY_INSANE) { throw Exception(getImpl()->sanitytext_.c_str()); } getImpl()->sanity_ = SANITY_INSANE; getImpl()->sanitytext_ = ""; ///// COLORSPACES StringSet existingColorSpaces; // Confirm all ColorSpaces are valid for(unsigned int i=0; icolorspaces_.size(); ++i) { if(!getImpl()->colorspaces_[i]) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "The colorspace at index " << i << " is null."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } const char * name = getImpl()->colorspaces_[i]->getName(); if(!name || strlen(name) == 0) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "The colorspace at index " << i << " is not named."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } std::string namelower = pystring::lower(name); StringSet::const_iterator it = existingColorSpaces.find(namelower); if(it != existingColorSpaces.end()) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "Two colorspaces are defined with the same name, '"; os << namelower << "'."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } existingColorSpaces.insert(namelower); } // Confirm all roles are valid { for(StringMap::const_iterator iter = getImpl()->roles_.begin(), end = getImpl()->roles_.end(); iter!=end; ++iter) { int csindex = -1; if(!FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, iter->second)) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "The role '" << iter->first << "' "; os << "refers to a colorspace, '" << iter->second << "', "; os << "which is not defined."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } // Confirm no name conflicts between colorspaces and roles if(FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, iter->first)) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "The role '" << iter->first << "' "; os << " is in conflict with a colorspace of the same name."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } } } ///// DISPLAYS int numviews = 0; // Confirm all Displays transforms refer to colorspaces that exit for(DisplayMap::const_iterator iter = getImpl()->displays_.begin(); iter != getImpl()->displays_.end(); ++iter) { std::string display = iter->first; const ViewVec & views = iter->second; if(views.empty()) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "The display '" << display << "' "; os << "does not define any views."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } for(unsigned int i=0; isanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } int csindex = -1; if(!FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, views[i].colorspace)) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "The display '" << display << "' "; os << "refers to a colorspace, '" << views[i].colorspace << "', "; os << "which is not defined."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } // Confirm looks references exist LookParseResult looks; const LookParseResult::Options & options = looks.parse(views[i].looks); for(unsigned int optionindex=0; optionindexsanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } } } ++numviews; } } // Confirm at least one display entry exists. if(numviews == 0) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "No displays are specified."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } // Confirm for all Transforms that reference internal colorspaces, // the named space exists { ConstTransformVec allTransforms; getImpl()->getAllIntenalTransforms(allTransforms); std::set colorSpaceNames; for(unsigned int i=0; i::iterator iter = colorSpaceNames.begin(); iter != colorSpaceNames.end(); ++iter) { int csindex = -1; if(!FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, *iter)) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "This config references a ColorSpace, '" << *iter << "', "; os << "which is not defined."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } } } ///// LOOKS // For all looks, confirm the process space exists and the look is named for(unsigned int i=0; ilooksList_.size(); ++i) { std::string name = getImpl()->looksList_[i]->getName(); if(name.empty()) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "The look at index '" << i << "' "; os << "does not specify a name."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } std::string processSpace = getImpl()->looksList_[i]->getProcessSpace(); if(processSpace.empty()) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "The look '" << name << "' "; os << "does not specify a process space."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } int csindex=0; if(!FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, processSpace)) { std::ostringstream os; os << "Config failed sanitycheck. "; os << "The look '" << name << "' "; os << "specifies a process color space, '"; os << processSpace << "', which is not defined."; getImpl()->sanitytext_ = os.str(); throw Exception(getImpl()->sanitytext_.c_str()); } } // Everything is groovy. getImpl()->sanity_ = SANITY_SANE; } /////////////////////////////////////////////////////////////////////////// const char * Config::getDescription() const { return getImpl()->description_.c_str(); } void Config::setDescription(const char * description) { getImpl()->description_ = description; AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } // RESOURCES ////////////////////////////////////////////////////////////// ConstContextRcPtr Config::getCurrentContext() const { return getImpl()->context_; } void Config::addEnvironmentVar(const char * name, const char * defaultValue) { if(defaultValue) { getImpl()->env_[std::string(name)] = std::string(defaultValue); getImpl()->context_->setStringVar(name, defaultValue); } else { StringMap::iterator iter = getImpl()->env_.find(std::string(name)); if(iter != getImpl()->env_.end()) getImpl()->env_.erase(iter); } AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } int Config::getNumEnvironmentVars() const { return static_cast(getImpl()->env_.size()); } const char * Config::getEnvironmentVarNameByIndex(int index) const { if(index < 0 || index >= (int)getImpl()->env_.size()) return ""; StringMap::const_iterator iter = getImpl()->env_.begin(); for(int i = 0; i < index; ++i) ++iter; return iter->first.c_str(); } const char * Config::getEnvironmentVarDefault(const char * name) const { return LookupEnvironment(getImpl()->env_, name); } void Config::clearEnvironmentVars() { getImpl()->env_.clear(); getImpl()->context_->clearStringVars(); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } void Config::setEnvironmentMode(EnvironmentMode mode) { getImpl()->context_->setEnvironmentMode(mode); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } EnvironmentMode Config::getEnvironmentMode() const { return getImpl()->context_->getEnvironmentMode(); } void Config::loadEnvironment() { getImpl()->context_->loadEnvironment(); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } const char * Config::getSearchPath() const { return getImpl()->context_->getSearchPath(); } void Config::setSearchPath(const char * path) { getImpl()->context_->setSearchPath(path); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } const char * Config::getWorkingDir() const { return getImpl()->context_->getWorkingDir(); } void Config::setWorkingDir(const char * dirname) { getImpl()->context_->setWorkingDir(dirname); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } /////////////////////////////////////////////////////////////////////////// int Config::getNumColorSpaces() const { return static_cast(getImpl()->colorspaces_.size()); } const char * Config::getColorSpaceNameByIndex(int index) const { if(index<0 || index >= (int)getImpl()->colorspaces_.size()) { return ""; } return getImpl()->colorspaces_[index]->getName(); } ConstColorSpaceRcPtr Config::getColorSpace(const char * name) const { int index = getIndexForColorSpace(name); if(index<0 || index >= (int)getImpl()->colorspaces_.size()) { return ColorSpaceRcPtr(); } return getImpl()->colorspaces_[index]; } int Config::getIndexForColorSpace(const char * name) const { int csindex = -1; // Check to see if the name is a color space if( FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, name) ) { return csindex; } // Check to see if the name is a role const char* csname = LookupRole(getImpl()->roles_, name); if( FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, csname) ) { return csindex; } // Is a default role defined? // (And, are we allowed to use it) if(!getImpl()->strictParsing_) { csname = LookupRole(getImpl()->roles_, ROLE_DEFAULT); if( FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, csname) ) { return csindex; } } return -1; } void Config::addColorSpace(const ConstColorSpaceRcPtr & original) { ColorSpaceRcPtr cs = original->createEditableCopy(); std::string name = cs->getName(); if(name.empty()) throw Exception("Cannot addColorSpace with an empty name."); // Check to see if the colorspace already exists int csindex = -1; if( FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, name) ) { getImpl()->colorspaces_[csindex] = cs; } else { // Otherwise, add it getImpl()->colorspaces_.push_back( cs ); } AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } void Config::clearColorSpaces() { getImpl()->colorspaces_.clear(); } const char * Config::parseColorSpaceFromString(const char * str) const { if(!str) return ""; // Search the entire filePath, including directory name (if provided) // convert the filename to lowercase. std::string fullstr = pystring::lower(std::string(str)); // See if it matches a lut name. // This is the position of the RIGHT end of the colorspace substring, not the left int rightMostColorPos=-1; std::string rightMostColorspace = ""; int rightMostColorSpaceIndex = -1; // Find the right-most occcurance within the string for each colorspace. for (unsigned int i=0; icolorspaces_.size(); ++i) { std::string csname = pystring::lower(getImpl()->colorspaces_[i]->getName()); // find right-most extension matched in filename int colorspacePos = pystring::rfind(fullstr, csname); if(colorspacePos < 0) continue; // If we have found a match, move the pointer over to the right end of the substring // This will allow us to find the longest name that matches the rightmost colorspace colorspacePos += (int)csname.size(); if ( (colorspacePos > rightMostColorPos) || ((colorspacePos == rightMostColorPos) && (csname.size() > rightMostColorspace.size())) ) { rightMostColorPos = colorspacePos; rightMostColorspace = csname; rightMostColorSpaceIndex = i; } } if(rightMostColorSpaceIndex>=0) { return getImpl()->colorspaces_[rightMostColorSpaceIndex]->getName(); } if(!getImpl()->strictParsing_) { // Is a default role defined? const char* csname = LookupRole(getImpl()->roles_, ROLE_DEFAULT); if(csname && *csname) { int csindex = -1; if( FindColorSpaceIndex(&csindex, getImpl()->colorspaces_, csname) ) { // This is necessary to not return a reference to // a local variable. return getImpl()->colorspaces_[csindex]->getName(); } } } return ""; } bool Config::isStrictParsingEnabled() const { return getImpl()->strictParsing_; } void Config::setStrictParsingEnabled(bool enabled) { getImpl()->strictParsing_ = enabled; AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } // Roles void Config::setRole(const char * role, const char * colorSpaceName) { // Set the role if(colorSpaceName) { getImpl()->roles_[pystring::lower(role)] = std::string(colorSpaceName); } // Unset the role else { StringMap::iterator iter = getImpl()->roles_.find(pystring::lower(role)); if(iter != getImpl()->roles_.end()) { getImpl()->roles_.erase(iter); } } AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } int Config::getNumRoles() const { return static_cast(getImpl()->roles_.size()); } bool Config::hasRole(const char * role) const { const char* rname = LookupRole(getImpl()->roles_, role); return rname && *rname; } const char * Config::getRoleName(int index) const { if(index < 0 || index >= (int)getImpl()->roles_.size()) return ""; StringMap::const_iterator iter = getImpl()->roles_.begin(); for(int i = 0; i < index; ++i) ++iter; return iter->first.c_str(); } /////////////////////////////////////////////////////////////////////////// // // Display/View Registration const char * Config::getDefaultDisplay() const { if(getImpl()->displayCache_.empty()) { ComputeDisplays(getImpl()->displayCache_, getImpl()->displays_, getImpl()->activeDisplays_, getImpl()->activeDisplaysEnvOverride_); } int index = -1; if(!getImpl()->activeDisplaysEnvOverride_.empty()) { StringVec orderedDisplays = IntersectStringVecsCaseIgnore(getImpl()->activeDisplaysEnvOverride_, getImpl()->displayCache_); if(!orderedDisplays.empty()) { index = FindInStringVecCaseIgnore(getImpl()->displayCache_, orderedDisplays[0]); } } else if(!getImpl()->activeDisplays_.empty()) { StringVec orderedDisplays = IntersectStringVecsCaseIgnore(getImpl()->activeDisplays_, getImpl()->displayCache_); if(!orderedDisplays.empty()) { index = FindInStringVecCaseIgnore(getImpl()->displayCache_, orderedDisplays[0]); } } if(index >= 0) { return getImpl()->displayCache_[index].c_str(); } if(!getImpl()->displayCache_.empty()) { return getImpl()->displayCache_[0].c_str(); } return ""; } int Config::getNumDisplays() const { if(getImpl()->displayCache_.empty()) { ComputeDisplays(getImpl()->displayCache_, getImpl()->displays_, getImpl()->activeDisplays_, getImpl()->activeDisplaysEnvOverride_); } return static_cast(getImpl()->displayCache_.size()); } const char * Config::getDisplay(int index) const { if(getImpl()->displayCache_.empty()) { ComputeDisplays(getImpl()->displayCache_, getImpl()->displays_, getImpl()->activeDisplays_, getImpl()->activeDisplaysEnvOverride_); } if(index>=0 || index < static_cast(getImpl()->displayCache_.size())) { return getImpl()->displayCache_[index].c_str(); } return ""; } const char * Config::getDefaultView(const char * display) const { if(getImpl()->displayCache_.empty()) { ComputeDisplays(getImpl()->displayCache_, getImpl()->displays_, getImpl()->activeDisplays_, getImpl()->activeDisplaysEnvOverride_); } if(!display) return ""; DisplayMap::const_iterator iter = find_display_const(getImpl()->displays_, display); if(iter == getImpl()->displays_.end()) return ""; const ViewVec & views = iter->second; StringVec masterViews; for(unsigned int i=0; iactiveViewsEnvOverride_.empty()) { StringVec orderedViews = IntersectStringVecsCaseIgnore(getImpl()->activeViewsEnvOverride_, masterViews); if(!orderedViews.empty()) { index = FindInStringVecCaseIgnore(masterViews, orderedViews[0]); } } else if(!getImpl()->activeViews_.empty()) { StringVec orderedViews = IntersectStringVecsCaseIgnore(getImpl()->activeViews_, masterViews); if(!orderedViews.empty()) { index = FindInStringVecCaseIgnore(masterViews, orderedViews[0]); } } if(index >= 0) { return views[index].name.c_str(); } if(!views.empty()) { return views[0].name.c_str(); } return ""; } int Config::getNumViews(const char * display) const { if(getImpl()->displayCache_.empty()) { ComputeDisplays(getImpl()->displayCache_, getImpl()->displays_, getImpl()->activeDisplays_, getImpl()->activeDisplaysEnvOverride_); } if(!display) return 0; DisplayMap::const_iterator iter = find_display_const(getImpl()->displays_, display); if(iter == getImpl()->displays_.end()) return 0; const ViewVec & views = iter->second; return static_cast(views.size()); } const char * Config::getView(const char * display, int index) const { if(getImpl()->displayCache_.empty()) { ComputeDisplays(getImpl()->displayCache_, getImpl()->displays_, getImpl()->activeDisplays_, getImpl()->activeDisplaysEnvOverride_); } if(!display) return ""; DisplayMap::const_iterator iter = find_display_const(getImpl()->displays_, display); if(iter == getImpl()->displays_.end()) return ""; const ViewVec & views = iter->second; return views[index].name.c_str(); } const char * Config::getDisplayColorSpaceName(const char * display, const char * view) const { if(!display || !view) return ""; DisplayMap::const_iterator iter = find_display_const(getImpl()->displays_, display); if(iter == getImpl()->displays_.end()) return ""; const ViewVec & views = iter->second; int index = find_view(views, view); if(index<0) return ""; return views[index].colorspace.c_str(); } const char * Config::getDisplayLooks(const char * display, const char * view) const { if(!display || !view) return ""; DisplayMap::const_iterator iter = find_display_const(getImpl()->displays_, display); if(iter == getImpl()->displays_.end()) return ""; const ViewVec & views = iter->second; int index = find_view(views, view); if(index<0) return ""; return views[index].looks.c_str(); } void Config::addDisplay(const char * display, const char * view, const char * colorSpaceName, const char * lookName) { if(!display || !view || !colorSpaceName || !lookName) return; AddDisplay(getImpl()->displays_, display, view, colorSpaceName, lookName); getImpl()->displayCache_.clear(); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } void Config::clearDisplays() { getImpl()->displays_.clear(); getImpl()->displayCache_.clear(); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } void Config::setActiveDisplays(const char * displays) { getImpl()->activeDisplays_.clear(); SplitStringEnvStyle(getImpl()->activeDisplays_, displays); getImpl()->displayCache_.clear(); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } const char * Config::getActiveDisplays() const { getImpl()->activeDisplaysStr_ = JoinStringEnvStyle(getImpl()->activeDisplays_); return getImpl()->activeDisplaysStr_.c_str(); } void Config::setActiveViews(const char * views) { getImpl()->activeViews_.clear(); SplitStringEnvStyle(getImpl()->activeViews_, views); getImpl()->displayCache_.clear(); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } const char * Config::getActiveViews() const { getImpl()->activeViewsStr_ = JoinStringEnvStyle(getImpl()->activeViews_); return getImpl()->activeViewsStr_.c_str(); } /////////////////////////////////////////////////////////////////////////// void Config::getDefaultLumaCoefs(float * c3) const { memcpy(c3, &getImpl()->defaultLumaCoefs_[0], 3*sizeof(float)); } void Config::setDefaultLumaCoefs(const float * c3) { memcpy(&getImpl()->defaultLumaCoefs_[0], c3, 3*sizeof(float)); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } /////////////////////////////////////////////////////////////////////////// ConstLookRcPtr Config::getLook(const char * name) const { std::string namelower = pystring::lower(name); for(unsigned int i=0; ilooksList_.size(); ++i) { if(pystring::lower(getImpl()->looksList_[i]->getName()) == namelower) { return getImpl()->looksList_[i]; } } return ConstLookRcPtr(); } int Config::getNumLooks() const { return static_cast(getImpl()->looksList_.size()); } const char * Config::getLookNameByIndex(int index) const { if(index<0 || index>=static_cast(getImpl()->looksList_.size())) { return ""; } return getImpl()->looksList_[index]->getName(); } void Config::addLook(const ConstLookRcPtr & look) { std::string name = look->getName(); if(name.empty()) throw Exception("Cannot addLook with an empty name."); std::string namelower = pystring::lower(name); // If the look exists, replace it for(unsigned int i=0; ilooksList_.size(); ++i) { if(pystring::lower(getImpl()->looksList_[i]->getName()) == namelower) { getImpl()->looksList_[i] = look->createEditableCopy(); return; } } // Otherwise, add it getImpl()->looksList_.push_back(look->createEditableCopy()); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } void Config::clearLooks() { getImpl()->looksList_.clear(); AutoMutex lock(getImpl()->cacheidMutex_); getImpl()->resetCacheIDs(); } /////////////////////////////////////////////////////////////////////////// ConstProcessorRcPtr Config::getProcessor(const ConstColorSpaceRcPtr & src, const ConstColorSpaceRcPtr & dst) const { ConstContextRcPtr context = getCurrentContext(); return getProcessor(context, src, dst); } ConstProcessorRcPtr Config::getProcessor(const ConstContextRcPtr & context, const ConstColorSpaceRcPtr & src, const ConstColorSpaceRcPtr & dst) const { if(!src) { throw Exception("Config::GetProcessor failed. Source colorspace is null."); } if(!dst) { throw Exception("Config::GetProcessor failed. Destination colorspace is null."); } ProcessorRcPtr processor = Processor::Create(); processor->getImpl()->addColorSpaceConversion(*this, context, src, dst); processor->getImpl()->finalize(); return processor; } ConstProcessorRcPtr Config::getProcessor(const char * srcName, const char * dstName) const { ConstContextRcPtr context = getCurrentContext(); return getProcessor(context, srcName, dstName); } //! Names can be colorspace name or role name ConstProcessorRcPtr Config::getProcessor(const ConstContextRcPtr & context, const char * srcName, const char * dstName) const { ConstColorSpaceRcPtr src = getColorSpace(srcName); if(!src) { std::ostringstream os; os << "Could not find colorspace '" << srcName << "'."; throw Exception(os.str().c_str()); } ConstColorSpaceRcPtr dst = getColorSpace(dstName); if(!dst) { std::ostringstream os; os << "Could not find colorspace '" << dstName << "'."; throw Exception(os.str().c_str()); } return getProcessor(context, src, dst); } ConstProcessorRcPtr Config::getProcessor(const ConstTransformRcPtr& transform) const { return getProcessor(transform, TRANSFORM_DIR_FORWARD); } ConstProcessorRcPtr Config::getProcessor(const ConstTransformRcPtr& transform, TransformDirection direction) const { ConstContextRcPtr context = getCurrentContext(); return getProcessor(context, transform, direction); } ConstProcessorRcPtr Config::getProcessor(const ConstContextRcPtr & context, const ConstTransformRcPtr& transform, TransformDirection direction) const { ProcessorRcPtr processor = Processor::Create(); processor->getImpl()->addTransform(*this, context, transform, direction); processor->getImpl()->finalize(); return processor; } std::ostream& operator<< (std::ostream& os, const Config& config) { config.serialize(os); return os; } /////////////////////////////////////////////////////////////////////////// // CacheID const char * Config::getCacheID() const { return getCacheID(getCurrentContext()); } const char * Config::getCacheID(const ConstContextRcPtr & context) const { AutoMutex lock(getImpl()->cacheidMutex_); // A null context will use the empty cacheid std::string contextcacheid = ""; if(context) contextcacheid = context->getCacheID(); StringMap::const_iterator cacheiditer = getImpl()->cacheids_.find(contextcacheid); if(cacheiditer != getImpl()->cacheids_.end()) { return cacheiditer->second.c_str(); } // Include the hash of the yaml config serialization if(getImpl()->cacheidnocontext_.empty()) { std::stringstream cacheid; serialize(cacheid); std::string fullstr = cacheid.str(); getImpl()->cacheidnocontext_ = CacheIDHash(fullstr.c_str(), (int)fullstr.size()); } // Also include all file references, using the context (if specified) std::string fileReferencesFashHash = ""; if(context) { std::ostringstream filehash; ConstTransformVec allTransforms; getImpl()->getAllIntenalTransforms(allTransforms); std::set files; for(unsigned int i=0; i::iterator iter = files.begin(); iter != files.end(); ++iter) { if(iter->empty()) continue; filehash << *iter << "="; try { std::string resolvedLocation = context->resolveFileLocation(iter->c_str()); filehash << GetFastFileHash(resolvedLocation) << " "; } catch(...) { filehash << "? "; continue; } } std::string fullstr = filehash.str(); fileReferencesFashHash = CacheIDHash(fullstr.c_str(), (int)fullstr.size()); } getImpl()->cacheids_[contextcacheid] = getImpl()->cacheidnocontext_ + ":" + fileReferencesFashHash; return getImpl()->cacheids_[contextcacheid].c_str(); } /////////////////////////////////////////////////////////////////////////// // Serialization void Config::serialize(std::ostream& os) const { try { getImpl()->io_.write(os, this); } catch( const std::exception & e) { std::ostringstream error; error << "Error building YAML: " << e.what(); throw Exception(error.str().c_str()); } } void Config::Impl::resetCacheIDs() { cacheids_.clear(); cacheidnocontext_ = ""; sanity_ = SANITY_UNKNOWN; sanitytext_ = ""; } void Config::Impl::getAllIntenalTransforms(ConstTransformVec & transformVec) const { // Grab all transforms from the ColorSpaces for(unsigned int i=0; igetTransform(COLORSPACE_DIR_TO_REFERENCE)) transformVec.push_back(colorspaces_[i]->getTransform(COLORSPACE_DIR_TO_REFERENCE)); if(colorspaces_[i]->getTransform(COLORSPACE_DIR_FROM_REFERENCE)) transformVec.push_back(colorspaces_[i]->getTransform(COLORSPACE_DIR_FROM_REFERENCE)); } // Grab all transforms from the Looks for(unsigned int i=0; igetTransform()) transformVec.push_back(looksList_[i]->getTransform()); if(looksList_[i]->getInverseTransform()) transformVec.push_back(looksList_[i]->getInverseTransform()); } } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" #include #include "pystring/pystring.h" #if 0 OIIO_ADD_TEST(Config, test_searchpath_filesystem) { OCIO::EnvMap env = OCIO::GetEnvMap(); std::string OCIO_TEST_AREA("$OCIO_TEST_AREA"); EnvExpand(&OCIO_TEST_AREA, &env); OCIO::ConfigRcPtr config = OCIO::Config::Create(); // basic get/set/expand config->setSearchPath("." ":$OCIO_TEST1" ":/$OCIO_JOB/${OCIO_SEQ}/$OCIO_SHOT/ocio"); OIIO_CHECK_ASSERT(strcmp(config->getSearchPath(), ".:$OCIO_TEST1:/$OCIO_JOB/${OCIO_SEQ}/$OCIO_SHOT/ocio") == 0); OIIO_CHECK_ASSERT(strcmp(config->getSearchPath(true), ".:foobar:/meatballs/cheesecake/mb-cc-001/ocio") == 0); // find some files config->setSearchPath(".." ":$OCIO_TEST1" ":${OCIO_TEST_AREA}/test_search/one" ":$OCIO_TEST_AREA/test_search/two"); // setup for search test std::string base_dir("$OCIO_TEST_AREA/test_search/"); EnvExpand(&base_dir, &env); mkdir(base_dir.c_str(), 0777); std::string one_dir("$OCIO_TEST_AREA/test_search/one/"); EnvExpand(&one_dir, &env); mkdir(one_dir.c_str(), 0777); std::string two_dir("$OCIO_TEST_AREA/test_search/two/"); EnvExpand(&two_dir, &env); mkdir(two_dir.c_str(), 0777); std::string lut1(one_dir+"somelut1.lut"); std::ofstream somelut1(lut1.c_str()); somelut1.close(); std::string lut2(two_dir+"somelut2.lut"); std::ofstream somelut2(lut2.c_str()); somelut2.close(); std::string lut3(two_dir+"somelut3.lut"); std::ofstream somelut3(lut3.c_str()); somelut3.close(); std::string lutdotdot(OCIO_TEST_AREA+"/lutdotdot.lut"); std::ofstream somelutdotdot(lutdotdot.c_str()); somelutdotdot.close(); // basic search test OIIO_CHECK_ASSERT(strcmp(config->findFile("somelut1.lut"), lut1.c_str()) == 0); OIIO_CHECK_ASSERT(strcmp(config->findFile("somelut2.lut"), lut2.c_str()) == 0); OIIO_CHECK_ASSERT(strcmp(config->findFile("somelut3.lut"), lut3.c_str()) == 0); OIIO_CHECK_ASSERT(strcmp(config->findFile("lutdotdot.lut"), lutdotdot.c_str()) == 0); } #endif OIIO_ADD_TEST(Config, InternalRawProfile) { std::istringstream is; is.str(OCIO::INTERNAL_RAW_PROFILE); OIIO_CHECK_NO_THROW(OCIO::ConstConfigRcPtr config = OCIO::Config::CreateFromStream(is)); } OIIO_ADD_TEST(Config, SimpleConfig) { std::string SIMPLE_PROFILE = "ocio_profile_version: 1\n" "resource_path: luts\n" "strictparsing: false\n" "luma: [0.2126, 0.7152, 0.0722]\n" "roles:\n" " compositing_log: lgh\n" " default: raw\n" " scene_linear: lnh\n" "displays:\n" " sRGB:\n" " - ! {name: Film1D, colorspace: vd8}\n" " - ! {name: Log, colorspace: lg10}\n" " - ! {name: Raw, colorspace: raw}\n" "colorspaces:\n" " - !\n" " name: raw\n" " family: raw\n" " equalitygroup: \n" " bitdepth: 32f\n" " description: |\n" " A raw color space. Conversions to and from this space are no-ops.\n" " isdata: true\n" " allocation: uniform\n" " - !\n" " name: lnh\n" " family: ln\n" " equalitygroup: \n" " bitdepth: 16f\n" " description: |\n" " The show reference space. This is a sensor referred linear\n" " representation of the scene with primaries that correspond to\n" " scanned film. 0.18 in this space corresponds to a properly\n" " exposed 18% grey card.\n" " isdata: false\n" " allocation: lg2\n" " - !\n" " name: loads_of_transforms\n" " family: vd8\n" " equalitygroup: \n" " bitdepth: 8ui\n" " description: 'how many transforms can we use?'\n" " isdata: false\n" " allocation: uniform\n" " to_reference: !\n" " direction: forward\n" " children:\n" " - !\n" " src: diffusemult.spimtx\n" " interpolation: unknown\n" " - !\n" " src: vd8\n" " dst: lnh\n" " - !\n" " value: [2.2, 2.2, 2.2, 1]\n" " - !\n" " matrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]\n" " offset: [0, 0, 0, 0]\n" " - !\n" " slope: [1, 1, 1]\n" " offset: [0, 0, 0]\n" " power: [1, 1, 1]\n" " saturation: 1\n" "\n"; std::istringstream is; is.str(SIMPLE_PROFILE); OCIO::ConstConfigRcPtr config; OIIO_CHECK_NO_THROW(config = OCIO::Config::CreateFromStream(is)); } OIIO_ADD_TEST(Config, Roles) { std::string SIMPLE_PROFILE = "ocio_profile_version: 1\n" "strictparsing: false\n" "roles:\n" " compositing_log: lgh\n" " default: raw\n" " scene_linear: lnh\n" "colorspaces:\n" " - !\n" " name: raw\n" " - !\n" " name: lnh\n" " - !\n" " name: lgh\n" "\n"; std::istringstream is; is.str(SIMPLE_PROFILE); OCIO::ConstConfigRcPtr config; OIIO_CHECK_NO_THROW(config = OCIO::Config::CreateFromStream(is)); OIIO_CHECK_EQUAL(config->getNumRoles(), 3); OIIO_CHECK_ASSERT(config->hasRole("compositing_log") == true); OIIO_CHECK_ASSERT(config->hasRole("cheese") == false); OIIO_CHECK_ASSERT(config->hasRole("") == false); OIIO_CHECK_ASSERT(strcmp(config->getRoleName(2), "scene_linear") == 0); OIIO_CHECK_ASSERT(strcmp(config->getRoleName(0), "compositing_log") == 0); OIIO_CHECK_ASSERT(strcmp(config->getRoleName(1), "default") == 0); OIIO_CHECK_ASSERT(strcmp(config->getRoleName(10), "") == 0); OIIO_CHECK_ASSERT(strcmp(config->getRoleName(-4), "") == 0); } OIIO_ADD_TEST(Config, Serialize) { OCIO::ConfigRcPtr config = OCIO::Config::Create(); { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("testing"); cs->setFamily("test"); OCIO::FileTransformRcPtr transform1 = \ OCIO::FileTransform::Create(); OCIO::GroupTransformRcPtr groupTransform = OCIO::GroupTransform::Create(); groupTransform->push_back(transform1); cs->setTransform(groupTransform, OCIO::COLORSPACE_DIR_TO_REFERENCE); config->addColorSpace(cs); config->setRole( OCIO::ROLE_COMPOSITING_LOG, cs->getName() ); } { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("testing2"); cs->setFamily("test"); OCIO::ExponentTransformRcPtr transform1 = \ OCIO::ExponentTransform::Create(); OCIO::GroupTransformRcPtr groupTransform = OCIO::GroupTransform::Create(); groupTransform->push_back(transform1); cs->setTransform(groupTransform, OCIO::COLORSPACE_DIR_TO_REFERENCE); config->addColorSpace(cs); config->setRole( OCIO::ROLE_COMPOSITING_LOG, cs->getName() ); } // for testing //std::ofstream outfile("/tmp/test.ocio"); //config->serialize(outfile); //outfile.close(); std::ostringstream os; config->serialize(os); std::string PROFILE_OUT = "ocio_profile_version: 1\n" "\n" "search_path: \"\"\n" "strictparsing: true\n" "luma: [0.2126, 0.7152, 0.0722]\n" "\n" "roles:\n" " compositing_log: testing2\n" "\n" "displays:\n" " {}\n" "\n" "active_displays: []\n" "active_views: []\n" "\n" "colorspaces:\n" " - !\n" " name: testing\n" " family: test\n" " equalitygroup: \"\"\n" " bitdepth: unknown\n" " isdata: false\n" " allocation: uniform\n" " to_reference: !\n" " children:\n" " - ! {src: \"\", interpolation: unknown}\n" "\n" " - !\n" " name: testing2\n" " family: test\n" " equalitygroup: \"\"\n" " bitdepth: unknown\n" " isdata: false\n" " allocation: uniform\n" " to_reference: !\n" " children:\n" " - ! {value: [1, 1, 1, 1]}\n"; std::vector osvec; OCIO::pystring::splitlines(os.str(), osvec); std::vector PROFILE_OUTvec; OCIO::pystring::splitlines(PROFILE_OUT, PROFILE_OUTvec); OIIO_CHECK_EQUAL(osvec.size(), PROFILE_OUTvec.size()); for(unsigned int i = 0; i < PROFILE_OUTvec.size(); ++i) OIIO_CHECK_EQUAL(osvec[i], PROFILE_OUTvec[i]); } OIIO_ADD_TEST(Config, SanityCheck) { { std::string SIMPLE_PROFILE = "ocio_profile_version: 1\n" "colorspaces:\n" " - !\n" " name: raw\n" " - !\n" " name: raw\n" "strictparsing: false\n" "roles:\n" " default: raw\n" "displays:\n" " sRGB:\n" " - ! {name: Raw, colorspace: raw}\n" "\n"; std::istringstream is; is.str(SIMPLE_PROFILE); OCIO::ConstConfigRcPtr config; OIIO_CHECK_THROW(config = OCIO::Config::CreateFromStream(is), OCIO::Exception); } { std::string SIMPLE_PROFILE = "ocio_profile_version: 1\n" "colorspaces:\n" " - !\n" " name: raw\n" "strictparsing: false\n" "roles:\n" " default: raw\n" "displays:\n" " sRGB:\n" " - ! {name: Raw, colorspace: raw}\n" "\n"; std::istringstream is; is.str(SIMPLE_PROFILE); OCIO::ConstConfigRcPtr config; OIIO_CHECK_NO_THROW(config = OCIO::Config::CreateFromStream(is)); OIIO_CHECK_NO_THROW(config->sanityCheck()); } } OIIO_ADD_TEST(Config, EnvCheck) { { std::string SIMPLE_PROFILE = "ocio_profile_version: 1\n" "environment:\n" " SHOW: super\n" " SHOT: test\n" " SEQ: foo\n" " test: bar${cheese}\n" " cheese: chedder\n" "colorspaces:\n" " - !\n" " name: raw\n" "strictparsing: false\n" "roles:\n" " default: raw\n" "displays:\n" " sRGB:\n" " - ! {name: Raw, colorspace: raw}\n" "\n"; std::string SIMPLE_PROFILE2 = "ocio_profile_version: 1\n" "colorspaces:\n" " - !\n" " name: raw\n" "strictparsing: false\n" "roles:\n" " default: raw\n" "displays:\n" " sRGB:\n" " - ! {name: Raw, colorspace: raw}\n" "\n"; std::string test("SHOW=bar"); putenv((char *)test.c_str()); std::string test2("TASK=lighting"); putenv((char *)test2.c_str()); std::istringstream is; is.str(SIMPLE_PROFILE); OCIO::ConstConfigRcPtr config; OIIO_CHECK_NO_THROW(config = OCIO::Config::CreateFromStream(is)); OIIO_CHECK_EQUAL(config->getNumEnvironmentVars(), 5); OIIO_CHECK_ASSERT(strcmp(config->getCurrentContext()->resolveStringVar("test${test}"), "testbarchedder") == 0); OIIO_CHECK_ASSERT(strcmp(config->getCurrentContext()->resolveStringVar("${SHOW}"), "bar") == 0); OIIO_CHECK_ASSERT(strcmp(config->getEnvironmentVarDefault("SHOW"), "super") == 0); OCIO::ConfigRcPtr edit = config->createEditableCopy(); edit->clearEnvironmentVars(); OIIO_CHECK_EQUAL(edit->getNumEnvironmentVars(), 0); edit->addEnvironmentVar("testing", "dupvar"); edit->addEnvironmentVar("testing", "dupvar"); edit->addEnvironmentVar("foobar", "testing"); edit->addEnvironmentVar("blank", ""); edit->addEnvironmentVar("dontadd", NULL); OIIO_CHECK_EQUAL(edit->getNumEnvironmentVars(), 3); edit->addEnvironmentVar("foobar", NULL); // remove OIIO_CHECK_EQUAL(edit->getNumEnvironmentVars(), 2); edit->clearEnvironmentVars(); edit->addEnvironmentVar("SHOW", "super"); edit->addEnvironmentVar("SHOT", "test"); edit->addEnvironmentVar("SEQ", "foo"); edit->addEnvironmentVar("test", "bar${cheese}"); edit->addEnvironmentVar("cheese", "chedder"); //Test OCIO::LoggingLevel loglevel = OCIO::GetLoggingLevel(); OCIO::SetLoggingLevel(OCIO::LOGGING_LEVEL_DEBUG); is.str(SIMPLE_PROFILE2); OCIO::ConstConfigRcPtr noenv; OIIO_CHECK_NO_THROW(noenv = OCIO::Config::CreateFromStream(is)); OIIO_CHECK_ASSERT(strcmp(noenv->getCurrentContext()->resolveStringVar("${TASK}"), "lighting") == 0); OCIO::SetLoggingLevel(loglevel); OIIO_CHECK_EQUAL(edit->getEnvironmentMode(), OCIO::ENV_ENVIRONMENT_LOAD_PREDEFINED); edit->setEnvironmentMode(OCIO::ENV_ENVIRONMENT_LOAD_ALL); OIIO_CHECK_EQUAL(edit->getEnvironmentMode(), OCIO::ENV_ENVIRONMENT_LOAD_ALL); } } OIIO_ADD_TEST(Config, RoleWithoutColorSpace) { OCIO::ConfigRcPtr config = OCIO::Config::Create()->createEditableCopy(); config->setRole("reference", "UnknownColorSpace"); std::ostringstream os; OIIO_CHECK_THROW(config->serialize(os), OCIO::Exception); } OIIO_ADD_TEST(Config, Env_colorspace_name) { const std::string MY_OCIO_CONFIG = "ocio_profile_version: 1\n" "\n" "search_path: luts\n" "strictparsing: true\n" "luma: [0.2126, 0.7152, 0.0722]\n" "\n" "roles:\n" " compositing_log: lgh\n" " default: raw\n" " scene_linear: lnh\n" "\n" "displays:\n" " sRGB:\n" " - ! {name: Raw, colorspace: raw}\n" "\n" "active_displays: []\n" "active_views: []\n" "\n" "colorspaces:\n" " - !\n" " name: raw\n" " family: \"\"\n" " equalitygroup: \"\"\n" " bitdepth: unknown\n" " isdata: false\n" " allocation: uniform\n" "\n" " - !\n" " name: lnh\n" " family: \"\"\n" " equalitygroup: \"\"\n" " bitdepth: unknown\n" " isdata: false\n" " allocation: uniform\n" "\n" " - !\n" " name: lgh\n" " family: \"\"\n" " equalitygroup: \"\"\n" " bitdepth: unknown\n" " isdata: false\n" " allocation: uniform\n" " allocationvars: [-0.125, 1.125]\n" " from_reference: ! {src: raw, dst: $CAMERARAW}\n"; { // Test when the env. variable is missing std::istringstream is; is.str(MY_OCIO_CONFIG); OCIO::ConstConfigRcPtr config; OIIO_CHECK_NO_THROW(config = OCIO::Config::CreateFromStream(is)); OIIO_CHECK_NO_THROW(config->sanityCheck()); OIIO_CHECK_THROW(config->getProcessor("raw", "lgh"), OCIO::Exception); } { char * env = (char *)"CAMERARAW=lnh"; putenv(env); std::istringstream is; is.str(MY_OCIO_CONFIG); OCIO::ConstConfigRcPtr config; OIIO_CHECK_NO_THROW(config = OCIO::Config::CreateFromStream(is)); OIIO_CHECK_NO_THROW(config->sanityCheck()); OIIO_CHECK_NO_THROW(config->getProcessor("raw", "lgh")); } { // Test when the env. variable content is wrong char * env = (char *)"CAMERARAW=FaultyColorSpaceName"; putenv(env); std::istringstream is; is.str(MY_OCIO_CONFIG); OCIO::ConstConfigRcPtr config; OIIO_CHECK_NO_THROW(config = OCIO::Config::CreateFromStream(is)); OIIO_CHECK_NO_THROW(config->sanityCheck()); OIIO_CHECK_THROW(config->getProcessor("raw", "lgh"), OCIO::Exception); } { // Check that the serialization preserves the env. variable std::istringstream is; is.str(MY_OCIO_CONFIG); OCIO::ConstConfigRcPtr config; OIIO_CHECK_NO_THROW(config = OCIO::Config::CreateFromStream(is)); OIIO_CHECK_NO_THROW(config->sanityCheck()); std::stringstream ss; ss << *config.get(); OIIO_CHECK_EQUAL(ss.str(), MY_OCIO_CONFIG); } } #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/Lut3DOp.h0000644000175000017500000000741513223553423017417 0ustar mfvmfv/* 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_OCIO_LUT3DOP_H #define INCLUDED_OCIO_LUT3DOP_H #include #include "Mutex.h" #include "Op.h" #include OCIO_NAMESPACE_ENTER { // TODO: turn into a class instead of a struct? struct Lut3D; typedef OCIO_SHARED_PTR Lut3DRcPtr; struct Lut3D { static Lut3DRcPtr Create(); float from_min[3]; float from_max[3]; int size[3]; typedef std::vector fv_t; fv_t lut; std::string getCacheID() const; private: Lut3D(); mutable std::string m_cacheID; mutable Mutex m_cacheidMutex; }; // RGB channel ordering. // Pixels ordered in such a way that the blue coordinate changes fastest, // then the green coordinate, and finally, the red coordinate changes slowest inline int GetLut3DIndex_B(int indexR, int indexG, int indexB, int sizeR, int sizeG, int /*sizeB*/) { return 3 * (indexR + sizeR * (indexG + sizeG * indexB)); } // RGB channel ordering. // Pixels ordered in such a way that the red coordinate changes fastest, // then the green coordinate, and finally, the blue coordinate changes slowest inline int GetLut3DIndex_R(int indexR, int indexG, int indexB, int /*sizeR*/, int sizeG, int sizeB) { return 3 * (indexB + sizeB * (indexG + sizeG * indexR)); } // What is the preferred order for the lut3d? // I.e., are the first two entries change along // the blue direction, or the red direction? // OpenGL expects 'red' enum Lut3DOrder { LUT3DORDER_FAST_RED = 0, LUT3DORDER_FAST_BLUE }; void GenerateIdentityLut3D(float* img, int edgeLen, int numChannels, Lut3DOrder lut3DOrder); // Essentially the cube root, but will throw an exception if the // cuberoot is not exact. int Get3DLutEdgeLenFromNumPixels(int numPixels); void CreateLut3DOp(OpRcPtrVec & ops, Lut3DRcPtr lut, Interpolation interpolation, TransformDirection direction); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/HashUtils.cpp0000644000175000017500000000510113223553423020412 0ustar mfvmfv/* 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 #include "HashUtils.h" #include "md5/md5.h" #include #include OCIO_NAMESPACE_ENTER { std::string CacheIDHash(const char * array, int size) { md5_state_t state; md5_byte_t digest[16]; md5_init(&state); md5_append(&state, (const md5_byte_t *)array, size); md5_finish(&state, digest); return GetPrintableHash(digest); } std::string GetPrintableHash(const md5_byte_t * digest) { static char charmap[] = "0123456789abcdef"; char printableResult[34]; char *ptr = printableResult; // build a printable string from unprintable chars. first character // of hashed cache IDs is '$', to later check if it's already been hashed *ptr++ = '$'; for (int i=0;i<16;++i) { *ptr++ = charmap[(digest[i] & 0x0F)]; *ptr++ = charmap[(digest[i] >> 4)]; } *ptr++ = 0; return std::string(printableResult); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/Transform.cpp0000644000175000017500000001530213223553423020465 0ustar mfvmfv/* 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 #include "FileTransform.h" #include "OpBuilders.h" #include "Processor.h" #include OCIO_NAMESPACE_ENTER { Transform::~Transform() { } void BuildOps(OpRcPtrVec & ops, const Config & config, const ConstContextRcPtr & context, const ConstTransformRcPtr & transform, TransformDirection dir) { // A null transform is valid, and corresponds to a no-op. if(!transform) return; if(ConstAllocationTransformRcPtr allocationTransform = \ DynamicPtrCast(transform)) { BuildAllocationOps(ops, config, *allocationTransform, dir); } else if(ConstCDLTransformRcPtr cdlTransform = \ DynamicPtrCast(transform)) { BuildCDLOps(ops, config, *cdlTransform, dir); } else if(ConstColorSpaceTransformRcPtr colorSpaceTransform = \ DynamicPtrCast(transform)) { BuildColorSpaceOps(ops, config, context, *colorSpaceTransform, dir); } else if(ConstDisplayTransformRcPtr displayTransform = \ DynamicPtrCast(transform)) { BuildDisplayOps(ops, config, context, *displayTransform, dir); } else if(ConstExponentTransformRcPtr exponentTransform = \ DynamicPtrCast(transform)) { BuildExponentOps(ops, config, *exponentTransform, dir); } else if(ConstFileTransformRcPtr fileTransform = \ DynamicPtrCast(transform)) { BuildFileOps(ops, config, context, *fileTransform, dir); } else if(ConstGroupTransformRcPtr groupTransform = \ DynamicPtrCast(transform)) { BuildGroupOps(ops, config, context, *groupTransform, dir); } else if(ConstLogTransformRcPtr logTransform = \ DynamicPtrCast(transform)) { BuildLogOps(ops, config, *logTransform, dir); } else if(ConstLookTransformRcPtr lookTransform = \ DynamicPtrCast(transform)) { BuildLookOps(ops, config, context, *lookTransform, dir); } else if(ConstMatrixTransformRcPtr matrixTransform = \ DynamicPtrCast(transform)) { BuildMatrixOps(ops, config, *matrixTransform, dir); } else if(ConstTruelightTransformRcPtr truelightTransform = \ DynamicPtrCast(transform)) { BuildTruelightOps(ops, config, *truelightTransform, dir); } else { std::ostringstream os; os << "Unknown transform type for Op Creation."; throw Exception(os.str().c_str()); } } std::ostream& operator<< (std::ostream & os, const Transform & transform) { const Transform* t = &transform; if(const AllocationTransform * allocationTransform = \ dynamic_cast(t)) { os << *allocationTransform; } else if(const CDLTransform * cdlTransform = \ dynamic_cast(t)) { os << *cdlTransform; } else if(const ColorSpaceTransform * colorSpaceTransform = \ dynamic_cast(t)) { os << *colorSpaceTransform; } else if(const DisplayTransform * displayTransform = \ dynamic_cast(t)) { os << *displayTransform; } else if(const ExponentTransform * exponentTransform = \ dynamic_cast(t)) { os << *exponentTransform; } else if(const FileTransform * fileTransform = \ dynamic_cast(t)) { os << *fileTransform; } else if(const GroupTransform * groupTransform = \ dynamic_cast(t)) { os << *groupTransform; } else if(const LogTransform * logTransform = \ dynamic_cast(t)) { os << *logTransform; } else if(const LookTransform * lookTransform = \ dynamic_cast(t)) { os << *lookTransform; } else if(const MatrixTransform * matrixTransform = \ dynamic_cast(t)) { os << *matrixTransform; } else if(const TruelightTransform * truelightTransform = \ dynamic_cast(t)) { os << *truelightTransform; } else { std::ostringstream error; os << "Unknown transform type for serialization."; throw Exception(error.str().c_str()); } return os; } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatSpiMtx.cpp0000644000175000017500000001554313223553423021716 0ustar mfvmfv/* 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 #include "FileTransform.h" #include "MatrixOps.h" #include "ParseUtils.h" #include "pystring/pystring.h" #include #include #include OCIO_NAMESPACE_ENTER { //////////////////////////////////////////////////////////////// namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile() { memset(m44, 0, 16*sizeof(float)); memset(offset4, 0, 4*sizeof(float)); }; ~LocalCachedFile() {}; float m44[16]; float offset4[4]; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "spimtx"; info.extension = "spimtx"; info.capabilities = FORMAT_CAPABILITY_READ; formatInfoVec.push_back(info); } CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { // Read the entire file. std::ostringstream fileStream; { const int MAX_LINE_SIZE = 4096; char lineBuffer[MAX_LINE_SIZE]; while (istream.good()) { istream.getline(lineBuffer, MAX_LINE_SIZE); fileStream << std::string(lineBuffer) << " "; } } // Turn it into parts std::vector lineParts; pystring::split(pystring::strip(fileStream.str()), lineParts); if(lineParts.size() != 12) { std::ostringstream os; os << "Error parsing .spimtx file. "; os << "File must contain 12 float entries. "; os << lineParts.size() << " found."; throw Exception(os.str().c_str()); } // Turn the parts into floats std::vector floatArray; if(!StringVecToFloatVec(floatArray, lineParts)) { std::ostringstream os; os << "Error parsing .spimtx file. "; os << "File must contain all float entries. "; throw Exception(os.str().c_str()); } // Put the bits in the right place LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile()); cachedFile->m44[0] = floatArray[0]; cachedFile->m44[1] = floatArray[1]; cachedFile->m44[2] = floatArray[2]; cachedFile->m44[3] = 0.0f; cachedFile->m44[4] = floatArray[4]; cachedFile->m44[5] = floatArray[5]; cachedFile->m44[6] = floatArray[6]; cachedFile->m44[7] = 0.0f; cachedFile->m44[8] = floatArray[8]; cachedFile->m44[9] = floatArray[9]; cachedFile->m44[10] = floatArray[10]; cachedFile->m44[11] = 0.0f; cachedFile->m44[12] = 0.0f; cachedFile->m44[13] = 0.0f; cachedFile->m44[14] = 0.0f; cachedFile->m44[15] = 1.0f; cachedFile->offset4[0] = floatArray[3] / 65535.0f; cachedFile->offset4[1] = floatArray[7] / 65535.0f; cachedFile->offset4[2] = floatArray[11] / 65535.0f; cachedFile->offset4[3] = 0.0f; return cachedFile; } void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops, const Config& /*config*/, const ConstContextRcPtr & /*context*/, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { LocalCachedFileRcPtr cachedFile = DynamicPtrCast(untypedCachedFile); if(!cachedFile) // This should never happen. { std::ostringstream os; os << "Cannot build SpiMtx Ops. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); CreateMatrixOffsetOp(ops, cachedFile->m44, cachedFile->offset4, newDir); } } FileFormat * CreateFileFormatSpiMtx() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/ImagePacking.h0000644000175000017500000000512113223553423020474 0ustar mfvmfv/* 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_OCIO_IMAGEPACKING_H #define INCLUDED_OCIO_IMAGEPACKING_H #include OCIO_NAMESPACE_ENTER { struct GenericImageDesc { long width; long height; ptrdiff_t xStrideBytes; ptrdiff_t yStrideBytes; float* rData; float* gData; float* bData; float* aData; GenericImageDesc(); ~GenericImageDesc(); // Resolves all AutoStride void init(const ImageDesc& img); bool isPackedRGBA() const; }; void PackRGBAFromImageDesc(const GenericImageDesc& srcImg, float* outputBuffer, int* numPixelsCopied, int outputBufferSize, long imagePixelStartIndex); void UnpackRGBAToImageDesc(GenericImageDesc& dstImg, float* inputBuffer, int numPixelsToUnpack, long imagePixelStartIndex); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/MathUtils.h0000644000175000017500000001360113223553423020071 0ustar mfvmfv/* 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_OCIO_MATHUTILS_H #define INCLUDED_OCIO_MATHUTILS_H #include #include #include #include "Op.h" #include "Platform.h" #ifdef WINDOWS #include #endif OCIO_NAMESPACE_ENTER { // From Imath //-------------------------------------------------------------------------- // Compare two numbers and test if they are "approximately equal": // // equalWithAbsError (x1, x2, e) // // Returns true if x1 is the same as x2 with an absolute error of // no more than e, // // abs (x1 - x2) <= e // // equalWithRelError (x1, x2, e) // // Returns true if x1 is the same as x2 with an relative error of // no more than e, // // abs (x1 - x2) <= e * x1 // //-------------------------------------------------------------------------- inline bool equalWithAbsError (float x1, float x2, float e) { return ((x1 > x2)? x1 - x2: x2 - x1) <= e; } inline bool equalWithRelError (float x1, float x2, float e) { return ((x1 > x2)? x1 - x2: x2 - x1) <= e * ((x1 > 0)? x1: -x1); } inline float lerpf(float a, float b, float z) { return (b - a) * z + a; } #ifdef WINDOWS inline double round (float val) { return floor (val + 0.5); } inline float roundf (float val) { return static_cast(round (val)); } inline int isnan (float val) { // Windows uses a non-standard version of 'isnan' return _isnan (val); } #else #ifdef ANDROID // support std::isnan - needs to be tested as it might not be part of the NDK #define _GLIBCXX_USE_C99_MATH 1 #endif // This lets all platforms just use isnan, within the OCIO namespace, // across all platforms. (Windows defines the function above). using std::isnan; #endif // Checks within fltmin tolerance bool IsScalarEqualToZero(float v); bool IsScalarEqualToOne(float v); bool IsScalarEqualToZeroFlt(double v); bool IsScalarEqualToOneFlt(double v); // Are all the vector components the specified value? bool IsVecEqualToZero(const float* v, int size); bool IsVecEqualToOne(const float* v, int size); bool IsVecEqualToOneFlt(const double* v, int size); // Is at least one of the specified components equal to 0? bool VecContainsZero(const float* v, int size); bool VecContainsOne(const float* v, int size); // Are two vectors equal? (Same size, same values?) bool VecsEqualWithRelError(const float* v1, int size1, const float* v2, int size2, float e); inline double GetHalfMax() { return 65504.0; // Largest positive half } inline double GetHalfMin() { return 5.96046448e-08; // Smallest positive half; } inline double GetHalfNormMin() { return 6.10351562e-05; // Smallest positive normalized half } //! Clamp the specified value to the valid range of normalized half. // (can be either positive or negative though double ClampToNormHalf(double val); float GetSafeScalarInverse(float v, float defaultValue = 1.0); // All matrix / vector operations use the following sizing... // // m : 4x4 matrix // v : 4 column vector // Return the 4x4 inverse, and whether the inverse has succeeded. // Supports in-place operations bool GetM44Inverse(float* mout, const float* m); // Is an identity matrix? (with fltmin tolerance) bool IsM44Identity(const float* m); // Is this a purely diagonal matrix? bool IsM44Diagonal(const float* m); // Extract the diagonal void GetM44Diagonal(float* vout, const float* m); // Get the product, out = m1*m2 // Supports in-place operations void GetM44Product(float* mout, const float* m1, const float* m2); // Combine two transforms in the mx+b form, into a single transform // mout*x+vout == m2*(m1*x+v1)+v2 // Supports in-place operations void GetMxbCombine(float* mout, float* vout, const float* m1, const float* v1, const float* m2, const float* v2); // Supports in-place operations bool GetMxbInverse(float* mout, float* vout, const float* m, const float* v); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatCC.cpp0000644000175000017500000001266413223553423020760 0ustar mfvmfv/* 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 #include "FileTransform.h" #include "OpBuilders.h" OCIO_NAMESPACE_ENTER { //////////////////////////////////////////////////////////////// namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile () { transform = CDLTransform::Create(); }; ~LocalCachedFile() {}; CDLTransformRcPtr transform; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "ColorCorrection"; info.extension = "cc"; info.capabilities = FORMAT_CAPABILITY_READ; formatInfoVec.push_back(info); } // Try and load the format // Raise an exception if it can't be loaded. CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { std::ostringstream rawdata; rawdata << istream.rdbuf(); LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile()); try { cachedFile->transform->setXML(rawdata.str().c_str()); } catch(Exception & e) { std::ostringstream os; os << "Error parsing .cc file. "; os << "Does not appear to contain a valid ASC CDL XML:"; os << e.what(); throw Exception(os.str().c_str()); } return cachedFile; } void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & /*context*/, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { LocalCachedFileRcPtr cachedFile = DynamicPtrCast(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build .cc Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_UNKNOWN) { std::ostringstream os; os << "Cannot build file format transform,"; os << " unspecified transform direction."; throw Exception(os.str().c_str()); } BuildCDLOps(ops, config, *cachedFile->transform, newDir); } } FileFormat * CreateFileFormatCC() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/FileFormat3DL.cpp0000644000175000017500000006037713223553423021061 0ustar mfvmfv/* 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 #include "FileTransform.h" #include "Lut1DOp.h" #include "Lut3DOp.h" #include "MathUtils.h" #include "ParseUtils.h" #include "pystring/pystring.h" #include #include #include #include /* // Discreet's Flame Lut Format // Use a loose interpretation of the format to allow other 3d luts that look // similar, but dont strictly adhere to the real definition. // If line starts with text or # skip it // If line is a bunch of ints (more than 3) , it's the 1d shaper lut // All remaining lines of size 3 int are data // cube size is determined from num entries // The bit depth of the shaper lut and the 3d lut need not be the same. Example 1, FLAME # Comment here 0 64 128 192 256 320 384 448 512 576 640 704 768 832 896 960 1023 0 0 0 0 0 100 0 0 200 Example 2, LUSTRE #Tokens required by applications - do not edit 3DMESH Mesh 4 12 0 64 128 192 256 320 384 448 512 576 640 704 768 832 896 960 1023 0 17 17 0 0 88 0 0 157 9 101 197 0 118 308 ... 4092 4094 4094 #Tokens required by applications - do not edit LUT8 gamma 1.0 In this example, the 3D LUT has an input bit depth of 4 bits and an output bit depth of 12 bits. You use the input value to calculate the RGB triplet to be 17*17*17 (where 17=(2 to the power of 4)+1, and 4 is the input bit depth). The first triplet is the output value at (0,0,0);(0,0,1);...; (0,0,16) r,g,b coordinates; the second triplet is the output value at (0,1,0);(0,1,1);...;(0,1,16) r,g,b coordinates; and so on. You use the output bit depth to set the output bit depth range (12 bits or 0-4095). NoteLustre supports an input and output depth of 16 bits for 3D LUTs; however, in the processing pipeline, the BLACK_LEVEL to WHITE_LEVEL range is only 14 bits. This means that even if the 3D LUT is 16 bits, it is normalized to fit the BLACK_LEVEL to WHITE_LEVEL range of Lustre. In Lustre, 3D LUT files can contain grids of 17 cubed, 33 cubed, and 65 cubed; however, Lustre converts 17 cubed and 65 cubed grids to 33 cubed for internal processing on the output (for rendering and calibration), but not on the input 3D LUT. */ OCIO_NAMESPACE_ENTER { //////////////////////////////////////////////////////////////// namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile () : has1D(false), has3D(false) { lut1D = Lut1D::Create(); lut3D = Lut3D::Create(); }; ~LocalCachedFile() {}; bool has1D; bool has3D; Lut1DRcPtr lut1D; Lut3DRcPtr lut3D; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void Write(const Baker & baker, const std::string & formatName, std::ostream & ostream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; // We use the maximum value found in the lut to infer // the bit depth. While this is fugly. We dont believe // there is a better way, looking at the file, to // determine this. // // Note: We allow for 2x overshoot in the luts. // As we dont allow for odd bit depths, this isnt a big deal. // So sizes from 1/2 max - 2x max are valid // // FILE EXPECTED MAX CORRECTLY DECODED IF MAX IN THIS RANGE // 8-bit 255 [0, 511] // 10-bit 1023 [512, 2047] // 12-bit 4095 [2048, 8191] // 14-bit 16383 [8192, 32767] // 16-bit 65535 [32768, 131071+] int GetLikelyLutBitDepth(int testval) { const int MIN_BIT_DEPTH = 8; const int MAX_BIT_DEPTH = 16; if(testval < 0) return -1; // Only test even bit depths for(int bitDepth = MIN_BIT_DEPTH; bitDepth <= MAX_BIT_DEPTH; bitDepth+=2) { int maxcode = static_cast(pow(2.0,bitDepth)); int adjustedMax = maxcode * 2 - 1; if(testval<=adjustedMax) return bitDepth; } return MAX_BIT_DEPTH; } int GetMaxValueFromIntegerBitDepth(int bitDepth) { return static_cast( pow(2.0, bitDepth) ) - 1; } int GetClampedIntFromNormFloat(float val, float scale) { val = std::min(std::max(0.0f, val), 1.0f) * scale; return static_cast(roundf(val)); } void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "flame"; info.extension = "3dl"; info.capabilities = (FORMAT_CAPABILITY_READ | FORMAT_CAPABILITY_WRITE); formatInfoVec.push_back(info); FormatInfo info2 = info; info2.name = "lustre"; formatInfoVec.push_back(info2); } // Try and load the format // Raise an exception if it can't be loaded. CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { std::vector rawshaper; std::vector raw3d; // Parse the file 3d lut data to an int array { const int MAX_LINE_SIZE = 4096; char lineBuffer[MAX_LINE_SIZE]; std::vector lineParts; std::vector tmpData; while(istream.good()) { istream.getline(lineBuffer, MAX_LINE_SIZE); // Strip and split the line pystring::split(pystring::strip(lineBuffer), lineParts); if(lineParts.empty()) continue; if((lineParts.size() > 0) && pystring::startswith(lineParts[0],"#")) continue; // If we havent found a list of ints, continue if(!StringVecToIntVec(tmpData, lineParts)) continue; // If we've found more than 3 ints, and dont have // a shaper lut yet, we've got it! if(tmpData.size()>3 && rawshaper.empty()) { for(unsigned int i=0; ihas1D = true; // Find the maximum shaper lut value to infer bit-depth int shapermax = 0; for(unsigned int i=0; i(bitdepthmax); for(int channel=0; channel<3; ++channel) { cachedFile->lut1D->luts[channel].resize(rawshaper.size()); for(unsigned int i=0; ilut1D->luts[channel][i] = static_cast(rawshaper[i])*scale; } } // The error threshold will be 2 code values. This will allow // shaper luts which use different int conversions (round vs. floor) // to both be optimized. // Required: Abs Tolerance const int FORMAT3DL_SHAPER_CODEVALUE_TOLERANCE = 2; cachedFile->lut1D->maxerror = FORMAT3DL_SHAPER_CODEVALUE_TOLERANCE*scale; cachedFile->lut1D->errortype = ERROR_ABSOLUTE; } // Interpret the parsed data. if(!raw3d.empty()) { cachedFile->has3D = true; // Find the maximum shaper lut value to infer bit-depth int lut3dmax = 0; for(unsigned int i=0; i(bitdepthmax); // Interpret the int array as a 3dlut int lutEdgeLen = Get3DLutEdgeLenFromNumPixels((int)raw3d.size()/3); // Reformat 3D data cachedFile->lut3D->size[0] = lutEdgeLen; cachedFile->lut3D->size[1] = lutEdgeLen; cachedFile->lut3D->size[2] = lutEdgeLen; cachedFile->lut3D->lut.reserve(lutEdgeLen * lutEdgeLen * lutEdgeLen * 3); for(int rIndex=0; rIndexlut3D->lut.push_back(static_cast(raw3d[i+0]) * scale); cachedFile->lut3D->lut.push_back(static_cast(raw3d[i+1]) * scale); cachedFile->lut3D->lut.push_back(static_cast(raw3d[i+2]) * scale); } } } } return cachedFile; } // 65 -> 6 // 33 -> 5 // 17 -> 4 int CubeDimensionLenToLustreBitDepth(int size) { float logval = logf(static_cast(size-1)) / logf(2.0); return static_cast(logval); } void LocalFileFormat::Write(const Baker & baker, const std::string & formatName, std::ostream & ostream) const { int DEFAULT_CUBE_SIZE = 0; int SHAPER_BIT_DEPTH = 10; int CUBE_BIT_DEPTH = 12; if(formatName == "lustre") { DEFAULT_CUBE_SIZE = 33; } else if(formatName == "flame") { DEFAULT_CUBE_SIZE = 17; } else { std::ostringstream os; os << "Unknown 3dl format name, '"; os << formatName << "'."; throw Exception(os.str().c_str()); } ConstConfigRcPtr config = baker.getConfig(); int cubeSize = baker.getCubeSize(); if(cubeSize==-1) cubeSize = DEFAULT_CUBE_SIZE; cubeSize = std::max(2, cubeSize); // smallest cube is 2x2x2 int shaperSize = baker.getShaperSize(); if(shaperSize==-1) shaperSize = cubeSize; std::vector cubeData; cubeData.resize(cubeSize*cubeSize*cubeSize*3); GenerateIdentityLut3D(&cubeData[0], cubeSize, 3, LUT3DORDER_FAST_BLUE); PackedImageDesc cubeImg(&cubeData[0], cubeSize*cubeSize*cubeSize, 1, 3); // Apply our conversion from the input space to the output space. ConstProcessorRcPtr inputToTarget; std::string looks = baker.getLooks(); if (!looks.empty()) { LookTransformRcPtr transform = LookTransform::Create(); transform->setLooks(looks.c_str()); transform->setSrc(baker.getInputSpace()); transform->setDst(baker.getTargetSpace()); inputToTarget = config->getProcessor(transform, TRANSFORM_DIR_FORWARD); } else { inputToTarget = config->getProcessor(baker.getInputSpace(), baker.getTargetSpace()); } inputToTarget->apply(cubeImg); // Write out the file. // For for maximum compatibility with other apps, we will // not utilize the shaper or output any metadata if(formatName == "lustre") { int meshInputBitDepth = CubeDimensionLenToLustreBitDepth(cubeSize); ostream << "3DMESH\n"; ostream << "Mesh " << meshInputBitDepth << " " << CUBE_BIT_DEPTH << "\n"; } std::vector shaperData(shaperSize); GenerateIdentityLut1D(&shaperData[0], shaperSize, 1); float shaperScale = static_cast( GetMaxValueFromIntegerBitDepth(SHAPER_BIT_DEPTH)); for(unsigned int i=0; i( GetMaxValueFromIntegerBitDepth(CUBE_BIT_DEPTH)); if(cubeSize < 2) { throw Exception("Internal cube size exception."); } for(int i=0; i(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build .3dl Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_UNKNOWN) { std::ostringstream os; os << "Cannot build file format transform,"; os << " unspecified transform direction."; throw Exception(os.str().c_str()); } // TODO: INTERP_LINEAR should not be hard-coded. // Instead query 'highest' interpolation? // (right now, it's linear). If cubic is added, consider // using it if(newDir == TRANSFORM_DIR_FORWARD) { if(cachedFile->has1D) { CreateLut1DOp(ops, cachedFile->lut1D, INTERP_LINEAR, newDir); } if(cachedFile->has3D) { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } } else if(newDir == TRANSFORM_DIR_INVERSE) { if(cachedFile->has3D) { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } if(cachedFile->has1D) { CreateLut1DOp(ops, cachedFile->lut1D, INTERP_LINEAR, newDir); } } } } FileFormat * CreateFileFormat3DL() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" // FILE EXPECTED MAX CORRECTLY DECODED IF MAX IN THIS RANGE // 8-bit 255 [0, 511] // 10-bit 1023 [512, 2047] // 12-bit 4095 [2048, 8191] // 14-bit 16383 [8192, 32767] // 16-bit 65535 [32768, 131071] OIIO_ADD_TEST(FileFormat3DL, GetLikelyLutBitDepth) { OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(-1), -1); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(0), 8); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(1), 8); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(255), 8); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(256), 8); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(511), 8); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(512), 10); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(1023), 10); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(1024), 10); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(2047), 10); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(2048), 12); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(4095), 12); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(4096), 12); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(8191), 12); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(16383), 14); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(65535), 16); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(65536), 16); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(131071), 16); OIIO_CHECK_EQUAL(OCIO::GetLikelyLutBitDepth(131072), 16); } #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/Exception.cpp0000644000175000017500000000446313223553423020456 0ustar mfvmfv/* 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 OCIO_NAMESPACE_ENTER { Exception::Exception(const char * msg) throw() : std::exception(), msg_(msg) {} Exception::Exception(const Exception& e) throw() : std::exception(), msg_(e.msg_) {} //*** operator= Exception& Exception::operator=(const Exception& e) throw() { msg_ = e.msg_; return *this; } //*** ~Exception Exception::~Exception() throw() { } //*** what const char* Exception::what() const throw() { return msg_.c_str(); } ExceptionMissingFile::ExceptionMissingFile(const char * msg) throw() : Exception(msg) {} ExceptionMissingFile::ExceptionMissingFile(const ExceptionMissingFile& e) throw() : Exception(e) {} } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/LookParse.h0000644000175000017500000000524213223553423020060 0ustar mfvmfv/* 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_OCIO_PARSED_LOOK_H #define INCLUDED_OCIO_PARSED_LOOK_H #include #include OCIO_NAMESPACE_ENTER { // Looks parse structures // This is contains a list, where each option entry corresponds to // an "or" separated looks token list. // I.e, " +cc,-onset | +cc " parses to TWO options: (+cc,-onset), (+cc) class LookParseResult { public: struct Token { std::string name; TransformDirection dir; Token(): dir(TRANSFORM_DIR_FORWARD) {} void parse(const std::string & str); void serialize(std::ostream & os) const; }; typedef std::vector Tokens; static void serialize(std::ostream & os, const Tokens & tokens); typedef std::vector Options; const Options & parse(const std::string & looksstr); const Options & getOptions() const; bool empty() const; void reverse(); private: Options m_options; }; } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/PathUtils.cpp0000644000175000017500000002070413223553423020431 0ustar mfvmfv/* 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 #include #include #include #include #include #include #include #include "Mutex.h" #include "PathUtils.h" #include "Platform.h" #include "pystring/pystring.h" #if !defined(WINDOWS) #include #else #include #define MAXPATHLEN 4096 #endif #if defined(__APPLE__) && !defined(__IPHONE__) #include // _NSGetEnviron() #include #elif !defined(WINDOWS) #include extern char **environ; #endif OCIO_NAMESPACE_ENTER { namespace { std::string ComputeHash(const std::string & filename) { struct stat results; if (stat(filename.c_str(), &results) == 0) { // Treat the mtime + inode as a proxy for the contents std::ostringstream fasthash; fasthash << results.st_ino << ":"; fasthash << results.st_mtime; return fasthash.str(); } return ""; } // We mutex both the main map and each item individually, so that // the potentially slow stat calls dont block other lookups to already // existing items. (The stat calls will block other lookups on the // *same* file though). struct FileHashResult { Mutex mutex; std::string hash; bool ready; FileHashResult(): ready(false) {} }; typedef OCIO_SHARED_PTR FileHashResultPtr; typedef std::map FileCacheMap; FileCacheMap g_fastFileHashCache; Mutex g_fastFileHashCache_mutex; } std::string GetFastFileHash(const std::string & filename) { FileHashResultPtr fileHashResultPtr; { AutoMutex lock(g_fastFileHashCache_mutex); FileCacheMap::iterator iter = g_fastFileHashCache.find(filename); if(iter != g_fastFileHashCache.end()) { fileHashResultPtr = iter->second; } else { fileHashResultPtr = FileHashResultPtr(new FileHashResult); g_fastFileHashCache[filename] = fileHashResultPtr; } } std::string hash; { AutoMutex lock(fileHashResultPtr->mutex); if(!fileHashResultPtr->ready) { fileHashResultPtr->ready = true; fileHashResultPtr->hash = ComputeHash(filename); } hash = fileHashResultPtr->hash; } return hash; } bool FileExists(const std::string & filename) { std::string hash = GetFastFileHash(filename); return (!hash.empty()); } void ClearPathCaches() { AutoMutex lock(g_fastFileHashCache_mutex); g_fastFileHashCache.clear(); } namespace pystring { namespace os { std::string getcwd() { #ifdef WINDOWS char path[MAXPATHLEN]; _getcwd(path, MAXPATHLEN); return path; #else std::vector current_dir; #ifdef PATH_MAX current_dir.resize(PATH_MAX); #else current_dir.resize(1024); #endif while (::getcwd(¤t_dir[0], current_dir.size()) == NULL && errno == ERANGE) { current_dir.resize(current_dir.size() + 1024); } return std::string(¤t_dir[0]); #endif } namespace path { std::string abspath(const std::string & path) { std::string p = path; if(!isabs(p)) p = join(getcwd(), p); return normpath(p); } } // namespace path } // namespace os } namespace { inline char** GetEnviron() { #if __IPHONE__ // TODO: fix this return NULL; #elif __APPLE__ return (*_NSGetEnviron()); #else return environ; #endif } const int MAX_PATH_LENGTH = 4096; } void LoadEnvironment(EnvMap & map, bool update) { for (char **env = GetEnviron(); *env != NULL; ++env) { // split environment up into std::map[name] = value std::string env_str = (char*)*env; int pos = static_cast(env_str.find_first_of('=')); std::string name = env_str.substr(0, pos); std::string value = env_str.substr(pos+1, env_str.length()); if(update) { // update existing key:values that match EnvMap::iterator iter = map.find(name); if(iter != map.end()) iter->second = value; } else { map.insert(EnvMap::value_type(name, value)); } } } std::string EnvExpand(const std::string & str, const EnvMap & map) { // Early exit if no magic characters are found. if(pystring::find(str, "$") == -1 && pystring::find(str, "%") == -1) return str; std::string orig = str; std::string newstr = str; // This walks through the envmap in key order, // from longest to shortest to handle envvars which are // substrings. // ie. '$TEST_$TESTING_$TE' will expand in this order '2 1 3' for (EnvMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) { newstr = pystring::replace(newstr, ("${"+iter->first+"}"), iter->second); newstr = pystring::replace(newstr, ("$"+iter->first), iter->second); newstr = pystring::replace(newstr, ("%"+iter->first+"%"), iter->second); } // recursively call till string doesn't expand anymore if(newstr != orig) { return EnvExpand(newstr, map); } return orig; } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" OIIO_ADD_TEST(PathUtils, EnvExpand) { // build env by hand for unit test OCIO::EnvMap env_map; // = OCIO::GetEnvMap(); // add some fake env vars so the test runs env_map.insert(OCIO::EnvMap::value_type("TEST1", "foo.bar")); env_map.insert(OCIO::EnvMap::value_type("TEST1NG", "bar.foo")); env_map.insert(OCIO::EnvMap::value_type("FOO_foo.bar", "cheese")); // std::string foo = "/a/b/${TEST1}/${TEST1NG}/$TEST1/$TEST1NG/${FOO_${TEST1}}/"; std::string foo_result = "/a/b/foo.bar/bar.foo/foo.bar/bar.foo/cheese/"; std::string testresult = OCIO::EnvExpand(foo, env_map); OIIO_CHECK_ASSERT( testresult == foo_result ); } #endif // OCIO_BUILD_TESTS opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatIridasItx.cpp0000644000175000017500000003036313223553423022367 0ustar mfvmfv/* 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 #include #include #include #include #include "FileTransform.h" #include "Lut1DOp.h" #include "Lut3DOp.h" #include "ParseUtils.h" #include "pystring/pystring.h" /* Iridas itx format LUT_3D_SIZE M #LUT_3D_SIZE M #where M is the size of the texture #a 3D texture has the size M x M x M #e.g. LUT_3D_SIZE 16 creates a 16 x 16 x 16 3D texture #for 1D textures, the data is simply a list of floating point values, #three per line, in RGB order #for 3D textures, the data is also RGB, and ordered in such a way #that the red coordinate changes fastest, then the green coordinate, #and finally, the blue coordinate changes slowest: 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 1.0 1.0 0.0 0.0 0.0 1.0 1.0 0.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 */ OCIO_NAMESPACE_ENTER { namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile () { lut3D = Lut3D::Create(); }; ~LocalCachedFile() {}; Lut3DRcPtr lut3D; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void Write(const Baker & baker, const std::string & formatName, std::ostream & ostream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "iridas_itx"; info.extension = "itx"; info.capabilities = (FORMAT_CAPABILITY_READ | FORMAT_CAPABILITY_WRITE); formatInfoVec.push_back(info); } CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { // this shouldn't happen if(!istream) { throw Exception ("File stream empty when trying to read Iridas .itx lut"); } // Parse the file std::vector raw; int size3d[] = { 0, 0, 0 }; bool in3d = false; { std::string line; std::vector parts; std::vector tmpfloats; while(nextline(istream, line)) { // All lines starting with '#' are comments if(pystring::startswith(line,"#")) continue; // Strip, lowercase, and split the line pystring::split(pystring::lower(pystring::strip(line)), parts); if(parts.empty()) continue; if(pystring::lower(parts[0]) == "lut_3d_size") { int size = 0; if(parts.size() != 2 || !StringToInt( &size, parts[1].c_str())) { throw Exception("Malformed LUT_3D_SIZE tag in Iridas .itx lut."); } size3d[0] = size; size3d[1] = size; size3d[2] = size; raw.reserve(3*size3d[0]*size3d[1]*size3d[2]); in3d = true; } else if(in3d) { // It must be a float triple! if(!StringVecToFloatVec(tmpfloats, parts) || tmpfloats.size() != 3) { std::ostringstream os; os << "Malformed color triples specified in Iridas .itx lut:"; os << "'" << line << "'."; throw Exception(os.str().c_str()); } for(int i=0; i<3; ++i) { raw.push_back(tmpfloats[i]); } } } } // Interpret the parsed data, validate lut sizes LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile()); if(in3d) { if(size3d[0]*size3d[1]*size3d[2] != static_cast(raw.size()/3)) { std::ostringstream os; os << "Parse error in Iridas .itx lut. "; os << "Incorrect number of lut3d entries. "; os << "Found " << raw.size()/3 << ", expected " << size3d[0]*size3d[1]*size3d[2] << "."; throw Exception(os.str().c_str()); } // Reformat 3D data cachedFile->lut3D->size[0] = size3d[0]; cachedFile->lut3D->size[1] = size3d[1]; cachedFile->lut3D->size[2] = size3d[2]; cachedFile->lut3D->lut = raw; } else { std::ostringstream os; os << "Parse error in Iridas .itx lut. "; os << "Lut type (1D/3D) unspecified."; throw Exception(os.str().c_str()); } return cachedFile; } void LocalFileFormat::Write(const Baker & baker, const std::string & formatName, std::ostream & ostream) const { int DEFAULT_CUBE_SIZE = 64; if(formatName != "iridas_itx") { std::ostringstream os; os << "Unknown 3dl format name, '"; os << formatName << "'."; throw Exception(os.str().c_str()); } ConstConfigRcPtr config = baker.getConfig(); int cubeSize = baker.getCubeSize(); if(cubeSize==-1) cubeSize = DEFAULT_CUBE_SIZE; cubeSize = std::max(2, cubeSize); // smallest cube is 2x2x2 std::vector cubeData; cubeData.resize(cubeSize*cubeSize*cubeSize*3); GenerateIdentityLut3D(&cubeData[0], cubeSize, 3, LUT3DORDER_FAST_RED); PackedImageDesc cubeImg(&cubeData[0], cubeSize*cubeSize*cubeSize, 1, 3); // Apply our conversion from the input space to the output space. ConstProcessorRcPtr inputToTarget; std::string looks = baker.getLooks(); if (!looks.empty()) { LookTransformRcPtr transform = LookTransform::Create(); transform->setLooks(looks.c_str()); transform->setSrc(baker.getInputSpace()); transform->setDst(baker.getTargetSpace()); inputToTarget = config->getProcessor(transform, TRANSFORM_DIR_FORWARD); } else { inputToTarget = config->getProcessor(baker.getInputSpace(), baker.getTargetSpace()); } inputToTarget->apply(cubeImg); // Write out the file. // For for maximum compatibility with other apps, we will // not utilize the shaper or output any metadata ostream << "LUT_3D_SIZE " << cubeSize << "\n"; if(cubeSize < 2) { throw Exception("Internal cube size exception."); } // Set to a fixed 6 decimal precision ostream.setf(std::ios::fixed, std::ios::floatfield); ostream.precision(6); for(int i=0; i(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build Iridas .itx Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_UNKNOWN) { std::ostringstream os; os << "Cannot build file format transform,"; os << " unspecified transform direction."; throw Exception(os.str().c_str()); } // TODO: INTERP_LINEAR should not be hard-coded. // Instead query 'highest' interpolation? // (right now, it's linear). If cubic is added, consider // using it if(newDir == TRANSFORM_DIR_FORWARD) { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } else if(newDir == TRANSFORM_DIR_INVERSE) { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } } } FileFormat * CreateFileFormatIridasItx() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// opencolorio-1.1.0~dfsg0.orig/src/core/Mutex.h0000644000175000017500000001000413223553423017253 0ustar mfvmfv/* 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_OCIO_MUTEX_H #define INCLUDED_OCIO_MUTEX_H /* PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. 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. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER 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 BASED 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 DAMAGES. */ #include "Platform.h" // #define DEBUG_THREADING /** For internal use only */ OCIO_NAMESPACE_ENTER { #ifndef NDEBUG template class DebugLock : public T { public: DebugLock() : _locked(0) {} void lock() { T::lock(); _locked = 1; } void unlock() { assert(_locked); _locked = 0; T::unlock(); } bool locked() { return _locked != 0; } private: int _locked; }; #endif /** Automatically acquire and release lock within enclosing scope. */ template class AutoLock { public: AutoLock(T& m) : _m(m) { _m.lock(); } ~AutoLock() { _m.unlock(); } private: T& _m; }; #ifndef NDEBUG // add debug wrappers to mutex typedef DebugLock<_Mutex> Mutex; #else typedef _Mutex Mutex; #endif typedef AutoLock AutoMutex; } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/FileTransform.h0000644000175000017500000001303213223553423020730 0ustar mfvmfv/* 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_OCIO_FILETRANSFORM_H #define INCLUDED_OCIO_FILETRANSFORM_H #include #include #include "Op.h" #include "Processor.h" OCIO_NAMESPACE_ENTER { void ClearFileTransformCaches(); class CachedFile { public: CachedFile() {}; virtual ~CachedFile() {}; }; typedef OCIO_SHARED_PTR CachedFileRcPtr; const int FORMAT_CAPABILITY_NONE = 0; const int FORMAT_CAPABILITY_READ = 1; const int FORMAT_CAPABILITY_WRITE = 2; const int FORMAT_CAPABILITY_ALL = (FORMAT_CAPABILITY_READ | FORMAT_CAPABILITY_WRITE); struct FormatInfo { std::string name; // name must be globally unique std::string extension; // extension does not need to be unique int capabilities; FormatInfo(): capabilities(FORMAT_CAPABILITY_NONE) { } }; typedef std::vector FormatInfoVec; class FileFormat { public: virtual ~FileFormat(); virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const = 0; virtual CachedFileRcPtr Read(std::istream & istream) const = 0; virtual void Write(const Baker & baker, const std::string & formatName, std::ostream & ostream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config & config, const ConstContextRcPtr & context, CachedFileRcPtr cachedFile, const FileTransform & fileTransform, TransformDirection dir) const = 0; // For logging purposes std::string getName() const; private: FileFormat& operator= (const FileFormat &); }; typedef std::map FileFormatMap; typedef std::vector FileFormatVector; // TODO: This interface is ugly. What private API is actually appropriate? // Maybe, instead of exposing the raw formats, we wrap it? // FileCachePair GetFile(const std::string & filepath) and all // lookups will move internal class FormatRegistry { public: static FormatRegistry & GetInstance(); // TODO: Make these return a vector of possible formats FileFormat* getFileFormatByName(const std::string & name) const; FileFormat* getFileFormatForExtension(const std::string & extension) const; int getNumRawFormats() const; FileFormat* getRawFormatByIndex(int index) const; int getNumFormats(int capability) const; const char * getFormatNameByIndex(int capability, int index) const; const char * getFormatExtensionByIndex(int capability, int index) const; private: FormatRegistry(); ~FormatRegistry(); void registerFileFormat(FileFormat* format); FileFormatMap m_formatsByName; FileFormatMap m_formatsByExtension; FileFormatVector m_rawFormats; typedef std::vector StringVec; StringVec m_readFormatNames; StringVec m_readFormatExtensions; StringVec m_writeFormatNames; StringVec m_writeFormatExtensions; }; // Registry Builders FileFormat * CreateFileFormat3DL(); FileFormat * CreateFileFormatCCC(); FileFormat * CreateFileFormatCDL(); FileFormat * CreateFileFormatCC(); FileFormat * CreateFileFormatCSP(); FileFormat * CreateFileFormatHDL(); FileFormat * CreateFileFormatIridasItx(); FileFormat * CreateFileFormatIridasCube(); FileFormat * CreateFileFormatIridasLook(); FileFormat * CreateFileFormatPandora(); FileFormat * CreateFileFormatSpi1D(); FileFormat * CreateFileFormatSpi3D(); FileFormat * CreateFileFormatSpiMtx(); FileFormat * CreateFileFormatTruelight(); FileFormat * CreateFileFormatVF(); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/Look.cpp0000644000175000017500000001131313223553423017414 0ustar mfvmfv/* 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 #include #include #include OCIO_NAMESPACE_ENTER { LookRcPtr Look::Create() { return LookRcPtr(new Look(), &deleter); } void Look::deleter(Look* c) { delete c; } class Look::Impl { public: std::string name_; std::string processSpace_; std::string description_; TransformRcPtr transform_; TransformRcPtr inverseTransform_; Impl() { } ~Impl() { } Impl& operator= (const Impl & rhs) { name_ = rhs.name_; processSpace_ = rhs.processSpace_; description_ = rhs.description_; transform_ = rhs.transform_; if(transform_) transform_ = transform_->createEditableCopy(); inverseTransform_ = rhs.inverseTransform_; if(inverseTransform_) inverseTransform_ = inverseTransform_->createEditableCopy(); return *this; } }; /////////////////////////////////////////////////////////////////////////// Look::Look() : m_impl(new Look::Impl) { } Look::~Look() { delete m_impl; m_impl = NULL; } LookRcPtr Look::createEditableCopy() const { LookRcPtr cs = Look::Create(); *cs->m_impl = *m_impl; return cs; } const char * Look::getName() const { return getImpl()->name_.c_str(); } void Look::setName(const char * name) { getImpl()->name_ = name; } const char * Look::getProcessSpace() const { return getImpl()->processSpace_.c_str(); } void Look::setProcessSpace(const char * processSpace) { getImpl()->processSpace_ = processSpace; } ConstTransformRcPtr Look::getTransform() const { return getImpl()->transform_; } void Look::setTransform(const ConstTransformRcPtr & transform) { getImpl()->transform_ = transform->createEditableCopy(); } ConstTransformRcPtr Look::getInverseTransform() const { return getImpl()->inverseTransform_; } void Look::setInverseTransform(const ConstTransformRcPtr & transform) { getImpl()->inverseTransform_ = transform->createEditableCopy(); } const char * Look::getDescription() const { return getImpl()->description_.c_str(); } void Look::setDescription(const char * description) { getImpl()->description_ = description; } std::ostream& operator<< (std::ostream& os, const Look& look) { os << ""; return os; } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatCSP.cpp0000644000175000017500000015424413223553423021121 0ustar mfvmfv/* 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 #include #include #include #include #include #include #include #include #include #include "FileTransform.h" #include "Lut1DOp.h" #include "Lut3DOp.h" #include "MathUtils.h" #include "ParseUtils.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { namespace { const int NUM_PRELUT_SAMPLES = 65536; // 2**16 samples // Always use linear interpolation for preluts to get the // best precision const Interpolation PRELUT_INTERPOLATION = INTERP_LINEAR; typedef struct rsr_Interpolator1D_Raw_ { float * stims; float * values; unsigned int length; } rsr_Interpolator1D_Raw; rsr_Interpolator1D_Raw * rsr_Interpolator1D_Raw_create( unsigned int prelutLength ); void rsr_Interpolator1D_Raw_destroy( rsr_Interpolator1D_Raw * prelut ); /* An opaque handle to the cineSpace 1D Interpolator object */ typedef struct rsr_Interpolator1D_ rsr_Interpolator1D; rsr_Interpolator1D * rsr_Interpolator1D_createFromRaw( rsr_Interpolator1D_Raw * data ); void rsr_Interpolator1D_destroy( rsr_Interpolator1D * rawdata ); float rsr_Interpolator1D_interpolate( float x, rsr_Interpolator1D * data ); /* * =========== INTERNAL HELPER FUNCTIONS ============ */ struct rsr_Interpolator1D_ { int nSamplePoints; float * stims; /* 5 * (nSamplePoints-1) long, holding a sequence of * 1.0/delta, a, b, c, d * such that the curve in interval i is given by * z = (stims[i] - x)* (1.0/delta) * y = a + b*z + c*z^2 + d*z^3 */ float * parameters; float minValue; /* = f( stims[0] ) */ float maxValue; /* = f(stims[nSamplePoints-1] ) */ }; static int rsr_internal_I1D_refineSegment( float x, float * data, int low, int high ) { int midPoint; // TODO: Change assert to an exception? assert( x>= data[low] ); assert( x<= data[high] ); assert( (high-low) > 0); if( high-low==1 ) return low; midPoint = (low+high)/2; if( xstims); free(data->parameters); free(data); } float rsr_Interpolator1D_interpolate( float x, rsr_Interpolator1D * data ) { int segId; float * segdata; float invDelta; float a,b,c,d,z; assert(data!=NULL); /* Is x in range? */ if( isnan(x) ) return x; if( xstims[0] ) return data->minValue; if (x>data->stims[ data->nSamplePoints -1] ) return data->maxValue; /* Ok so its between the begining and end .. lets find out where... */ segId = rsr_internal_I1D_findSegmentContaining( x, data->stims, data->nSamplePoints ); assert(data->parameters !=NULL ); segdata = data->parameters + 5 * segId; invDelta = segdata[0]; a = segdata[1]; b = segdata[2]; c = segdata[3]; d = segdata[4]; z = ( x - data->stims[segId] ) * invDelta; return a + z * ( b + z * ( c + d * z ) ) ; } rsr_Interpolator1D * rsr_Interpolator1D_createFromRaw( rsr_Interpolator1D_Raw * data ) { rsr_Interpolator1D * retval = NULL; /* Check the sanity of the data */ assert(data!=NULL); assert(data->length>=2); assert(data->stims!=NULL); assert(data->values!=NULL); /* Create the real data. */ retval = (rsr_Interpolator1D*)malloc( sizeof(rsr_Interpolator1D) ); // OCIO change: explicit cast if(retval==NULL) { return NULL; } retval->stims = (float*)malloc( sizeof(float) * data->length ); // OCIO change: explicit cast if(retval->stims==NULL) { free(retval); return NULL; } memcpy( retval->stims, data->stims, sizeof(float) * data->length ); retval->parameters = (float*)malloc( 5*sizeof(float) * ( data->length - 1 ) ); // OCIO change: explicit cast if(retval->parameters==NULL) { free(retval->stims); free(retval); return NULL; } retval->nSamplePoints = data->length; retval->minValue = data->values[0]; retval->maxValue = data->values[ data->length -1]; /* Now the fun part .. filling in the coeficients. */ if(data->length==2) { retval->parameters[0] = 1.0f/(data->stims[1]-data->stims[0]); retval->parameters[1] = data->values[0]; retval->parameters[2] = ( data->values[1] - data->values[0] ); retval->parameters[3] = 0; retval->parameters[4] = 0; } else { unsigned int i; float * params = retval->parameters; for(i=0; i< data->length-1; ++i) { float f0 = data->values[i+0]; float f1 = data->values[i+1]; params[0] = 1.0f/(retval->stims[i+1]-retval->stims[i+0]); if(i==0) { float delta = data->stims[i+1] - data->stims[i]; float delta2 = (data->stims[i+2] - data->stims[i+1])/delta; float f2 = data->values[i+2]; float dfdx1 = (f2-f0)/(1+delta2); params[1] = 1.0f * f0 + 0.0f * f1 + 0.0f * dfdx1; params[2] = -2.0f * f0 + 2.0f * f1 - 1.0f * dfdx1; params[3] = 1.0f * f0 - 1.0f * f1 + 1.0f * dfdx1; params[4] = 0.0; } else if (i==data->length-2) { float delta = data->stims[i+1] - data->stims[i]; float delta1 = (data->stims[i]-data->stims[i-1])/delta; float fn1 = data->values[i-1]; float dfdx0 = (f1-fn1)/(1+delta1); params[1] = 1.0f * f0 + 0.0f * f1 + 0.0f * dfdx0; params[2] = 0.0f * f0 + 0.0f * f1 + 1.0f * dfdx0; params[3] = -1.0f * f0 + 1.0f * f1 - 1.0f * dfdx0; params[4] = 0.0; } else { float delta = data->stims[i+1] - data->stims[i]; float fn1=data->values[i-1]; float delta1 = (data->stims[i] - data->stims[i-1])/delta; float f2=data->values[i+2]; float delta2 = (data->stims[i+2] - data->stims[i+1])/delta; float dfdx0 = (f1-fn1)/(1.0f+delta1); float dfdx1 = (f2-f0)/(1.0f+delta2); params[1] = 1.0f * f0 + 0.0f * dfdx0 + 0.0f * f1 + 0.0f * dfdx1; params[2] = 0.0f * f0 + 1.0f * dfdx0 + 0.0f * f1 + 0.0f * dfdx1; params[3] =-3.0f * f0 - 2.0f * dfdx0 + 3.0f * f1 - 1.0f * dfdx1; params[4] = 2.0f * f0 + 1.0f * dfdx0 - 2.0f * f1 + 1.0f * dfdx1; } params+=5; } } return retval; } rsr_Interpolator1D_Raw * rsr_Interpolator1D_Raw_create( unsigned int prelutLength) { unsigned int i; rsr_Interpolator1D_Raw * prelut = (rsr_Interpolator1D_Raw*)malloc( sizeof(rsr_Interpolator1D_Raw) ); // OCIO change: explicit cast if(prelut==NULL) return NULL; prelut->stims = (float*)malloc( sizeof(float) * prelutLength ); // OCIO change: explicit cast if(prelut->stims==NULL) { free(prelut); return NULL; } prelut->values = (float*)malloc( sizeof(float) * prelutLength ); // OCIO change: explicit cast if(prelut->values == NULL) { free(prelut->stims); free(prelut); return NULL; } prelut->length = prelutLength; for( i=0; istims[i] = 0.0; prelut->values[i] = 0.0; } return prelut; } void rsr_Interpolator1D_Raw_destroy( rsr_Interpolator1D_Raw * prelut ) { if(prelut==NULL) return; free( prelut->stims ); free( prelut->values ); free( prelut ); } } // End unnamed namespace for Interpolators.c namespace { class CachedFileCSP : public CachedFile { public: CachedFileCSP () : hasprelut(false), csptype("unknown"), metadata("none") { prelut = Lut1D::Create(); lut1D = Lut1D::Create(); lut3D = Lut3D::Create(); }; ~CachedFileCSP() {}; bool hasprelut; std::string csptype; std::string metadata; Lut1DRcPtr prelut; Lut1DRcPtr lut1D; Lut3DRcPtr lut3D; }; typedef OCIO_SHARED_PTR CachedFileCSPRcPtr; inline bool startswithU(const std::string & str, const std::string & prefix) { return pystring::startswith(pystring::upper(pystring::strip(str)), prefix); } class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void Write(const Baker & baker, const std::string & formatName, std::ostream & ostream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; // TODO: remove this when we don't need to debug /* template std::ostream& operator<< (std::ostream& os, const std::vector& v) { copy(v.begin(), v.end(), std::ostream_iterator(std::cout, " ")); return os; } */ void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "cinespace"; info.extension = "csp"; info.capabilities = (FORMAT_CAPABILITY_READ | FORMAT_CAPABILITY_WRITE); formatInfoVec.push_back(info); } CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { // this shouldn't happen if (!istream) { throw Exception ("file stream empty when trying to read csp lut"); } Lut1DRcPtr prelut_ptr = Lut1D::Create(); Lut1DRcPtr lut1d_ptr = Lut1D::Create(); Lut3DRcPtr lut3d_ptr = Lut3D::Create(); // try and read the lut header std::string line; nextline (istream, line); if (!startswithU(line, "CSPLUTV100")) { std::ostringstream os; os << "Lut doesn't seem to be a csp file, expected 'CSPLUTV100'."; os << "First line: '" << line << "'."; throw Exception(os.str().c_str()); } // next line tells us if we are reading a 1D or 3D lut nextline (istream, line); if (!startswithU(line, "1D") && !startswithU(line, "3D")) { std::ostringstream os; os << "Unsupported CSP lut type. Require 1D or 3D. "; os << "Found, '" << line << "'."; throw Exception(os.str().c_str()); } std::string csptype = line; // read meta data block std::string metadata; bool lineUpdateNeeded = false; nextline (istream, line); if(startswithU(line, "BEGIN METADATA")) { while (!startswithU(line, "END METADATA") || !istream) { nextline (istream, line); if (!startswithU(line, "END METADATA")) metadata += line + "\n"; } lineUpdateNeeded = true; }// else line update not needed // Make 3 vectors of prelut inputs + output values std::vector prelut_in[3]; std::vector prelut_out[3]; bool useprelut[3] = { false, false, false }; // Parse the prelut block for (int c = 0; c < 3; ++c) { // how many points do we have for this channel if (lineUpdateNeeded) nextline (istream, line); int cpoints = 0; if(!StringToInt(&cpoints, line.c_str()) || cpoints<0) { std::ostringstream os; os << "Prelut does not specify valid dimension size on channel '"; os << c << ": " << line; throw Exception(os.str().c_str()); } if(cpoints>=2) { std::vector inputparts, outputparts; nextline (istream, line); pystring::split(pystring::strip(line), inputparts); nextline (istream, line); pystring::split(pystring::strip(line), outputparts); if(static_cast(inputparts.size()) != cpoints || static_cast(outputparts.size()) != cpoints) { std::ostringstream os; os << "Prelut does not specify the expected number of data points. "; os << "Expected: " << cpoints << "."; os << "Found: " << inputparts.size() << ", " << outputparts.size() << "."; throw Exception(os.str().c_str()); } if(!StringVecToFloatVec(prelut_in[c], inputparts) || !StringVecToFloatVec(prelut_out[c], outputparts)) { std::ostringstream os; os << "Prelut data is malformed, cannot to float array."; throw Exception(os.str().c_str()); } useprelut[c] = (!VecsEqualWithRelError(&(prelut_in[c][0]), static_cast(prelut_in[c].size()), &(prelut_out[c][0]), static_cast(prelut_out[c].size()), 1e-6f)); } else { // Even though it's probably not part of the spec, why not allow for a size 0 // in a channel to be specified? It should be synonymous with identity, // and allows the code lower down to assume all 3 channels exist prelut_in[c].push_back(0.0f); prelut_in[c].push_back(1.0f); prelut_out[c].push_back(0.0f); prelut_out[c].push_back(1.0f); useprelut[c] = false; } lineUpdateNeeded = true; } if (csptype == "1D") { // how many 1D lut points do we have nextline (istream, line); int points1D = atoi (line.c_str()); // float from_min = 0.0; float from_max = 1.0; for(int i=0; i<3; ++i) { lut1d_ptr->from_min[i] = from_min; lut1d_ptr->from_max[i] = from_max; lut1d_ptr->luts[i].clear(); lut1d_ptr->luts[i].reserve(points1D); } for(int i = 0; i < points1D; ++i) { // scan for the three floats float lp[3]; nextline (istream, line); if (sscanf (line.c_str(), "%f %f %f", &lp[0], &lp[1], &lp[2]) != 3) { throw Exception ("malformed 1D csp lut"); } // store each channel lut1d_ptr->luts[0].push_back(lp[0]); lut1d_ptr->luts[1].push_back(lp[1]); lut1d_ptr->luts[2].push_back(lp[2]); } } else if (csptype == "3D") { // read the cube size nextline (istream, line); if (sscanf (line.c_str(), "%d %d %d", &lut3d_ptr->size[0], &lut3d_ptr->size[1], &lut3d_ptr->size[2]) != 3 ) { throw Exception("malformed 3D csp lut, couldn't read cube size"); } // resize cube int num3dentries = lut3d_ptr->size[0] * lut3d_ptr->size[1] * lut3d_ptr->size[2]; lut3d_ptr->lut.resize(num3dentries * 3); for(int i=0; ilut[3*i+0], &lut3d_ptr->lut[3*i+1], &lut3d_ptr->lut[3*i+2]) != 3 ) { std::ostringstream os; os << "Malformed 3D csp lut, couldn't read cube row ("; os << i << "): " << line << " ."; throw Exception(os.str().c_str()); } } } CachedFileCSPRcPtr cachedFile = CachedFileCSPRcPtr (new CachedFileCSP ()); cachedFile->csptype = csptype; cachedFile->metadata = metadata; if(useprelut[0] || useprelut[1] || useprelut[2]) { cachedFile->hasprelut = true; for (int c = 0; c < 3; ++c) { size_t prelut_numpts = prelut_in[c].size(); float from_min = prelut_in[c][0]; float from_max = prelut_in[c][prelut_numpts-1]; // Allocate the interpolator rsr_Interpolator1D_Raw * cprelut_raw = rsr_Interpolator1D_Raw_create(static_cast(prelut_numpts)); // Copy our prelut data into the interpolator for(size_t i=0; istims[i] = prelut_in[c][i]; cprelut_raw->values[i] = prelut_out[c][i]; } // Create interpolater, to resample to simple 1D lut rsr_Interpolator1D * interpolater = rsr_Interpolator1D_createFromRaw(cprelut_raw); // Resample into 1D lut // TODO: Fancy spline analysis to determine required number of samples prelut_ptr->from_min[c] = from_min; prelut_ptr->from_max[c] = from_max; prelut_ptr->luts[c].clear(); prelut_ptr->luts[c].reserve(NUM_PRELUT_SAMPLES); for (int i = 0; i < NUM_PRELUT_SAMPLES; ++i) { float interpo = float(i) / float(NUM_PRELUT_SAMPLES-1); float srcval = lerpf(from_min, from_max, interpo); float newval = rsr_Interpolator1D_interpolate(srcval, interpolater); prelut_ptr->luts[c].push_back(newval); } rsr_Interpolator1D_Raw_destroy(cprelut_raw); rsr_Interpolator1D_destroy(interpolater); } prelut_ptr->maxerror = 1e-6f; prelut_ptr->errortype = ERROR_RELATIVE; cachedFile->prelut = prelut_ptr; } if(csptype == "1D") { lut1d_ptr->maxerror = 0.0f; lut1d_ptr->errortype = ERROR_RELATIVE; cachedFile->lut1D = lut1d_ptr; } else if (csptype == "3D") { cachedFile->lut3D = lut3d_ptr; } return cachedFile; } void LocalFileFormat::Write(const Baker & baker, const std::string & /*formatName*/, std::ostream & ostream) const { const int DEFAULT_CUBE_SIZE = 32; const int DEFAULT_SHAPER_SIZE = 1024; ConstConfigRcPtr config = baker.getConfig(); // TODO: Add 1d/3d lut writing switch, using hasChannelCrosstalk int cubeSize = baker.getCubeSize(); if(cubeSize==-1) cubeSize = DEFAULT_CUBE_SIZE; cubeSize = std::max(2, cubeSize); // smallest cube is 2x2x2 std::vector cubeData; cubeData.resize(cubeSize*cubeSize*cubeSize*3); GenerateIdentityLut3D(&cubeData[0], cubeSize, 3, LUT3DORDER_FAST_RED); PackedImageDesc cubeImg(&cubeData[0], cubeSize*cubeSize*cubeSize, 1, 3); std::string looks = baker.getLooks(); std::vector shaperInData; std::vector shaperOutData; // Use an explicitly shaper space // TODO: Use the optional allocation for the shaper space, // instead of the implied 0-1 uniform allocation std::string shaperSpace = baker.getShaperSpace(); if(!shaperSpace.empty()) { int shaperSize = baker.getShaperSize(); if(shaperSize<0) shaperSize = DEFAULT_SHAPER_SIZE; if(shaperSize<2) { std::ostringstream os; os << "When a shaper space has been specified, '"; os << baker.getShaperSpace() << "', a shaper size less than 2 is not allowed."; throw Exception(os.str().c_str()); } shaperOutData.resize(shaperSize*3); shaperInData.resize(shaperSize*3); GenerateIdentityLut1D(&shaperOutData[0], shaperSize, 3); GenerateIdentityLut1D(&shaperInData[0], shaperSize, 3); ConstProcessorRcPtr shaperToInput = config->getProcessor(baker.getShaperSpace(), baker.getInputSpace()); if(shaperToInput->hasChannelCrosstalk()) { // TODO: Automatically turn shaper into non-crosstalked version? std::ostringstream os; os << "The specified shaperSpace, '"; os << baker.getShaperSpace() << "' has channel crosstalk, which is not appropriate for shapers. "; os << "Please select an alternate shaper space or omit this option."; throw Exception(os.str().c_str()); } PackedImageDesc shaperInImg(&shaperInData[0], shaperSize, 1, 3); shaperToInput->apply(shaperInImg); ConstProcessorRcPtr shaperToTarget; if (!looks.empty()) { LookTransformRcPtr transform = LookTransform::Create(); transform->setLooks(looks.c_str()); transform->setSrc(baker.getShaperSpace()); transform->setDst(baker.getTargetSpace()); shaperToTarget = config->getProcessor(transform, TRANSFORM_DIR_FORWARD); } else { shaperToTarget = config->getProcessor(baker.getShaperSpace(), baker.getTargetSpace()); } shaperToTarget->apply(cubeImg); } else { // A shaper is not specified, let's fake one, using the input space allocation as // our guide ConstColorSpaceRcPtr inputColorSpace = config->getColorSpace(baker.getInputSpace()); if(!inputColorSpace) { std::ostringstream os; os << "Could not find colorspace '" << baker.getInputSpace() << "'"; throw Exception(os.str().c_str()); } // Let's make an allocation transform for this colorspace AllocationTransformRcPtr allocationTransform = AllocationTransform::Create(); allocationTransform->setAllocation(inputColorSpace->getAllocation()); // numVars may be '0' int numVars = inputColorSpace->getAllocationNumVars(); if(numVars>0) { std::vector vars(numVars); inputColorSpace->getAllocationVars(&vars[0]); allocationTransform->setVars(numVars, &vars[0]); } else { allocationTransform->setVars(0, NULL); } // What size shaper should we make? int shaperSize = baker.getShaperSize(); if(shaperSize<0) shaperSize = DEFAULT_SHAPER_SIZE; shaperSize = std::max(2, shaperSize); if(inputColorSpace->getAllocation() == ALLOCATION_UNIFORM) { // This is an awesome optimization. // If we know it's a uniform scaling, only 2 points will suffice! shaperSize = 2; } shaperOutData.resize(shaperSize*3); shaperInData.resize(shaperSize*3); GenerateIdentityLut1D(&shaperOutData[0], shaperSize, 3); GenerateIdentityLut1D(&shaperInData[0], shaperSize, 3); // Apply the forward to the allocation to the output shaper y axis, and the cube ConstProcessorRcPtr shaperToInput = config->getProcessor(allocationTransform, TRANSFORM_DIR_INVERSE); PackedImageDesc shaperInImg(&shaperInData[0], shaperSize, 1, 3); shaperToInput->apply(shaperInImg); shaperToInput->apply(cubeImg); // Apply the 3d lut to the remainder (from the input to the output) ConstProcessorRcPtr inputToTarget; if (!looks.empty()) { LookTransformRcPtr transform = LookTransform::Create(); transform->setLooks(looks.c_str()); transform->setSrc(baker.getInputSpace()); transform->setDst(baker.getTargetSpace()); inputToTarget = config->getProcessor(transform, TRANSFORM_DIR_FORWARD); } else { inputToTarget = config->getProcessor(baker.getInputSpace(), baker.getTargetSpace()); } inputToTarget->apply(cubeImg); } // Write out the file ostream << "CSPLUTV100\n"; ostream << "3D\n"; ostream << "\n"; ostream << "BEGIN METADATA\n"; std::string metadata = baker.getMetadata(); if(!metadata.empty()) { ostream << metadata << "\n"; } ostream << "END METADATA\n"; ostream << "\n"; // Write out the 1D Prelut ostream.setf(std::ios::fixed, std::ios::floatfield); ostream.precision(6); if(shaperInData.size()<2 || shaperOutData.size() != shaperInData.size()) { throw Exception("Internal shaper size exception."); } if(!shaperInData.empty()) { for(int c=0; c<3; ++c) { ostream << shaperInData.size()/3 << "\n"; for(unsigned int i = 0; i(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build CSP Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_FORWARD) { if(cachedFile->hasprelut) { CreateLut1DOp(ops, cachedFile->prelut, PRELUT_INTERPOLATION, newDir); } if(cachedFile->csptype == "1D") CreateLut1DOp(ops, cachedFile->lut1D, fileTransform.getInterpolation(), newDir); else if(cachedFile->csptype == "3D") CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } else if(newDir == TRANSFORM_DIR_INVERSE) { if(cachedFile->csptype == "1D") CreateLut1DOp(ops, cachedFile->lut1D, fileTransform.getInterpolation(), newDir); else if(cachedFile->csptype == "3D") CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); if(cachedFile->hasprelut) { CreateLut1DOp(ops, cachedFile->prelut, PRELUT_INTERPOLATION, newDir); } } return; } } FileFormat * CreateFileFormatCSP() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" void compareFloats(const std::string& floats1, const std::string& floats2) { // number comparison std::vector strings1; OCIO::pystring::split(OCIO::pystring::strip(floats1), strings1); std::vector numbers1; OCIO::StringVecToFloatVec(numbers1, strings1); std::vector strings2; OCIO::pystring::split(OCIO::pystring::strip(floats2), strings2); std::vector numbers2; OCIO::StringVecToFloatVec(numbers2, strings2); OIIO_CHECK_EQUAL(numbers1.size(), numbers2.size()); for(unsigned int j=0; j(cachedFile); // check metadata OIIO_CHECK_EQUAL(csplut->metadata, std::string("foobar\n")); // check prelut data OIIO_CHECK_ASSERT(csplut->hasprelut); // check prelut data (note: the spline is resampled into a 1D LUT) for(int c=0; c<3; ++c) { for (unsigned int i = 0; i < csplut->prelut->luts[c].size(); i += 128) { float input = float(i) / float(csplut->prelut->luts[c].size()-1); float output = csplut->prelut->luts[c][i]; OIIO_CHECK_CLOSE(input*2.0f, output, 1e-4); } } // check 1D data // red unsigned int i; for(i = 0; i < csplut->lut1D->luts[0].size(); ++i) OIIO_CHECK_EQUAL(red[i], csplut->lut1D->luts[0][i]); // green for(i = 0; i < csplut->lut1D->luts[1].size(); ++i) OIIO_CHECK_EQUAL(green[i], csplut->lut1D->luts[1][i]); // blue for(i = 0; i < csplut->lut1D->luts[2].size(); ++i) OIIO_CHECK_EQUAL(blue[i], csplut->lut1D->luts[2][i]); // check 3D data OIIO_CHECK_EQUAL(csplut->lut3D->lut.size(), 0); } OIIO_ADD_TEST(FileFormatCSP, simple3D) { std::ostringstream strebuf; strebuf << "CSPLUTV100" << "\n"; strebuf << "3D" << "\n"; strebuf << "" << "\n"; strebuf << "BEGIN METADATA" << "\n"; strebuf << "foobar" << "\n"; strebuf << "END METADATA" << "\n"; strebuf << "" << "\n"; strebuf << "11" << "\n"; strebuf << "0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0" << "\n"; strebuf << "0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0" << "\n"; strebuf << "6" << "\n"; strebuf << "0.0 0.2 0.4 0.6 0.8 1.0" << "\n"; strebuf << "0.0 0.2000000 0.4 0.6 0.8 1.0" << "\n"; strebuf << "5" << "\n"; strebuf << "0.0 0.25 0.5 0.6 0.7" << "\n"; strebuf << "0.0 0.25000001 0.5 0.6 0.7" << "\n"; strebuf << "" << "\n"; strebuf << "1 2 3" << "\n"; strebuf << "0.0 0.0 0.0" << "\n"; strebuf << "1.0 0.0 0.0" << "\n"; strebuf << "0.0 0.5 0.0" << "\n"; strebuf << "1.0 0.5 0.0" << "\n"; strebuf << "0.0 1.0 0.0" << "\n"; strebuf << "1.0 1.0 0.0" << "\n"; float cube[1 * 2 * 3 * 3] = { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0 }; std::istringstream simple3D; simple3D.str(strebuf.str()); // Load file OCIO::LocalFileFormat tester; OCIO::CachedFileRcPtr cachedFile = tester.Read(simple3D); OCIO::CachedFileCSPRcPtr csplut = OCIO::DynamicPtrCast(cachedFile); // check metadata OIIO_CHECK_EQUAL(csplut->metadata, std::string("foobar\n")); // check prelut data OIIO_CHECK_ASSERT(!csplut->hasprelut); // as in & out preLut values are the same // there is nothing to do. // check cube data for(unsigned int i = 0; i < csplut->lut3D->lut.size(); ++i) { OIIO_CHECK_EQUAL(cube[i], csplut->lut3D->lut[i]); } // check 1D data OIIO_CHECK_EQUAL(csplut->lut1D->luts[0].size(), 0); OIIO_CHECK_EQUAL(csplut->lut1D->luts[1].size(), 0); OIIO_CHECK_EQUAL(csplut->lut1D->luts[2].size(), 0); } OIIO_ADD_TEST(FileFormatCSP, complete3D) { // check baker output OCIO::ConfigRcPtr config = OCIO::Config::Create(); { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("lnf"); cs->setFamily("lnf"); config->addColorSpace(cs); config->setRole(OCIO::ROLE_REFERENCE, cs->getName()); } { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("shaper"); cs->setFamily("shaper"); OCIO::ExponentTransformRcPtr transform1 = OCIO::ExponentTransform::Create(); float test[4] = {2.6f, 2.6f, 2.6f, 1.0f}; transform1->setValue(test); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_TO_REFERENCE); config->addColorSpace(cs); } { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("target"); cs->setFamily("target"); OCIO::CDLTransformRcPtr transform1 = OCIO::CDLTransform::Create(); float rgb[3] = {0.1f, 0.1f, 0.1f}; transform1->setOffset(rgb); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_FROM_REFERENCE); config->addColorSpace(cs); } std::ostringstream bout; bout << "CSPLUTV100" << "\n"; bout << "3D" << "\n"; bout << "" << "\n"; bout << "BEGIN METADATA" << "\n"; bout << "date: 2011:02:21 15:22:55" << "\n"; bout << "END METADATA" << "\n"; bout << "" << "\n"; bout << "10" << "\n"; bout << "0.000000 0.003303 0.020028 0.057476 0.121430 0.216916 0.348468 0.520265 0.736213 1.000000" << "\n"; bout << "0.000000 0.111111 0.222222 0.333333 0.444444 0.555556 0.666667 0.777778 0.888889 1.000000" << "\n"; bout << "10" << "\n"; bout << "0.000000 0.003303 0.020028 0.057476 0.121430 0.216916 0.348468 0.520265 0.736213 1.000000" << "\n"; bout << "0.000000 0.111111 0.222222 0.333333 0.444444 0.555556 0.666667 0.777778 0.888889 1.000000" << "\n"; bout << "10" << "\n"; bout << "0.000000 0.003303 0.020028 0.057476 0.121430 0.216916 0.348468 0.520265 0.736213 1.000000" << "\n"; bout << "0.000000 0.111111 0.222222 0.333333 0.444444 0.555556 0.666667 0.777778 0.888889 1.000000" << "\n"; bout << "" << "\n"; bout << "2 2 2" << "\n"; bout << "0.100000 0.100000 0.100000" << "\n"; bout << "1.100000 0.100000 0.100000" << "\n"; bout << "0.100000 1.100000 0.100000" << "\n"; bout << "1.100000 1.100000 0.100000" << "\n"; bout << "0.100000 0.100000 1.100000" << "\n"; bout << "1.100000 0.100000 1.100000" << "\n"; bout << "0.100000 1.100000 1.100000" << "\n"; bout << "1.100000 1.100000 1.100000" << "\n"; bout << "" << "\n"; OCIO::BakerRcPtr baker = OCIO::Baker::Create(); baker->setConfig(config); baker->setMetadata("date: 2011:02:21 15:22:55"); baker->setFormat("cinespace"); baker->setInputSpace("lnf"); baker->setShaperSpace("shaper"); baker->setTargetSpace("target"); baker->setShaperSize(10); baker->setCubeSize(2); std::ostringstream output; baker->bake(output); // std::vector osvec; OCIO::pystring::splitlines(output.str(), osvec); std::vector resvec; OCIO::pystring::splitlines(bout.str(), resvec); OIIO_CHECK_EQUAL(osvec.size(), resvec.size()); for(unsigned int i = 0; i < resvec.size(); ++i) { if(i>6) { // number comparison compareFloats(osvec[i], resvec[i]); } else { // text comparison OIIO_CHECK_EQUAL(osvec[i], resvec[i]); } } } OIIO_ADD_TEST(FileFormatCSP, shaper_hdr) { // check baker output OCIO::ConfigRcPtr config = OCIO::Config::Create(); { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("lnf"); cs->setFamily("lnf"); config->addColorSpace(cs); config->setRole(OCIO::ROLE_REFERENCE, cs->getName()); } { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("lnf_tweak"); cs->setFamily("lnf_tweak"); OCIO::CDLTransformRcPtr transform1 = OCIO::CDLTransform::Create(); float rgb[3] = {2.0f, -2.0f, 0.9f}; transform1->setOffset(rgb); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_FROM_REFERENCE); config->addColorSpace(cs); } { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("target"); cs->setFamily("target"); OCIO::CDLTransformRcPtr transform1 = OCIO::CDLTransform::Create(); float rgb[3] = {0.1f, 0.1f, 0.1f}; transform1->setOffset(rgb); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_FROM_REFERENCE); config->addColorSpace(cs); } std::ostringstream bout; bout << "CSPLUTV100" << "\n"; bout << "3D" << "\n"; bout << "" << "\n"; bout << "BEGIN METADATA" << "\n"; bout << "date: 2011:02:21 15:22:55" << "\n"; bout << "END METADATA" << "\n"; bout << "" << "\n"; bout << "10" << "\n"; bout << "2.000000 2.111111 2.222222 2.333333 2.444444 2.555556 2.666667 2.777778 2.888889 3.000000" << "\n"; bout << "0.000000 0.111111 0.222222 0.333333 0.444444 0.555556 0.666667 0.777778 0.888889 1.000000" << "\n"; bout << "10" << "\n"; bout << "-2.000000 -1.888889 -1.777778 -1.666667 -1.555556 -1.444444 -1.333333 -1.222222 -1.111111 -1.000000" << "\n"; bout << "0.000000 0.111111 0.222222 0.333333 0.444444 0.555556 0.666667 0.777778 0.888889 1.000000" << "\n"; bout << "10" << "\n"; bout << "0.900000 1.011111 1.122222 1.233333 1.344444 1.455556 1.566667 1.677778 1.788889 1.900000" << "\n"; bout << "0.000000 0.111111 0.222222 0.333333 0.444444 0.555556 0.666667 0.777778 0.888889 1.000000" << "\n"; bout << "" << "\n"; bout << "2 2 2" << "\n"; bout << "0.100000 0.100000 0.100000" << "\n"; bout << "1.100000 0.100000 0.100000" << "\n"; bout << "0.100000 1.100000 0.100000" << "\n"; bout << "1.100000 1.100000 0.100000" << "\n"; bout << "0.100000 0.100000 1.100000" << "\n"; bout << "1.100000 0.100000 1.100000" << "\n"; bout << "0.100000 1.100000 1.100000" << "\n"; bout << "1.100000 1.100000 1.100000" << "\n"; bout << "" << "\n"; OCIO::BakerRcPtr baker = OCIO::Baker::Create(); baker->setConfig(config); baker->setMetadata("date: 2011:02:21 15:22:55"); baker->setFormat("cinespace"); baker->setInputSpace("lnf_tweak"); baker->setShaperSpace("lnf"); baker->setTargetSpace("target"); baker->setShaperSize(10); baker->setCubeSize(2); std::ostringstream output; baker->bake(output); // std::vector osvec; OCIO::pystring::splitlines(output.str(), osvec); std::vector resvec; OCIO::pystring::splitlines(bout.str(), resvec); OIIO_CHECK_EQUAL(osvec.size(), resvec.size()); for(unsigned int i = 0; i < resvec.size(); ++i) { if(i>6) { // number comparison compareFloats(osvec[i], resvec[i]); } else { // text comparison OIIO_CHECK_EQUAL(osvec[i], resvec[i]); } } } OIIO_ADD_TEST(FileFormatCSP, no_shaper) { // check baker output OCIO::ConfigRcPtr config = OCIO::Config::Create(); { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("lnf"); cs->setFamily("lnf"); config->addColorSpace(cs); config->setRole(OCIO::ROLE_REFERENCE, cs->getName()); } { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("target"); cs->setFamily("target"); OCIO::CDLTransformRcPtr transform1 = OCIO::CDLTransform::Create(); float rgb[3] = {0.1f, 0.1f, 0.1f}; transform1->setOffset(rgb); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_FROM_REFERENCE); config->addColorSpace(cs); } std::ostringstream bout; bout << "CSPLUTV100" << "\n"; bout << "3D" << "\n"; bout << "" << "\n"; bout << "BEGIN METADATA" << "\n"; bout << "date: 2011:02:21 15:22:55" << "\n"; bout << "END METADATA" << "\n"; bout << "" << "\n"; bout << "2" << "\n"; bout << "0.000000 1.000000" << "\n"; bout << "0.000000 1.000000" << "\n"; bout << "2" << "\n"; bout << "0.000000 1.000000" << "\n"; bout << "0.000000 1.000000" << "\n"; bout << "2" << "\n"; bout << "0.000000 1.000000" << "\n"; bout << "0.000000 1.000000" << "\n"; bout << "" << "\n"; bout << "2 2 2" << "\n"; bout << "0.100000 0.100000 0.100000" << "\n"; bout << "1.100000 0.100000 0.100000" << "\n"; bout << "0.100000 1.100000 0.100000" << "\n"; bout << "1.100000 1.100000 0.100000" << "\n"; bout << "0.100000 0.100000 1.100000" << "\n"; bout << "1.100000 0.100000 1.100000" << "\n"; bout << "0.100000 1.100000 1.100000" << "\n"; bout << "1.100000 1.100000 1.100000" << "\n"; bout << "" << "\n"; OCIO::BakerRcPtr baker = OCIO::Baker::Create(); baker->setConfig(config); baker->setMetadata("date: 2011:02:21 15:22:55"); baker->setFormat("cinespace"); baker->setInputSpace("lnf"); baker->setTargetSpace("target"); baker->setShaperSize(10); baker->setCubeSize(2); std::ostringstream output; baker->bake(output); // std::vector osvec; OCIO::pystring::splitlines(output.str(), osvec); std::vector resvec; OCIO::pystring::splitlines(bout.str(), resvec); OIIO_CHECK_EQUAL(osvec.size(), resvec.size()); for(unsigned int i = 0; i < resvec.size(); ++i) { OIIO_CHECK_EQUAL(osvec[i], resvec[i]); } } OIIO_ADD_TEST(FileFormatCSP, lessStrictParse) { std::ostringstream strebuf; strebuf << " CspluTV100 malformed" << "\n"; strebuf << "3D" << "\n"; strebuf << "" << "\n"; strebuf << " BegIN MEtadATA malformed malformed malfo" << "\n"; strebuf << "foobar" << "\n"; strebuf << " end metadata malformed malformed m a l" << "\n"; strebuf << "" << "\n"; strebuf << "11" << "\n"; strebuf << "0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0" << "\n"; strebuf << "0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0" << "\n"; strebuf << "6" << "\n"; strebuf << "0.0 0.2 0.4 0.6 0.8 1.0" << "\n"; strebuf << "0.0 0.2000000 0.4 0.6 0.8 1.0" << "\n"; strebuf << "5" << "\n"; strebuf << "0.0 0.25 0.5 0.6 0.7" << "\n"; strebuf << "0.0 0.25000001 0.5 0.6 0.7" << "\n"; strebuf << "" << "\n"; strebuf << "1 2 3" << "\n"; strebuf << "0.0 0.0 0.0" << "\n"; strebuf << "1.0 0.0 0.0" << "\n"; strebuf << "0.0 0.5 0.0" << "\n"; strebuf << "1.0 0.5 0.0" << "\n"; strebuf << "0.0 1.0 0.0" << "\n"; strebuf << "1.0 1.0 0.0" << "\n"; std::istringstream simple3D; simple3D.str(strebuf.str()); // Load file OCIO::LocalFileFormat tester; OCIO::CachedFileRcPtr cachedFile; OIIO_CHECK_NO_THROW(cachedFile = tester.Read(simple3D)); OCIO::CachedFileCSPRcPtr csplut = OCIO::DynamicPtrCast(cachedFile); // check metadata OIIO_CHECK_EQUAL(csplut->metadata, std::string("foobar\n")); // check prelut data OIIO_CHECK_ASSERT(!csplut->hasprelut); // as in & out from the preLut are the same, // there is nothing to do. } // TODO: More strenuous tests of prelut resampling (non-noop preluts) #endif // OCIO_UNIT_TEST opencolorio-1.1.0~dfsg0.orig/src/core/MatrixOps.h0000644000175000017500000000574313223553423020115 0ustar mfvmfv/* 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_OCIO_MATRIXOFFSETOP_H #define INCLUDED_OCIO_MATRIXOFFSETOP_H #include #include "Op.h" #include OCIO_NAMESPACE_ENTER { // Use whichever is most convenient; they are equally efficient void CreateScaleOp(OpRcPtrVec & ops, const float * scale4, TransformDirection direction); void CreateMatrixOp(OpRcPtrVec & ops, const float * m44, TransformDirection direction); void CreateOffsetOp(OpRcPtrVec & ops, const float * offset4, TransformDirection direction); void CreateMatrixOffsetOp(OpRcPtrVec & ops, const float * m44, const float * offset4, TransformDirection direction); void CreateScaleOffsetOp(OpRcPtrVec & ops, const float * scale4, const float * offset4, TransformDirection direction); void CreateFitOp(OpRcPtrVec & ops, const float * oldmin4, const float * oldmax4, const float * newmin4, const float * newmax4, TransformDirection direction); void CreateSaturationOp(OpRcPtrVec & ops, float sat, const float * lumaCoef3, TransformDirection direction); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatPandora.cpp0000644000175000017500000002630713223553423022056 0ustar mfvmfv/* 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 #include #include #include #include "FileTransform.h" #include "Lut1DOp.h" #include "Lut3DOp.h" #include "ParseUtils.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile () { lut3D = Lut3D::Create(); }; ~LocalCachedFile() {}; Lut3DRcPtr lut3D; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "pandora_mga"; info.extension = "mga"; info.capabilities = FORMAT_CAPABILITY_READ; formatInfoVec.push_back(info); FormatInfo info2; info2.name = "pandora_m3d"; info2.extension = "m3d"; info2.capabilities = FORMAT_CAPABILITY_READ; formatInfoVec.push_back(info2); } CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { // this shouldn't happen if(!istream) { throw Exception ("File stream empty when trying to read Pandora lut"); } // Validate the file type std::string line; // Parse the file std::string format; int lutEdgeLen = 0; int outputBitDepthMaxValue = 0; std::vector raw3d; { std::vector parts; std::vector tmpints; bool inLut3d = false; while(nextline(istream, line)) { // Strip, lowercase, and split the line pystring::split(pystring::lower(pystring::strip(line)), parts); if(parts.empty()) continue; // Skip all lines starting with '#' if(pystring::startswith(parts[0],"#")) continue; if(parts[0] == "channel") { if(parts.size() != 2 || pystring::lower(parts[1]) != "3d") { throw Exception("Parse error in Pandora lut. Only 3d luts are currently supported. (channel: 3d)."); } } else if(parts[0] == "in") { int inval = 0; if(parts.size() != 2 || !StringToInt( &inval, parts[1].c_str())) { throw Exception("Malformed 'in' tag in Pandora lut."); } raw3d.reserve(inval*3); lutEdgeLen = Get3DLutEdgeLenFromNumPixels(inval); } else if(parts[0] == "out") { if(parts.size() != 2 || !StringToInt( &outputBitDepthMaxValue, parts[1].c_str())) { throw Exception("Malformed 'out' tag in Pandora lut."); } } else if(parts[0] == "format") { if(parts.size() != 2 || pystring::lower(parts[1]) != "lut") { throw Exception("Parse error in Pandora lut. Only luts are currently supported. (format: lut)."); } } else if(parts[0] == "values") { if(parts.size() != 4 || pystring::lower(parts[1]) != "red" || pystring::lower(parts[2]) != "green" || pystring::lower(parts[3]) != "blue") { throw Exception("Parse error in Pandora lut. Only rgb luts are currently supported. (values: red green blue)."); } inLut3d = true; } else if(inLut3d) { if(!StringVecToIntVec(tmpints, parts) || tmpints.size() != 4) { std::ostringstream os; os << "Parse error in Pandora lut. Expected to find 4 integers. Instead found '" << line << "'"; throw Exception(os.str().c_str()); } raw3d.push_back(tmpints[1]); raw3d.push_back(tmpints[2]); raw3d.push_back(tmpints[3]); } } } // Interpret the parsed data, validate lut sizes if(lutEdgeLen*lutEdgeLen*lutEdgeLen != static_cast(raw3d.size()/3)) { std::ostringstream os; os << "Parse error in Pandora lut. "; os << "Incorrect number of lut3d entries. "; os << "Found " << raw3d.size()/3 << ", expected " << lutEdgeLen*lutEdgeLen*lutEdgeLen << "."; throw Exception(os.str().c_str()); } if(lutEdgeLen*lutEdgeLen*lutEdgeLen == 0) { std::ostringstream os; os << "Parse error in Pandora lut. "; os << "No 3D Lut entries found."; throw Exception(os.str().c_str()); } if(outputBitDepthMaxValue <= 0) { std::ostringstream os; os << "Parse error in Pandora lut. "; os << "A valid 'out' tag was not found."; throw Exception(os.str().c_str()); } LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile()); // Reformat 3D data cachedFile->lut3D->size[0] = lutEdgeLen; cachedFile->lut3D->size[1] = lutEdgeLen; cachedFile->lut3D->size[2] = lutEdgeLen; cachedFile->lut3D->lut.reserve(raw3d.size()); float scale = 1.0f / ((float)outputBitDepthMaxValue - 1.0f); for(int rIndex=0; rIndexlut3D->lut.push_back(static_cast(raw3d[i+0]) * scale); cachedFile->lut3D->lut.push_back(static_cast(raw3d[i+1]) * scale); cachedFile->lut3D->lut.push_back(static_cast(raw3d[i+2]) * scale); } } } return cachedFile; } void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops, const Config& /*config*/, const ConstContextRcPtr & /*context*/, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { LocalCachedFileRcPtr cachedFile = DynamicPtrCast(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build Truelight .cub Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_UNKNOWN) { std::ostringstream os; os << "Cannot build file format transform,"; os << " unspecified transform direction."; throw Exception(os.str().c_str()); } if(newDir == TRANSFORM_DIR_FORWARD) { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } else if(newDir == TRANSFORM_DIR_INVERSE) { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } } } FileFormat * CreateFileFormatPandora() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/DisplayTransform.cpp0000644000175000017500000003411013223553423022011 0ustar mfvmfv/* 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 #include "OpBuilders.h" #include #include #include OCIO_NAMESPACE_ENTER { DisplayTransformRcPtr DisplayTransform::Create() { return DisplayTransformRcPtr(new DisplayTransform(), &deleter); } void DisplayTransform::deleter(DisplayTransform* t) { delete t; } class DisplayTransform::Impl { public: TransformDirection dir_; std::string inputColorSpaceName_; TransformRcPtr linearCC_; TransformRcPtr colorTimingCC_; TransformRcPtr channelView_; std::string display_; std::string view_; TransformRcPtr displayCC_; std::string looksOverride_; bool looksOverrideEnabled_; Impl() : dir_(TRANSFORM_DIR_FORWARD), looksOverrideEnabled_(false) { } ~Impl() { } Impl& operator= (const Impl & rhs) { dir_ = rhs.dir_; inputColorSpaceName_ = rhs.inputColorSpaceName_; linearCC_ = rhs.linearCC_; if(linearCC_) linearCC_ = linearCC_->createEditableCopy(); colorTimingCC_ = rhs.colorTimingCC_; if(colorTimingCC_) colorTimingCC_ = colorTimingCC_->createEditableCopy(); channelView_ = rhs.channelView_; if(channelView_) channelView_ = channelView_->createEditableCopy(); display_ = rhs.display_; view_ = rhs.view_; displayCC_ = rhs.displayCC_; if(displayCC_) displayCC_ = displayCC_->createEditableCopy(); looksOverride_ = rhs.looksOverride_; looksOverrideEnabled_ = rhs.looksOverrideEnabled_; return *this; } }; /////////////////////////////////////////////////////////////////////////// DisplayTransform::DisplayTransform() : m_impl(new DisplayTransform::Impl) { } TransformRcPtr DisplayTransform::createEditableCopy() const { DisplayTransformRcPtr transform = DisplayTransform::Create(); *(transform->m_impl) = *m_impl; return transform; } DisplayTransform::~DisplayTransform() { delete m_impl; m_impl = NULL; } DisplayTransform& DisplayTransform::operator= (const DisplayTransform & rhs) { *m_impl = *rhs.m_impl; return *this; } TransformDirection DisplayTransform::getDirection() const { return getImpl()->dir_; } void DisplayTransform::setDirection(TransformDirection dir) { getImpl()->dir_ = dir; } void DisplayTransform::setInputColorSpaceName(const char * name) { getImpl()->inputColorSpaceName_ = name; } const char * DisplayTransform::getInputColorSpaceName() const { return getImpl()->inputColorSpaceName_.c_str(); } void DisplayTransform::setLinearCC(const ConstTransformRcPtr & cc) { getImpl()->linearCC_ = cc->createEditableCopy(); } ConstTransformRcPtr DisplayTransform::getLinearCC() const { return getImpl()->linearCC_; } void DisplayTransform::setColorTimingCC(const ConstTransformRcPtr & cc) { getImpl()->colorTimingCC_ = cc->createEditableCopy(); } ConstTransformRcPtr DisplayTransform::getColorTimingCC() const { return getImpl()->colorTimingCC_; } void DisplayTransform::setChannelView(const ConstTransformRcPtr & transform) { getImpl()->channelView_ = transform->createEditableCopy(); } ConstTransformRcPtr DisplayTransform::getChannelView() const { return getImpl()->channelView_; } void DisplayTransform::setDisplay(const char * display) { getImpl()->display_ = display; } const char * DisplayTransform::getDisplay() const { return getImpl()->display_.c_str(); } void DisplayTransform::setView(const char * view) { getImpl()->view_ = view; } const char * DisplayTransform::getView() const { return getImpl()->view_.c_str(); } void DisplayTransform::setDisplayCC(const ConstTransformRcPtr & cc) { getImpl()->displayCC_ = cc->createEditableCopy(); } ConstTransformRcPtr DisplayTransform::getDisplayCC() const { return getImpl()->displayCC_; } void DisplayTransform::setLooksOverride(const char * looks) { getImpl()->looksOverride_ = looks; } const char * DisplayTransform::getLooksOverride() const { return getImpl()->looksOverride_.c_str(); } void DisplayTransform::setLooksOverrideEnabled(bool enabled) { getImpl()->looksOverrideEnabled_ = enabled; } bool DisplayTransform::getLooksOverrideEnabled() const { return getImpl()->looksOverrideEnabled_; } std::ostream& operator<< (std::ostream& os, const DisplayTransform& t) { os << ""; return os; } /////////////////////////////////////////////////////////////////////////// void BuildDisplayOps(OpRcPtrVec & ops, const Config & config, const ConstContextRcPtr & context, const DisplayTransform & displayTransform, TransformDirection dir) { TransformDirection combinedDir = CombineTransformDirections(dir, displayTransform.getDirection()); if(combinedDir != TRANSFORM_DIR_FORWARD) { std::ostringstream os; os << "DisplayTransform can only be applied in the forward direction."; throw Exception(os.str().c_str()); } std::string inputColorSpaceName = displayTransform.getInputColorSpaceName(); ConstColorSpaceRcPtr inputColorSpace = config.getColorSpace(inputColorSpaceName.c_str()); if(!inputColorSpace) { std::ostringstream os; os << "DisplayTransform error."; if(inputColorSpaceName.empty()) os << " InputColorSpaceName is unspecified."; else os << " Cannot find inputColorSpace, named '" << inputColorSpaceName << "'."; throw Exception(os.str().c_str()); } std::string display = displayTransform.getDisplay(); std::string view = displayTransform.getView(); std::string displayColorSpaceName = config.getDisplayColorSpaceName(display.c_str(), view.c_str()); ConstColorSpaceRcPtr displayColorspace = config.getColorSpace(displayColorSpaceName.c_str()); if(!displayColorspace) { std::ostringstream os; os << "DisplayTransform error."; os << " Cannot find display colorspace, '" << displayColorSpaceName << "'."; throw Exception(os.str().c_str()); } bool skipColorSpaceConversions = (inputColorSpace->isData() || displayColorspace->isData()); // If we're viewing alpha, also skip all color space conversions. // If the user does uses a different transform for the channel view, // in place of a simple matrix, they run the risk that when viewing alpha // the colorspace transforms will not be skipped. (I.e., filmlook will be applied // to alpha.) If this ever becomes an issue, additional engineering will be // added at that time. ConstMatrixTransformRcPtr typedChannelView = DynamicPtrCast( displayTransform.getChannelView()); if(typedChannelView) { float matrix44[16]; typedChannelView->getValue(matrix44, 0x0); if((matrix44[3]>0.0f) || (matrix44[7]>0.0f) || (matrix44[11]>0.0f)) { skipColorSpaceConversions = true; } } ConstColorSpaceRcPtr currentColorSpace = inputColorSpace; // Apply a transform in ROLE_SCENE_LINEAR ConstTransformRcPtr linearCC = displayTransform.getLinearCC(); if(linearCC) { // Put the new ops into a temp array, to see if it's a no-op // If it is a no-op, dont bother doing the colorspace conversion. OpRcPtrVec tmpOps; BuildOps(tmpOps, config, context, linearCC, TRANSFORM_DIR_FORWARD); if(!IsOpVecNoOp(tmpOps)) { ConstColorSpaceRcPtr targetColorSpace = config.getColorSpace(ROLE_SCENE_LINEAR); if(!skipColorSpaceConversions) { BuildColorSpaceOps(ops, config, context, currentColorSpace, targetColorSpace); currentColorSpace = targetColorSpace; } std::copy(tmpOps.begin(), tmpOps.end(), std::back_inserter(ops)); } } // Apply a color correction, in ROLE_COLOR_TIMING ConstTransformRcPtr colorTimingCC = displayTransform.getColorTimingCC(); if(colorTimingCC) { // Put the new ops into a temp array, to see if it's a no-op // If it is a no-op, dont bother doing the colorspace conversion. OpRcPtrVec tmpOps; BuildOps(tmpOps, config, context, colorTimingCC, TRANSFORM_DIR_FORWARD); if(!IsOpVecNoOp(tmpOps)) { ConstColorSpaceRcPtr targetColorSpace = config.getColorSpace(ROLE_COLOR_TIMING); if(!skipColorSpaceConversions) { BuildColorSpaceOps(ops, config, context, currentColorSpace, targetColorSpace); currentColorSpace = targetColorSpace; } std::copy(tmpOps.begin(), tmpOps.end(), std::back_inserter(ops)); } } // Apply a look, if specified LookParseResult looks; if(displayTransform.getLooksOverrideEnabled()) { looks.parse(displayTransform.getLooksOverride()); } else if(!skipColorSpaceConversions) { looks.parse(config.getDisplayLooks(display.c_str(), view.c_str())); } if(!looks.empty()) { BuildLookOps(ops, currentColorSpace, skipColorSpaceConversions, config, context, looks); } // Apply a channel view ConstTransformRcPtr channelView = displayTransform.getChannelView(); if(channelView) { BuildOps(ops, config, context, channelView, TRANSFORM_DIR_FORWARD); } // Apply the conversion to the display color space if(!skipColorSpaceConversions) { BuildColorSpaceOps(ops, config, context, currentColorSpace, displayColorspace); currentColorSpace = displayColorspace; } // Apply a display cc ConstTransformRcPtr displayCC = displayTransform.getDisplayCC(); if(displayCC) { BuildOps(ops, config, context, displayCC, TRANSFORM_DIR_FORWARD); } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/Op.cpp0000644000175000017500000000744013223553423017074 0ustar mfvmfv/* 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 #include "Op.h" #include "pystring/pystring.h" #include OCIO_NAMESPACE_ENTER { Op::~Op() { } bool Op::canCombineWith(const OpRcPtr & /*op*/) const { return false; } void Op::combineWith(OpRcPtrVec & /*ops*/, const OpRcPtr & /*secondOp*/) const { std::ostringstream os; os << "Op: " << getInfo() << " cannot be combined. "; os << "A type-specific combining function is not defined."; throw Exception(os.str().c_str()); } std::ostream& operator<< (std::ostream & os, const Op & op) { os << op.getInfo(); return os; } namespace { const int FLOAT_DECIMALS = 7; } std::string AllocationData::getCacheID() const { std::ostringstream os; os.precision(FLOAT_DECIMALS); os << AllocationToString(allocation) << " "; for(unsigned int i=0; igetCacheID() << " supports_gpu:" << ops[i]->supportsGpuShader(); os << "\n"; } return os.str(); } bool IsOpVecNoOp(const OpRcPtrVec & ops) { for(OpRcPtrVec::size_type i = 0, size = ops.size(); i < size; ++i) { if(!ops[i]->isNoOp()) return false; } return true; } void FinalizeOpVec(OpRcPtrVec & ops, bool optimize) { // TODO: Add envvar to force disable optimizations if(optimize) { OptimizeOpVec(ops); } for(OpRcPtrVec::size_type i = 0, size = ops.size(); i < size; ++i) { ops[i]->finalize(); } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/TruelightOp.cpp0000644000175000017500000003556013223553423020770 0ustar mfvmfv/* 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 #ifdef OCIO_TRUELIGHT_SUPPORT #include #else #define TL_INPUT_LOG 0 #define TL_INPUT_LIN 1 #define TL_INPUT_VID 2 #endif // OCIO_TRUELIGHT_SUPPORT #include #include "TruelightOp.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { namespace { class TruelightOp : public Op { public: TruelightOp(const char * configroot, const char * profile, const char * camera, const char * inputdisplay, const char * recorder, const char * print, const char * lamp, const char * outputcamera, const char * display, const char * cubeinput, TransformDirection direction); virtual ~TruelightOp(); virtual OpRcPtr clone() const; virtual std::string getInfo() const; virtual std::string getCacheID() const; virtual bool isNoOp() const; virtual bool isSameType(const OpRcPtr & op) const; virtual bool isInverse(const OpRcPtr & op) const; virtual bool hasChannelCrosstalk() const; virtual void finalize(); virtual void apply(float* rgbaBuffer, long numPixels) const; virtual bool supportsGpuShader() const; virtual void writeGpuShader(std::ostream & shader, const std::string & pixelName, const GpuShaderDesc & shaderDesc) const; private: TransformDirection m_direction; void *m_truelight; std::string m_configroot; std::string m_profile; std::string m_camera; std::string m_inputdisplay; std::string m_recorder; std::string m_print; std::string m_lamp; std::string m_outputcamera; std::string m_display; int m_cubeinput; std::string m_cacheID; }; TruelightOp::TruelightOp(const char * configroot, const char * profile, const char * camera, const char * inputdisplay, const char * recorder, const char * print, const char * lamp, const char * outputcamera, const char * display, const char * cubeinput, TransformDirection direction): Op(), m_direction(direction), m_configroot(configroot), m_profile(profile), m_camera(camera), m_inputdisplay(inputdisplay), m_recorder(recorder), m_print(print), m_lamp(lamp), m_outputcamera(outputcamera), m_display(display) { if(m_direction == TRANSFORM_DIR_UNKNOWN) { throw Exception("Cannot apply TruelightOp op, unspecified transform direction."); } std::string _tmp = pystring::lower(cubeinput); if(_tmp == "log") m_cubeinput = TL_INPUT_LOG; else if(_tmp == "linear") m_cubeinput = TL_INPUT_LIN; else if(_tmp == "video") m_cubeinput = TL_INPUT_VID; else { std::ostringstream err; err << "we don't support cubeinput of type " << cubeinput; err << " try log, linear or video."; throw Exception(err.str().c_str()); } #ifdef OCIO_TRUELIGHT_SUPPORT if((TruelightBegin("")) == 0) { std::ostringstream err; err << "Error: " << TruelightGetErrorString(); throw Exception(err.str().c_str()); } m_truelight = TruelightCreateInstance(); if(!m_truelight) { std::ostringstream err; err << "Error: '" << TruelightGetErrorString(); throw Exception(err.str().c_str()); } // floating point TruelightInstanceSetMax(m_truelight, 1); // where too look for the profiles, prints etc TruelightSetRoot(m_configroot.c_str()); // invert the transform depending on direction if(m_direction == TRANSFORM_DIR_FORWARD) { TruelightInstanceSetInvertFlag(m_truelight, 0); } else if(m_direction == TRANSFORM_DIR_INVERSE) { TruelightInstanceSetInvertFlag(m_truelight, 1); } #endif // OCIO_TRUELIGHT_SUPPORT } OpRcPtr TruelightOp::clone() const { std::string _cubeinput = "unknown"; if(m_cubeinput == TL_INPUT_LOG) _cubeinput = "log"; else if(m_cubeinput == TL_INPUT_LIN) _cubeinput = "linear"; else if(m_cubeinput == TL_INPUT_VID) _cubeinput = "video"; OpRcPtr op = OpRcPtr(new TruelightOp(m_configroot.c_str(), m_profile.c_str(), m_camera.c_str(), m_inputdisplay.c_str(), m_recorder.c_str(), m_print.c_str(), m_lamp.c_str(), m_outputcamera.c_str(), m_display.c_str(), _cubeinput.c_str(), m_direction)); return op; } TruelightOp::~TruelightOp() { #ifdef OCIO_TRUELIGHT_SUPPORT if(m_truelight) TruelightDestroyInstance(m_truelight); #endif // OCIO_TRUELIGHT_SUPPORT } std::string TruelightOp::getInfo() const { return ""; } std::string TruelightOp::getCacheID() const { return m_cacheID; } bool TruelightOp::isNoOp() const { return false; } bool TruelightOp::isSameType(const OpRcPtr & /*op*/) const { // TODO: TruelightOp::isSameType return false; } bool TruelightOp::isInverse(const OpRcPtr & /*op*/) const { // TODO: TruelightOp::isInverse return false; } bool TruelightOp::hasChannelCrosstalk() const { return true; } void TruelightOp::finalize() { #ifndef OCIO_TRUELIGHT_SUPPORT std::ostringstream err; err << "OCIO has been built without Truelight support"; throw Exception(err.str().c_str()); #else if(m_profile != "") { if(TruelightInstanceSetProfile(m_truelight, m_profile.c_str()) == 0) { std::ostringstream err; err << "Error: " << TruelightGetErrorString(); throw Exception(err.str().c_str()); } } if(m_camera != "") { if(TruelightInstanceSetCamera(m_truelight, m_camera.c_str()) == 0) { std::ostringstream err; err << "Error: " << TruelightGetErrorString(); throw Exception(err.str().c_str()); } } if(m_inputdisplay != "") { if(TruelightInstanceSetInputDisplay(m_truelight, m_inputdisplay.c_str()) == 0) { std::ostringstream err; err << "Error: " << TruelightGetErrorString(); throw Exception(err.str().c_str()); } } if(m_recorder != "") { if(TruelightInstanceSetRecorder(m_truelight, m_recorder.c_str()) == 0) { std::ostringstream err; err << "Error: " << TruelightGetErrorString(); throw Exception(err.str().c_str()); } } if(m_print != "") { if(TruelightInstanceSetPrint(m_truelight, m_print.c_str()) == 0) { std::ostringstream err; err << "Error: " << TruelightGetErrorString(); throw Exception(err.str().c_str()); } } if(m_lamp != "") { if(TruelightInstanceSetLamp(m_truelight, m_lamp.c_str()) == 0) { std::ostringstream err; err << "Error: " << TruelightGetErrorString(); throw Exception(err.str().c_str()); } } if(m_outputcamera != "") { if(TruelightInstanceSetOutputCamera(m_truelight, m_outputcamera.c_str()) == 0) { std::ostringstream err; err << "Error: " << TruelightGetErrorString(); throw Exception(err.str().c_str()); } } if(m_display != "") { if(TruelightInstanceSetDisplay(m_truelight, m_display.c_str()) == 0) { std::ostringstream err; err << "Error: " << TruelightGetErrorString(); throw Exception(err.str().c_str()); } } if(TruelightInstanceSetCubeInput(m_truelight, m_cubeinput) == 0) { std::ostringstream err; err << "Error: " << TruelightGetErrorString(); throw Exception(err.str().c_str()); } if(TruelightInstanceSetUp(m_truelight) == 0) { std::ostringstream err; err << "Error: " << TruelightGetErrorString(); throw Exception(err.str().c_str()); } #endif // OCIO_TRUELIGHT_SUPPORT // build cache id std::ostringstream cacheIDStream; cacheIDStream << ""; m_cacheID = cacheIDStream.str(); } void TruelightOp::apply(float* rgbaBuffer, long numPixels) const { for(long pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) { #ifdef OCIO_TRUELIGHT_SUPPORT TruelightInstanceTransformF(m_truelight, rgbaBuffer); #endif // OCIO_TRUELIGHT_SUPPORT rgbaBuffer += 4; // skip alpha } } bool TruelightOp::supportsGpuShader() const { return false; } void TruelightOp::writeGpuShader(std::ostream & /*shader*/, const std::string & /*pixelName*/, const GpuShaderDesc & /*shaderDesc*/) const { throw Exception("TruelightOp does not define an gpu shader."); } } // anonymous namespace void CreateTruelightOps(OpRcPtrVec & ops, const TruelightTransform & data, TransformDirection direction) { ops.push_back(OpRcPtr(new TruelightOp(data.getConfigRoot(), data.getProfile(), data.getCamera(), data.getInputDisplay(), data.getRecorder(), data.getPrint(), data.getLamp(), data.getOutputCamera(), data.getDisplay(), data.getCubeInput(), direction))); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/md5/0000755000175000017500000000000013223553423016472 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/core/md5/md5.h0000644000175000017500000000704013223553423017331 0ustar mfvmfv/* Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ /* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being copyrighted. The original and principal author of md5.h is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 2002-04-13 lpd Removed support for non-ANSI compilers; removed references to Ghostscript; clarified derivation from RFC 1321; now handles byte order either statically or dynamically. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); added conditionalization for C++ compilation from Martin Purschke . 1999-05-03 lpd Original version. */ // This file was altered for OCIO compilation purposes #ifndef INCLUDED_OCIO_md5_INCLUDED #define INCLUDED_OCIO_md5_INCLUDED #include OCIO_NAMESPACE_ENTER { // Note: the md5 functions should not be wrapped in extern "C', otherwise // the symbols will not be appropriately wrapped in the OCIO namespace /* * This package supports both compile-time and run-time determination of CPU * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is * defined as non-zero, the code will be compiled to run only on big-endian * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to * run on either big- or little-endian CPUs, but will run slightly less * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. */ typedef unsigned char md5_byte_t; /* 8-bit byte */ typedef unsigned int md5_word_t; /* 32-bit word */ /* Define the state of the MD5 Algorithm. */ typedef struct md5_state_s { md5_word_t count[2]; /* message length in bits, lsw first */ md5_word_t abcd[4]; /* digest buffer */ md5_byte_t buf[64]; /* accumulate block */ } md5_state_t; /* Initialize the algorithm. */ void md5_init(md5_state_t *pms); /* Append a string to the message. */ void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); /* Finish the message and return the digest. */ void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); } OCIO_NAMESPACE_EXIT #endif /* md5_INCLUDED */ opencolorio-1.1.0~dfsg0.orig/src/core/md5/md5.cpp0000644000175000017500000003037313223553423017671 0ustar mfvmfv/* Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ /* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being copyrighted. The original and principal author of md5.c is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order either statically or dynamically; added missing #include in library. 2002-03-11 lpd Corrected argument list for main(), and added int return type, in test program and T value program. 2002-02-21 lpd Added missing #include in test program. 2000-07-03 lpd Patched to eliminate warnings about "constant is unsigned in ANSI C, signed in traditional"; made test program self-checking. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. */ // This file was altered for OCIO compilation purposes #include "md5.h" #include OCIO_NAMESPACE_ENTER { #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ #ifdef ARCH_IS_BIG_ENDIAN # define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) #else # define BYTE_ORDER 0 #endif #define T_MASK ((md5_word_t)~0) #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) #define T3 0x242070db #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) #define T6 0x4787c62a #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) #define T9 0x698098d8 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) #define T13 0x6b901122 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) #define T16 0x49b40821 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) #define T19 0x265e5a51 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) #define T22 0x02441453 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) #define T25 0x21e1cde6 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) #define T28 0x455a14ed #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) #define T31 0x676f02d9 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) #define T35 0x6d9d6122 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) #define T38 0x4bdecfa9 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) #define T41 0x289b7ec6 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) #define T44 0x04881d05 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) #define T47 0x1fa27cf8 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) #define T50 0x432aff97 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) #define T53 0x655b59c3 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) #define T57 0x6fa87e4f #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) #define T60 0x4e0811a1 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) #define T63 0x2ad7d2bb #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) { md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], d = pms->abcd[3]; md5_word_t t; #if BYTE_ORDER > 0 /* Define storage only for big-endian CPUs. */ md5_word_t X[16]; #else /* Define storage for little-endian or both types of CPUs. */ md5_word_t xbuf[16]; const md5_word_t *X; #endif { #if BYTE_ORDER == 0 /* * Determine dynamically whether this is a big-endian or * little-endian machine, since we can use a more efficient * algorithm on the latter. */ static const int w = 1; if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ #endif #if BYTE_ORDER <= 0 /* little-endian */ { /* * On little-endian machines, we can process properly aligned * data without copying it. */ if (!((data - (const md5_byte_t *)0) & 3)) { /* data are properly aligned */ X = (const md5_word_t *)data; } else { /* not aligned */ memcpy(xbuf, data, 64); X = xbuf; } } #endif #if BYTE_ORDER == 0 else /* dynamic big-endian */ #endif #if BYTE_ORDER >= 0 /* big-endian */ { /* * On big-endian machines, we must arrange the bytes in the * right order. */ const md5_byte_t *xp = data; int i; # if BYTE_ORDER == 0 X = xbuf; /* (dynamic only) */ # else # define xbuf X /* (static only) */ # endif for (i = 0; i < 16; ++i, xp += 4) xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); } #endif } #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) /* Round 1. */ /* Let [abcd k s i] denote the operation a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + F(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 7, T1); SET(d, a, b, c, 1, 12, T2); SET(c, d, a, b, 2, 17, T3); SET(b, c, d, a, 3, 22, T4); SET(a, b, c, d, 4, 7, T5); SET(d, a, b, c, 5, 12, T6); SET(c, d, a, b, 6, 17, T7); SET(b, c, d, a, 7, 22, T8); SET(a, b, c, d, 8, 7, T9); SET(d, a, b, c, 9, 12, T10); SET(c, d, a, b, 10, 17, T11); SET(b, c, d, a, 11, 22, T12); SET(a, b, c, d, 12, 7, T13); SET(d, a, b, c, 13, 12, T14); SET(c, d, a, b, 14, 17, T15); SET(b, c, d, a, 15, 22, T16); #undef SET /* Round 2. */ /* Let [abcd k s i] denote the operation a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + G(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 1, 5, T17); SET(d, a, b, c, 6, 9, T18); SET(c, d, a, b, 11, 14, T19); SET(b, c, d, a, 0, 20, T20); SET(a, b, c, d, 5, 5, T21); SET(d, a, b, c, 10, 9, T22); SET(c, d, a, b, 15, 14, T23); SET(b, c, d, a, 4, 20, T24); SET(a, b, c, d, 9, 5, T25); SET(d, a, b, c, 14, 9, T26); SET(c, d, a, b, 3, 14, T27); SET(b, c, d, a, 8, 20, T28); SET(a, b, c, d, 13, 5, T29); SET(d, a, b, c, 2, 9, T30); SET(c, d, a, b, 7, 14, T31); SET(b, c, d, a, 12, 20, T32); #undef SET /* Round 3. */ /* Let [abcd k s t] denote the operation a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define H(x, y, z) ((x) ^ (y) ^ (z)) #define SET(a, b, c, d, k, s, Ti)\ t = a + H(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 5, 4, T33); SET(d, a, b, c, 8, 11, T34); SET(c, d, a, b, 11, 16, T35); SET(b, c, d, a, 14, 23, T36); SET(a, b, c, d, 1, 4, T37); SET(d, a, b, c, 4, 11, T38); SET(c, d, a, b, 7, 16, T39); SET(b, c, d, a, 10, 23, T40); SET(a, b, c, d, 13, 4, T41); SET(d, a, b, c, 0, 11, T42); SET(c, d, a, b, 3, 16, T43); SET(b, c, d, a, 6, 23, T44); SET(a, b, c, d, 9, 4, T45); SET(d, a, b, c, 12, 11, T46); SET(c, d, a, b, 15, 16, T47); SET(b, c, d, a, 2, 23, T48); #undef SET /* Round 4. */ /* Let [abcd k s t] denote the operation a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define I(x, y, z) ((y) ^ ((x) | ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + I(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 6, T49); SET(d, a, b, c, 7, 10, T50); SET(c, d, a, b, 14, 15, T51); SET(b, c, d, a, 5, 21, T52); SET(a, b, c, d, 12, 6, T53); SET(d, a, b, c, 3, 10, T54); SET(c, d, a, b, 10, 15, T55); SET(b, c, d, a, 1, 21, T56); SET(a, b, c, d, 8, 6, T57); SET(d, a, b, c, 15, 10, T58); SET(c, d, a, b, 6, 15, T59); SET(b, c, d, a, 13, 21, T60); SET(a, b, c, d, 4, 6, T61); SET(d, a, b, c, 11, 10, T62); SET(c, d, a, b, 2, 15, T63); SET(b, c, d, a, 9, 21, T64); #undef SET /* Then perform the following additions. (That is increment each of the four registers by the value it had before this block was started.) */ pms->abcd[0] += a; pms->abcd[1] += b; pms->abcd[2] += c; pms->abcd[3] += d; } void md5_init(md5_state_t *pms) { pms->count[0] = pms->count[1] = 0; pms->abcd[0] = 0x67452301; pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; pms->abcd[3] = 0x10325476; } void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) { const md5_byte_t *p = data; int left = nbytes; int offset = (pms->count[0] >> 3) & 63; md5_word_t nbits = (md5_word_t)(nbytes << 3); if (nbytes <= 0) return; /* Update the message length. */ pms->count[1] += nbytes >> 29; pms->count[0] += nbits; if (pms->count[0] < nbits) pms->count[1]++; /* Process an initial partial block. */ if (offset) { int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); memcpy(pms->buf + offset, p, copy); if (offset + copy < 64) return; p += copy; left -= copy; md5_process(pms, pms->buf); } /* Process full blocks. */ for (; left >= 64; p += 64, left -= 64) md5_process(pms, p); /* Process a final partial block. */ if (left) memcpy(pms->buf, p, left); } void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) { static const md5_byte_t pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; md5_byte_t data[8]; int i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); /* Pad to 56 bytes mod 64. */ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ md5_append(pms, data, 8); for (i = 0; i < 16; ++i) digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/Logging.h0000644000175000017500000000352413223553423017550 0ustar mfvmfv/* 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_OCIO_LOGGING_H #define INCLUDED_OCIO_LOGGING_H #include #include OCIO_NAMESPACE_ENTER { void LogWarning(const std::string & text); void LogInfo(const std::string & text); void LogDebug(const std::string & text); bool IsDebugLoggingEnabled(); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/ColorSpaceTransform.cpp0000644000175000017500000002124313223553423022441 0ustar mfvmfv/* 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 #include "NoOps.h" #include "OpBuilders.h" OCIO_NAMESPACE_ENTER { ColorSpaceTransformRcPtr ColorSpaceTransform::Create() { return ColorSpaceTransformRcPtr(new ColorSpaceTransform(), &deleter); } void ColorSpaceTransform::deleter(ColorSpaceTransform* t) { delete t; } class ColorSpaceTransform::Impl { public: TransformDirection dir_; std::string src_; std::string dst_; Impl() : dir_(TRANSFORM_DIR_FORWARD) { } ~Impl() { } Impl& operator= (const Impl & rhs) { dir_ = rhs.dir_; src_ = rhs.src_; dst_ = rhs.dst_; return *this; } }; /////////////////////////////////////////////////////////////////////////// ColorSpaceTransform::ColorSpaceTransform() : m_impl(new ColorSpaceTransform::Impl) { } TransformRcPtr ColorSpaceTransform::createEditableCopy() const { ColorSpaceTransformRcPtr transform = ColorSpaceTransform::Create(); *(transform->m_impl) = *m_impl; return transform; } ColorSpaceTransform::~ColorSpaceTransform() { delete m_impl; m_impl = NULL; } ColorSpaceTransform& ColorSpaceTransform::operator= (const ColorSpaceTransform & rhs) { *m_impl = *rhs.m_impl; return *this; } TransformDirection ColorSpaceTransform::getDirection() const { return getImpl()->dir_; } void ColorSpaceTransform::setDirection(TransformDirection dir) { getImpl()->dir_ = dir; } const char * ColorSpaceTransform::getSrc() const { return getImpl()->src_.c_str(); } void ColorSpaceTransform::setSrc(const char * src) { getImpl()->src_ = src; } const char * ColorSpaceTransform::getDst() const { return getImpl()->dst_.c_str(); } void ColorSpaceTransform::setDst(const char * dst) { getImpl()->dst_ = dst; } std::ostream& operator<< (std::ostream& os, const ColorSpaceTransform& t) { os << ""; return os; } /////////////////////////////////////////////////////////////////////////////////////////////////////// void BuildColorSpaceOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, const ColorSpaceTransform & colorSpaceTransform, TransformDirection dir) { TransformDirection combinedDir = CombineTransformDirections(dir, colorSpaceTransform.getDirection()); ConstColorSpaceRcPtr src, dst; if(combinedDir == TRANSFORM_DIR_FORWARD) { src = config.getColorSpace( context->resolveStringVar( colorSpaceTransform.getSrc() ) ); dst = config.getColorSpace( context->resolveStringVar( colorSpaceTransform.getDst() ) ); } else if(combinedDir == TRANSFORM_DIR_INVERSE) { dst = config.getColorSpace( context->resolveStringVar( colorSpaceTransform.getSrc() ) ); src = config.getColorSpace( context->resolveStringVar( colorSpaceTransform.getDst() ) ); } BuildColorSpaceOps(ops, config, context, src, dst); } namespace { bool AreColorSpacesInSameEqualityGroup(const ConstColorSpaceRcPtr & csa, const ConstColorSpaceRcPtr & csb) { std::string a = csa->getEqualityGroup(); std::string b = csb->getEqualityGroup(); if(!a.empty()) return (a==b); return false; } } void BuildColorSpaceOps(OpRcPtrVec & ops, const Config & config, const ConstContextRcPtr & context, const ConstColorSpaceRcPtr & srcColorSpace, const ConstColorSpaceRcPtr & dstColorSpace) { if(!srcColorSpace) throw Exception("BuildColorSpaceOps failed, null srcColorSpace."); if(!dstColorSpace) throw Exception("BuildColorSpaceOps failed, null dstColorSpace."); if(AreColorSpacesInSameEqualityGroup(srcColorSpace, dstColorSpace)) return; if(dstColorSpace->isData() || srcColorSpace->isData()) return; // Consider dt8 -> vd8? // One would have to explode the srcColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE); // result, and walk through it step by step. If the dstColorspace family were // ever encountered in transit, we'd want to short circuit the result. AllocationData srcAllocation; srcAllocation.allocation = srcColorSpace->getAllocation(); srcAllocation.vars.resize( srcColorSpace->getAllocationNumVars()); if(srcAllocation.vars.size() > 0) { srcColorSpace->getAllocationVars(&srcAllocation.vars[0]); } CreateGpuAllocationNoOp(ops, srcAllocation); // Go to the reference space, either by using // * cs->ref in the forward direction // * ref->cs in the inverse direction if(srcColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE)) { BuildOps(ops, config, context, srcColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE), TRANSFORM_DIR_FORWARD); } else if(srcColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE)) { BuildOps(ops, config, context, srcColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE), TRANSFORM_DIR_INVERSE); } // Otherwise, both are not defined so its a no-op. This is not an error condition. // Go from the reference space, either by using // * ref->cs in the forward direction // * cs->ref in the inverse direction if(dstColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE)) { BuildOps(ops, config, context, dstColorSpace->getTransform(COLORSPACE_DIR_FROM_REFERENCE), TRANSFORM_DIR_FORWARD); } else if(dstColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE)) { BuildOps(ops, config, context, dstColorSpace->getTransform(COLORSPACE_DIR_TO_REFERENCE), TRANSFORM_DIR_INVERSE); } // Otherwise, both are not defined so its a no-op. This is not an error condition. AllocationData dstAllocation; dstAllocation.allocation = dstColorSpace->getAllocation(); dstAllocation.vars.resize( dstColorSpace->getAllocationNumVars()); if(dstAllocation.vars.size() > 0) { dstColorSpace->getAllocationVars(&dstAllocation.vars[0]); } CreateGpuAllocationNoOp(ops, dstAllocation); } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatIridasCube.cpp0000644000175000017500000003602013223553423022475 0ustar mfvmfv/* 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 #include #include #include #include "FileTransform.h" #include "Lut1DOp.h" #include "Lut3DOp.h" #include "ParseUtils.h" #include "pystring/pystring.h" /* http://doc.iridas.com/index.php/LUT_Formats #comments start with '#' #title is currently ignored, but it's not an error to enter one TITLE "title" #LUT_1D_SIZE M or #LUT_3D_SIZE M #where M is the size of the texture #a 3D texture has the size M x M x M #e.g. LUT_3D_SIZE 16 creates a 16 x 16 x 16 3D texture LUT_3D_SIZE 2 #Default input value range (domain) is 0.0 (black) to 1.0 (white) #Specify other min/max values to map the cube to any custom input #range you wish to use, for example if you're working with HDR data DOMAIN_MIN 0.0 0.0 0.0 DOMAIN_MAX 1.0 1.0 1.0 #for 1D textures, the data is simply a list of floating point values, #three per line, in RGB order #for 3D textures, the data is also RGB, and ordered in such a way #that the red coordinate changes fastest, then the green coordinate, #and finally, the blue coordinate changes slowest: 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 0.0 1.0 1.0 0.0 0.0 0.0 1.0 1.0 0.0 1.0 0.0 1.0 1.0 1.0 1.0 1.0 #Note that the LUT data is not limited to any particular range #and can contain values under 0.0 and over 1.0 #The processing application might however still clip the #output values to the 0.0 - 1.0 range, depending on the internal #precision of that application's pipeline #IRIDAS applications generally use a floating point pipeline #with little or no clipping */ OCIO_NAMESPACE_ENTER { namespace { class LocalCachedFile : public CachedFile { public: LocalCachedFile () : has1D(false), has3D(false) { lut1D = Lut1D::Create(); lut3D = Lut3D::Create(); }; ~LocalCachedFile() {}; bool has1D; bool has3D; Lut1DRcPtr lut1D; Lut3DRcPtr lut3D; }; typedef OCIO_SHARED_PTR LocalCachedFileRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "iridas_cube"; info.extension = "cube"; info.capabilities = FORMAT_CAPABILITY_READ; formatInfoVec.push_back(info); } CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { // this shouldn't happen if(!istream) { throw Exception ("File stream empty when trying to read Iridas .cube lut"); } // Parse the file std::vector raw; int size3d[] = { 0, 0, 0 }; int size1d = 0; bool in1d = false; bool in3d = false; float domain_min[] = { 0.0f, 0.0f, 0.0f }; float domain_max[] = { 1.0f, 1.0f, 1.0f }; { std::string line; std::vector parts; std::vector tmpfloats; while(nextline(istream, line)) { // All lines starting with '#' are comments if(pystring::startswith(line,"#")) continue; // Strip, lowercase, and split the line pystring::split(pystring::lower(pystring::strip(line)), parts); if(parts.empty()) continue; if(pystring::lower(parts[0]) == "title") { // Optional, and currently unhandled } else if(pystring::lower(parts[0]) == "lut_1d_size") { if(parts.size() != 2 || !StringToInt( &size1d, parts[1].c_str())) { throw Exception("Malformed LUT_1D_SIZE tag in Iridas .cube lut."); } raw.reserve(3*size1d); in1d = true; } else if(pystring::lower(parts[0]) == "lut_2d_size") { throw Exception("Unsupported Iridas .cube lut tag: 'LUT_2D_SIZE'."); } else if(pystring::lower(parts[0]) == "lut_3d_size") { int size = 0; if(parts.size() != 2 || !StringToInt( &size, parts[1].c_str())) { throw Exception("Malformed LUT_3D_SIZE tag in Iridas .cube lut."); } size3d[0] = size; size3d[1] = size; size3d[2] = size; raw.reserve(3*size3d[0]*size3d[1]*size3d[2]); in3d = true; } else if(pystring::lower(parts[0]) == "domain_min") { if(parts.size() != 4 || !StringToFloat( &domain_min[0], parts[1].c_str()) || !StringToFloat( &domain_min[1], parts[2].c_str()) || !StringToFloat( &domain_min[2], parts[3].c_str())) { throw Exception("Malformed DOMAIN_MIN tag in Iridas .cube lut."); } } else if(pystring::lower(parts[0]) == "domain_max") { if(parts.size() != 4 || !StringToFloat( &domain_max[0], parts[1].c_str()) || !StringToFloat( &domain_max[1], parts[2].c_str()) || !StringToFloat( &domain_max[2], parts[3].c_str())) { throw Exception("Malformed DOMAIN_MAX tag in Iridas .cube lut."); } } else { // It must be a float triple! if(!StringVecToFloatVec(tmpfloats, parts) || tmpfloats.size() != 3) { std::ostringstream os; os << "Malformed color triples specified in Iridas .cube lut:"; os << "'" << line << "'."; throw Exception(os.str().c_str()); } for(int i=0; i<3; ++i) { raw.push_back(tmpfloats[i]); } } } } // Interpret the parsed data, validate lut sizes LocalCachedFileRcPtr cachedFile = LocalCachedFileRcPtr(new LocalCachedFile()); if(in1d) { if(size1d != static_cast(raw.size()/3)) { std::ostringstream os; os << "Parse error in Iridas .cube lut. "; os << "Incorrect number of lut1d entries. "; os << "Found " << raw.size()/3 << ", expected " << size1d << "."; throw Exception(os.str().c_str()); } // Reformat 1D data if(size1d>0) { cachedFile->has1D = true; memcpy(cachedFile->lut1D->from_min, domain_min, 3*sizeof(float)); memcpy(cachedFile->lut1D->from_max, domain_max, 3*sizeof(float)); for(int channel=0; channel<3; ++channel) { cachedFile->lut1D->luts[channel].resize(size1d); for(int i=0; ilut1D->luts[channel][i] = raw[3*i+channel]; } } // 1e-5 rel error is a good threshold when float numbers near 0 // are written out with 6 decimal places of precision. This is // a bit aggressive, I.e., changes in the 6th decimal place will // be considered roundoff error, but changes in the 5th decimal // will be considered lut 'intent'. // 1.0 // 1.000005 equal to 1.0 // 1.000007 equal to 1.0 // 1.000010 not equal // 0.0 // 0.000001 not equal cachedFile->lut1D->maxerror = 1e-5f; cachedFile->lut1D->errortype = ERROR_RELATIVE; } } else if(in3d) { cachedFile->has3D = true; if(size3d[0]*size3d[1]*size3d[2] != static_cast(raw.size()/3)) { std::ostringstream os; os << "Parse error in Iridas .cube lut. "; os << "Incorrect number of lut3d entries. "; os << "Found " << raw.size()/3 << ", expected " << size3d[0]*size3d[1]*size3d[2] << "."; throw Exception(os.str().c_str()); } // Reformat 3D data memcpy(cachedFile->lut3D->from_min, domain_min, 3*sizeof(float)); memcpy(cachedFile->lut3D->from_max, domain_max, 3*sizeof(float)); cachedFile->lut3D->size[0] = size3d[0]; cachedFile->lut3D->size[1] = size3d[1]; cachedFile->lut3D->size[2] = size3d[2]; cachedFile->lut3D->lut = raw; } else { std::ostringstream os; os << "Parse error in Iridas .cube lut. "; os << "Lut type (1D/3D) unspecified."; throw Exception(os.str().c_str()); } return cachedFile; } void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops, const Config& /*config*/, const ConstContextRcPtr & /*context*/, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { LocalCachedFileRcPtr cachedFile = DynamicPtrCast(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build Iridas .cube Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_UNKNOWN) { std::ostringstream os; os << "Cannot build file format transform,"; os << " unspecified transform direction."; throw Exception(os.str().c_str()); } // TODO: INTERP_LINEAR should not be hard-coded. // Instead query 'highest' interpolation? // (right now, it's linear). If cubic is added, consider // using it if(newDir == TRANSFORM_DIR_FORWARD) { if(cachedFile->has1D) { CreateLut1DOp(ops, cachedFile->lut1D, INTERP_LINEAR, newDir); } if(cachedFile->has3D) { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } } else if(newDir == TRANSFORM_DIR_INVERSE) { if(cachedFile->has3D) { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } if(cachedFile->has1D) { CreateLut1DOp(ops, cachedFile->lut1D, INTERP_LINEAR, newDir); } } } } FileFormat * CreateFileFormatIridasCube() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// opencolorio-1.1.0~dfsg0.orig/src/core/ColorSpace.cpp0000644000175000017500000002034113223553423020543 0ustar mfvmfv/* 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 #include #include #include OCIO_NAMESPACE_ENTER { ColorSpaceRcPtr ColorSpace::Create() { return ColorSpaceRcPtr(new ColorSpace(), &deleter); } void ColorSpace::deleter(ColorSpace* c) { delete c; } class ColorSpace::Impl { public: std::string name_; std::string family_; std::string equalityGroup_; std::string description_; BitDepth bitDepth_; bool isData_; Allocation allocation_; std::vector allocationVars_; TransformRcPtr toRefTransform_; TransformRcPtr fromRefTransform_; bool toRefSpecified_; bool fromRefSpecified_; Impl() : bitDepth_(BIT_DEPTH_UNKNOWN), isData_(false), allocation_(ALLOCATION_UNIFORM), toRefSpecified_(false), fromRefSpecified_(false) { } ~Impl() { } Impl& operator= (const Impl & rhs) { name_ = rhs.name_; family_ = rhs.family_; equalityGroup_ = rhs.equalityGroup_; description_ = rhs.description_; bitDepth_ = rhs.bitDepth_; isData_ = rhs.isData_; allocation_ = rhs.allocation_; allocationVars_ = rhs.allocationVars_; toRefTransform_ = rhs.toRefTransform_; if(toRefTransform_) toRefTransform_ = toRefTransform_->createEditableCopy(); fromRefTransform_ = rhs.fromRefTransform_; if(fromRefTransform_) fromRefTransform_ = fromRefTransform_->createEditableCopy(); toRefSpecified_ = rhs.toRefSpecified_; fromRefSpecified_ = rhs.fromRefSpecified_; return *this; } }; /////////////////////////////////////////////////////////////////////////// ColorSpace::ColorSpace() : m_impl(new ColorSpace::Impl) { } ColorSpace::~ColorSpace() { delete m_impl; m_impl = NULL; } ColorSpaceRcPtr ColorSpace::createEditableCopy() const { ColorSpaceRcPtr cs = ColorSpace::Create(); *cs->m_impl = *m_impl; return cs; } const char * ColorSpace::getName() const { return getImpl()->name_.c_str(); } void ColorSpace::setName(const char * name) { getImpl()->name_ = name; } const char * ColorSpace::getFamily() const { return getImpl()->family_.c_str(); } void ColorSpace::setFamily(const char * family) { getImpl()->family_ = family; } const char * ColorSpace::getEqualityGroup() const { return getImpl()->equalityGroup_.c_str(); } void ColorSpace::setEqualityGroup(const char * equalityGroup) { getImpl()->equalityGroup_ = equalityGroup; } const char * ColorSpace::getDescription() const { return getImpl()->description_.c_str(); } void ColorSpace::setDescription(const char * description) { getImpl()->description_ = description; } BitDepth ColorSpace::getBitDepth() const { return getImpl()->bitDepth_; } void ColorSpace::setBitDepth(BitDepth bitDepth) { getImpl()->bitDepth_ = bitDepth; } bool ColorSpace::isData() const { return getImpl()->isData_; } void ColorSpace::setIsData(bool val) { getImpl()->isData_ = val; } Allocation ColorSpace::getAllocation() const { return getImpl()->allocation_; } void ColorSpace::setAllocation(Allocation allocation) { getImpl()->allocation_ = allocation; } int ColorSpace::getAllocationNumVars() const { return static_cast(getImpl()->allocationVars_.size()); } void ColorSpace::getAllocationVars(float * vars) const { if(!getImpl()->allocationVars_.empty()) { memcpy(vars, &getImpl()->allocationVars_[0], getImpl()->allocationVars_.size()*sizeof(float)); } } void ColorSpace::setAllocationVars(int numvars, const float * vars) { getImpl()->allocationVars_.resize(numvars); if(!getImpl()->allocationVars_.empty()) { memcpy(&getImpl()->allocationVars_[0], vars, numvars*sizeof(float)); } } ConstTransformRcPtr ColorSpace::getTransform(ColorSpaceDirection dir) const { if(dir == COLORSPACE_DIR_TO_REFERENCE) return getImpl()->toRefTransform_; else if(dir == COLORSPACE_DIR_FROM_REFERENCE) return getImpl()->fromRefTransform_; throw Exception("Unspecified ColorSpaceDirection"); } void ColorSpace::setTransform(const ConstTransformRcPtr & transform, ColorSpaceDirection dir) { TransformRcPtr transformCopy; if(transform) transformCopy = transform->createEditableCopy(); if(dir == COLORSPACE_DIR_TO_REFERENCE) getImpl()->toRefTransform_ = transformCopy; else if(dir == COLORSPACE_DIR_FROM_REFERENCE) getImpl()->fromRefTransform_ = transformCopy; else throw Exception("Unspecified ColorSpaceDirection"); } std::ostream& operator<< (std::ostream& os, const ColorSpace& cs) { int numVars(cs.getAllocationNumVars()); std::vector vars(numVars); cs.getAllocationVars(&vars[0]); os << ""; if(cs.getTransform(COLORSPACE_DIR_TO_REFERENCE)) { os << "\n " << cs.getName() << " --> Reference"; os << "\n\t" << *cs.getTransform(COLORSPACE_DIR_TO_REFERENCE); } if(cs.getTransform(COLORSPACE_DIR_FROM_REFERENCE)) { os << "\n Reference --> " << cs.getName(); os << "\n\t" << *cs.getTransform(COLORSPACE_DIR_FROM_REFERENCE); } return os; } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core/AllocationOp.h0000644000175000017500000000351413223553423020545 0ustar mfvmfv/* 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_OCIO_ALLOCATIONOP_H #define INCLUDED_OCIO_ALLOCATIONOP_H #include #include "Op.h" OCIO_NAMESPACE_ENTER { void CreateAllocationOps(OpRcPtrVec & ops, const AllocationData & data, TransformDirection dir); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/core/FileFormatHDL.cpp0000644000175000017500000015627413223553423021110 0ustar mfvmfv/* 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. */ /* Houdini LUTs http://www.sidefx.com/docs/hdk11.0/hdk_io_lut.html Types: - 1D Lut (partial support) - 3D Lut - 3D Lut with 1D Prelut TODO: - Add support for other 1D types (R, G, B, A, RGB, RGBA, All) we only support type 'C' atm. - Add support for 'Sampling' tag */ #include #include #include #include #include #include #include #include #include #include "FileTransform.h" #include "Lut1DOp.h" #include "Lut3DOp.h" #include "ParseUtils.h" #include "MathUtils.h" #include "pystring/pystring.h" OCIO_NAMESPACE_ENTER { namespace { // HDL parser helpers // HDL headers/LUT's are shoved into these datatypes typedef std::map > StringToStringVecMap; typedef std::map > StringToFloatVecMap; void readHeaders(StringToStringVecMap& headers, std::istream& istream) { std::string line; while(nextline(istream, line)) { std::vector chunks; // Remove trailing/leading whitespace, lower-case and // split into words pystring::split(pystring::lower(pystring::strip(line)), chunks); // Skip empty lines if(chunks.empty()) continue; // Stop looking for headers at the "LUT:" line if(chunks[0] == "lut:") break; // Use first index as key, and remove it from the value std::string key = chunks[0]; chunks.erase(chunks.begin()); headers[key] = chunks; } } // Try to grab key (e.g "version") from headers. Throws // exception if not found, or if number of chunks in value is // not between min_vals and max_vals (e.g the "length" key // must exist, and must have either 1 or 2 values) std::vector findHeaderItem(StringToStringVecMap& headers, const std::string key, const unsigned int min_vals, const unsigned int max_vals) { StringToStringVecMap::iterator iter; iter = headers.find(key); // Error if key is not found if(iter == headers.end()) { std::ostringstream os; os << "'" << key << "' line not found"; throw Exception(os.str().c_str()); } // Error if incorrect number of values is found if(iter->second.size() < min_vals || iter->second.size() > max_vals) { std::ostringstream os; os << "Incorrect number of chunks (" << iter->second.size() << ")"; os << " after '" << key << "' line, expected "; if(min_vals == max_vals) { os << min_vals; } else { os << "between " << min_vals << " and " << max_vals; } throw Exception(os.str().c_str()); } return iter->second; } // Simple wrapper to call findHeaderItem with a fixed number // of values (e.g "version" should have a single value) std::vector findHeaderItem(StringToStringVecMap& chunks, const std::string key, const unsigned int numvals) { return findHeaderItem(chunks, key, numvals, numvals); } // Crudely parse LUT's - doesn't do any length checking etc, // just grabs a series of floats for Pre{...}, 3d{...} etc // Does some basic error checking, but there are situations // were it could incorrectly accept broken data (like // "Pre{0.0\n1.0}blah"), but hopefully none where it misses // data void readLuts(std::istream& istream, StringToFloatVecMap& lutValues) { // State variables bool inlut = false; std::string lutname; std::string word; while(istream >> word) { if(!inlut) { if(word == "{") { // Lone "{" is for a 3D inlut = true; lutname = "3d"; } else { // Named lut, e.g "Pre {" inlut = true; lutname = pystring::lower(word); // Ensure next word is "{" std::string nextword; istream >> nextword; if(nextword != "{") { std::ostringstream os; os << "Malformed LUT - Unknown word '"; os << word << "' after LUT name '"; os << nextword << "'"; throw Exception(os.str().c_str()); } } } else if(word == "}") { // end of LUT inlut = false; lutname = ""; } else if(inlut) { // StringToFloat was far slower, for 787456 values: // - StringToFloat took 3879 (avg nanoseconds per value) // - stdtod took 169 nanoseconds char* endptr = 0; float v = static_cast(strtod(word.c_str(), &endptr)); if(!*endptr) { // Since each word should contain a single // float value, the pointer should be null lutValues[lutname].push_back(v); } else { // stdtod endptr still contained stuff, // meaning an invalid float value std::ostringstream os; os << "Invalid float value in " << lutname; os << " LUT, '" << word << "'"; throw Exception(os.str().c_str()); } } else { std::ostringstream os; os << "Unexpected word, possibly a value outside"; os <<" a LUT {} block. Word was '" << word << "'"; throw Exception(os.str().c_str()); } } } } // end anonymous "HDL parser helpers" namespace namespace { class CachedFileHDL : public CachedFile { public: CachedFileHDL () { hdlversion = "unknown"; hdlformat = "unknown"; hdltype = "unknown"; hdlblack = 0.0; hdlwhite = 1.0; lut1D = Lut1D::Create(); lut3D = Lut3D::Create(); }; ~CachedFileHDL() {}; std::string hdlversion; std::string hdlformat; std::string hdltype; float to_min; // TODO: maybe add this to Lut1DOp? float to_max; // TODO: maybe add this to Lut1DOp? float hdlblack; float hdlwhite; Lut1DRcPtr lut1D; Lut3DRcPtr lut3D; }; typedef OCIO_SHARED_PTR CachedFileHDLRcPtr; class LocalFileFormat : public FileFormat { public: ~LocalFileFormat() {}; virtual void GetFormatInfo(FormatInfoVec & formatInfoVec) const; virtual CachedFileRcPtr Read(std::istream & istream) const; virtual void Write(const Baker & baker, const std::string & formatName, std::ostream & ostream) const; virtual void BuildFileOps(OpRcPtrVec & ops, const Config& config, const ConstContextRcPtr & context, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const; }; void LocalFileFormat::GetFormatInfo(FormatInfoVec & formatInfoVec) const { FormatInfo info; info.name = "houdini"; info.extension = "lut"; info.capabilities = FORMAT_CAPABILITY_READ | FORMAT_CAPABILITY_WRITE; formatInfoVec.push_back(info); } CachedFileRcPtr LocalFileFormat::Read(std::istream & istream) const { // this shouldn't happen if (!istream) throw Exception ("file stream empty when trying to read Houdini lut"); // CachedFileHDLRcPtr cachedFile = CachedFileHDLRcPtr (new CachedFileHDL ()); Lut1DRcPtr lut1d_ptr = Lut1D::Create(); Lut3DRcPtr lut3d_ptr = Lut3D::Create(); // Parse headers into key-value pairs StringToStringVecMap header_chunks; StringToStringVecMap::iterator iter; // Read headers, ending after the "LUT:" line readHeaders(header_chunks, istream); // Grab useful values from headers std::vector value; // "Version 3" - format version (currently one version // number per LUT type) value = findHeaderItem(header_chunks, "version", 1); cachedFile->hdlversion = value[0]; // "Format any" - bit depth of image the LUT should be // applied to (this is basically ignored) value = findHeaderItem(header_chunks, "format", 1); cachedFile->hdlformat = value[0]; // "Type 3d" - type of LUT { value = findHeaderItem(header_chunks, "type", 1); cachedFile->hdltype = value[0]; } // "From 0.0 1.0" - range of input values { float from_min, from_max; value = findHeaderItem(header_chunks, "from", 2); if(!StringToFloat(&from_min, value[0].c_str()) || !StringToFloat(&from_max, value[1].c_str())) { std::ostringstream os; os << "Invalid float value(s) on 'From' line, '"; os << value[0] << "' and '" << value[1] << "'"; throw Exception(os.str().c_str()); } for(int i = 0; i < 3; ++i) { lut1d_ptr->from_min[i] = from_min; lut1d_ptr->from_max[i] = from_max; } } // "To 0.0 1.0" - range of values in LUT (e.g "0 255" // to specify values as 8-bit numbers, usually "0 1") { float to_min, to_max; value = findHeaderItem(header_chunks, "to", 2); if(!StringToFloat(&to_min, value[0].c_str()) || !StringToFloat(&to_max, value[1].c_str())) { std::ostringstream os; os << "Invalid float value(s) on 'To' line, '"; os << value[0] << "' and '" << value[1] << "'"; throw Exception(os.str().c_str()); } cachedFile->to_min = to_min; cachedFile->to_max = to_max; } // "Black 0" and "White 1" - obsolete options, should be 0 // and 1 { value = findHeaderItem(header_chunks, "black", 1); float black; if(!StringToFloat(&black, value[0].c_str())) { std::ostringstream os; os << "Invalid float value on 'Black' line, '"; os << value[0] << "'"; throw Exception(os.str().c_str()); } cachedFile->hdlblack = black; } { value = findHeaderItem(header_chunks, "white", 1); float white; if(!StringToFloat(&white, value[0].c_str())) { std::ostringstream os; os << "Invalid float value on 'White' line, '"; os << value[0] << "'"; throw Exception(os.str().c_str()); } cachedFile->hdlwhite = white; } // Verify type is valid and supported - used to handle // length sensibly, and checking the LUT later { std::string ltype = cachedFile->hdltype; if(ltype != "3d" && ltype != "3d+1d" && ltype != "c") { std::ostringstream os; os << "Unsupported Houdini LUT type: '" << ltype << "'"; throw Exception(os.str().c_str()); } } // "Length 2" or "Length 2 5" - either "[cube size]", or "[cube // size] [prelut size]" int size_3d = -1; int size_prelut = -1; int size_1d = -1; { std::vector lut_sizes; value = findHeaderItem(header_chunks, "length", 1, 2); for(unsigned int i = 0; i < value.size(); ++i) { int tmpsize = -1; if(!StringToInt(&tmpsize, value[i].c_str())) { std::ostringstream os; os << "Invalid integer on 'Length' line: "; os << "'" << value[0] << "'"; throw Exception(os.str().c_str()); } lut_sizes.push_back(tmpsize); } if(cachedFile->hdltype == "3d" || cachedFile->hdltype == "3d+1d") { // Set cube size size_3d = lut_sizes[0]; lut3d_ptr->size[0] = lut_sizes[0]; lut3d_ptr->size[1] = lut_sizes[0]; lut3d_ptr->size[2] = lut_sizes[0]; } if(cachedFile->hdltype == "c") { size_1d = lut_sizes[0]; } if(cachedFile->hdltype == "3d+1d") { size_prelut = lut_sizes[1]; } } // Read stuff after "LUT:" StringToFloatVecMap lut_data; readLuts(istream, lut_data); // StringToFloatVecMap::iterator lut_iter; if(cachedFile->hdltype == "3d+1d") { // Read prelut, and bind onto cachedFile lut_iter = lut_data.find("pre"); if(lut_iter == lut_data.end()) { std::ostringstream os; os << "3D+1D LUT should contain Pre{} LUT section"; throw Exception(os.str().c_str()); } if(size_prelut != static_cast(lut_iter->second.size())) { std::ostringstream os; os << "Pre{} LUT was " << lut_iter->second.size(); os << " values long, expected " << size_prelut << " values"; throw Exception(os.str().c_str()); } lut1d_ptr->luts[0] = lut_iter->second; lut1d_ptr->luts[1] = lut_iter->second; lut1d_ptr->luts[2] = lut_iter->second; lut1d_ptr->maxerror = 0.0f; lut1d_ptr->errortype = ERROR_RELATIVE; cachedFile->lut1D = lut1d_ptr; } if(cachedFile->hdltype == "3d" || cachedFile->hdltype == "3d+1d") { // Bind 3D LUT to lut3d_ptr, along with some // slightly-elabourate error messages lut_iter = lut_data.find("3d"); if(lut_iter == lut_data.end()) { std::ostringstream os; os << "3D LUT section not found"; throw Exception(os.str().c_str()); } int size_3d_cubed = size_3d * size_3d * size_3d; if(size_3d_cubed * 3 != static_cast(lut_iter->second.size())) { int foundsize = static_cast(lut_iter->second.size()); int foundlines = foundsize / 3; std::ostringstream os; os << "3D LUT contains incorrect number of values. "; os << "Contained " << foundsize << " values "; os << "(" << foundlines << " lines), "; os << "expected " << (size_3d_cubed*3) << " values "; os << "(" << size_3d_cubed << " lines)"; throw Exception(os.str().c_str()); } lut3d_ptr->lut = lut_iter->second; // Bind to cachedFile cachedFile->lut3D = lut3d_ptr; } if(cachedFile->hdltype == "c") { // Bind simple 1D RGB LUT lut_iter = lut_data.find("rgb"); if(lut_iter == lut_data.end()) { std::ostringstream os; os << "3D+1D LUT should contain Pre{} LUT section"; throw Exception(os.str().c_str()); } if(size_1d != static_cast(lut_iter->second.size())) { std::ostringstream os; os << "RGB{} LUT was " << lut_iter->second.size(); os << " values long, expected " << size_1d << " values"; throw Exception(os.str().c_str()); } lut1d_ptr->luts[0] = lut_iter->second; lut1d_ptr->luts[1] = lut_iter->second; lut1d_ptr->luts[2] = lut_iter->second; lut1d_ptr->maxerror = 0.0f; lut1d_ptr->errortype = ERROR_RELATIVE; cachedFile->lut1D = lut1d_ptr; } return cachedFile; } void LocalFileFormat::Write(const Baker & baker, const std::string & formatName, std::ostream & ostream) const { if(formatName != "houdini") { std::ostringstream os; os << "Unknown hdl format name, '"; os << formatName << "'."; throw Exception(os.str().c_str()); } // Get config ConstConfigRcPtr config = baker.getConfig(); // setup the floating point precision ostream.setf(std::ios::fixed, std::ios::floatfield); ostream.precision(6); // Default sizes const int DEFAULT_SHAPER_SIZE = 1024; // MPlay produces bad results with 32^3 cube (in a way // that looks more quantised than even "nearest" // interpolation in OCIOFileTransform) const int DEFAULT_CUBE_SIZE = 64; const int DEFAULT_1D_SIZE = 1024; // Get configured sizes int cubeSize = baker.getCubeSize(); int shaperSize = baker.getShaperSize(); // FIXME: Misusing cube size to set 1D LUT size, as it seemed // slightly less confusing than using the shaper LUT size int onedSize = baker.getCubeSize(); // Defaults and sanity check on cube size if(cubeSize == -1) cubeSize = DEFAULT_CUBE_SIZE; if(cubeSize < 0) cubeSize = DEFAULT_CUBE_SIZE; if(cubeSize<2) { std::ostringstream os; os << "Cube size must be 2 or larger (was " << cubeSize << ")"; throw Exception(os.str().c_str()); } // ..and same for shaper size if(shaperSize<0) shaperSize = DEFAULT_SHAPER_SIZE; if(shaperSize<2) { std::ostringstream os; os << "A shaper space ('" << baker.getShaperSpace() << "') has"; os << " been specified, so the shaper size must be 2 or larger"; throw Exception(os.str().c_str()); } // ..and finally, for the 1D LUT size if(onedSize == -1) onedSize = DEFAULT_1D_SIZE; if(onedSize < 2) { std::ostringstream os; os << "1D LUT size must be higher than 2 (was " << onedSize << ")"; throw Exception(os.str().c_str()); } // Version numbers const int HDL_1D = 1; // 1D LUT version number const int HDL_3D = 2; // 3D LUT version number const int HDL_3D1D = 3; // 3D LUT with 1D prelut // Get spaces from baker const std::string shaperSpace = baker.getShaperSpace(); const std::string inputSpace = baker.getInputSpace(); const std::string targetSpace = baker.getTargetSpace(); const std::string looks = baker.getLooks(); // Determine required LUT type ConstProcessorRcPtr inputToTargetProc; if (!looks.empty()) { LookTransformRcPtr transform = LookTransform::Create(); transform->setLooks(looks.c_str()); transform->setSrc(inputSpace.c_str()); transform->setDst(targetSpace.c_str()); inputToTargetProc = config->getProcessor(transform, TRANSFORM_DIR_FORWARD); } else { inputToTargetProc = config->getProcessor( inputSpace.c_str(), targetSpace.c_str()); } int required_lut = -1; if(inputToTargetProc->hasChannelCrosstalk()) { if(shaperSpace.empty()) { // Has crosstalk, but no prelut, so need 3D LUT required_lut = HDL_3D; } else { // Crosstalk with shaper-space required_lut = HDL_3D1D; } } else { // No crosstalk required_lut = HDL_1D; } if(required_lut == -1) { // Unnecessary paranoia throw Exception( "Internal logic error, LUT type was not determined"); } // Make prelut std::vector prelutData; float fromInStart = 0; // for "From:" part of header float fromInEnd = 1; if(required_lut == HDL_3D1D) { // TODO: Later we only grab the green channel for the prelut, // should ensure the prelut is monochromatic somehow? ConstProcessorRcPtr inputToShaperProc = config->getProcessor( inputSpace.c_str(), shaperSpace.c_str()); if(inputToShaperProc->hasChannelCrosstalk()) { // TODO: Automatically turn shaper into // non-crosstalked version? std::ostringstream os; os << "The specified shaperSpace, '" << baker.getShaperSpace(); os << "' has channel crosstalk, which is not appropriate for"; os << " shapers. Please select an alternate shaper space or"; os << " omit this option."; throw Exception(os.str().c_str()); } // Calculate min/max value { // Get input value of 1.0 in shaper space, as this // is the higest value that is transformed by the // cube (e.g for a generic lin-to-log trasnform, // what the log value 1.0 is in linear). ConstProcessorRcPtr shaperToInputProc = config->getProcessor( shaperSpace.c_str(), inputSpace.c_str()); float minval[3] = {0.0f, 0.0f, 0.0f}; float maxval[3] = {1.0f, 1.0f, 1.0f}; shaperToInputProc->applyRGB(minval); shaperToInputProc->applyRGB(maxval); // Grab green channel, as this is the one used later fromInStart = minval[1]; fromInEnd = maxval[1]; } // Generate the identity prelut values, then apply the transform. // Prelut is linearly sampled from fromInStart to fromInEnd prelutData.resize(shaperSize*3); for (int i = 0; i < shaperSize; ++i) { const float x = (float)(double(i) / double(shaperSize - 1)); float cur_value = lerpf(fromInStart, fromInEnd, x); prelutData[3*i+0] = cur_value; prelutData[3*i+1] = cur_value; prelutData[3*i+2] = cur_value; } PackedImageDesc prelutImg(&prelutData[0], shaperSize, 1, 3); inputToShaperProc->apply(prelutImg); } // TODO: Do same "auto prelut" input-space allocation as FileFormatCSP? // Make 3D LUT std::vector cubeData; if(required_lut == HDL_3D || required_lut == HDL_3D1D) { cubeData.resize(cubeSize*cubeSize*cubeSize*3); GenerateIdentityLut3D(&cubeData[0], cubeSize, 3, LUT3DORDER_FAST_RED); PackedImageDesc cubeImg(&cubeData[0], cubeSize*cubeSize*cubeSize, 1, 3); ConstProcessorRcPtr cubeProc; if(required_lut == HDL_3D1D) { // Prelut goes from input-to-shaper, so cube goes from shaper-to-target if (!looks.empty()) { LookTransformRcPtr transform = LookTransform::Create(); transform->setLooks(looks.c_str()); transform->setSrc(shaperSpace.c_str()); transform->setDst(targetSpace.c_str()); cubeProc = config->getProcessor(transform, TRANSFORM_DIR_FORWARD); } else { cubeProc = config->getProcessor(shaperSpace.c_str(), targetSpace.c_str()); } } else { // No prelut, so cube goes from input-to-target cubeProc = inputToTargetProc; } cubeProc->apply(cubeImg); } // Make 1D LUT std::vector onedData; if(required_lut == HDL_1D) { onedData.resize(onedSize * 3); GenerateIdentityLut1D(&onedData[0], onedSize, 3); PackedImageDesc onedImg(&onedData[0], onedSize, 1, 3); inputToTargetProc->apply(onedImg); } // Write the file contents ostream << "Version\t\t" << required_lut << "\n"; ostream << "Format\t\t" << "any" << "\n"; ostream << "Type\t\t"; if(required_lut == HDL_1D) ostream << "RGB"; if(required_lut == HDL_3D) ostream << "3D"; if(required_lut == HDL_3D1D) ostream << "3D+1D"; ostream << "\n"; ostream << "From\t\t" << fromInStart << " " << fromInEnd << "\n"; ostream << "To\t\t" << 0.0f << " " << 1.0f << "\n"; ostream << "Black\t\t" << 0.0f << "\n"; ostream << "White\t\t" << 1.0f << "\n"; if(required_lut == HDL_3D1D) ostream << "Length\t\t" << cubeSize << " " << shaperSize << "\n"; if(required_lut == HDL_3D) ostream << "Length\t\t" << cubeSize << "\n"; if(required_lut == HDL_1D) ostream << "Length\t\t" << onedSize << "\n"; ostream << "LUT:\n"; // Write prelut if(required_lut == HDL_3D1D) { ostream << "Pre {\n"; for(int i=0; i < shaperSize; ++i) { // Grab green channel from RGB prelut ostream << "\t" << prelutData[i*3+1] << "\n"; } ostream << "}\n"; } // Write "3D {" part of output of 3D+1D LUT if(required_lut == HDL_3D1D) { ostream << "3D {\n"; } // Write the slightly-different "{" without line for the 3D-only LUT if(required_lut == HDL_3D) { ostream << " {\n"; } // Write the cube data after the "{" if(required_lut == HDL_3D || required_lut == HDL_3D1D) { for(int i=0; i < cubeSize*cubeSize*cubeSize; ++i) { // TODO: Original baker code clamped values to // 1.0, was this necessary/desirable? ostream << "\t" << cubeData[3*i+0]; ostream << " " << cubeData[3*i+1]; ostream << " " << cubeData[3*i+2] << "\n"; } // Write closing "}" ostream << " }\n"; } // Write out channels for 1D LUT if(required_lut == HDL_1D) { ostream << "R {\n"; for(int i=0; i < onedSize; ++i) ostream << "\t" << onedData[i*3+0] << "\n"; ostream << "}\n"; ostream << "G {\n"; for(int i=0; i < onedSize; ++i) ostream << "\t" << onedData[i*3+1] << "\n"; ostream << "}\n"; ostream << "B {\n"; for(int i=0; i < onedSize; ++i) ostream << "\t" << onedData[i*3+2] << "\n"; ostream << "}\n"; } } void LocalFileFormat::BuildFileOps(OpRcPtrVec & ops, const Config& /*config*/, const ConstContextRcPtr & /*context*/, CachedFileRcPtr untypedCachedFile, const FileTransform& fileTransform, TransformDirection dir) const { CachedFileHDLRcPtr cachedFile = DynamicPtrCast(untypedCachedFile); // This should never happen. if(!cachedFile) { std::ostringstream os; os << "Cannot build Houdini Op. Invalid cache type."; throw Exception(os.str().c_str()); } TransformDirection newDir = CombineTransformDirections(dir, fileTransform.getDirection()); if(newDir == TRANSFORM_DIR_FORWARD) { if(cachedFile->hdltype == "c") { CreateLut1DOp(ops, cachedFile->lut1D, fileTransform.getInterpolation(), newDir); } else if(cachedFile->hdltype == "3d") { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } else if(cachedFile->hdltype == "3d+1d") { CreateLut1DOp(ops, cachedFile->lut1D, fileTransform.getInterpolation(), newDir); CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } else { throw Exception("Unhandled hdltype while creating forward ops"); } } else if(newDir == TRANSFORM_DIR_INVERSE) { if(cachedFile->hdltype == "c") { CreateLut1DOp(ops, cachedFile->lut1D, fileTransform.getInterpolation(), newDir); } else if(cachedFile->hdltype == "3d") { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); } else if(cachedFile->hdltype == "3d+1d") { CreateLut3DOp(ops, cachedFile->lut3D, fileTransform.getInterpolation(), newDir); CreateLut1DOp(ops, cachedFile->lut1D, fileTransform.getInterpolation(), newDir); } else { throw Exception("Unhandled hdltype while creating reverse ops"); } } return; } } FileFormat * CreateFileFormatHDL() { return new LocalFileFormat(); } } OCIO_NAMESPACE_EXIT /////////////////////////////////////////////////////////////////////////////// #ifdef OCIO_UNIT_TEST namespace OCIO = OCIO_NAMESPACE; #include "UnitTest.h" OIIO_ADD_TEST(FileFormatHDL, Read1D) { std::ostringstream strebuf; strebuf << "Version\t\t1" << "\n"; strebuf << "Format\t\tany" << "\n"; strebuf << "Type\t\tC" << "\n"; strebuf << "From\t\t0.1 3.2" << "\n"; strebuf << "To\t\t0 1" << "\n"; strebuf << "Black\t\t0" << "\n"; strebuf << "White\t\t0.99" << "\n"; strebuf << "Length\t\t9" << "\n"; strebuf << "LUT:" << "\n"; strebuf << "RGB {" << "\n"; strebuf << "\t0" << "\n"; strebuf << "\t0.000977517" << "\n"; strebuf << "\t0.00195503" << "\n"; strebuf << "\t0.00293255" << "\n"; strebuf << "\t0.00391007" << "\n"; strebuf << "\t0.00488759" << "\n"; strebuf << "\t0.0058651" << "\n"; strebuf << "\t0.999022" << "\n"; strebuf << "\t1.67 }" << "\n"; // float from_min = 0.1f; float from_max = 3.2f; float to_min = 0.0f; float to_max = 1.0f; float black = 0.0f; float white = 0.99f; float lut1d[9] = { 0.0f, 0.000977517f, 0.00195503f, 0.00293255f, 0.00391007f, 0.00488759f, 0.0058651f, 0.999022f, 1.67f }; std::istringstream simple3D1D; simple3D1D.str(strebuf.str()); // Load file OCIO::LocalFileFormat tester; OCIO::CachedFileRcPtr cachedFile = tester.Read(simple3D1D); OCIO::CachedFileHDLRcPtr lut = OCIO::DynamicPtrCast(cachedFile); // OIIO_CHECK_EQUAL(to_min, lut->to_min); OIIO_CHECK_EQUAL(to_max, lut->to_max); OIIO_CHECK_EQUAL(black, lut->hdlblack); OIIO_CHECK_EQUAL(white, lut->hdlwhite); // check 1D data (each channel has the same data) for(int c = 0; c < 3; ++c) { OIIO_CHECK_EQUAL(from_min, lut->lut1D->from_min[c]); OIIO_CHECK_EQUAL(from_max, lut->lut1D->from_max[c]); OIIO_CHECK_EQUAL(9, lut->lut1D->luts[c].size()); for(unsigned int i = 0; i < lut->lut1D->luts[c].size(); ++i) { OIIO_CHECK_EQUAL(lut1d[i], lut->lut1D->luts[c][i]); } } } OIIO_ADD_TEST(FileFormatHDL, Bake1D) { OCIO::ConfigRcPtr config = OCIO::Config::Create(); // Add lnf space { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("lnf"); cs->setFamily("lnf"); config->addColorSpace(cs); config->setRole(OCIO::ROLE_REFERENCE, cs->getName()); } // Add target space { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("target"); cs->setFamily("target"); OCIO::CDLTransformRcPtr transform1 = OCIO::CDLTransform::Create(); float rgb[3] = {0.1f, 0.1f, 0.1f}; transform1->setOffset(rgb); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_FROM_REFERENCE); config->addColorSpace(cs); } std::string bout = "Version\t\t1\n" "Format\t\tany\n" "Type\t\tRGB\n" "From\t\t0.000000 1.000000\n" "To\t\t0.000000 1.000000\n" "Black\t\t0.000000\n" "White\t\t1.000000\n" "Length\t\t10\n" "LUT:\n" "R {\n" "\t0.100000\n" "\t0.211111\n" "\t0.322222\n" "\t0.433333\n" "\t0.544444\n" "\t0.655556\n" "\t0.766667\n" "\t0.877778\n" "\t0.988889\n" "\t1.100000\n" " }\n" "G {\n" "\t0.100000\n" "\t0.211111\n" "\t0.322222\n" "\t0.433333\n" "\t0.544444\n" "\t0.655556\n" "\t0.766667\n" "\t0.877778\n" "\t0.988889\n" "\t1.100000\n" " }\n" "B {\n" "\t0.100000\n" "\t0.211111\n" "\t0.322222\n" "\t0.433333\n" "\t0.544444\n" "\t0.655556\n" "\t0.766667\n" "\t0.877778\n" "\t0.988889\n" "\t1.100000\n" " }\n"; // OCIO::BakerRcPtr baker = OCIO::Baker::Create(); baker->setConfig(config); baker->setFormat("houdini"); baker->setInputSpace("lnf"); baker->setTargetSpace("target"); baker->setCubeSize(10); // FIXME: Misusing the cube size to set the 1D LUT size std::ostringstream output; baker->bake(output); //std::cerr << "The LUT: " << std::endl << output.str() << std::endl; //std::cerr << "Expected:" << std::endl << bout << std::endl; // std::vector osvec; OCIO::pystring::splitlines(output.str(), osvec); std::vector resvec; OCIO::pystring::splitlines(bout, resvec); OIIO_CHECK_EQUAL(osvec.size(), resvec.size()); for(unsigned int i = 0; i < std::min(osvec.size(), resvec.size()); ++i) OIIO_CHECK_EQUAL(OCIO::pystring::strip(osvec[i]), OCIO::pystring::strip(resvec[i])); } OIIO_ADD_TEST(FileFormatHDL, Read3D) { std::ostringstream strebuf; strebuf << "Version 2" << "\n"; strebuf << "Format any" << "\n"; strebuf << "Type 3D" << "\n"; strebuf << "From 0.2 0.9" << "\n"; strebuf << "To 0.001 0.999" << "\n"; strebuf << "Black 0.002" << "\n"; strebuf << "White 0.98" << "\n"; strebuf << "Length 2" << "\n"; strebuf << "LUT:" << "\n"; strebuf << " {" << "\n"; strebuf << " 0 0 0" << "\n"; strebuf << " 0 0 0" << "\n"; strebuf << " 0 0.390735 2.68116e-28" << "\n"; strebuf << " 0 0.390735 0" << "\n"; strebuf << " 0 0 0" << "\n"; strebuf << " 0 0 0.599397" << "\n"; strebuf << " 0 0.601016 0" << "\n"; strebuf << " 0 0.601016 0.917034" << "\n"; strebuf << " }" << "\n"; std::istringstream simple3D1D; simple3D1D.str(strebuf.str()); // Load file OCIO::LocalFileFormat tester; OCIO::CachedFileRcPtr cachedFile = tester.Read(simple3D1D); OCIO::CachedFileHDLRcPtr lut = OCIO::DynamicPtrCast(cachedFile); // //float from_min = 0.2; //float from_max = 0.9; float to_min = 0.001f; float to_max = 0.999f; float black = 0.002f; float white = 0.98f; float cube[2 * 2 * 2 * 3 ] = { 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.390735f, 2.68116e-28f, 0.f, 0.390735f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.599397f, 0.f, 0.601016f, 0.f, 0.f, 0.601016f, 0.917034f }; // OIIO_CHECK_EQUAL(to_min, lut->to_min); OIIO_CHECK_EQUAL(to_max, lut->to_max); OIIO_CHECK_EQUAL(black, lut->hdlblack); OIIO_CHECK_EQUAL(white, lut->hdlwhite); // check cube data OIIO_CHECK_EQUAL(2*2*2*3, lut->lut3D->lut.size()); for(unsigned int i = 0; i < lut->lut3D->lut.size(); ++i) { OIIO_CHECK_EQUAL(cube[i], lut->lut3D->lut[i]); } } OIIO_ADD_TEST(FileFormatHDL, Bake3D) { OCIO::ConfigRcPtr config = OCIO::Config::Create(); // Set luma coef's to simple values { float lumaCoef[3] = {0.333f, 0.333f, 0.333f}; config->setDefaultLumaCoefs(lumaCoef); } // Add lnf space { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("lnf"); cs->setFamily("lnf"); config->addColorSpace(cs); config->setRole(OCIO::ROLE_REFERENCE, cs->getName()); } // Add target space { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("target"); cs->setFamily("target"); OCIO::CDLTransformRcPtr transform1 = OCIO::CDLTransform::Create(); // Set saturation to cause channel crosstalk, making a 3D LUT transform1->setSat(0.5f); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_FROM_REFERENCE); config->addColorSpace(cs); } std::string bout = "Version\t\t2\n" "Format\t\tany\n" "Type\t\t3D\n" "From\t\t0.000000 1.000000\n" "To\t\t0.000000 1.000000\n" "Black\t\t0.000000\n" "White\t\t1.000000\n" "Length\t\t2\n" "LUT:\n" " {\n" "\t0.000000 0.000000 0.000000\n" "\t0.606300 0.106300 0.106300\n" "\t0.357600 0.857600 0.357600\n" "\t0.963900 0.963900 0.463900\n" "\t0.036100 0.036100 0.536100\n" "\t0.642400 0.142400 0.642400\n" "\t0.393700 0.893700 0.893700\n" "\t1.000000 1.000000 1.000000\n" " }\n"; // OCIO::BakerRcPtr baker = OCIO::Baker::Create(); baker->setConfig(config); baker->setFormat("houdini"); baker->setInputSpace("lnf"); baker->setTargetSpace("target"); baker->setCubeSize(2); std::ostringstream output; baker->bake(output); //std::cerr << "The LUT: " << std::endl << output.str() << std::endl; //std::cerr << "Expected:" << std::endl << bout << std::endl; // std::vector osvec; OCIO::pystring::splitlines(output.str(), osvec); std::vector resvec; OCIO::pystring::splitlines(bout, resvec); OIIO_CHECK_EQUAL(osvec.size(), resvec.size()); for(unsigned int i = 0; i < std::min(osvec.size(), resvec.size()); ++i) OIIO_CHECK_EQUAL(OCIO::pystring::strip(osvec[i]), OCIO::pystring::strip(resvec[i])); } OIIO_ADD_TEST(FileFormatHDL, Read3D1D) { std::ostringstream strebuf; strebuf << "Version 3" << "\n"; strebuf << "Format any" << "\n"; strebuf << "Type 3D+1D" << "\n"; strebuf << "From 0.005478 14.080103" << "\n"; strebuf << "To 0 1" << "\n"; strebuf << "Black 0" << "\n"; strebuf << "White 1" << "\n"; strebuf << "Length 2 10" << "\n"; strebuf << "LUT:" << "\n"; strebuf << "Pre {" << "\n"; strebuf << " 0.994922" << "\n"; strebuf << " 0.995052" << "\n"; strebuf << " 0.995181" << "\n"; strebuf << " 0.995310" << "\n"; strebuf << " 0.995439" << "\n"; strebuf << " 0.995568" << "\n"; strebuf << " 0.995697" << "\n"; strebuf << " 0.995826" << "\n"; strebuf << " 0.995954" << "\n"; strebuf << " 0.996082" << "\n"; strebuf << "}" << "\n"; strebuf << "3D {" << "\n"; strebuf << " 0.093776 0.093776 0.093776" << "\n"; strebuf << " 0.105219 0.093776 0.093776" << "\n"; strebuf << " 0.118058 0.093776 0.093776" << "\n"; strebuf << " 0.132463 0.093776 0.093776" << "\n"; strebuf << " 0.148626 0.093776 0.093776" << "\n"; strebuf << " 0.166761 0.093776 0.093776" << "\n"; strebuf << " 0.187109 0.093776 0.093776" << "\n"; strebuf << " 0.209939 0.093776 0.093776" << "\n"; strebuf << "}" << "\n"; // float from_min = 0.005478f; float from_max = 14.080103f; float to_min = 0.0f; float to_max = 1.0f; float black = 0.0f; float white = 1.0f; float prelut[10] = { 0.994922f, 0.995052f, 0.995181f, 0.995310f, 0.995439f, 0.995568f, 0.995697f, 0.995826f, 0.995954f, 0.996082f }; float cube[2 * 2 * 2 * 3 ] = { 0.093776f, 0.093776f, 0.093776f, 0.105219f, 0.093776f, 0.093776f, 0.118058f, 0.093776f, 0.093776f, 0.132463f, 0.093776f, 0.093776f, 0.148626f, 0.093776f, 0.093776f, 0.166761f, 0.093776f, 0.093776f, 0.187109f, 0.093776f, 0.093776f, 0.209939f, 0.093776f, 0.093776f }; std::istringstream simple3D1D; simple3D1D.str(strebuf.str()); // Load file OCIO::LocalFileFormat tester; OCIO::CachedFileRcPtr cachedFile = tester.Read(simple3D1D); OCIO::CachedFileHDLRcPtr lut = OCIO::DynamicPtrCast(cachedFile); // OIIO_CHECK_EQUAL(to_min, lut->to_min); OIIO_CHECK_EQUAL(to_max, lut->to_max); OIIO_CHECK_EQUAL(black, lut->hdlblack); OIIO_CHECK_EQUAL(white, lut->hdlwhite); // check prelut data (each channel has the same data) for(int c = 0; c < 3; ++c) { OIIO_CHECK_EQUAL(from_min, lut->lut1D->from_min[c]); OIIO_CHECK_EQUAL(from_max, lut->lut1D->from_max[c]); OIIO_CHECK_EQUAL(10, lut->lut1D->luts[c].size()); for(unsigned int i = 0; i < lut->lut1D->luts[c].size(); ++i) { OIIO_CHECK_EQUAL(prelut[i], lut->lut1D->luts[c][i]); } } OIIO_CHECK_EQUAL(2*2*2*3, lut->lut3D->lut.size()); // check cube data for(unsigned int i = 0; i < lut->lut3D->lut.size(); ++i) { OIIO_CHECK_EQUAL(cube[i], lut->lut3D->lut[i]); } } OIIO_ADD_TEST(FileFormatHDL, Bake3D1D) { // check baker output OCIO::ConfigRcPtr config = OCIO::Config::Create(); // Set luma coef's to simple values { float lumaCoef[3] = {0.333f, 0.333f, 0.333f}; config->setDefaultLumaCoefs(lumaCoef); } // Add lnf space { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("lnf"); cs->setFamily("lnf"); config->addColorSpace(cs); config->setRole(OCIO::ROLE_REFERENCE, cs->getName()); } // Add shaper space { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("shaper"); cs->setFamily("shaper"); OCIO::ExponentTransformRcPtr transform1 = OCIO::ExponentTransform::Create(); float test[4] = {2.6f, 2.6f, 2.6f, 1.0f}; transform1->setValue(test); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_TO_REFERENCE); config->addColorSpace(cs); } // Add target space { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("target"); cs->setFamily("target"); OCIO::CDLTransformRcPtr transform1 = OCIO::CDLTransform::Create(); // Set saturation to cause channel crosstalk, making a 3D LUT transform1->setSat(0.5f); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_FROM_REFERENCE); config->addColorSpace(cs); } std::string bout = "Version\t\t3\n" "Format\t\tany\n" "Type\t\t3D+1D\n" "From\t\t0.000000 1.000000\n" "To\t\t0.000000 1.000000\n" "Black\t\t0.000000\n" "White\t\t1.000000\n" "Length\t\t2 10\n" "LUT:\n" "Pre {\n" "\t0.000000\n" "\t0.429520\n" "\t0.560744\n" "\t0.655378\n" "\t0.732057\n" "\t0.797661\n" "\t0.855604\n" "\t0.907865\n" "\t0.955710\n" "\t1.000000\n" "}\n" "3D {\n" "\t0.000000 0.000000 0.000000\n" "\t0.606300 0.106300 0.106300\n" "\t0.357600 0.857600 0.357600\n" "\t0.963900 0.963900 0.463900\n" "\t0.036100 0.036100 0.536100\n" "\t0.642400 0.142400 0.642400\n" "\t0.393700 0.893700 0.893700\n" "\t1.000000 1.000000 1.000000\n" "}\n"; // OCIO::BakerRcPtr baker = OCIO::Baker::Create(); baker->setConfig(config); baker->setFormat("houdini"); baker->setInputSpace("lnf"); baker->setShaperSpace("shaper"); baker->setTargetSpace("target"); baker->setShaperSize(10); baker->setCubeSize(2); std::ostringstream output; baker->bake(output); //std::cerr << "The LUT: " << std::endl << output.str() << std::endl; //std::cerr << "Expected:" << std::endl << bout << std::endl; // std::vector osvec; OCIO::pystring::splitlines(output.str(), osvec); std::vector resvec; OCIO::pystring::splitlines(bout, resvec); OIIO_CHECK_EQUAL(osvec.size(), resvec.size()); // TODO: Get this working on osx /* for(unsigned int i = 0; i < std::min(osvec.size(), resvec.size()); ++i) OIIO_CHECK_EQUAL(OCIO::pystring::strip(osvec[i]), OCIO::pystring::strip(resvec[i])); */ } OIIO_ADD_TEST(FileFormatHDL, LookTest) { // Note this sets up a Look with the same parameters as the Bake3D1D test // however it uses a different shaper space, to ensure we catch that case. // Also ensure we detect the effects of the desaturation by using a 3 cubed // LUT, which will thus test colour values other than the corner points of // the cube OCIO::ConfigRcPtr config = OCIO::Config::Create(); // Add lnf space { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("lnf"); cs->setFamily("lnf"); config->addColorSpace(cs); config->setRole(OCIO::ROLE_REFERENCE, cs->getName()); } // Add shaper space { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("shaper"); cs->setFamily("shaper"); OCIO::ExponentTransformRcPtr transform1 = OCIO::ExponentTransform::Create(); float test[4] = {2.2f, 2.2f, 2.2f, 1.0f}; transform1->setValue(test); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_TO_REFERENCE); config->addColorSpace(cs); } // Add Look process space { OCIO::ColorSpaceRcPtr cs = OCIO::ColorSpace::Create(); cs->setName("look_process"); cs->setFamily("look_process"); OCIO::ExponentTransformRcPtr transform1 = OCIO::ExponentTransform::Create(); float test[4] = {2.6f, 2.6f, 2.6f, 1.0f}; transform1->setValue(test); cs->setTransform(transform1, OCIO::COLORSPACE_DIR_TO_REFERENCE); config->addColorSpace(cs); } // Add Look process space { OCIO::LookRcPtr look = OCIO::Look::Create(); look->setName("look"); look->setProcessSpace("look_process"); OCIO::CDLTransformRcPtr transform1 = OCIO::CDLTransform::Create(); // Set saturation to cause channel crosstalk, making a 3D LUT transform1->setSat(0.5f); look->setTransform(transform1); config->addLook(look); } std::string bout = "Version\t\t3\n" "Format\t\tany\n" "Type\t\t3D+1D\n" "From\t\t0.000000 1.000000\n" "To\t\t0.000000 1.000000\n" "Black\t\t0.000000\n" "White\t\t1.000000\n" "Length\t\t3 10\n" "LUT:\n" "Pre {\n" "\t0.000000\n" "\t0.368344\n" "\t0.504760\n" "\t0.606913\n" "\t0.691699\n" "\t0.765539\n" "\t0.831684\n" "\t0.892049\n" "\t0.947870\n" "\t1.000000\n" "}\n" "3D {\n" "\t0.000000 0.000000 0.000000\n" "\t0.276787 0.035360 0.035360\n" "\t0.553575 0.070720 0.070720\n" "\t0.148309 0.416989 0.148309\n" "\t0.478739 0.478739 0.201718\n" "\t0.774120 0.528900 0.245984\n" "\t0.296618 0.833978 0.296618\n" "\t0.650361 0.902354 0.355417\n" "\t0.957478 0.957478 0.403436\n" "\t0.009867 0.009867 0.239325\n" "\t0.296368 0.049954 0.296368\n" "\t0.575308 0.086766 0.343137\n" "\t0.166161 0.437812 0.437812\n" "\t0.500000 0.500000 0.500000\n" "\t0.796987 0.550484 0.550484\n" "\t0.316402 0.857106 0.607391\n" "\t0.672631 0.925760 0.672631\n" "\t0.981096 0.981096 0.725386\n" "\t0.019735 0.019735 0.478650\n" "\t0.312132 0.062101 0.541651\n" "\t0.592736 0.099909 0.592736\n" "\t0.180618 0.454533 0.695009\n" "\t0.517061 0.517061 0.761560\n" "\t0.815301 0.567796 0.815301\n" "\t0.332322 0.875624 0.875624\n" "\t0.690478 0.944497 0.944497\n" "\t1.000000 1.000000 1.000000\n" "}\n"; // OCIO::BakerRcPtr baker = OCIO::Baker::Create(); baker->setConfig(config); baker->setFormat("houdini"); baker->setInputSpace("lnf"); baker->setShaperSpace("shaper"); baker->setTargetSpace("shaper"); baker->setLooks("look"); baker->setShaperSize(10); baker->setCubeSize(3); std::ostringstream output; baker->bake(output); //std::cerr << "The LUT: " << std::endl << output.str() << std::endl; //std::cerr << "Expected:" << std::endl << bout << std::endl; // std::vector osvec; OCIO::pystring::splitlines(output.str(), osvec); std::vector resvec; OCIO::pystring::splitlines(bout, resvec); OIIO_CHECK_EQUAL(osvec.size(), resvec.size()); for(unsigned int i = 0; i < std::min(osvec.size(), resvec.size()); ++i) OIIO_CHECK_EQUAL(OCIO::pystring::strip(osvec[i]), OCIO::pystring::strip(resvec[i])); } #endif // OCIO_BUILD_TESTS opencolorio-1.1.0~dfsg0.orig/src/mari/0000755000175000017500000000000013223553423016005 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/mari/1.4v1/0000755000175000017500000000000013223553423016556 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/mari/1.4v1/ocio.py0000755000175000017500000010647413223553423020100 0ustar mfvmfv#------------------------------------------------------------------------------- # OpenColorIO (color management) related Mari scripts # coding: utf-8 # Copyright (c) 2011 The Foundry Visionmongers Ltd. All Rights Reserved. #------------------------------------------------------------------------------- import mari, time, PythonQt, os, math ############################################################################################## # Enable to output extended debugging messages. VERBOSE_ENABLED = False # Message type identifiers. class MessageType: DEBUG = 1 INFO = 2 WARNING = 3 ERROR = 4 def printMessage(type, message): if type == MessageType.DEBUG: if VERBOSE_ENABLED: mari.app.log('[ OpenColorIO ] %s' % message) elif type == MessageType.INFO: mari.app.log('[ OpenColorIO ] %s' % message) elif type == MessageType.WARNING: mari.app.log('[ OpenColorIO ] [ WARNING ] %s' % message) elif type == MessageType.ERROR: mari.app.log('[ OpenColorIO ] [ ERROR ] %s' % message) ############################################################################################## def configFileFilter(): return 'OpenColorIO Configuration (*.ocio)' #--------------------------------------------------------------------------------------------- def lutFileFilter(): result = 'All LUT Files (*.3dl *.ccc *.cc *.csp *.cub *.cube *.hdl *.m3d *.mga *.spi1d *.spi3d *.spimtx *.vf);;' result += 'Autodesk LUT (*.3dl);;' result += 'ASC CDL Color Correction Collection LUT (*.ccc);;' result += 'ASC CDL Color Correction LUT (*.cc);;' result += 'Cinespace LUT (*.csp);;' result += 'Truelight LUT (*.cub);;' result += 'Iridas LUT (*.cube);;' result += 'Houdini LUT (*.hdl);;' result += 'Pandora LUT (*.m3d *.mga);;' result += 'Imageworks LUT (*.spi1d *.spi3d *.spimtx);;' result += 'Inventor LUT (*.vf)' return result ############################################################################################## # Make sure the OpenColorIO python bindings are okay. try: import PyOpenColorIO printMessage(MessageType.INFO, 'Loaded Python bindings \'%s\' successfully' % PyOpenColorIO.__file__) except ImportError, e: PyOpenColorIO = None printMessage(MessageType.ERROR, 'Failed to load Python bindings \'%s\'' % e) LUT_FILE_LIST_RESET = mari.FileList(mari.FileList.TYPE_SINGLE_FILE) LUT_FILE_LIST_RESET.setAcceptNonExisting(True) LUT_FILE_LIST_RESET.setFilter(lutFileFilter()) CONFIG_FILE_LIST_RESET = mari.FileList(mari.FileList.TYPE_SINGLE_FILE) if mari.app.isRunning(): CONFIG_FILE_LIST_RESET.append(mari.resources.path(mari.resources.COLOR) + '/OpenColorIO/nuke-default/config.ocio') else: CONFIG_FILE_LIST_RESET.append('/OpenColorIO/nuke-default/config.ocio') CONFIG_FILE_LIST_RESET.setPickedFile(CONFIG_FILE_LIST_RESET.at(0)) CONFIG_FILE_LIST_RESET.setAcceptNonExisting(True) CONFIG_FILE_LIST_RESET.setFilter(configFileFilter()) SQRT_TWO = math.sqrt(2.0) LUT_SIZE_TYPES = ['Small', 'Medium', 'Large'] LUT_SIZE_VALUES = {'Small': 16, 'Medium': 32, 'Large': 64} LUT_SIZE_RESET = LUT_SIZE_TYPES[1] ENABLED_RESET = True PROFILE_RESET = 'Color Space' LUT_EXTRAPOLATE_RESET = True COLOR_SPACE_RESET = 'sRGB' DISPLAY_RESET = 'default' VIEW_RESET = 'sRGB' SWIZZLE_TYPES = ['Luminance', 'RGB', 'R', 'G', 'B', 'A'] SWIZZLE_VALUES = {'Luminance': ( True, True, True, False), 'RGB': ( True, True, True, True), 'R': ( True, False, False, False), 'G': (False, True, False, False), 'B': (False, False, True, False), 'A': (False, False, False, True)} SWIZZLE_RESET = SWIZZLE_TYPES[1] FSTOP_STEP_SIZE = 0.5 FSTOP_CENTER_MIN = 1.0 FSTOP_CENTER_MAX = 64.0 FSTOP_CENTER_STEP_SIZE = 0.001 FSTOP_CENTER_RESET = 8.0 EXPOSURE_MIN = -6.0 EXPOSURE_MAX = +6.0 EXPOSURE_DELTA = EXPOSURE_MAX - EXPOSURE_MIN EXPOSURE_STEP_SIZE = 0.1 GAIN_RESET = 1.0 GAIN_MIN = 2.0 ** EXPOSURE_MIN GAIN_MAX = 2.0 ** EXPOSURE_MAX GAIN_STEP_SIZE = 0.000001 GAIN_PRECISION = 6 GAMMA_RESET = 1.0 GAMMA_MIN = 0.0 GAMMA_MAX = 4.0 GAMMA_STEP_SIZE = 0.01 GAMMA_PRECISION = 2 enabled_default = ENABLED_RESET profile_default = PROFILE_RESET lut_file_list_default = mari.FileList(LUT_FILE_LIST_RESET) lut_extrapolate_default = LUT_EXTRAPOLATE_RESET config_file_list_default = mari.FileList(CONFIG_FILE_LIST_RESET) color_space_default = COLOR_SPACE_RESET display_default = DISPLAY_RESET view_default = VIEW_RESET swizzle_default = SWIZZLE_RESET gain_default = GAIN_RESET gamma_default = GAMMA_RESET lut_size = LUT_SIZE_RESET fstop_center = FSTOP_CENTER_RESET config_default = None lut_size_functions = [] fstop_center_functions = [] ############################################################################################## def registerLUTSizeChanged(function): global lut_size_functions lut_size_functions.append(function) #--------------------------------------------------------------------------------------------- def registerFStopCenterChanged(function): global fstop_center_functions fstop_center_functions.append(function) #--------------------------------------------------------------------------------------------- def _enabledDefaultChanged(): global enabled_default enabled_default = mari.prefs.get('/Color/Color Management Defaults/colorEnabledDefault') _savePreferences() #--------------------------------------------------------------------------------------------- def _profileDefaultChanged(): global profile_default profile_default = mari.prefs.get('/Color/Color Management Defaults/colorProfileDefault') _savePreferences() #--------------------------------------------------------------------------------------------- def _postFilterCollectionAdded(filter_collection): mari.prefs.setItemList('/Color/Color Management Defaults/colorProfileDefault', mari.gl_render.postFilterCollectionNames()) #--------------------------------------------------------------------------------------------- def _postFilterCollectionRemoved(name): collection_names = mari.gl_render.postFilterCollectionNames() mari.prefs.setItemList('/Color/Color Management Defaults/colorProfileDefault', collection_names) global PROFILE_RESET if name == PROFILE_RESET: PROFILE_RESET = collection_names[0] mari.prefs.setDefault('/Color/Color Management Defaults/colorProfileDefault', PROFILE_RESET) global profile_default if name == profile_default: profile_default = PROFILE_RESET mari.prefs.set('/Color/Color Management Defaults/colorProfileDefault', profile_default) _savePreferences() #--------------------------------------------------------------------------------------------- def _lutPathDefaultChanged(): global lut_file_list_default lut_file_list_default = mari.FileList(mari.prefs.get('/Color/LUT Defaults/lutPathDefault')) _savePreferences() #--------------------------------------------------------------------------------------------- def _lutExtrapolateDefaultChanged(): global lut_extrapolate_default lut_extrapolate_default = mari.prefs.get('/Color/LUT Defaults/lutExtrapolateDefault') _savePreferences() #--------------------------------------------------------------------------------------------- def _configPathDefaultChanged(): global config_file_list_default # Only replace the existing configuration file if the new one is valid! config_file_list = mari.FileList(mari.prefs.get('/Color/Display Defaults/displayConfigPathDefault')) if not config_file_list.isEmpty(): config = loadConfig(config_file_list.at(0), True) if config is not None: config_file_list_default = config_file_list global config_default config_default = config _updateColorSpaceDefault() _updateDisplayDefault() _updateViewDefault() _savePreferences() else: # Put back the existing configuration file that works... mari.prefs.set('/Color/Display Defaults/displayConfigPathDefault', config_file_list_default) else: # Put back the existing configuration file that works... mari.prefs.set('/Color/Display Defaults/displayConfigPathDefault', config_file_list_default) #--------------------------------------------------------------------------------------------- def _colorSpaceDefaultChanged(): global color_space_default color_space_default = mari.prefs.get('/Color/Display Defaults/displayColorSpaceDefault') _updateDisplayDefault() _updateViewDefault() _savePreferences() #--------------------------------------------------------------------------------------------- def _displayDefaultChanged(): global display_default display_default = mari.prefs.get('/Color/Display Defaults/displayDisplayDefault') _updateViewDefault() _savePreferences() #--------------------------------------------------------------------------------------------- def _viewDefaultChanged(): global view_default view_default = mari.prefs.get('/Color/Display Defaults/displayViewDefault') _savePreferences() #--------------------------------------------------------------------------------------------- def _swizzleDefaultChanged(): global swizzle_default swizzle_default = mari.prefs.get('/Color/Display Defaults/displaySwizzleDefault') _savePreferences() #--------------------------------------------------------------------------------------------- def _gainDefaultChanged(): global gain_default gain_default = mari.prefs.get('/Color/Display Defaults/displayGainDefault') _savePreferences() #--------------------------------------------------------------------------------------------- def _gammaDefaultChanged(): global gamma_default gamma_default = mari.prefs.get('/Color/Display Defaults/displayGammaDefault') _savePreferences() #--------------------------------------------------------------------------------------------- def _lutSizeChanged(): global lut_size global lut_size_functions lut_size = mari.prefs.get('/Color/Display General/displayLutSize') _savePreferences() for function in lut_size_functions: function() #--------------------------------------------------------------------------------------------- def _fstopCenterChanged(): global fstop_center global fstop_center_functions fstop_center = mari.prefs.get('/Color/Display General/displayFStopCenter') _savePreferences() for function in fstop_center_functions: function() #--------------------------------------------------------------------------------------------- def _registerPreferences(): global enabled_default mari.prefs.set('/Color/Color Management Defaults/colorEnabledDefault', enabled_default) mari.prefs.setChangedScript('/Color/Color Management Defaults/colorEnabledDefault', 'mari.utils.ocio._enabledDefaultChanged()') mari.prefs.setDisplayName('/Color/Color Management Defaults/colorEnabledDefault', 'Enabled') mari.prefs.setDefault('/Color/Color Management Defaults/colorEnabledDefault', ENABLED_RESET) global profile_default mari.prefs.set('/Color/Color Management Defaults/colorProfileDefault', profile_default) mari.prefs.setChangedScript('/Color/Color Management Defaults/colorProfileDefault', 'mari.utils.ocio._profileDefaultChanged()') mari.prefs.setDisplayName('/Color/Color Management Defaults/colorProfileDefault', 'Color Profile') mari.prefs.setDefault('/Color/Color Management Defaults/colorProfileDefault', PROFILE_RESET) mari.prefs.setItemList('/Color/Color Management Defaults/colorProfileDefault', mari.gl_render.postFilterCollectionNames()) global lut_file_list_default if not lut_file_list_default.isEmpty() and not os.path.isfile(lut_file_list_default.at(0)): message = 'LUT file \'%s\' does not exist' % lut_file_list_default.at(0) printMessage(MessageType.ERROR, '%s' % message) lut_file_list_default = mari.FileList(LUT_FILE_LIST_RESET) mari.prefs.set('/Color/LUT Defaults/lutPathDefault', lut_file_list_default) mari.prefs.setChangedScript('/Color/LUT Defaults/lutPathDefault', 'mari.utils.ocio._lutPathDefaultChanged()') mari.prefs.setDisplayName('/Color/LUT Defaults/lutPathDefault', 'File') mari.prefs.setDefault('/Color/LUT Defaults/lutPathDefault', LUT_FILE_LIST_RESET) global lut_extrapolate_default mari.prefs.set('/Color/LUT Defaults/lutExtrapolateDefault', lut_extrapolate_default) mari.prefs.setChangedScript('/Color/LUT Defaults/lutExtrapolateDefault', 'mari.utils.ocio._lutExtrapolateDefaultChanged()') mari.prefs.setDisplayName('/Color/LUT Defaults/lutExtrapolateDefault', 'Extrapolate') mari.prefs.setDefault('/Color/LUT Defaults/lutExtrapolateDefault', LUT_EXTRAPOLATE_RESET) global config_file_list_default global config_default if not config_file_list_default.isEmpty(): config = loadConfig(config_file_list_default.at(0), False) if config is not None: config_default = config else: config_file_list_default = mari.FileList(CONFIG_FILE_LIST_RESET) else: config_file_list_default = mari.FileList(CONFIG_FILE_LIST_RESET) mari.prefs.set('/Color/Display Defaults/displayConfigPathDefault', config_file_list_default) mari.prefs.setChangedScript('/Color/Display Defaults/displayConfigPathDefault', 'mari.utils.ocio._configPathDefaultChanged()') mari.prefs.setDisplayName('/Color/Display Defaults/displayConfigPathDefault', 'Configuration File') mari.prefs.setDefault('/Color/Display Defaults/displayConfigPathDefault', CONFIG_FILE_LIST_RESET) color_spaces = [color_space.getName() for color_space in config_default.getColorSpaces()] color_space_reset = COLOR_SPACE_RESET if color_spaces.count(color_space_reset) == 0: color_space_reset = color_spaces[0] global color_space_default if color_spaces.count(color_space_default) == 0: color_space_default = color_space_reset mari.prefs.set('/Color/Display Defaults/displayColorSpaceDefault', color_space_default) mari.prefs.setChangedScript('/Color/Display Defaults/displayColorSpaceDefault', 'mari.utils.ocio._colorSpaceDefaultChanged()') mari.prefs.setDisplayName('/Color/Display Defaults/displayColorSpaceDefault', 'Input Color Space') mari.prefs.setDefault('/Color/Display Defaults/displayColorSpaceDefault', color_space_reset) mari.prefs.setItemList('/Color/Display Defaults/displayColorSpaceDefault', color_spaces) displays = config_default.getDisplays() display_reset = DISPLAY_RESET if displays.count(display_reset) == 0: display_reset = config_default.getDefaultDisplay() global display_default if displays.count(display_default) == 0: display_default = display_reset mari.prefs.set('/Color/Display Defaults/displayDisplayDefault', display_default) mari.prefs.setChangedScript('/Color/Display Defaults/displayDisplayDefault', 'mari.utils.ocio._displayDefaultChanged()') mari.prefs.setDisplayName('/Color/Display Defaults/displayDisplayDefault', 'Display') mari.prefs.setDefault('/Color/Display Defaults/displayDisplayDefault', display_reset) mari.prefs.setItemList('/Color/Display Defaults/displayDisplayDefault', displays) views = config_default.getViews(display_default) view_reset = VIEW_RESET if views.count(view_reset) == 0: view_reset = config_default.getDefaultView(display_default) global view_default if views.count(view_default) == 0: view_default = view_reset mari.prefs.set('/Color/Display Defaults/displayViewDefault', view_default) mari.prefs.setChangedScript('/Color/Display Defaults/displayViewDefault', 'mari.utils.ocio._viewDefaultChanged()') mari.prefs.setDisplayName('/Color/Display Defaults/displayViewDefault', 'View') mari.prefs.setDefault('/Color/Display Defaults/displayViewDefault', view_reset) mari.prefs.setItemList('/Color/Display Defaults/displayViewDefault', views) global swizzle_default if SWIZZLE_TYPES.count(swizzle_default) == 0: swizzle_default = SWIZZLE_RESET mari.prefs.set('/Color/Display Defaults/displaySwizzleDefault', swizzle_default) mari.prefs.setChangedScript('/Color/Display Defaults/displaySwizzleDefault', 'mari.utils.ocio._swizzleDefaultChanged()') mari.prefs.setDisplayName('/Color/Display Defaults/displaySwizzleDefault', 'Component') mari.prefs.setDefault('/Color/Display Defaults/displaySwizzleDefault', SWIZZLE_RESET) mari.prefs.setItemList('/Color/Display Defaults/displaySwizzleDefault', SWIZZLE_TYPES) global gain_default mari.prefs.set('/Color/Display Defaults/displayGainDefault', gain_default) mari.prefs.setChangedScript('/Color/Display Defaults/displayGainDefault', 'mari.utils.ocio._gainDefaultChanged()') mari.prefs.setDisplayName('/Color/Display Defaults/displayGainDefault', 'Gain') mari.prefs.setDefault('/Color/Display Defaults/displayGainDefault', GAIN_RESET) mari.prefs.setRange('/Color/Display Defaults/displayGainDefault', GAIN_MIN, GAIN_MAX) mari.prefs.setStep('/Color/Display Defaults/displayGainDefault', GAIN_STEP_SIZE) global gamma_default mari.prefs.set('/Color/Display Defaults/displayGammaDefault', gamma_default) mari.prefs.setChangedScript('/Color/Display Defaults/displayGammaDefault', 'mari.utils.ocio._gammaDefaultChanged()') mari.prefs.setDisplayName('/Color/Display Defaults/displayGammaDefault', 'Gamma') mari.prefs.setDefault('/Color/Display Defaults/displayGammaDefault', GAMMA_RESET) mari.prefs.setRange('/Color/Display Defaults/displayGammaDefault', GAMMA_MIN, GAMMA_MAX) mari.prefs.setStep('/Color/Display Defaults/displayGammaDefault', GAMMA_STEP_SIZE) global lut_size mari.prefs.set('/Color/Display General/displayLutSize', lut_size) mari.prefs.setChangedScript('/Color/Display General/displayLutSize', 'mari.utils.ocio._lutSizeChanged()') mari.prefs.setDisplayName('/Color/Display General/displayLutSize', 'LUT Size') mari.prefs.setDefault('/Color/Display General/displayLutSize', LUT_SIZE_RESET) mari.prefs.setItemList('/Color/Display General/displayLutSize', LUT_SIZE_TYPES) global fstop_center mari.prefs.set('/Color/Display General/displayFStopCenter', fstop_center) mari.prefs.setChangedScript('/Color/Display General/displayFStopCenter', 'mari.utils.ocio._fstopCenterChanged()') mari.prefs.setDisplayName('/Color/Display General/displayFStopCenter', 'Center F-Stop') mari.prefs.setDefault('/Color/Display General/displayFStopCenter', FSTOP_CENTER_RESET) mari.prefs.setRange('/Color/Display General/displayFStopCenter', FSTOP_CENTER_MIN, FSTOP_CENTER_MAX) mari.prefs.setStep('/Color/Display General/displayFStopCenter', FSTOP_CENTER_STEP_SIZE) # Attach ourselves to the appropriate project signals so we can update widgets. PythonQt.QtCore.QObject.connect(mari.gl_render.postFilterCollectionAdded.__self__, mari.gl_render.postFilterCollectionAdded.__name__, _postFilterCollectionAdded) PythonQt.QtCore.QObject.connect(mari.gl_render.postFilterCollectionRemoved.__self__, mari.gl_render.postFilterCollectionRemoved.__name__, _postFilterCollectionRemoved) #--------------------------------------------------------------------------------------------- def _updateColorSpaceDefault(): global config_default global color_space_default color_spaces = [color_space.getName() for color_space in config_default.getColorSpaces()] color_space_reset = COLOR_SPACE_RESET if color_spaces.count(color_space_reset) == 0: color_space_reset = color_spaces[0] if color_spaces.count(color_space_default) == 0: color_space_default = color_space_reset mari.prefs.setItemList('/Color/Display Defaults/displayColorSpaceDefault', color_spaces) mari.prefs.set('/Color/Display Defaults/displayColorSpaceDefault', color_space_default) mari.prefs.setDefault('/Color/Display Defaults/displayColorSpaceDefault', color_space_reset) #--------------------------------------------------------------------------------------------- def _updateDisplayDefault(): global config_default global display_default displays = config_default.getDisplays() display_reset = DISPLAY_RESET if displays.count(display_reset) == 0: display_reset = config_default.getDefaultDisplay() if displays.count(display_default) == 0: display_default = display_reset mari.prefs.setItemList('/Color/Display Defaults/displayDisplayDefault', displays) mari.prefs.set('/Color/Display Defaults/displayDisplayDefault', display_default) mari.prefs.setDefault('/Color/Display Defaults/displayDisplayDefault', display_reset) #--------------------------------------------------------------------------------------------- def _updateViewDefault(): global config_default global display_default global view_default views = config_default.getViews(display_default) view_reset = VIEW_RESET if views.count(view_reset) == 0: view_reset = config_default.getDefaultView(display_default) if views.count(view_default) == 0: view_default = view_reset mari.prefs.setItemList('/Color/Display Defaults/displayViewDefault', views) mari.prefs.set('/Color/Display Defaults/displayViewDefault', view_default) mari.prefs.setDefault('/Color/Display Defaults/displayViewDefault', view_reset) #--------------------------------------------------------------------------------------------- def _loadPreferences(): settings = mari.Settings() settings.beginGroup('OpenColorIO') try: global enabled_default global profile_default global lut_file_list_default global lut_extrapolate_default global config_file_list_default global color_space_default global display_default global view_default global swizzle_default global gain_default global gamma_default global lut_size global fstop_center enabled_default = False if int(settings.value('enabledDefault', ENABLED_RESET)) == 0 else True profile_default = str(settings.value('profileDefault', PROFILE_RESET)) lut_path = buildLoadPath(str(settings.value('lutPathDefault', '' if LUT_FILE_LIST_RESET.isEmpty() else LUT_FILE_LIST_RESET.at(0)))) lut_extrapolate_default = False if int(settings.value('lutExtrapolateDefault', LUT_EXTRAPOLATE_RESET)) == 0 else True config_path = buildLoadPath(str(settings.value('configPathDefault', '' if CONFIG_FILE_LIST_RESET.isEmpty() else CONFIG_FILE_LIST_RESET.at(0)))) color_space_default = str(settings.value('colorSpaceDefault', COLOR_SPACE_RESET)) display_default = str(settings.value('displayDefault', DISPLAY_RESET)) view_default = str(settings.value('viewDefault', VIEW_RESET)) swizzle_default = str(settings.value('swizzleDefault', SWIZZLE_RESET)) gain_default = max(min(float(settings.value('gainDefault', GAIN_RESET)), GAIN_MAX), GAIN_MIN) gamma_default = max(min(float(settings.value('gammaDefault', GAMMA_RESET)), GAMMA_MAX), GAMMA_MIN) lut_size = str(settings.value('lutSize', LUT_SIZE_RESET)) fstop_center = max(min(float(settings.value('fstopCenter', FSTOP_CENTER_RESET)), FSTOP_CENTER_MAX), FSTOP_CENTER_MIN) if os.path.isfile(lut_path): lut_file_list_default.clear() lut_file_list_default.append(lut_path) lut_file_list_default.setPickedFile(lut_path) if os.path.isfile(config_path): config_file_list_default.clear() config_file_list_default.append(config_path) config_file_list_default.setPickedFile(config_path) except ValueError, e: printMessage(MessageType.ERROR, 'Failed to load preferences \'%s\'' % e) settings.endGroup() _printPreferences(MessageType.DEBUG, 'Loaded Preferences:') #--------------------------------------------------------------------------------------------- def _savePreferences(): settings = mari.Settings() settings.beginGroup('OpenColorIO') global enabled_default global profile_default global lut_file_list_default global lut_extrapolate_default global config_file_list_default global color_space_default global display_default global view_default global swizzle_default global gain_default global gamma_default global lut_size global fstop_center settings.setValue( 'enabledDefault', 1 if enabled_default else 0) settings.setValue( 'profileDefault', profile_default) settings.setValue( 'lutPathDefault', '' if lut_file_list_default.isEmpty() else buildSavePath(lut_file_list_default.at(0))) settings.setValue('lutExtrapolateDefault', 1 if lut_extrapolate_default else 0) settings.setValue( 'configPathDefault', '' if config_file_list_default.isEmpty() else buildSavePath(config_file_list_default.at(0))) settings.setValue( 'colorSpaceDefault', color_space_default) settings.setValue( 'displayDefault', display_default) settings.setValue( 'viewDefault', view_default) settings.setValue( 'swizzleDefault', swizzle_default) settings.setValue( 'gainDefault', gain_default) settings.setValue( 'gammaDefault', gamma_default) settings.setValue( 'lutSize', lut_size) settings.setValue( 'fstopCenter', fstop_center) settings.endGroup() _printPreferences(MessageType.DEBUG, 'Saved Preferences:') #--------------------------------------------------------------------------------------------- def _printPreferences(type, title): global enabled_default global profile_default global lut_file_list_default global lut_extrapolate_default global config_file_list_default global color_space_default global display_default global view_default global swizzle_default global gain_default global fstop_center global lut_size global gamma_default printMessage(type, '==============================================================') printMessage(type, title) printMessage(type, '==============================================================') printMessage(type, ' Enabled: %s' % enabled_default) printMessage(type, ' Profile: %s' % profile_default) printMessage(type, ' LUT Path: %s' % '' if lut_file_list_default.isEmpty() else lut_file_list_default.at(0)) printMessage(type, ' Extrapolate: %s' % lut_extrapolate_default) printMessage(type, ' Config Path: %s' % '' if config_file_list_default.isEmpty() else config_file_list_default.at(0)) printMessage(type, ' Color Space: %s' % color_space_default) printMessage(type, ' Display: %s' % display_default) printMessage(type, ' View: %s' % view_default) printMessage(type, ' Swizzle: %s' % swizzle_default) printMessage(type, ' F-Stop: %f; Center: %f' % (convertGainToFStop(gain_default), fstop_center)) printMessage(type, ' Gain: %f' % gain_default) printMessage(type, ' Gamma: %f' % gamma_default) printMessage(type, ' LUT Size: %s' % lut_size) printMessage(type, '==============================================================') ############################################################################################## def convertExposureToGain(exposure): return 2.0 ** exposure #--------------------------------------------------------------------------------------------- def convertGainToExposure(gain): return math.log(gain, 2.0) #--------------------------------------------------------------------------------------------- def convertExposureToFStop(exposure): global fstop_center exposure_center = math.log(fstop_center, SQRT_TWO) return math.pow(SQRT_TWO, exposure_center - exposure) #--------------------------------------------------------------------------------------------- def convertGainToFStop(gain): exposure = convertGainToExposure(gain) return convertExposureToFStop(exposure) #--------------------------------------------------------------------------------------------- def buildProcessorFilter(processor, filter, filter_cache_id, texture_cache_id, extrapolate = False, force_shader_build = False): # Create a name, using the filter's name, that can be used in uniquely naming parameters and functions. name = filter.name(); name = name.lower() name = name.replace(' ', '_') sampler_name = 'ocio_' + name + '_lut_$ID_' function_name = 'ocio_' + name + '_$ID_' global lut_size shader_desc = { 'language': PyOpenColorIO.Constants.GPU_LANGUAGE_GLSL_1_3, 'functionName': function_name, 'lut3DEdgeLen': LUT_SIZE_VALUES[lut_size]} cache_id = processor.getGpuShaderTextCacheID(shader_desc) if cache_id != filter_cache_id or force_shader_build: filter_cache_id = cache_id printMessage(MessageType.DEBUG, 'Creating new GLSL filter...') desc = 'uniform sampler3D ' + sampler_name + ';\n' desc += processor.getGpuShaderText(shader_desc) body = '' if extrapolate: # The following code was taken from Nuke's 'LUT3D::Extrapolate' functionality. It attempts to estimate what # the corresponding color value would be when the incoming color value is outside the normal range of [0-1], # such as the case with HDR images. rcp_lut_edge_length = 1.0 / float(LUT_SIZE_VALUES[lut_size]) body += '{\n' body += ' if( 1.0 < Out.r || 1.0 < Out.g || 1.0 < Out.b )\n' body += ' {\n' body += ' vec4 closest;\n' body += ' closest.rgb = clamp(Out.rgb, vec3(0.0), vec3(1.0));\n' body += ' closest.a = Out.a;\n' body += '\n' body += ' vec3 offset = Out.rgb - closest.rgb;\n' body += ' float offset_distance = length(offset);\n' body += ' offset = normalize(offset);\n' body += '\n' body += ' vec4 nbr_position;\n' body += ' nbr_position.rgb = closest.rgb - %f * offset;\n' % rcp_lut_edge_length body += ' nbr_position.a = Out.a;\n' body += '\n' body += ' Out = ' + function_name + '(closest, ' + sampler_name + ');\n' body += ' Out.rgb += (Out.rgb - ' + function_name + '(nbr_position, ' + sampler_name + ').rgb) / %f * offset_distance;\n' % rcp_lut_edge_length body += ' }\n' body += ' else\n' body += ' {\n' body += ' Out = ' + function_name + '(Out, ' + sampler_name + ');\n' body += ' }\n' body += '}\n' else: body += '{ Out = ' + function_name + '(Out, ' + sampler_name + '); }\n' filter.setDefinitionsSnippet(desc) filter.setBodySnippet(body) else: printMessage(MessageType.DEBUG, 'No GLSL filter update required') cache_id = processor.getGpuLut3DCacheID(shader_desc) if cache_id != texture_cache_id: lut = processor.getGpuLut3D(shader_desc) printMessage(MessageType.DEBUG, 'Updating LUT...') if texture_cache_id is None: filter.setTexture3D(sampler_name, LUT_SIZE_VALUES[lut_size], LUT_SIZE_VALUES[lut_size], LUT_SIZE_VALUES[lut_size], filter.FORMAT_RGB, lut) else: filter.updateTexture3D(sampler_name, lut) texture_cache_id = cache_id else: printMessage(MessageType.DEBUG, 'No LUT update required') return (filter_cache_id, texture_cache_id, sampler_name) #--------------------------------------------------------------------------------------------- def buildLUTFilter(config, path, filter, filter_cache_id, texture_cache_id, extrapolate, force_shader_build = False): file_transform = PyOpenColorIO.FileTransform() file_transform.setSrc(path) file_transform.setInterpolation('linear') processor = config.getProcessor(file_transform) return buildProcessorFilter(processor, filter, filter_cache_id, texture_cache_id, extrapolate, force_shader_build) #--------------------------------------------------------------------------------------------- def loadConfig(path, display_message_box = True): try: config = PyOpenColorIO.Config.CreateFromFile(path) return config except Exception, e: message = 'Failed to load configuration file \'%s\' due to \'%s\'' % (path, e) printMessage(MessageType.ERROR, '%s' % message) if display_message_box and not mari.app.inTerminalMode(): mari.utils.misc.message(message, 'Color Space', 1024, 2) return None #--------------------------------------------------------------------------------------------- # This converts a path into a form which can be shared among different platforms and installations. def buildSavePath(path): result = path.replace(mari.resources.path(mari.resources.COLOR), '$MARI_COLOR_PATH', 1) return result #--------------------------------------------------------------------------------------------- # This converts a path saved out to disk back into a form which can used by the application. def buildLoadPath(path): result = path.replace('$MARI_COLOR_PATH', mari.resources.path(mari.resources.COLOR), 1) return result ############################################################################################## if mari.app.isRunning(): if PyOpenColorIO is not None: # Attempt to load the default configuration file... without it we can't do nothing! config_file_lists = [config_file_list_default, CONFIG_FILE_LIST_RESET] for config_file_list in config_file_lists: if not config_file_list.isEmpty(): config_default = loadConfig(config_file_list.at(0), False) if config_default is not None: config_file_list_default = mari.FileList(config_file_list) break if config_default is not None: _loadPreferences() _registerPreferences() _savePreferences() else: message = 'Failed to find a working configuration file. OpenColorIO will be disabled!' printMessage(MessageType.ERROR, message) if not mari.app.inTerminalMode(): mari.utils.misc.message(message, 'OpenColorIO', 1024, 3) opencolorio-1.1.0~dfsg0.orig/src/mari/1.4v1/_ocio_filter.py0000755000175000017500000001342213223553423021572 0ustar mfvmfv#------------------------------------------------------------------------------- # Post processing (color management) related Mari scripts # coding: utf-8 # Copyright (c) 2011 The Foundry Visionmongers Ltd. All Rights Reserved. #------------------------------------------------------------------------------- import mari, time, PythonQt, os, math ocio = mari.utils.ocio ############################################################################################## filter = None class OcioFilter(): #----------------------------------------------------------------------------------------- def __init__(self): # Default all members... self._config_file_list = mari.FileList(ocio.config_file_list_default) self._config = ocio.config_default self._input_color_space = ocio.color_space_default self._output_color_space = ocio.color_space_default self._filter = mari.gl_render.createQuickApplyGLSL('Color Correction', '', '', 'ColorManager.png') self._filter_cache_id = None self._texture_cache_id = None self._sampler_name = None self._filter.setMetadata('ConfigPath', self._config_file_list) self._filter.setMetadataDisplayName('ConfigPath', 'Configuration File') self._filter.setMetadataDefault('ConfigPath', ocio.CONFIG_FILE_LIST_RESET) self._filter.setMetadataFlags('ConfigPath', self._filter.METADATA_VISIBLE | self._filter.METADATA_EDITABLE) color_spaces = [color_space.getName() for color_space in self._config.getColorSpaces()] color_space_reset = ocio.COLOR_SPACE_RESET if color_spaces.count(color_space_reset) == 0: color_space_reset = color_spaces[0] self._filter.setMetadata('InputColorSpace', self._input_color_space) self._filter.setMetadataDisplayName('InputColorSpace', 'Input Color Space') self._filter.setMetadataDefault('InputColorSpace', color_space_reset) self._filter.setMetadataItemList('InputColorSpace', color_spaces) self._filter.setMetadataFlags('InputColorSpace', self._filter.METADATA_VISIBLE | self._filter.METADATA_EDITABLE) self._filter.setMetadata('OutputColorSpace', self._output_color_space) self._filter.setMetadataDisplayName('OutputColorSpace', 'Output Color Space') self._filter.setMetadataDefault('OutputColorSpace', color_space_reset) self._filter.setMetadataItemList('OutputColorSpace', color_spaces) self._filter.setMetadataFlags('OutputColorSpace', self._filter.METADATA_VISIBLE | self._filter.METADATA_EDITABLE) mari.utils.connect(self._filter.metadataValueChanged, self._metadataValueChanged) self._rebuildFilter() #----------------------------------------------------------------------------------------- def _metadataValueChanged(self, name, value): ocio.printMessage(ocio.MessageType.DEBUG, 'Metadata \'%s\' changed to \'%s\'' % (name, value)) if name == 'ConfigPath': if value == self._config_file_list: return self._config_file_list = mari.FileList(value) self._config = ocio.loadConfig(self._config_file_list.at(0), False) color_spaces = [color_space.getName() for color_space in self._config.getColorSpaces()] color_space_reset = ocio.COLOR_SPACE_RESET if color_spaces.count(color_space_reset) == 0: color_space_reset = color_spaces[0] if color_spaces.count(self._input_color_space) == 0: self._input_color_space = color_space_reset if color_spaces.count(self._output_color_space) == 0: self._output_color_space = color_space_reset self._filter.setMetadataItemList('InputColorSpace', color_spaces) self._filter.setMetadataItemList('OutputColorSpace', color_spaces) self._filter.setMetadataDefault('InputColorSpace', color_space_reset) self._filter.setMetadataDefault('OutputColorSpace', color_space_reset) self._filter.setMetadata('InputColorSpace', self._input_color_space ) self._filter.setMetadata('OutputColorSpace', self._output_color_space) elif name == 'InputColorSpace': if value == self._input_color_space: return self._input_color_space = value elif name == 'OutputColorSpace': if value == self._output_color_space: return self._output_color_space = value else: return self._rebuildFilter() #----------------------------------------------------------------------------------------- def _rebuildFilter(self): input_color_space = self._config.getColorSpace(self._input_color_space) if input_color_space is not None: output_color_space = self._config.getColorSpace(self._output_color_space) if output_color_space is not None: processor = self._config.getProcessor(input_color_space, output_color_space) self._filter_cache_id, self._texture_cache_id, self._sampler_name = ocio.buildProcessorFilter( processor, self._filter, self._filter_cache_id, self._texture_cache_id) current_canvas = mari.canvases.current() if current_canvas is not None: current_canvas.repaint() ############################################################################################## if mari.app.isRunning(): if not hasattr(mari.gl_render, 'createQuickApplyGLSL'): printMessage(MessageType.ERROR, 'This version of Mari does not support the mari.gl_render.createQuickApplyGLSL API') elif ocio is not None: filter = OcioFilter() opencolorio-1.1.0~dfsg0.orig/src/mari/1.4v1/_ocio_toolbar.py0000755000175000017500000016477413223553423021770 0ustar mfvmfv#------------------------------------------------------------------------------- # Post processing (color management) related Mari scripts # coding: utf-8 # Copyright (c) 2011 The Foundry Visionmongers Ltd. All Rights Reserved. #------------------------------------------------------------------------------- import mari, time, PythonQt, os, math QtGui = PythonQt.QtGui QtCore = PythonQt.QtCore ocio = mari.utils.ocio ############################################################################################## GAIN_GROUP_MAX_WIDTH = 312 FSTOP_MAX_WIDTH = 50 EXPOSURE_MAX_WIDTH = 102 GAIN_MAX_WIDTH = 80 GAMMA_MAX_WIDTH = 200 TOOLBAR_SPACING = 3 toolbar = None class OcioToolBar(): #----------------------------------------------------------------------------------------- def __init__(self): # Default all members... self._config_file_list = mari.FileList(ocio.config_file_list_default) self._config = ocio.config_default self._lut_file_list = mari.FileList(ocio.lut_file_list_default) self._lut_extrapolate = ocio.lut_extrapolate_default self._color_space = ocio.color_space_default self._display = ocio.display_default self._view = ocio.view_default self._swizzle = ocio.swizzle_default self._gain = ocio.gain_default self._gamma = ocio.gamma_default self._lut_filter = None self._lut_filter_cache_id = None self._lut_texture_cache_id = None self._lut_sampler_name = None self._display_filter = None self._display_filter_cache_id = None self._display_texture_cache_id = None self._display_sampler_name = None self._lut_extrapolate_widget = None self._color_space_widget = None self._display_widget = None self._view_widget = None self._swizzle_widget = None self._fstop_widget = None self._fstop_decrement_widget = None self._fstop_increment_widget = None self._gain_widget = None self._exposure_widget = None self._gain_reset_widget = None self._gamma_widget = None self._gamma_reset_widget = None self._buildWidgets() self._toggle_color_management_action.setEnabled(False) self._enableWidgets(False) # Enable/disable color management. mari.gl_render.setPostProcessingEnabled(self.isColorManagementEnabled()) # *** IMPORTANT *** The post filter collection used to be called 'OpenColorIO' but was renamed to hide the fact # we use OpenColorIO from our users. So as a temporary workaround we need to check for the old filter collection # on startup and remove it if found. delete_filter_collection = mari.gl_render.findPostFilterCollection('OpenColorIO') if delete_filter_collection is not None: mari.gl_render.deletePostFilterCollection(delete_filter_collection) # Create the OCIO post filter collection if not present. self._filter_collection = mari.gl_render.findPostFilterCollection('Color Space') if self._filter_collection is None: self._filter_collection = mari.gl_render.createPostFilterCollection('Color Space') else: self._filter_collection.clear() self._filter_collection.setReadOnly(True) self._lut_filter = self._filter_collection.createGLSL('LUT Transform') if not self._lut_file_list.isEmpty() and not self._rebuildLUTFilter(self._lut_file_list.at(0)): self._lut_file_list.clear() self._display_filter = self._filter_collection.createGLSL('Display Transform') self._rebuildDisplayFilter() self._buildMetadata() # Set the color management filter stack as the current. mari.gl_render.setPostFilterCollection(self._filter_collection) # Attach ourselves to the applications toolbar created signal so we can rebuild the toolbar when it's been # destoyed. mari.utils.connect(mari.app.toolBarsCreated, self._toolBarsCreated) # Attach ourselves to the appropriate GL signals so we can enable and disable widgets. mari.utils.connect(mari.gl_render.postProcessingEnabled, self._postProcessingEnabled) mari.utils.connect(mari.gl_render.setCurrentPostFilterCollection, self._setCurrentPostFilterCollection) # Attach ourselves to the appropriate project signals so we can load and save settings. mari.utils.connect(mari.projects.openedProject, self._openedProject) mari.utils.connect(mari.projects.aboutToSaveProject, self._aboutToSaveProject) mari.utils.connect(mari.projects.projectClosed, self._closedProject) # Update the UI to match the current project, if we have one. current_project = mari.projects.current() if current_project is not None: self._openedProject(current_project) #----------------------------------------------------------------------------------------- def isColorManagementEnabled(self): return self._toggle_color_management_action.isChecked() #----------------------------------------------------------------------------------------- def setLUTPath(self, value, update_metadata = True, force_shader_build = False): if (self._lut_file_list.isEmpty() and value != '') or \ (not self._lut_file_list.isEmpty() and value == '') or \ (not self._lut_file_list.isEmpty() and value != self._lut_file_list.at(0)) \ : if self._rebuildLUTFilter(value, force_shader_build): self._lut_file_list.clear() if value != '': self._lut_file_list.append(value) self._lut_file_list.setPickedFile(value) self._clear_lut_action.setEnabled(True) self._lut_extrapolate_widget.setEnabled(True) self._lut_filter.setEnabled(True) else: self._clear_lut_action.setEnabled(False) self._lut_extrapolate_widget.setEnabled(False) self._lut_filter.setEnabled(False) if update_metadata: mari.utils.disconnect(self._lut_filter.metadataValueChanged, lutMetadataValueChanged) self._lut_filter.setMetadata('File', self._lut_file_list) mari.utils.connect(self._lut_filter.metadataValueChanged, lutMetadataValueChanged) else: # If this was a request via the metadata system we will need to put the value back to what it was # before. if not update_metadata: mari.utils.disconnect(self._lut_filter.metadataValueChanged, lutMetadataValueChanged) self._lut_filter.setMetadata('File', self._lut_file_list) mari.utils.connect(self._lut_filter.metadataValueChanged, lutMetadataValueChanged) return False return True #----------------------------------------------------------------------------------------- def resetLUT(self): if ocio.lut_file_list_default.isEmpty() or not self.setLUTPath(ocio.lut_file_list_default.at(0)): self.setLUTPath('') #----------------------------------------------------------------------------------------- def selectLUT(self): lut_path = mari.utils.misc.getOpenFileName(None, 'Select LUT File', '' if self._lut_file_list.isEmpty() else self._lut_file_list.at(0), ocio.lutFileFilter(), None, 0) if os.path.isfile(lut_path): self.setLUTPath(lut_path) #----------------------------------------------------------------------------------------- def setExtrapolateEnabled(self, value, update_widget = True, update_metadata = True): if value != self._lut_extrapolate: self._lut_extrapolate = value if update_widget: block = self._lut_extrapolate_widget.blockSignals(True) self._lut_extrapolate_widget.setChecked(self._lut_extrapolate) self._lut_extrapolate_widget.blockSignals(block) if update_metadata: mari.utils.disconnect(self._lut_filter.metadataValueChanged, lutMetadataValueChanged) self._lut_filter.setMetadata('Extrapolate', self._lut_extrapolate) mari.utils.connect(self._lut_filter.metadataValueChanged, lutMetadataValueChanged) if not self._rebuildLUTFilter(lut_path = '' if self._lut_file_list.isEmpty() else self._lut_file_list.at(0), force_shader_build = True): self.resetLUT() ocio.printMessage(ocio.MessageType.DEBUG, 'Changed extrapolate to \'%s\'' % self._lut_extrapolate) #----------------------------------------------------------------------------------------- def setConfigPath(self, value, update_metadata = True): if self._config_file_list.isEmpty() or value != self._config_file_list.at(0): config = ocio.loadConfig(value, True) if config is not None: self._config_file_list.clear() self._config_file_list.append(value) self._config_file_list.setPickedFile(value) self._config = config self._updateDisplayWidgets() self._updateDisplayMetadata() self._rebuildDisplayFilter() ocio.printMessage(ocio.MessageType.DEBUG, 'Changed config to \'%s\'' % self._config_file_list.at(0)) else: # If this was a request via the metadata system we will need to put the value back to what it was # before. if not update_metadata: mari.utils.disconnect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._display_filter.setMetadata('ConfigPath', self._config_file_list) mari.utils.connect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) return False return True #----------------------------------------------------------------------------------------- def selectConfig(self): config_path = mari.utils.misc.getOpenFileName(None, 'Select Configuration File', '' if self._config_file_list.isEmpty() else self._config_file_list.at(0), ocio.configFileFilter(), None, 0) if os.path.isfile(config_path): self.setConfigPath(config_path) #----------------------------------------------------------------------------------------- def setColorSpace(self, value, update_widget = True, update_metadata = True): if value != self._color_space: self._color_space = value if update_widget: block = self._color_space_widget.blockSignals(True) index = self._color_space_widget.findText(self._color_space) self._color_space_widget.setCurrentIndex(index) self._color_space_widget.blockSignals(block) if update_metadata: mari.utils.disconnect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._display_filter.setMetadata('InputColorSpace', self._color_space) mari.utils.connect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._rebuildDisplayFilter() ocio.printMessage(ocio.MessageType.DEBUG, 'Changed input color space to \'%s\'' % self._color_space) #----------------------------------------------------------------------------------------- def setDisplay(self, value, update_widget = True, update_metadata = True): if value != self._display: self._display = value if update_widget: block = self._display_widget.blockSignals(True) index = self._display_widget.findText(self._display) self._display_widget.setCurrentIndex(index) self._display_widget.blockSignals(block) if update_metadata: mari.utils.disconnect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._display_filter.setMetadata('Display', self._display) mari.utils.connect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self.setView(self._config.getDefaultView(self._display), update_widget, update_metadata) self._rebuildDisplayFilter() ocio.printMessage(ocio.MessageType.DEBUG, 'Changed display to \'%s\'' % self._display) #----------------------------------------------------------------------------------------- def setView(self, value, update_widget = True, update_metadata = True): if value != self._view: self._view = value if update_widget: block = self._view_widget.blockSignals(True) index = self._view_widget.findText(self._view) self._view_widget.setCurrentIndex(index) self._view_widget.blockSignals(block) if update_metadata: mari.utils.disconnect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._display_filter.setMetadata('View', self._view) mari.utils.connect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._rebuildDisplayFilter() ocio.printMessage(ocio.MessageType.DEBUG, 'Changed view to \'%s\'' % self._view) #----------------------------------------------------------------------------------------- def setSwizzle(self, value, update_widget = True, update_metadata = True): if value != self._swizzle: self._swizzle = value if update_widget: block = self._swizzle_widget.blockSignals(True) index = self._swizzle_widget.findText(self._swizzle) self._swizzle_widget.setCurrentIndex(index) self._swizzle_widget.blockSignals(block) if update_metadata: mari.utils.disconnect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._display_filter.setMetadata('Swizzle', self._swizzle) mari.utils.connect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._rebuildDisplayFilter() ocio.printMessage(ocio.MessageType.DEBUG, 'Changed swizzle to \'%s\'' % self._swizzle) #----------------------------------------------------------------------------------------- def setGain(self, value, update_widget = True, update_metadata = True): if value != self._gain: self._gain = value if update_widget: self._updateGainWidgets() if update_metadata: mari.utils.disconnect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._display_filter.setMetadata('Gain', self._gain) mari.utils.connect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._rebuildDisplayFilter() ocio.printMessage(ocio.MessageType.DEBUG, 'Changed gain to \'%s\'' % self._gain) #----------------------------------------------------------------------------------------- def setGamma(self, value, update_widget = True, update_metadata = True): if value != self._gamma: self._gamma = value if update_widget: block = self._gamma_widget.blockSignals(True) self._gamma_widget.setValue(self._gamma) self._gamma_widget.blockSignals(block) if update_metadata: mari.utils.disconnect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._display_filter.setMetadata('Gamma', self._gamma) mari.utils.connect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._rebuildDisplayFilter() ocio.printMessage(ocio.MessageType.DEBUG, 'Changed gamma to \'%s\'' % self._gamma) #----------------------------------------------------------------------------------------- def updateLUTSize(self): ocio.printMessage(ocio.MessageType.DEBUG, 'Updating LUT size...') # Rebuild the LUT filter. if self._lut_sampler_name is not None: self._lut_filter.deleteTexture(self._lut_sampler_name) self._lut_sampler_name = None self._lut_filter_cache_id = None self._lut_texture_cache_id = None if not self._rebuildLUTFilter(lut_path = '' if self._lut_file_list.isEmpty() else self._lut_file_list.at(0), force_shader_build = True): self.resetLUT() # Rebuild the display filter. if self._display_sampler_name is not None: self._display_filter.deleteTexture(self._display_sampler_name) self._display_sampler_name = None self._display_filter_cache_id = None self._display_texture_cache_id = None self._rebuildDisplayFilter() #----------------------------------------------------------------------------------------- def updateFStopCenter(self): ocio.printMessage(ocio.MessageType.DEBUG, 'Updating f-stop center...') fstop = ocio.convertGainToFStop(self._gain) self._updateFStopWidgetText(fstop) #----------------------------------------------------------------------------------------- # Widgets: #----------------------------------------------------------------------------------------- def _buildWidgets(self): action_list = list() self._toggle_color_management_action = self._addAction( '/Mari/OpenColorIO/&Toggle Color Management', 'mari.system._ocio_toolbar.toolbar._toggleColorManagement()', 'ColorManager.png', 'Toggle on/off color management', 'Toggle color management') self._toggle_color_management_action.setCheckable(True) self._toggle_color_management_action.setChecked(ocio.enabled_default) action_list.append('/Mari/OpenColorIO/&Toggle Color Management') self._select_config_action = self._addAction( '/Mari/OpenColorIO/&Select Config', 'mari.system._ocio_toolbar.toolbar.selectConfig()', 'LoadColorConfig.png', 'Select color space configuration file', 'Select config') action_list.append('/Mari/OpenColorIO/&Select Config') self._select_lut_action = self._addAction( '/Mari/OpenColorIO/&Select LUT', 'mari.system._ocio_toolbar.toolbar.selectLUT()', 'LoadLookupTable.png', 'Select LUT file', 'Select LUT') action_list.append('/Mari/OpenColorIO/&Select LUT') self._clear_lut_action = self._addAction( '/Mari/OpenColorIO/&Clear LUT', 'mari.system._ocio_toolbar.toolbar._clearLUT()', 'ClearLookupTable.png', 'Clear current LUT', 'Clear LUT') action_list.append('/Mari/OpenColorIO/&Clear LUT') mari.app.deleteToolBar('Color Space') self._toolbar = mari.app.createToolBar('Color Space', True) self._toolbar.addActionList(action_list, False) self._toolbar.setLockedSlot(True) self._toolbar.setSpacing(TOOLBAR_SPACING) self._toolbar.insertSeparator('/Mari/OpenColorIO/&Select LUT') # Extrapolate: self._toolbar.addWidget(QtGui.QLabel('Extrapolate')) self._lut_extrapolate_widget = QtGui.QCheckBox() self._lut_extrapolate_widget.setToolTip('Extrapolate if outside LUT range'); self._lut_extrapolate_widget.setChecked(self._lut_extrapolate) self._lut_extrapolate_widget.connect( QtCore.SIGNAL('toggled(bool)'), lambda value: self.setExtrapolateEnabled(value = value, update_widget = False, update_metadata = True)) self._toolbar.addWidget(self._lut_extrapolate_widget) self._toolbar.addSeparator() color_spaces = [color_space.getName() for color_space in self._config.getColorSpaces()] # Color-Space: self._color_space_widget = self._addComboBox( 'Input Color Space', color_spaces, self._color_space, ocio.color_space_default, lambda value: self.setColorSpace(value = value, update_widget = False, update_metadata = True)) self._color_space = self._color_space_widget.currentText # Display: self._display_widget = self._addComboBox( 'Display Device', self._config.getDisplays(), self._display, ocio.display_default, lambda value: self.setDisplay(value = value, update_widget = False, update_metadata = True)) self._display = self._display_widget.currentText # View: self._view_widget = self._addComboBox( 'View Transform', self._config.getViews(self._display), self._view, ocio.view_default, lambda value: self.setView(value = value, update_widget = False, update_metadata = True)) self._view = self._view_widget.currentText # Swizzle: self._swizzle_widget = self._addComboBox( 'Component', ocio.SWIZZLE_TYPES, self._swizzle, ocio.swizzle_default, lambda value: self.setSwizzle(value = value, update_widget = False, update_metadata = True)) self._swizzle = self._swizzle_widget.currentText # Gain Group: group_widget, layout = self._addWidgetGroup() group_widget.setMaximumWidth(GAIN_GROUP_MAX_WIDTH) layout.addWidget(QtGui.QLabel('Gain')) # F-Stop: subgroup_widget = QtGui.QWidget() layout.addWidget(subgroup_widget) sublayout = QtGui.QHBoxLayout() sublayout.setSpacing(0) sublayout.setMargin(0) subgroup_widget.setLayout(sublayout) exposure = ocio.convertGainToExposure(self._gain) fstop = ocio.convertExposureToFStop(exposure) scale = (exposure - ocio.EXPOSURE_MIN) / ocio.EXPOSURE_DELTA widget_max = int(math.ceil(ocio.EXPOSURE_DELTA / ocio.FSTOP_STEP_SIZE)) widget_value = scale * widget_max self._fstop_widget = mari.LineEdit() self._fstop_widget.setRange(widget_max) self._fstop_widget.setMaximumWidth(FSTOP_MAX_WIDTH) self._fstop_widget.setReadOnly(True) self._updateFStopWidgetText(fstop) self._fstop_widget.setValue(widget_value) mari.utils.connect(self._fstop_widget.movedMouse, self._fstopMovedMouse) self._fstop_widget.addToLayout(sublayout) self._fstop_decrement_widget = self._addSmallButtom( sublayout, '-', 'Decrease gain 1/2 stop', lambda: self.setGain(ocio.convertExposureToGain(ocio.convertGainToExposure(self._gain) - 0.5))) self._fstop_increment_widget = self._addSmallButtom( sublayout, '+', 'Increase gain 1/2 stop', lambda: self.setGain(ocio.convertExposureToGain(ocio.convertGainToExposure(self._gain) + 0.5))) ocio.registerLUTSizeChanged(self.updateLUTSize) ocio.registerFStopCenterChanged(self.updateFStopCenter) # Gain: subgroup_widget = QtGui.QWidget() layout.addWidget(subgroup_widget) sublayout = QtGui.QHBoxLayout() sublayout.setSpacing(3) sublayout.setMargin(0) subgroup_widget.setLayout(sublayout) widget_max = int(math.ceil(ocio.EXPOSURE_DELTA / ocio.EXPOSURE_STEP_SIZE)) widget_value = scale * widget_max self._gain_widget = mari.LineEdit() self._gain_widget.setRange(widget_max) self._gain_widget.addFloatValidator(ocio.GAIN_MIN, ocio.GAIN_MAX, ocio.GAIN_PRECISION) self._gain_widget.setMaximumWidth(GAIN_MAX_WIDTH) self._updateGainWidgetText() self._gain_widget.setValue(widget_value) mari.utils.connect( self._gain_widget.lostFocus, lambda: self.setGain(max(min(float(self._gain_widget.text()), ocio.GAIN_MAX), ocio.GAIN_MIN))) mari.utils.connect(self._gain_widget.movedMouse, self._gainMovedMouse) self._gain_widget.addToLayout(sublayout) # Exposure: self._exposure_widget = QtGui.QSlider() self._exposure_widget.orientation = 1 self._exposure_widget.setMaximum(widget_max) self._exposure_widget.setValue(widget_value) self._exposure_widget.setMinimumWidth(EXPOSURE_MAX_WIDTH) self._exposure_widget.setMaximumWidth(EXPOSURE_MAX_WIDTH) mari.utils.connect(self._exposure_widget.valueChanged, self._exposureChanged) sublayout.addWidget(self._exposure_widget) self._gain_reset_widget = self._addSmallButtom( layout, 'R', 'Reset gain to default', lambda: self.setGain(value = ocio.GAIN_RESET, update_widget = True, update_metadata = True)) # Gamma: group_widget, layout = self._addWidgetGroup() group_widget.setMaximumWidth(GAMMA_MAX_WIDTH) layout.addWidget(QtGui.QLabel('Gamma')) self._gamma_widget = mari.FloatSlider() self._gamma_widget.setRange(ocio.GAMMA_MIN, ocio.GAMMA_MAX) self._gamma_widget.setStepSize(ocio.GAMMA_STEP_SIZE) self._gamma_widget.setPrecision(ocio.GAMMA_PRECISION) self._gamma_widget.setValue(self._gamma) mari.utils.connect( self._gamma_widget.valueChanged, lambda value: self.setGamma(value = value, update_widget = False, update_metadata = True)) self._gamma_widget.addToLayout(layout) self._gamma_reset_widget = self._addSmallButtom( layout, 'R', 'Reset gamma to default', lambda: self.setGamma(value = ocio.GAMMA_RESET, update_widget = True, update_metadata = True)) #----------------------------------------------------------------------------------------- def _updateDisplayWidgets(self): color_spaces = [color_space.getName() for color_space in self._config.getColorSpaces()] self._updateComboBox(self._color_space_widget, color_spaces, self._color_space, ocio.color_space_default) self._color_space = self._color_space_widget.currentText self._updateComboBox(self._display_widget, self._config.getDisplays(), self._display, ocio.display_default) self._display = self._display_widget.currentText self._updateComboBox(self._view_widget, self._config.getViews(self._display), self._view, ocio.view_default) self._view = self._view_widget.currentText self._updateComboBox(self._swizzle_widget, ocio.SWIZZLE_TYPES, self._swizzle, ocio.swizzle_default) self._swizzle = self._swizzle_widget.currentText self._updateGainWidgets() self._gamma_widget.setValue(self._gamma) #----------------------------------------------------------------------------------------- def _enableWidgets(self, enable): self._select_config_action.setEnabled(enable) self._select_lut_action.setEnabled(enable) lut_enable = enable and not self._lut_file_list.isEmpty() self._clear_lut_action.setEnabled(lut_enable) self._lut_extrapolate_widget.setEnabled(lut_enable) self._color_space_widget.setEnabled(enable) self._display_widget.setEnabled(enable) self._view_widget.setEnabled(enable) self._swizzle_widget.setEnabled(enable) self._fstop_widget.setEnabled(enable) self._fstop_decrement_widget.setEnabled(enable) self._fstop_increment_widget.setEnabled(enable) self._gain_widget.setEnabled(enable) self._exposure_widget.setEnabled(enable) self._gain_reset_widget.setEnabled(enable) self._gamma_widget.setEnabled(enable) self._gamma_reset_widget.setEnabled(enable) #----------------------------------------------------------------------------------------- def _addAction(self, identifier, command, icon_filename, tip, whats_this): action = mari.actions.find(identifier) if action is None: action = mari.actions.create(identifier, command) icon_path = mari.resources.path(mari.resources.ICONS) + '/' + icon_filename action.setIconPath(icon_path) action.setStatusTip(tip) action.setToolTip(tip) action.setWhatsThis(whats_this) return action #----------------------------------------------------------------------------------------- def _addWidgetGroup(self): group_widget = QtGui.QWidget() self._toolbar.addWidget(group_widget) layout = QtGui.QHBoxLayout() layout.setSpacing(1) layout.setMargin(1) group_widget.setLayout(layout) return (group_widget, layout) #----------------------------------------------------------------------------------------- def _addComboBox(self, label, items, value, default, value_changed, *args): group_widget, layout = self._addWidgetGroup() layout.addWidget(QtGui.QLabel(label)) widget = QtGui.QComboBox() self._updateComboBox(widget, items, value, default) widget.connect(QtCore.SIGNAL('currentIndexChanged(const QString &)'), value_changed) layout.addWidget(widget) return widget #----------------------------------------------------------------------------------------- def _updateComboBox(self, widget, items, value, default): block = widget.blockSignals(True) widget.clear() for item in items: widget.addItem(item) if items.count(value) != 0: widget.setCurrentIndex(items.index(value)) elif items.count(default) != 0: widget.setCurrentIndex(items.index(default)) widget.blockSignals(block) #----------------------------------------------------------------------------------------- def _addSmallButtom(self, layout, label, tool_tip, value_changed, *args): widget = QtGui.QPushButton(label); widget.setToolTip(tool_tip); widget.setFixedHeight(16); widget.setFixedWidth(16); widget.connect(QtCore.SIGNAL('released()'), value_changed) layout.addWidget(widget); return widget #----------------------------------------------------------------------------------------- def _convertFStopWidgetValueToGain(self, value): widget_max = int(math.ceil(ocio.EXPOSURE_DELTA / ocio.FSTOP_STEP_SIZE)) scale = float(value) / float(widget_max) exposure = ocio.EXPOSURE_MIN + scale * ocio.EXPOSURE_DELTA return ocio.convertExposureToGain(exposure) #----------------------------------------------------------------------------------------- def _convertExposureWidgetValueToGain(self, value): widget_max = int(math.ceil(ocio.EXPOSURE_DELTA / ocio.EXPOSURE_STEP_SIZE)) scale = float(value) / float(widget_max) exposure = ocio.EXPOSURE_MIN + scale * ocio.EXPOSURE_DELTA return ocio.convertExposureToGain(exposure) #----------------------------------------------------------------------------------------- def _updateFStopWidgetText(self, fstop): block = self._fstop_widget.blockSignals(True) if fstop < 10.0: # Floor the value to one decimal place and only display the decimal point if necessary text = '%f' % fstop index = text.index('.') if text[index + 1] == '0': text = text[:index] else: text = text[:index + 2] self._fstop_widget.setText('f/%s' % text) else: self._fstop_widget.setText('f/%d' % int(fstop)) self._fstop_widget.blockSignals(block) #----------------------------------------------------------------------------------------- def _updateGainWidgetText(self): block = self._gain_widget.blockSignals(True) self._gain_widget.setText(('%.' + ('%d' % ocio.GAIN_PRECISION) + 'f') % self._gain) self._gain_widget.home(False) self._gain_widget.blockSignals(block) #----------------------------------------------------------------------------------------- def _updateGainWidgets(self): exposure = ocio.convertGainToExposure(self._gain) fstop = ocio.convertExposureToFStop(exposure) self._updateFStopWidgetText(fstop) scale = (exposure - ocio.EXPOSURE_MIN) / ocio.EXPOSURE_DELTA widget_max = int(math.ceil(ocio.EXPOSURE_DELTA / ocio.FSTOP_STEP_SIZE)) widget_value = int(round(scale * float(widget_max))) block = self._fstop_widget.blockSignals(True) self._fstop_widget.setValue(widget_value) self._fstop_widget.blockSignals(block) self._updateGainWidgetText() widget_max = int(math.ceil(ocio.EXPOSURE_DELTA / ocio.EXPOSURE_STEP_SIZE)) widget_value = int(round(scale * float(widget_max))) block = self._gain_widget.blockSignals(True) self._gain_widget.setValue(widget_value) self._gain_widget.blockSignals(block) block = self._exposure_widget.blockSignals(True) self._exposure_widget.setValue(widget_value) self._exposure_widget.blockSignals(block) #----------------------------------------------------------------------------------------- def _toggleColorManagement(self): enabled = self.isColorManagementEnabled() mari.gl_render.setPostProcessingEnabled(enabled) self._enableWidgets(enabled) ocio.printMessage(ocio.MessageType.DEBUG, 'Toggled color management to \'%s\'' % ('on' if enabled else 'off')) #----------------------------------------------------------------------------------------- def _clearLUT(self): self.setLUTPath('') ocio.printMessage(ocio.MessageType.DEBUG, 'Cleared lut') #----------------------------------------------------------------------------------------- def _fstopMovedMouse(self, value): self.setGain(self._convertFStopWidgetValueToGain(float(value)), False) exposure = ocio.convertGainToExposure(self._gain) fstop = ocio.convertExposureToFStop(exposure) self._updateFStopWidgetText(fstop) self._updateGainWidgetText() widget_max = int(math.ceil(ocio.EXPOSURE_DELTA / ocio.EXPOSURE_STEP_SIZE)) scale = (exposure - ocio.EXPOSURE_MIN) / ocio.EXPOSURE_DELTA value = int(round(scale * float(widget_max))) self._gain_widget.setValue(value) value = max(min(value, widget_max), 0) self._exposure_widget.setValue(value) #----------------------------------------------------------------------------------------- def _gainMovedMouse(self, value): self.setGain(self._convertExposureWidgetValueToGain(float(value)), False) self._updateGainWidgetText() widget_max = int(math.ceil(ocio.EXPOSURE_DELTA / ocio.EXPOSURE_STEP_SIZE)) value = max(min(value, widget_max), 0) self._exposure_widget.setValue(value) exposure = ocio.convertGainToExposure(self._gain) fstop = ocio.convertExposureToFStop(exposure) self._updateFStopWidgetText(fstop) scale = (exposure - ocio.EXPOSURE_MIN) / ocio.EXPOSURE_DELTA widget_max = int(math.ceil(ocio.EXPOSURE_DELTA / ocio.FSTOP_STEP_SIZE)) value = int(round(scale * float(widget_max))) self._fstop_widget.setValue(value) #----------------------------------------------------------------------------------------- def _exposureChanged(self, value): self.setGain(value = self._convertExposureWidgetValueToGain(float(value)), update_widget = False, update_metadata = True) self._updateGainWidgetText() self._gain_widget.setValue(value) exposure = ocio.convertGainToExposure(self._gain) fstop = ocio.convertExposureToFStop(exposure) self._updateFStopWidgetText(fstop) scale = (exposure - ocio.EXPOSURE_MIN) / ocio.EXPOSURE_DELTA widget_max = int(math.ceil(ocio.EXPOSURE_DELTA / ocio.FSTOP_STEP_SIZE)) value = int(round(scale * float(widget_max))) self._fstop_widget.setValue(value) #----------------------------------------------------------------------------------------- # Metadata: #----------------------------------------------------------------------------------------- def _buildMetadata(self): # LUT: # --- mari.utils.connect(self._lut_filter.metadataValueChanged, lutMetadataValueChanged) self._updateLUTMetadata() flags = self._lut_filter.METADATA_VISIBLE | self._lut_filter.METADATA_EDITABLE self._lut_filter.setMetadataFlags('File', flags) self._lut_filter.setMetadataFlags('Extrapolate', flags) # Display: # ------- mari.utils.connect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._updateDisplayMetadata() self._display_filter.setMetadataDisplayName('ConfigPath', 'Configuration File') flags = self._display_filter.METADATA_VISIBLE | self._display_filter.METADATA_EDITABLE self._display_filter.setMetadataFlags('ConfigPath', flags) self._display_filter.setMetadataDisplayName('InputColorSpace', 'Input Color Space') self._display_filter.setMetadataFlags('InputColorSpace', flags) self._display_filter.setMetadataDisplayName('Display', 'Display Device') self._display_filter.setMetadataFlags('Display', flags) self._display_filter.setMetadataDisplayName('View', 'View Transform') self._display_filter.setMetadataFlags('View', flags) self._display_filter.setMetadataDisplayName('Swizzle', 'Component') self._display_filter.setMetadataFlags('Swizzle', flags) self._display_filter.setMetadataDefault('Gain', ocio.GAIN_RESET) self._display_filter.setMetadataRange('Gain', ocio.GAIN_MIN, ocio.GAIN_MAX) self._display_filter.setMetadataStep('Gain', ocio.GAIN_STEP_SIZE) self._display_filter.setMetadataFlags('Gain', flags) self._display_filter.setMetadataDefault('Gamma', ocio.GAMMA_RESET) self._display_filter.setMetadataRange('Gamma', ocio.GAMMA_MIN, ocio.GAMMA_MAX) self._display_filter.setMetadataStep('Gamma', ocio.GAMMA_STEP_SIZE) self._display_filter.setMetadataFlags('Gamma', flags) #----------------------------------------------------------------------------------------- def _updateLUTMetadata(self): mari.utils.disconnect(self._lut_filter.metadataValueChanged, lutMetadataValueChanged) self._lut_filter.setMetadata('File', self._lut_file_list) self._lut_filter.setMetadata('Extrapolate', self._lut_extrapolate) mari.utils.connect(self._lut_filter.metadataValueChanged, lutMetadataValueChanged) #----------------------------------------------------------------------------------------- def _updateDisplayMetadata(self): mari.utils.disconnect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) self._display_filter.setMetadata('ConfigPath', self._config_file_list) color_spaces = [color_space.getName() for color_space in self._config.getColorSpaces()] self._display_filter.setMetadata('InputColorSpace', self._color_space) self._display_filter.setMetadataItemList('InputColorSpace', color_spaces) self._display_filter.setMetadata('Display', self._display) self._display_filter.setMetadataItemList('Display', self._config.getDisplays()) self._display_filter.setMetadata('View', self._view) self._display_filter.setMetadataItemList('View', self._config.getViews(self._display)) self._display_filter.setMetadata('Swizzle', self._swizzle) self._display_filter.setMetadataItemList('Swizzle', ocio.SWIZZLE_TYPES) self._display_filter.setMetadata('Gain', self._gain) self._display_filter.setMetadata('Gamma', self._gain) mari.utils.connect(self._display_filter.metadataValueChanged, displayMetadataValueChanged) #----------------------------------------------------------------------------------------- # External Connections: #----------------------------------------------------------------------------------------- def _openedProject(self, project): ocio.printMessage(ocio.MessageType.DEBUG, 'Loading settings for project \'%s\'' % project.name()) # Load the settings stored as metadata on the project... # General: # ------- self._toggle_color_management_action.setEnabled(True) self._toggle_color_management_action.setChecked(project.metadata('ColorEnabled') if project.hasMetadata('ColorEnabled') else ocio.enabled_default) # Enable/disable color management (MUST be done after modifications to 'self._toggle_color_management_action'. mari.gl_render.setPostProcessingEnabled(self.isColorManagementEnabled()) filter_collection = None if project.hasMetadata('ColorProfile'): # *** IMPORTANT *** The post filter collection used to be called 'OpenColorIO' but was renamed to hide the # fact we use OpenColorIO from our users. So as a temporary workaround we need to check for the old filter # collection correct for it. name = project.metadata('ColorProfile') if name == 'OpenColorIO': name = 'Color Space' filter_collection = mari.gl_render.findPostFilterCollection(name) # Default the color management filter stack if the working one doesn't exist. if filter_collection is None: filter_collection = mari.gl_render.findPostFilterCollection(ocio.profile_default) mari.gl_render.setPostFilterCollection(filter_collection) # LUT: # --- lut_extrapolate = project.metadata('OcioLutExtrapolate') if project.hasMetadata('OcioLutExtrapolate') else ocio.lut_extrapolate_default force_shader_build = lut_extrapolate != self._lut_extrapolate self._lut_extrapolate = lut_extrapolate self._lut_extrapolate_widget.setChecked(self._lut_extrapolate) if project.hasMetadata('OcioLutPath'): lut_path = ocio.buildLoadPath(project.metadata('OcioLutPath')) if not self.setLUTPath(value = lut_path, update_metadata = True, force_shader_build = force_shader_build): self.resetLUT() else: self.resetLUT() # Display: # ------- self._color_space = project.metadata( 'OcioColorSpace') if project.hasMetadata('OcioColorSpace') else ocio.color_space_default self._display = project.metadata( 'OcioDisplay') if project.hasMetadata( 'OcioDisplay') else ocio.display_default self._view = project.metadata( 'OcioView') if project.hasMetadata( 'OcioView') else ocio.view_default self._swizzle = project.metadata( 'OcioSwizzle') if project.hasMetadata( 'OcioSwizzle') else ocio.swizzle_default self._gain = max(min(project.metadata('OcioGain'), ocio.GAIN_MAX), ocio.GAIN_MIN) if project.hasMetadata( 'OcioGain') else ocio.gain_default self._gamma = project.metadata( 'OcioGamma') if project.hasMetadata( 'OcioGamma') else ocio.gamma_default # Attempt to load a configuration file... self._config_file_list.clear() self._config = None # 1. Environment variable. config_path = os.getenv('OCIO') if config_path is not None: self.setConfigPath(config_path) # 2. Project setting. if self._config is None and project.hasMetadata('OcioConfigPath'): self.setConfigPath(ocio.buildLoadPath(project.metadata('OcioConfigPath'))) # 3. Use the default if nothing was found. if self._config is None: self._config_file_list = mari.FileList(ocio.config_file_list_default) self._config = ocio.config_default self._updateDisplayWidgets() self._rebuildDisplayFilter() self._enableWidgets(filter_collection.name() == 'Color Space' and self._toggle_color_management_action.isChecked()) self._updateLUTMetadata() self._updateDisplayMetadata() self._printLog() #----------------------------------------------------------------------------------------- def _aboutToSaveProject(self, project): ocio.printMessage(ocio.MessageType.DEBUG, 'Saving settings for project \'%s\'' % project.name()) # Store the settings as metadata on the project. project.setMetadata( 'ColorEnabled', self.isColorManagementEnabled()) filter_collection = mari.gl_render.currentPostFilterCollection() if filter_collection is not None: project.setMetadata( 'ColorProfile', filter_collection.name()) project.setMetadata('OcioLutExtrapolate', self._lut_extrapolate) project.setMetadata( 'OcioLutPath', '' if self._lut_file_list.isEmpty() else ocio.buildSavePath(self._lut_file_list.at(0))) if os.getenv('OCIO') is None: project.setMetadata('OcioConfigPath', '' if self._config_file_list.isEmpty() else ocio.buildSavePath(self._config_file_list.at(0))) project.setMetadata( 'OcioColorSpace', self._color_space) project.setMetadata( 'OcioDisplay', self._display) project.setMetadata( 'OcioView', self._view) project.setMetadata( 'OcioSwizzle', self._swizzle) project.setMetadata( 'OcioGain', self._gain) project.setMetadata( 'OcioGamma', self._gamma) #----------------------------------------------------------------------------------------- def _closedProject(self): self._toggle_color_management_action.setEnabled(False) self._enableWidgets(False) #----------------------------------------------------------------------------------------- def _toolBarsCreated(self): # Things like deleting Mari's configuration file and reseting the layout to the default will destroy the toolbar # so we need to detect if this is the case and rebuild it! toolbar = mari.app.findToolBar('Color Space') if toolbar is None: ocio.printMessage(ocio.MessageType.DEBUG, 'Rebuilding missing toolbar...') self._buildWidgets() #----------------------------------------------------------------------------------------- def _postProcessingEnabled(self, enabled): self._toggle_color_management_action.setChecked(enabled) # Only enable or disable UI if we have a current project. current_project = mari.projects.current() if current_project is not None: self._enableWidgets(enabled) #----------------------------------------------------------------------------------------- def _setCurrentPostFilterCollection(self): # Only enable or disable UI if we have a current project. current_project = mari.projects.current() if current_project is not None: filter_collection = mari.gl_render.currentPostFilterCollection() if filter_collection is None or filter_collection.name() != 'Color Space': ocio.printMessage(ocio.MessageType.DEBUG, 'Disabling OpenColorIO') self._enableWidgets(False) else: ocio.printMessage(ocio.MessageType.DEBUG, 'Enabling OpenColorIO') self._enableWidgets(True) #----------------------------------------------------------------------------------------- # Filter: #----------------------------------------------------------------------------------------- def _rebuildLUTFilter(self, lut_path, force_shader_build = False): if lut_path == '': self._lut_filter.setDefinitionsSnippet('') self._lut_filter.setBodySnippet('') if self._lut_sampler_name is not None: self._lut_filter.deleteTexture(self._lut_sampler_name) self._lut_sampler_name = None self._lut_filter_cache_id = None self._lut_texture_cache_id = None else: # There is a chance this is a bad file so we need to guard against it. try: self._lut_filter_cache_id, self._lut_texture_cache_id, self._lut_sampler_name = ocio.buildLUTFilter( self._config, lut_path, self._lut_filter, self._lut_filter_cache_id, self._lut_texture_cache_id, self._lut_extrapolate, force_shader_build) except Exception, e: message = 'Failed to load LUT file \'%s\' due to \'%s\'' % (lut_path, e) ocio.printMessage(ocio.MessageType.ERROR, '%s' % message) if not mari.app.inTerminalMode(): mari.utils.misc.message(message, 'Color Space', 1024, 2) return False ocio.printMessage(ocio.MessageType.DEBUG, 'Changed LUT to \'%s\'' % lut_path) return True #----------------------------------------------------------------------------------------- def _rebuildDisplayFilter(self): display_transform = ocio.PyOpenColorIO.DisplayTransform() display_transform.setInputColorSpaceName(self._color_space) if hasattr(display_transform, 'setDisplay'): # OCIO 1.0+ display_transform.setDisplay(self._display) display_transform.setView(self._view) else: # OCIO 0.8.X display_color_space = self._config.getDisplayColorSpaceName(self._display, self._view) display_transform.setDisplayColorSpaceName(display_color_space) # Add the channel sizzle. luma_coefs = self._config.getDefaultLumaCoefs() mtx, offset = ocio.PyOpenColorIO.MatrixTransform.View(ocio.SWIZZLE_VALUES[self._swizzle], luma_coefs) transform = ocio.PyOpenColorIO.MatrixTransform() transform.setValue(mtx, offset) display_transform.setChannelView(transform) # Add the linear gain. transform = ocio.PyOpenColorIO.CDLTransform() transform.setSlope((self._gain, self._gain, self._gain)) display_transform.setLinearCC(transform) # Add the post-display CC. transform = ocio.PyOpenColorIO.ExponentTransform() transform.setValue([1.0 / max(1e-6, v) for v in (self._gamma, self._gamma, self._gamma, self._gamma)]) display_transform.setDisplayCC(transform) processor = self._config.getProcessor(display_transform) self._display_filter_cache_id, self._display_texture_cache_id, self._display_sampler_name = ocio.buildProcessorFilter( processor, self._display_filter, self._display_filter_cache_id, self._display_texture_cache_id) current_canvas = mari.canvases.current() if current_canvas is not None: current_canvas.repaint() #----------------------------------------------------------------------------------------- # Debugging: #----------------------------------------------------------------------------------------- def _printLog(self): ocio.printMessage( ocio.MessageType.INFO, '==============================================================') ocio.printMessage( ocio.MessageType.INFO, 'Configuration:') ocio.printMessage( ocio.MessageType.INFO, '==============================================================') ocio.printMessage( ocio.MessageType.INFO, ' Enabled: %s; Default: %s' % (mari.gl_render.isPostProcessingEnabled(), ocio.enabled_default)) filter_collection = mari.gl_render.currentPostFilterCollection() if filter_collection is not None: ocio.printMessage(ocio.MessageType.INFO, ' Profile: %s; Default: %s' % (filter_collection.name(), ocio.profile_default)) else: ocio.printMessage(ocio.MessageType.INFO, ' Profile: None; Default: %s' % (ocio.profile_default)) ocio.printMessage( ocio.MessageType.INFO, ' LUT Path: %s; Default: %s' % ('' if self._lut_file_list.isEmpty() else self._lut_file_list.at(0), '' if ocio.lut_file_list_default.isEmpty() else ocio.lut_file_list_default.at(0))) ocio.printMessage( ocio.MessageType.INFO, ' Extrapolate: %s; Default: %s' % (self._lut_extrapolate, ocio.lut_extrapolate_default)) ocio.printMessage( ocio.MessageType.INFO, ' Config Path: %s; Default: %s' % ('' if self._config_file_list.isEmpty() else self._config_file_list.at(0), '' if ocio.config_file_list_default.isEmpty() else ocio.config_file_list_default.at(0))) ocio.printMessage( ocio.MessageType.INFO, ' Color Space: %s; Default: %s' % (self._color_space, ocio.color_space_default)) ocio.printMessage( ocio.MessageType.INFO, ' Display: %s; Default: %s' % (self._display, ocio.display_default)) ocio.printMessage( ocio.MessageType.INFO, ' View: %s; Default: %s' % (self._view, ocio.view_default)) ocio.printMessage( ocio.MessageType.INFO, ' Swizzle: %s; Default: %s' % (self._swizzle, ocio.swizzle_default)) ocio.printMessage( ocio.MessageType.INFO, ' F-Stop: %f; Default: %f; Center: %f' % (ocio.convertGainToFStop(self._gain), ocio.convertGainToFStop(ocio.gain_default), ocio.fstop_center)) ocio.printMessage( ocio.MessageType.INFO, ' Gain: %f; Default: %f' % (self._gain, ocio.gain_default)) ocio.printMessage( ocio.MessageType.INFO, ' Gamma: %f; Default: %f' % (self._gamma, ocio.gamma_default)) ocio.printMessage( ocio.MessageType.INFO, '==============================================================') ############################################################################################## # The following functions CAN'T be part of the toolbar class as a potential bug in PythonQt # causes the disconnect function to fail def lutMetadataValueChanged(name, value): global toolbar ocio.printMessage(ocio.MessageType.DEBUG, 'LUT metadata \'%s\' changed to \'%s\'' % (name, value)) if name == 'File': toolbar.setLUTPath(value = '' if value.isEmpty() else value.at(0), update_metadata = False, force_shader_build = False) elif name == 'Extrapolate': toolbar.setExtrapolateEnabled(value = value, update_widget = True, update_metadata = False) #----------------------------------------------------------------------------------------- def displayMetadataValueChanged(name, value): global toolbar ocio.printMessage(ocio.MessageType.DEBUG, 'Display metadata \'%s\' changed to \'%s\'' % (name, value)) if name == 'ConfigPath': toolbar.setConfigPath(value = '' if value.isEmpty() else value.at(0), update_metadata = False) elif name == 'InputColorSpace': toolbar.setColorSpace(value = value, update_widget = True, update_metadata = False) elif name == 'Display': toolbar.setDisplay(value = value, update_widget = True, update_metadata = False) elif name == 'View': toolbar.setView(value = value, update_widget = True, update_metadata = False) elif name == 'Swizzle': toolbar.setSwizzle(value = value, update_widget = True, update_metadata = False) elif name == 'Gain': toolbar.setGain(value = value, update_widget = True, update_metadata = False) elif name == 'Gamma': toolbar.setGamma(value = value, update_widget = True, update_metadata = False) ############################################################################################## if mari.app.isRunning(): if not hasattr(mari.gl_render, 'createPostFilterCollection'): ocio.printMessage(ocio.MessageType.ERROR, 'This version of Mari does not support the mari.gl_render.createPostFilterCollection API') else: if ocio.config_default is not None: toolbar = OcioToolBar() else: # Destroy the OCIO post filter collection if present to prevent the user trying to use it. filter_collection = mari.gl_render.findPostFilterCollection('Color Space') if filter_collection is not None: mari.gl_render.deletePostFilterCollection(filter_collection) # Destroy the toolbar to prevent the user trying to use it. mari.app.deleteToolBar('Color Space') opencolorio-1.1.0~dfsg0.orig/src/mari/1.4v1/README0000644000175000017500000000060713223553423017441 0ustar mfvmfvThese files ship with Mari, and are *not* required to be manually installed. They are provided as a reference example of using the OCIO API to create a GPU monitor implementation in python. Media/Scripts/mari/utils/ocio.py Media/Scripts/mari/system/_ocio_toolbar.py Media/Scripts/mari/system/_ocio_filter.py All code in these examples is Copyright (c) 2011 The Foundry Visionmongers Ltd. opencolorio-1.1.0~dfsg0.orig/src/mari/prototype/0000755000175000017500000000000013223553423020052 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/mari/prototype/README0000644000175000017500000000032413223553423020731 0ustar mfvmfvThis is a prototype implemetation for a python display integration, which worked in early Mari versions. It's provided as a simple example of how to use the OCIO python API to query the GPU interface functions. opencolorio-1.1.0~dfsg0.orig/src/mari/prototype/ociodisplay.py0000644000175000017500000002164613223553423022754 0ustar mfvmfv""" This script allows the use of OpenColorIO display transforms (3d luts) in the Mari Viewer. Requires Mari 1.3v2+. This example is not represntative of the final Mari OCIO workflow, merely an API demonstration. This code is a work in progress, to demonstrate the integration of OpenColorIO and Mari. The APIs this code relies on are subject to change at any time, and as such should not be relied on for production use (yet). LINUX testing instructions: * Build OCIO mkdir -p dist_mari mkdir -p build_mari && cd build_mari cmake -D CMAKE_BUILD_TYPE=Release \ -D CMAKE_INSTALL_PREFIX=../dist_mari \ -D PYTHON=/usr/bin/python2.6 \ -D OCIO_NAMESPACE=OpenColorIO_Mari \ ../ make install -j8 * Set $OCIO color environment setenv OCIO setenv OCIO /ocio.configs/spi-vfx/config.ocio (Profiles available for download from opencolorio.org) * Run Mari with OpenColorIO added to the LD_LIBRARY_PATH, and Python env LD_LIBRARY_PATH=/dist_mari/lib/ PYTHONPATH=/dist_mari/lib/python2.6 mari * Source this script in the python console. Also - IMPORTANT - you must enable 'Use Color Correction' in the Color Manager. """ import mari, time, PythonQt QtGui = PythonQt.QtGui QtCore = PythonQt.QtCore try: import PyOpenColorIO as OCIO mari.app.log("OCIODisplay: %s" % OCIO.__file__) except Exception,e: OCIO = None mari.app.log("OCIODisplay: Error: Could not import OpenColorIO python bindings.") mari.app.log("OCIODisplay: Please confirm PYTHONPATH has dir containing PyOpenColorIO.so") __all__ = [ 'OCIO', 'CreateOCIODisplayTransform', 'OCIODisplayUI'] LUT3D_SIZE = 32 WINDOW_NAME = "OpenColorIO Display Manager" CREATE_FLOATING = True class OCIODisplayUI(QtGui.QWidget): def __init__(self): QtGui.QWidget.__init__(self) QtGui.QGridLayout(self) self.setWindowTitle(WINDOW_NAME) self.setMinimumWidth(300) config = OCIO.GetCurrentConfig() self.__inputColorSpace = OCIO.Constants.ROLE_DEFAULT inputColorSpaces = [ OCIO.Constants.ROLE_TEXTURE_PAINT, 'dt8', OCIO.Constants.ROLE_SCENE_LINEAR ] for cs in inputColorSpaces: if config.getColorSpace(cs) is None: continue self.__inputColorSpace = cs break self.__fStopOffset = 0.0 self.__viewGamma = 1.0 self.__swizzle = (True, True, True, True) self.__filter_cacheID = None self.__filter = None self.__texture3d_cacheID = None self.__counter_hack = 0 self.__buildUI() self.__rebuildFilter() def __buildUI(self): config = OCIO.GetCurrentConfig() self.layout().addWidget( QtGui.QLabel("Input Color Space", self), 0, 0) csWidget = QtGui.QComboBox(self) self.layout().addWidget( csWidget, 0, 1) csIndex = None for name in (cs.getName() for cs in config.getColorSpaces()): csWidget.addItem(name) if name == self.__inputColorSpace: csIndex = csWidget.count - 1 if csIndex is not None: csWidget.setCurrentIndex(csIndex) csWidget.connect( QtCore.SIGNAL('currentIndexChanged(const QString &)'), self.__csChanged) # This doesnt work until the Horizontal enum is exposed. """ self.__fstopWidget_numStops = 3.0 self.__fstopWidget_ticksPerStop = 4 self.layout().addWidget( QtGui.QLabel("FStop", self), 1, 0) fstopWidget = QtGui.QSlider(Horizontal, self) self.layout().addWidget( fstopWidget, 1, 1) fstopWidget.setMinimum(int(-self.__fstopWidget_numStops*self.__fstopWidget_ticksPerStop)) fstopWidget.setMaximum(int(self.__fstopWidget_numStops*self.__fstopWidget_ticksPerStop)) fstopWidget.setTickInterval(self.__fstopWidget_ticksPerStop) """ def __csChanged(self, text): text = str(text) if text != self.__inputColorSpace: self.__inputColorSpace = text self.__rebuildFilter() def __rebuildFilter(self): config = OCIO.GetCurrentConfig() display = config.getDefaultDisplay() view = config.getDefaultView(display) transform = CreateOCIODisplayTransform(config, self.__inputColorSpace, display, view, self.__swizzle, self.__fStopOffset, self.__viewGamma) processor = config.getProcessor(transform) shaderDesc = dict( [('language', OCIO.Constants.GPU_LANGUAGE_GLSL_1_3), ('functionName', 'display_ocio_$ID_'), ('lut3DEdgeLen', LUT3D_SIZE)] ) filterCacheID = processor.getGpuShaderTextCacheID(shaderDesc) if filterCacheID != self.__filter_cacheID: self.__filter_cacheID = filterCacheID mari.app.log("OCIODisplay: Creating filter %s" % self.__filter_cacheID) desc = "sampler3D lut3d_ocio_$ID_;\n" desc += processor.getGpuShaderText(shaderDesc) body = "{ Out = display_ocio_$ID_(Out, lut3d_ocio_$ID_); }" # Clear the existing color managment filter stack and create a new filter # HACK: Increment a counter by 1 each time to force a refresh #self.__counter_hack += 1 #name = "OCIO %s %s %s v%d" % (display, view, self.__inputColorSpace, self.__counter_hack) name = "OCIO %s %s %s" % (display, view, self.__inputColorSpace) self.__filter = None self.__texture3d_cacheID = None mari.gl_render.clearPostFilterStack() self.__filter = mari.gl_render.createPostFilter(name, desc, body) mari.gl_render.appendPostFilter(self.__filter) else: mari.app.log('OCIODisplay: no shader text update required') texture3d_cacheID = processor.getGpuLut3DCacheID(shaderDesc) if texture3d_cacheID != self.__texture3d_cacheID: lut3d = processor.getGpuLut3D(shaderDesc) mari.app.log("OCIODisplay: Updating 3dlut %s" % texture3d_cacheID) if self.__texture3d_cacheID is None: self.__filter.setTexture3D("lut3d_ocio_$ID_", LUT3D_SIZE, LUT3D_SIZE, LUT3D_SIZE, self.__filter.FORMAT_RGB, lut3d) else: self.__filter.updateTexture3D( "lut3d_ocio_$ID_", lut3d) self.__texture3d_cacheID = texture3d_cacheID else: mari.app.log("OCIODisplay: No lut3d update required") def CreateOCIODisplayTransform(config, inputColorSpace, display, view, swizzle, fstopOffset, viewGamma): displayTransform = OCIO.DisplayTransform() displayTransform.setInputColorSpaceName( inputColorSpace ) displayColorSpace = config.getDisplayColorSpaceName(display, view) displayTransform.setDisplayColorSpaceName( displayColorSpace ) # Add the channel sizzle lumacoef = config.getDefaultLumaCoefs() mtx, offset = OCIO.MatrixTransform.View(swizzle, lumacoef) transform = OCIO.MatrixTransform() transform.setValue(mtx, offset) displayTransform.setChannelView(transform) # Add the linear fstop gain gain = 2**fstopOffset mtx, offset = OCIO.MatrixTransform.Scale((gain,gain,gain,gain)) transform = OCIO.MatrixTransform() transform.setValue(mtx, offset) displayTransform.setLinearCC(transform) # Add the post-display CC transform = OCIO.ExponentTransform() transform.setValue([1.0 / max(1e-6, v) for v in \ (viewGamma, viewGamma, viewGamma, viewGamma)]) displayTransform.setDisplayCC(transform) return displayTransform """ SWIZZLE_COLOR = (True, True, True, True) SWIZZLE_RED = (True, False, False, False) SWIZZLE_GREEN = (False, True, False, False) SWIZZLE_BLUE = (False, False, True, False) SWIZZLE_ALPHA = (False, False, False, True) SWIZZLE_LUMA = (True, True, True, False) Timings OCIO Setup: 0.5 ms OCIO 3D Lut creation: 14.7 ms Mari Setup: 21.3 ms Mari Texture Upload: 44.2 ms """ if __name__ == '__main__': if not hasattr(mari.gl_render,"createPostFilter"): mari.app.log("OCIODisplay: Error: This version of Mari does not support the mari.gl_render.createPostFilter API") else: if OCIO is not None: if CREATE_FLOATING: w = OCIODisplayUI() w.show() else: if WINDOW_NAME in mari.app.tabNames(): mari.app.removeTab(WINDOW_NAME) w = OCIODisplayUI() mari.app.addTab(WINDOW_NAME, w) opencolorio-1.1.0~dfsg0.orig/src/mari/prototype/ociofiletransform.py0000644000175000017500000000652513223553423024161 0ustar mfvmfv""" This script allows the loading of a specied lut (1d/3d/mtx) in the Mari Viewer. Requires Mari 1.3v2+. This example is not represntative of the final Mari OCIO workflow, merely an API demonstration. This code is a work in progress, to demonstrate the integration of OpenColorIO and Mari. The APIs this code relies on are subject to change at any time, and as such should not be relied on for production use (yet). LINUX testing instructions: * Build OCIO mkdir -p dist_mari mkdir -p build_mari && cd build_mari cmake -D CMAKE_BUILD_TYPE=Release \ -D CMAKE_INSTALL_PREFIX=../dist_mari \ -D PYTHON=/usr/bin/python2.6 \ -D OCIO_NAMESPACE=OpenColorIO_Mari \ ../ make install -j8 * Edit this file to point to use viewer lut you want to use * Run Mari with OpenColorIO added to the LD_LIBRARY_PATH, and Python env LD_LIBRARY_PATH=/dist_mari/lib/ PYTHONPATH=/dist_mari/lib/python2.6 mari * Source this script in the python console. Also - IMPORTANT - you must enable 'Use Color Correction' in the Color Manager. """ # YOU MUST CHANGE THIS TO MODIFY WHICH LUT TO USE LUT_FILENAME = "/shots/spi/home/lib/lut/dev/v29/luts/LC3DL_Kodak2383_Sony_GDM.3dl" LUT3D_SIZE = 32 import mari, time, os try: import PyOpenColorIO as OCIO print OCIO.__file__ except Exception,e: print "Error: Could not import OpenColorIO python bindings." print "Please confirm PYTHONPATH has dir containing PyOpenColorIO.so" def RegisterOCIOLut(): if not hasattr(mari.gl_render,"createPostFilter"): print "Error: This version of Mari does not support the mari.gl_render.createPostFilter API" return config = OCIO.Config() transform = OCIO.FileTransform(src = os.path.realpath(LUT_FILENAME), interpolation = OCIO.Constants.INTERP_LINEAR, direction = OCIO.Constants.TRANSFORM_DIR_FORWARD) processor = config.getProcessor(transform) shaderDesc = dict( [('language', OCIO.Constants.GPU_LANGUAGE_GLSL_1_3), ('functionName', 'display_ocio_$ID_'), ('lut3DEdgeLen', LUT3D_SIZE)] ) shaderText = processor.getGpuShaderText(shaderDesc) lut3d = processor.getGpuLut3D(shaderDesc) # Clear the existing color managment filter stack mari.gl_render.clearPostFilterStack() # Create variable pre-declarations desc = "sampler3D lut3d_ocio_$ID_;\n" desc += shaderText # Set the body of the filter body = "{ Out = display_ocio_$ID_(Out, lut3d_ocio_$ID_); }" # HACK: Increment a counter by 1 each time to force a refresh if not hasattr(mari, "ocio_lut_counter_hack"): mari.ocio_lut_counter_hack = 0 else: mari.ocio_lut_counter_hack += 1 ocio_lut_counter_hack = mari.ocio_lut_counter_hack # Create a new filter name = "OCIO %s v%d" % (os.path.basename(LUT_FILENAME), ocio_lut_counter_hack) postfilter = mari.gl_render.createPostFilter(name, desc, body) # Set the texture to use for the given sampler on this filter postfilter.setTexture3D("lut3d_ocio_$ID_", LUT3D_SIZE, LUT3D_SIZE, LUT3D_SIZE, postfilter.FORMAT_RGB, lut3d) # Append the filter to the end of the current list of filters mari.gl_render.appendPostFilter(postfilter) RegisterOCIOLut() opencolorio-1.1.0~dfsg0.orig/src/rv/0000755000175000017500000000000013223553423015504 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/rv/Packages/0000755000175000017500000000000013223553423017222 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/rv/Packages/rvinstall0000644000175000017500000000001413223553423021156 0ustar mfvmfv*ociorv.zip opencolorio-1.1.0~dfsg0.orig/src/rv/Packages/.gitignore0000644000175000017500000000001313223553423021204 0ustar mfvmfvociorv.zip opencolorio-1.1.0~dfsg0.orig/src/rv/Makefile0000644000175000017500000000016113223553423017142 0ustar mfvmfv.phony: all: ociorv.zip ociorv.zip: mkdir -p Packages zip Packages/ociorv.zip Python/ociorv.py Python/PACKAGE opencolorio-1.1.0~dfsg0.orig/src/rv/Python/0000755000175000017500000000000013223553423016765 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/rv/Python/ociorv.py0000644000175000017500000002153013223553423020641 0ustar mfvmfvimport time import itertools import contextlib import PyOpenColorIO as OCIO import rv from rv.commands import setStringProperty, setIntProperty, setFloatProperty @contextlib.contextmanager def timer(msg): start = time.time() yield end = time.time() print "%s: %.02fms" % (msg, (end-start)*1000) def set_lut(proc, nodename): """Given an PyOpenColorIO.Processor instance, create a LUT and sets it for the specified node """ if proc.isNoOp(): return if hasattr(proc, "hasChannelCrosstalk"): # Determine if transform has crosstalk, and switch 1D/3D based on this crosstalk = proc.hasChannelCrosstalk() else: # Assume crosstalk in lieu of latest OCIO Python bindings crosstalk = True # TODO: Maybe allow configuration of LUT sizes? size_1d = 2048 size_3d = 32 if crosstalk: _set_lut_3d(proc = proc, nodename = nodename, size = size_3d) else: _set_lut_1d(proc = proc, nodename = nodename, size = size_1d) # TODO: Can also set nodename.lut.inMatrix - could maybe avoid creating a # 3D LUT for linear transforms def _set_lut_3d(proc, nodename, size = 32): # FIXME: This clips with >1 scene-linear values, use allocation # vars # Make noop cube size_minus_one = float(size-1) one_axis = (x/size_minus_one for x in range(size)) cube_raw = itertools.product(one_axis, repeat=3) # Unpack and fix ordering, by turning [(0, 0, 0), (0, 0, 1), ...] # into [0, 0, 0, 1, 0, 0] as generator cube_raw = (item for sublist in cube_raw for item in sublist[::-1]) # Apply transform cube_processed = proc.applyRGB(cube_raw) # Set LUT type and size, then LUT values setStringProperty("%s.lut.type" % nodename, ["RGB"], False) setIntProperty("%s.lut.size" % nodename, [size, size, size], False) setFloatProperty("%s.lut.lut" % nodename, cube_processed, True) # Activate setIntProperty("%s.lut.active" % nodename, [1], False) def _set_lut_1d(proc, nodename, size = 1024): # TODO: Use allocation vars also # Make noop ramp def gen_noop_ramp(size): size_minus_one = float(size-1) for x in range(size): val = x/size_minus_one for i in range(3): yield val ramp_raw = gen_noop_ramp(size = size) # Apply transform # TODO: Make applyRGB accept an iterable, rather than requiring a # list, to avoid making the intermediate list ramp_transformed = proc.applyRGB(ramp_raw) # Set LUT type and size, then LUT values setStringProperty("%s.lut.type" % nodename, ["RGB"], False) setIntProperty("%s.lut.size" % nodename, [size], False) setFloatProperty("%s.lut.lut" % nodename, ramp_transformed, True) # Activate setIntProperty("%s.lut.active" % nodename, [1], False) def set_noop(nodename): """Just ensure sure the LUT is deactivated, in case source changes from switch from a non-noop to a noop processor """ is_active = False setIntProperty("%s.lut.active" % nodename, [is_active], False) def view_to_uistr(view): # sRGB/Film return "/".join(view) class PyMyStuffMode(rv.rvtypes.MinorMode): def set_display(self, event): avail = self.get_views() cur = self.active_view curindex = avail.index(cur) newindex = (curindex + 1) % len(avail) self.active_view = avail[newindex] rv.extra_commands.displayFeedback( "Changing display to %s" % view_to_uistr(self.active_view), 2.0, # timeout ) self.refresh() def get_cfg(self): return OCIO.GetCurrentConfig() def refresh(self): """Refresh LUT on all sources """ for src in rv.commands.nodesOfType("RVSource"): path = rv.commands.getStringProperty( "%s.media.movie" % src, 0, 99999999)[0] # defaultish arguments self._config_source(src = src, srcpath = path) def source_setup(self, event): # Event content example: # sourceGroup000001_source;;RVSource;;/path/to/myimg.exr print event.contents() args = event.contents().split(";;") src = args[0] srcpath = args[2] self._config_source(src = src, srcpath = srcpath) def _config_source(self, src, srcpath): filelut_node = rv.extra_commands.associatedNode("RVColor", src) looklut_node = rv.extra_commands.associatedNode("RVLookLUT", src) # Set 3D LUT, and activate cfg = self.get_cfg() # FIXME: Need a way to customise this per-facility without # modifying this file (try: import ociorv_custom_stuff ?) inspace = cfg.parseColorSpaceFromString(srcpath) test_transform = OCIO.DisplayTransform() test_transform.setInputColorSpaceName(inspace) display, view = self.active_view test_transform.setDisplay(display) test_transform.setView(view) try: test_proc = cfg.getProcessor(test_transform) except OCIO.Exception, e: print "INFO: Cannot create test OCIODisplay for %s - display LUT disabled. OCIO message was %s" % ( inspace, e) set_noop(nodename = filelut_node) set_noop(nodename = looklut_node) return if test_proc.isNoOp(): print "Source is NoOp" set_noop(nodename = filelut_node) set_noop(nodename = looklut_node) return # Input -> scene-linear processor. Allow grading controls etc # to work as expected try: input_proc = cfg.getProcessor(inspace, OCIO.Constants.ROLE_SCENE_LINEAR) except OCIO.Exception, e: # TODO: This mostly catches "3D Luts can only be applied # in the forward direction.", could handle this better print "INFO: Cannot linearise %s - display LUT disabled. OCIO message was %s" % ( inspace, e) set_noop(nodename = filelut_node) set_noop(nodename = looklut_node) return # Scene-linear -> output display transform transform = OCIO.DisplayTransform() transform.setDisplay(self.active_view[0]) transform.setView(self.active_view[1]) transform.setInputColorSpaceName(OCIO.Constants.ROLE_SCENE_LINEAR) try: output_proc = cfg.getProcessor(transform) except OCIO.Exception, e: print "INFO: Cannot apply scene-linear to %s - OCIO error was %s" % ( srcpath, e) set_noop(nodename = filelut_node) set_noop(nodename = looklut_node) return # LUT to be applied to input file, before any grading etc set_lut(proc = input_proc, nodename = filelut_node) # LUT after grading etc performed set_lut(proc = output_proc, nodename = looklut_node) # Update LUT rv.commands.updateLUT() def set_view(self, display, view): """Set view, and update all sources """ print "display: %s, view: %s" % (display, view) self.active_view = (display, view) self.refresh() def get_views(self): """Return [("sRGB", "Film"), ("sRGB", "Log"), ...] """ available_views = [] cfg = self.get_cfg() for a_display in cfg.getDisplays(): if a_display not in cfg.getActiveDisplays().split(", "): continue for a_view in cfg.getViews(a_display): if a_view not in cfg.getActiveViews(): continue available_views.append( (a_display, a_view)) return available_views def __init__(self): rv.rvtypes.MinorMode.__init__(self) mode_name = "ociorv-mode" global_bindings = [ ("key-down--d", self.set_display, "set display"), ("new-source", self.source_setup, "OCIO source setup"), ] local_bindings = [] # Create [("sRGB/Film", self.set_menu(...)), ("sRGB/Log", ...)] views_menu = [] for cur_view in self.get_views(): def set_view(event, cur_view = cur_view): display, view = cur_view self.set_view(display = display, view = view) mi = ( "/".join(cur_view), # label set_view, # actionHook ) views_menu.append(mi) # Set default view cfg = self.get_cfg() self.active_view = ( cfg.getDefaultDisplay(), cfg.getDefaultView(cfg.getDefaultDisplay())) # Construct top-level menu menu = [("OCIO", [ ("Display/Views", views_menu)])] self.init(mode_name, global_bindings, local_bindings, menu) def createMode(): return PyMyStuffMode() opencolorio-1.1.0~dfsg0.orig/src/rv/Python/PACKAGE0000644000175000017500000000024313223553423017742 0ustar mfvmfvpackage: OpenColorIO version: 1.0 rv: 3.12 requires: '' modes: - file: ociorv.py load: immediate description: | Integrates OCIO, and that's about it opencolorio-1.1.0~dfsg0.orig/src/rv/Mu/0000755000175000017500000000000013223553423016065 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/rv/Mu/rvload20000644000175000017500000000006513223553423017362 0ustar mfvmfv3 ociorv,ociorv.zip,nil,nil,nil,true,true,3.12,false opencolorio-1.1.0~dfsg0.orig/src/rv/Mu/rvload0000644000175000017500000000000213223553423017267 0ustar mfvmfv1 opencolorio-1.1.0~dfsg0.orig/src/jniglue/0000755000175000017500000000000013223553423016512 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/jniglue/org/0000755000175000017500000000000013223553423017301 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/0000755000175000017500000000000013223553423021431 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/LookTransform.java0000644000175000017500000000372413223553423025102 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class LookTransform extends Transform { public LookTransform() { super(); } protected LookTransform(long impl) { super(impl); } public native LookTransform Create(); public native String getSrc(); public native void setSrc(String src); public native String getDst(); public native void setDst(String dst); public native void setLooks(String looks); public native String getLooks(); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/Processor.java0000644000175000017500000000457213223553423024263 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; import java.nio.FloatBuffer; public class Processor extends LoadLibrary { public Processor() { super(); } protected Processor(long impl) { super(impl); } public native void dispose(); protected void finalize() { dispose(); } public native Processor Create(); public native boolean isNoOp(); public native boolean hasChannelCrosstalk(); public native void apply(ImageDesc img); public native void applyRGB(float[] pixel); public native void applyRGBA(float[] pixel); public native String getCpuCacheID(); public native String getGpuShaderText(GpuShaderDesc shaderDesc); public native String getGpuShaderTextCacheID(GpuShaderDesc shaderDesc); public native void getGpuLut3D(FloatBuffer lut3d, GpuShaderDesc shaderDesc); public native String getGpuLut3DCacheID(GpuShaderDesc shaderDesc); }; opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/ColorSpaceTransform.java0000644000175000017500000000363013223553423026224 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class ColorSpaceTransform extends Transform { public ColorSpaceTransform() { super(); } protected ColorSpaceTransform(long impl) { super(impl); } public native ColorSpaceTransform Create(); public native String getSrc(); public native void setSrc(String src); public native String getDst(); public native void setDst(String dst); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/Baker.java0000644000175000017500000000563313223553423023327 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class Baker extends LoadLibrary { public Baker() { super(); } protected Baker(long impl) { super(impl); } public native void dispose(); protected void finalize() { dispose(); } public native Baker Create(); public native Baker createEditableCopy(); public native void setConfig(Config config); public native Config getConfig(); public native void setFormat(String formatName); public native String getFormat(); public native void setType(String type); public native String getType(); public native void setMetadata(String metadata); public native String getMetadata(); public native void setInputSpace(String inputSpace); public native String getInputSpace(); public native void setShaperSpace(String shaperSpace); public native String getShaperSpace(); public native void setLooks(String looks); public native String getLooks(); public native void setTargetSpace(String targetSpace); public native String getTargetSpace(); public native void setShaperSize(int shapersize); public native int getShaperSize(); public native void setCubeSize(int cubesize); public native int getCubeSize(); public native String bake(); public native int getNumFormats(); public native String getFormatNameByIndex(int index); public native String getFormatExtensionByIndex(int index); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/ExceptionMissingFile.java0000644000175000017500000000325513223553423026371 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class ExceptionMissingFile extends ExceptionBase { public ExceptionMissingFile(String msg) { super(msg); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/Context.java0000644000175000017500000000515313223553423023724 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class Context extends LoadLibrary { public Context() { super(); } protected Context(long impl) { super(impl); } public native void dispose(); protected void finalize() { dispose(); } public native Context Create(); public native Context createEditableCopy(); public native String getCacheID(); public native void setSearchPath(String path); public native String getSearchPath(); public native void setWorkingDir(String dirname); public native String getWorkingDir(); public native void setStringVar(String name, String value); public native String getStringVar(String name); public native int getNumStringVars(); public native String getStringVarNameByIndex(int index); public native void clearStringVars(); public native void setEnvironmentMode(EnvironmentMode mode); public native EnvironmentMode getEnvironmentMode(); public native void loadEnvironment(); public native String resolveStringVar(String val); public native String resolveFileLocation(String filename) throws ExceptionMissingFile; } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/ExponentTransform.java0000644000175000017500000000352213223553423025772 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class ExponentTransform extends Transform { public ExponentTransform() { super(); } protected ExponentTransform(long impl) { super(impl); } public native ExponentTransform Create(); public native void setValue(float[] vec4); public native void getValue(float[] vec4); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/GroupTransform.java0000644000175000017500000000366513223553423025276 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class GroupTransform extends Transform { public GroupTransform() { super(); } protected GroupTransform(long impl) { super(impl); } public native GroupTransform Create(); public native Transform getTransform(int index); public native int size(); public native void push_back(Transform transform); public native void clear(); public native boolean empty(); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/MatrixTransform.java0000644000175000017500000000526113223553423025440 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class MatrixTransform extends Transform { public MatrixTransform() { super(); } protected MatrixTransform(long impl) { super(impl); } public native MatrixTransform Create(); public native boolean equals(MatrixTransform obj); public native void setValue(float[] m44, float[] offset4); public native void getValue(float[] m44, float[] offset4); public native void setMatrix(float[] m44); public native void getMatrix(float[] m44); public native void setOffset(float[] offset4); public native void getOffset(float[] offset4); public native void Fit(float[] m44, float[] offset4, float[] oldmin4, float[] oldmax4, float[] newmin4, float[] newmax4); public native void Identity(float[] m44, float[] offset4); public native void Sat(float[] m44, float[] offset4, float sat, float[] lumaCoef3); public native void Scale(float[] m44, float[] offset4, float[] scale4); public native void View(float[] m44, float[] offset4, int[] channelHot4, float[] lumaCoef3); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/PackedImageDesc.java0000644000175000017500000000541213223553423025227 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; import java.nio.FloatBuffer; public class PackedImageDesc extends ImageDesc { public PackedImageDesc(FloatBuffer data, long width, long height, long numChannels) { super(); create(data, width, height, numChannels); } public PackedImageDesc(FloatBuffer data, long width, long height, long numChannels, long chanStrideBytes, long xStrideBytes, long yStrideBytes) { super(); create(data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes); } protected PackedImageDesc(long impl) { super(impl); } protected native void create(FloatBuffer data, long width, long height, long numChannels); protected native void create(FloatBuffer data, long width, long height, long numChannels, long chanStrideBytes, long xStrideBytes, long yStrideBytes); public native void dispose(); protected void finalize() { dispose(); } public native FloatBuffer getData(); public native long getWidth(); public native long getHeight(); public native long getNumChannels(); public native long getChanStrideBytes(); public native long getXStrideBytes(); public native long getYStrideBytes(); }; opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/ExceptionBase.java0000644000175000017500000000324513223553423025031 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class ExceptionBase extends java.lang.Exception { public ExceptionBase(String msg) { super(msg); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/FileTransform.java0000644000175000017500000000422613223553423025053 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class FileTransform extends Transform { public FileTransform() { super(); } protected FileTransform(long impl) { super(impl); } public native FileTransform Create(); public native String getSrc(); public native void setSrc(String src); public native String getCCCId(); public native void setCCCId(String id); public native Interpolation getInterpolation(); public native void setInterpolation(Interpolation interp); public native int getNumFormats(); public native String getFormatNameByIndex(int index); public native String getFormatExtensionByIndex(int index); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/ColorSpaceDirection.java0000644000175000017500000000413413223553423026171 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class ColorSpaceDirection extends LoadLibrary { private final int m_enum; protected ColorSpaceDirection(int type) { super(); m_enum = type; } public native String toString(); public native boolean equals(Object obj); public static final ColorSpaceDirection COLORSPACE_DIR_UNKNOWN = new ColorSpaceDirection(0); public static final ColorSpaceDirection COLORSPACE_DIR_TO_REFERENCE = new ColorSpaceDirection(1); public static final ColorSpaceDirection COLORSPACE_DIR_FROM_REFERENCE = new ColorSpaceDirection(2); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/LoggingLevel.java0000644000175000017500000000431113223553423024651 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class LoggingLevel extends LoadLibrary { private final int m_enum; protected LoggingLevel(int type) { super(); m_enum = type; } public native String toString(); public native boolean equals(Object obj); public static final LoggingLevel LOGGING_LEVEL_NONE = new LoggingLevel(0); public static final LoggingLevel LOGGING_LEVEL_WARNING = new LoggingLevel(1); public static final LoggingLevel LOGGING_LEVEL_INFO = new LoggingLevel(2); public static final LoggingLevel LOGGING_LEVEL_DEBUG = new LoggingLevel(3); public static final LoggingLevel LOGGING_LEVEL_UNKNOWN = new LoggingLevel(255); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/AllocationTransform.java0000644000175000017500000000376413223553423026267 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class AllocationTransform extends Transform { public AllocationTransform() { super(); } protected AllocationTransform(long impl) { super(impl); } public native AllocationTransform Create(); public native Allocation getAllocation(); public native void setAllocation(Allocation allocation); public native int getNumVars(); public native void getVars(float[] vars); public native void setVars(int numvars, float[] vars); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/Look.java0000644000175000017500000000441513223553423023204 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class Look extends LoadLibrary { public Look() { super(); } protected Look(long impl) { super(impl); } public native void dispose(); protected void finalize() { dispose(); } public native Look Create(); public native String getName(); public native void setName(String name); public native String getProcessSpace(); public native void setProcessSpace(String processSpace); public native String getDescription(); public native void setDescription(String description); public native Transform getTransform(); public native void setTransform(Transform transform); public native Transform getInverseTransform(); public native void setInverseTransform(Transform transform); }; opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/ImageDesc.java0000644000175000017500000000326113223553423024117 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class ImageDesc extends LoadLibrary { public ImageDesc() { super(); } protected ImageDesc(long impl) { super(impl); } }; opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/Globals.java0000644000175000017500000000752213223553423023665 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class Globals extends LoadLibrary { public native void ClearAllCaches(); public native String GetVersion(); public native int GetVersionHex(); public native LoggingLevel GetLoggingLevel(); public native void SetLoggingLevel(LoggingLevel level); public native Config GetCurrentConfig(); public native void SetCurrentConfig(Config config); // Types public native String BoolToString(boolean val); public native boolean BoolFromString(String s); public native String LoggingLevelToString(LoggingLevel level); public native LoggingLevel LoggingLevelFromString(String s); public native String TransformDirectionToString(TransformDirection dir); public native TransformDirection TransformDirectionFromString(String s); public native TransformDirection GetInverseTransformDirection(TransformDirection dir); public native TransformDirection CombineTransformDirections(TransformDirection d1, TransformDirection d2); public native String ColorSpaceDirectionToString(ColorSpaceDirection dir); public native ColorSpaceDirection ColorSpaceDirectionFromString(String s); public native String BitDepthToString(BitDepth bitDepth); public native BitDepth BitDepthFromString(String s); public native boolean BitDepthIsFloat(BitDepth bitDepth); public native int BitDepthToInt(BitDepth bitDepth); public native String AllocationToString(Allocation allocation); public native Allocation AllocationFromString(String s); public native String InterpolationToString(Interpolation interp); public native Interpolation InterpolationFromString(String s); public native String GpuLanguageToString(GpuLanguage language); public native GpuLanguage GpuLanguageFromString(String s); public native String EnvironmentModeToString(EnvironmentMode mode); public native GpuLanguage EnvironmentModeFromString(String s); // Roles public String ROLE_DEFAULT; public String ROLE_REFERENCE; public String ROLE_DATA; public String ROLE_COLOR_PICKING; public String ROLE_SCENE_LINEAR; public String ROLE_COMPOSITING_LOG; public String ROLE_COLOR_TIMING; public String ROLE_TEXTURE_PAINT; public String ROLE_MATTE_PAINT; // public Globals() { super(); create(); } private native void create(); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/LogTransform.java0000644000175000017500000000345613223553423024721 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class LogTransform extends Transform { public LogTransform() { super(); } protected LogTransform(long impl) { super(impl); } public native LogTransform Create(); public native void setBase(float val); public native float getBase(); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/DisplayTransform.java0000644000175000017500000000516113223553423025600 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class DisplayTransform extends Transform { public DisplayTransform() { super(); } protected DisplayTransform(long impl) { super(impl); } public native DisplayTransform Create(); public native void setInputColorSpaceName(String name); public native String getInputColorSpaceName(); public native void setLinearCC(Transform cc); public native Transform getLinearCC(); public native void setColorTimingCC(Transform cc); public native Transform getColorTimingCC(); public native void setChannelView(Transform transform); public native Transform getChannelView(); public native void setDisplay(String display); public native String getDisplay(); public native void setView(String view); public native String getView(); public native void setDisplayCC(Transform cc); public native Transform getDisplayCC(); public native void setLooksOverride(String looks); public native String getLooksOverride(); public native void setLooksOverrideEnabled(boolean enabled); public native boolean getLooksOverrideEnabled(); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/BitDepth.java0000644000175000017500000000466413223553423024011 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class BitDepth extends LoadLibrary { private final int m_enum; protected BitDepth(int type) { super(); m_enum = type; } public native String toString(); public native boolean equals(Object obj); public static final BitDepth BIT_DEPTH_UNKNOWN = new BitDepth(0); public static final BitDepth BIT_DEPTH_UINT8 = new BitDepth(1); public static final BitDepth BIT_DEPTH_UINT10 = new BitDepth(2); public static final BitDepth BIT_DEPTH_UINT12 = new BitDepth(3); public static final BitDepth BIT_DEPTH_UINT14 = new BitDepth(4); public static final BitDepth BIT_DEPTH_UINT16 = new BitDepth(5); public static final BitDepth BIT_DEPTH_UINT32 = new BitDepth(6); public static final BitDepth BIT_DEPTH_F16 = new BitDepth(7); public static final BitDepth BIT_DEPTH_F32 = new BitDepth(8); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/ColorSpace.java0000644000175000017500000000547113223553423024335 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class ColorSpace extends LoadLibrary { public ColorSpace() { super(); } protected ColorSpace(long impl) { super(impl); } public native void dispose(); protected void finalize() { dispose(); } public native ColorSpace Create(); public native ColorSpace createEditableCopy(); public native String getName(); public native void setName(String name); public native String getFamily(); public native void setFamily(String family); public native String getEqualityGroup(); public native void setEqualityGroup(String equalityGroup); public native String getDescription(); public native void setDescription(String description); public native BitDepth getBitDepth(); public native void setBitDepth(BitDepth bitDepth); public native boolean isData(); public native void setIsData(boolean isData); public native Allocation getAllocation(); public native void setAllocation(Allocation allocation); public native int getAllocationNumVars(); public native void getAllocationVars(float[] vars); public native void setAllocationVars(int numvars, float[] vars); public native Transform getTransform(ColorSpaceDirection dir); public native void setTransform(Transform transform, ColorSpaceDirection dir); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/GpuShaderDesc.java0000644000175000017500000000417513223553423024764 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class GpuShaderDesc extends LoadLibrary { public GpuShaderDesc() { super(); create(); } protected GpuShaderDesc(long impl) { super(impl); } private native void create(); public native void dispose(); protected void finalize() { dispose(); } public native void setLanguage(GpuLanguage lang); public native GpuLanguage getLanguage(); public native void setFunctionName(String name); public native String getFunctionName(); public native void setLut3DEdgeLen(int len); public native int getLut3DEdgeLen(); public native String getCacheID(); }; opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/GpuLanguage.java0000644000175000017500000000413413223553423024475 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class GpuLanguage extends LoadLibrary { private final int m_enum; protected GpuLanguage(int type) { super(); m_enum = type; } public native String toString(); public native boolean equals(Object obj); public static final GpuLanguage GPU_LANGUAGE_UNKNOWN = new GpuLanguage(0); public static final GpuLanguage GPU_LANGUAGE_CG = new GpuLanguage(1); public static final GpuLanguage GPU_LANGUAGE_GLSL_1_0 = new GpuLanguage(2); public static final GpuLanguage GPU_LANGUAGE_GLSL_1_3 = new GpuLanguage(3); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/TruelightTransform.java0000644000175000017500000000521313223553423026140 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class TruelightTransform extends Transform { public TruelightTransform() { super(); } protected TruelightTransform(long impl) { super(impl); } public native TruelightTransform Create(); public native void setConfigRoot(String configroot); public native String getConfigRoot(); public native void setProfile(String profile); public native String getProfile(); public native void setCamera(String camera); public native String getCamera(); public native void setInputDisplay(String display); public native String getInputDisplay(); public native void setRecorder(String recorder); public native String getRecorder(); public native void setPrint(String print); public native String getPrint(); public native void setLamp(String lamp); public native String getLamp(); public native void setOutputCamera(String camera); public native String getOutputCamera(); public native void setDisplay(String display); public native String getDisplay(); public native void setCubeInput(String type); public native String getCubeInput(); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/PlanarImageDesc.java0000644000175000017500000000570213223553423025257 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; import java.nio.FloatBuffer; public class PlanarImageDesc extends ImageDesc { public PlanarImageDesc(FloatBuffer rData, FloatBuffer gData, FloatBuffer bData, FloatBuffer aData, long width, long height) { super(); create(rData, gData, bData, aData, width, height); } public PlanarImageDesc(FloatBuffer rData, FloatBuffer gData, FloatBuffer bData, FloatBuffer aData, long width, long height, long yStrideBytes) { super(); create(rData, gData, bData, aData, width, height, yStrideBytes); } protected PlanarImageDesc(long impl) { super(impl); } public native void dispose(); protected void finalize() { dispose(); } protected native void create(FloatBuffer rData, FloatBuffer gData, FloatBuffer bData, FloatBuffer aData, long width, long height); protected native void create(FloatBuffer rData, FloatBuffer gData, FloatBuffer bData, FloatBuffer aData, long width, long height, long yStrideBytes); public native FloatBuffer getRData(); public native FloatBuffer getGData(); public native FloatBuffer getBData(); public native FloatBuffer getAData(); public native long getWidth(); public native long getHeight(); public native long getYStrideBytes(); }; opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/CDLTransform.java0000644000175000017500000000510613223553423024574 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class CDLTransform extends Transform { public CDLTransform() { super(); } protected CDLTransform(long impl) { super(impl); } public native CDLTransform Create(); public native CDLTransform CreateFromFile(String src, String cccid); public native boolean equals(CDLTransform obj); public native String getXML(); public native void setXML(String xml); public native void setSlope(float[] rgb); public native void getSlope(float[] rgb); public native void setOffset(float[] rgb); public native void getOffset(float[] rgb); public native void setPower(float[] rgb); public native void getPower(float[] rgb); public native void setSOP(float[] vec9); public native void getSOP(float[] vec9); public native void setSat(float sat); public native float getSat(); public native void getSatLumaCoefs(float[] rgb); public native void setID(String id); public native String getID(); public native void setDescription(String desc); public native String getDescription(); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/TransformDirection.java0000644000175000017500000000411313223553423026107 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class TransformDirection extends LoadLibrary { private final int m_enum; protected TransformDirection(int type) { super(); m_enum = type; } public native String toString(); public native boolean equals(Object obj); public static final TransformDirection TRANSFORM_DIR_UNKNOWN = new TransformDirection(0); public static final TransformDirection TRANSFORM_DIR_FORWARD = new TransformDirection(1); public static final TransformDirection TRANSFORM_DIR_INVERSE = new TransformDirection(2); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/Allocation.java0000644000175000017500000000377613223553423024376 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class Allocation extends LoadLibrary { private final int m_enum; protected Allocation(int type) { super(); m_enum = type; } public native String toString(); public native boolean equals(Object obj); public static final Allocation ALLOCATION_UNKNOWN = new Allocation(0); public static final Allocation ALLOCATION_UNIFORM = new Allocation(1); public static final Allocation ALLOCATION_LG2 = new Allocation(2); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/Config.java0000644000175000017500000001237513223553423023511 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class Config extends LoadLibrary { public Config() { super(); } protected Config(long impl) { super(impl); } public native void dispose(); protected void finalize() { dispose(); } public native Config Create(); public native Config CreateFromEnv(); public native Config CreateFromFile(String filename); public native Config CreateFromStream(String istream); public native Config createEditableCopy(); public native void sanityCheck(); public native String getDescription(); public native void setDescription(String description); public native String serialize(); public native String getCacheID(); public native String getCacheID(Context context); public native Context getCurrentContext(); public native void addEnvironmentVar(String name, String defaultValue); public native int getNumEnvironmentVars(); public native String getEnvironmentVarNameByIndex(int index); public native String getEnvironmentVarDefault(String name); public native void clearEnvironmentVars(); public native String getSearchPath(); public native void setSearchPath(String path); public native String getWorkingDir(); public native void setWorkingDir(String dirname); public native int getNumColorSpaces(); public native String getColorSpaceNameByIndex(int index); public native ColorSpace getColorSpace(String name); public native int getIndexForColorSpace(String name); public native void addColorSpace(ColorSpace cs); public native void clearColorSpaces(); public native String parseColorSpaceFromString(String str); public native boolean isStrictParsingEnabled(); public native void setStrictParsingEnabled(boolean enabled); public native void setRole(String role, String colorSpaceName); public native int getNumRoles(); public native boolean hasRole(String role); public native String getRoleName(int index); public native String getDefaultDisplay(); public native int getNumDisplays(); public native String getDisplay(int index); public native String getDefaultView(String display); public native int getNumViews(String display); public native String getView(String display, int index); public native String getDisplayColorSpaceName(String display, String view); public native String getDisplayLooks(String display, String view); // TODO: seems that 4 string params causes a memory error in the JNI layer? // public native void addDisplay(String display, String view, String colorSpaceName, int looks); public native void clearDisplays(); public native void setActiveDisplays(String displays); public native String getActiveDisplays(); public native void setActiveViews(String views); public native String getActiveViews(); public native void getDefaultLumaCoefs(float[] rgb); public native void setDefaultLumaCoefs(float[] rgb); public native Look getLook(String name); public native int getNumLooks(); public native String getLookNameByIndex(int index); public native void addLook(Look look); public native void clearLooks(); public native Processor getProcessor(Context context, ColorSpace srcColorSpace, ColorSpace dstColorSpace); public native Processor getProcessor(ColorSpace srcColorSpace, ColorSpace dstColorSpace); public native Processor getProcessor(String srcName, String dstName); public native Processor getProcessor(Context context, String srcName, String dstName); public native Processor getProcessor(Transform transform); public native Processor getProcessor(Transform transform, TransformDirection direction); public native Processor getProcessor(Context context, Transform transform, TransformDirection direction); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/Interpolation.java0000644000175000017500000000427213223553423025130 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class Interpolation extends LoadLibrary { private final int m_enum; protected Interpolation(int type) { super(); m_enum = type; } public native String toString(); public native boolean equals(Object obj); public static final Interpolation INTERP_UNKNOWN = new Interpolation(0); public static final Interpolation INTERP_NEAREST = new Interpolation(1); public static final Interpolation INTERP_LINEAR = new Interpolation(2); public static final Interpolation INTERP_TETRAHEDRAL = new Interpolation(3); public static final Interpolation INTERP_BEST = new Interpolation(255); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/org/OpenColorIO/Transform.java0000644000175000017500000000364313223553423024255 0ustar mfvmfv/* 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. */ package org.OpenColorIO; import org.OpenColorIO.*; public class Transform extends LoadLibrary { public Transform() { super(); } protected Transform(long impl) { super(impl); } public native void dispose(); protected void finalize() { dispose(); } public native Transform createEditableCopy(); public native TransformDirection getDirection(); public native void setDirection(TransformDirection dir); } opencolorio-1.1.0~dfsg0.orig/src/jniglue/CMakeLists.txt0000644000175000017500000000664213223553423021262 0ustar mfvmfv include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/export/ ${CMAKE_BINARY_DIR}/export/ ${JNI_INCLUDE_DIRS} ) set(JNIOCIO_CLASSES # Core org.OpenColorIO.ExceptionBase org.OpenColorIO.ExceptionMissingFile org.OpenColorIO.Globals org.OpenColorIO.Config org.OpenColorIO.ColorSpace org.OpenColorIO.Processor org.OpenColorIO.GpuShaderDesc org.OpenColorIO.Context org.OpenColorIO.Look org.OpenColorIO.ImageDesc org.OpenColorIO.Transform org.OpenColorIO.PackedImageDesc org.OpenColorIO.PlanarImageDesc org.OpenColorIO.Baker # Enums org.OpenColorIO.LoggingLevel org.OpenColorIO.ColorSpaceDirection org.OpenColorIO.TransformDirection org.OpenColorIO.Interpolation org.OpenColorIO.BitDepth org.OpenColorIO.Allocation org.OpenColorIO.GpuLanguage org.OpenColorIO.EnvironmentMode # Transforms org.OpenColorIO.AllocationTransform org.OpenColorIO.CDLTransform org.OpenColorIO.ColorSpaceTransform org.OpenColorIO.DisplayTransform org.OpenColorIO.ExponentTransform org.OpenColorIO.FileTransform org.OpenColorIO.GroupTransform org.OpenColorIO.LogTransform org.OpenColorIO.LookTransform org.OpenColorIO.MatrixTransform org.OpenColorIO.TruelightTransform ) file(GLOB JNIOCIO_JAVAS "org/OpenColorIO/*.java") message(STATUS "Creating Jar Manifest.txt") configure_file(${CMAKE_SOURCE_DIR}/src/jniglue/Manifest.txt.in ${CMAKE_CURRENT_BINARY_DIR}/Manifest.txt @ONLY) message(STATUS "Creating LoadLibrary.java") configure_file(${CMAKE_SOURCE_DIR}/src/jniglue/LoadLibrary.java.in ${CMAKE_CURRENT_BINARY_DIR}/LoadLibrary.java @ONLY) list(APPEND JNIOCIO_JAVAS ${CMAKE_CURRENT_BINARY_DIR}/LoadLibrary.java) set(JNIOCIO_HEADERS) set(JNIOCIO_H_INCLUDE "/* DO NOT EDIT THIS FILE - it is machine generated */\n\n") foreach(_CLASS ${JNIOCIO_CLASSES}) string(REPLACE "." "_" _CLASS_H ${_CLASS}) set(_CLASS_H "${_CLASS_H}.h") set(JNIOCIO_HEADERS ${JNIOCIO_HEADERS} "${_CLASS_H}") set(JNIOCIO_H_INCLUDE "${JNIOCIO_H_INCLUDE}#include \"${_CLASS_H}\"\n") endforeach() message(STATUS "Creating OpenColorIOJNI.h that includes all the ocio jni headers") file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/OpenColorIOJNI.h" "${JNIOCIO_H_INCLUDE}") set(JNIOCIO_JAR "${CMAKE_CURRENT_BINARY_DIR}/OpenColorIO-${OCIO_VERSION}.jar") add_custom_command(OUTPUT ${JNIOCIO_HEADERS} COMMAND cmake -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/org/OpenColorIO COMMAND ${Java_JAVAC_EXECUTABLE} -cp ${CMAKE_CURRENT_BINARY_DIR} -d ${CMAKE_CURRENT_BINARY_DIR} ${JNIOCIO_JAVAS} COMMAND ${Java_JAVAH_EXECUTABLE} -jni -force ${JNIOCIO_CLASSES} COMMAND ${Java_JAR_EXECUTABLE} vcfm ${JNIOCIO_JAR} Manifest.txt org IMPLICIT_DEPENDS ${JNIOCIO_JAVAS} COMMENT "Compiling .java files, packaged .jar and creating jni C headers") file(GLOB JNIOCIO_SRC "*.cpp") add_library(OpenColorIO-JNI SHARED ${JNIOCIO_SRC} ${JNIOCIO_HEADERS}) set_target_properties(OpenColorIO-JNI PROPERTIES VERSION ${OCIO_VERSION} SOVERSION ${SOVERSION}) if(OCIO_STATIC_JNIGLUE) target_link_libraries(OpenColorIO-JNI OpenColorIO_STATIC) else() target_link_libraries(OpenColorIO-JNI OpenColorIO) endif() add_subdirectory(tests) install(TARGETS OpenColorIO-JNI EXPORT OpenColorIO DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib${LIB_SUFFIX}) install(FILES ${JNIOCIO_JAR} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/ocio/) opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNIUtil.h0000644000175000017500000002306013223553423020142 0ustar mfvmfv/* 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_OCIO_JNIUTIL_H #define INCLUDED_OCIO_JNIUTIL_H #include #include #include "OpenColorIOJNI.h" OCIO_NAMESPACE_ENTER { template struct JObject { jobject back_ptr; C * constcppobj; E * cppobj; bool isconst; }; typedef OCIO_SHARED_PTR ConstGpuShaderDescRcPtr; typedef OCIO_SHARED_PTR GpuShaderDescRcPtr; typedef OCIO_SHARED_PTR ConstImageDescRcPtr; typedef OCIO_SHARED_PTR ImageDescRcPtr; typedef OCIO_SHARED_PTR ConstPackedImageDescRcPtr; typedef OCIO_SHARED_PTR PackedImageDescRcPtr; typedef OCIO_SHARED_PTR ConstPlanarImageDescRcPtr; typedef OCIO_SHARED_PTR PlanarImageDescRcPtr; typedef JObject ConfigJNI; typedef JObject ContextJNI; typedef JObject ProcessorJNI; typedef JObject ColorSpaceJNI; typedef JObject LookJNI; typedef JObject BakerJNI; typedef JObject GpuShaderDescJNI; typedef JObject ImageDescJNI; typedef JObject TransformJNI; typedef JObject AllocationTransformJNI; typedef JObject CDLTransformJNI; typedef JObject ColorSpaceTransformJNI; typedef JObject DisplayTransformJNI; typedef JObject ExponentTransformJNI; typedef JObject FileTransformJNI; typedef JObject GroupTransformJNI; typedef JObject LogTransformJNI; typedef JObject LookTransformJNI; typedef JObject MatrixTransformJNI; typedef JObject TruelightTransformJNI; template inline jobject BuildJConstObject(JNIEnv * env, jobject self, jclass cls, T ptr) { S * jnistruct = new S (); jnistruct->back_ptr = env->NewGlobalRef(self); jnistruct->constcppobj = new T (); *jnistruct->constcppobj = ptr; jnistruct->isconst = true; jmethodID mid = env->GetMethodID(cls, "", "(J)V"); return env->NewObject(cls, mid, (jlong)jnistruct); } template inline jobject BuildJObject(JNIEnv * env, jobject self, jclass cls, T ptr) { S * jnistruct = new S (); jnistruct->back_ptr = env->NewGlobalRef(self); jnistruct->cppobj = new T (); *jnistruct->cppobj = ptr; jnistruct->isconst = false; jmethodID mid = env->GetMethodID(cls, "", "(J)V"); return env->NewObject(cls, mid, (jlong)jnistruct); } template inline void DisposeJOCIO(JNIEnv * env, jobject self) { jclass wclass = env->GetObjectClass(self); jfieldID fid = env->GetFieldID(wclass, "m_impl", "J"); jlong m_impl = env->GetLongField(self, fid); if(m_impl == 0) return; // nothing to do S * jni = reinterpret_cast (m_impl); delete jni->constcppobj; delete jni->cppobj; env->DeleteGlobalRef(jni->back_ptr); delete jni; env->SetLongField(self, fid, 0); return; } template inline T GetConstJOCIO(JNIEnv * env, jobject self) { jclass wclass = env->GetObjectClass(self); jfieldID fid = env->GetFieldID(wclass, "m_impl", "J"); jlong m_impl = env->GetLongField(self, fid); if(m_impl == 0) { throw Exception("Java object doesn't point to a OCIO object"); } S * jni = reinterpret_cast (m_impl); if(jni->isconst && jni->constcppobj) { return *jni->constcppobj; } if(!jni->isconst && jni->cppobj) { return *jni->cppobj; } throw Exception("Could not get a const OCIO object"); } template inline T GetEditableJOCIO(JNIEnv * env, jobject self) { jclass wclass = env->GetObjectClass(self); jfieldID fid = env->GetFieldID(wclass, "m_impl", "J"); jlong m_impl = env->GetLongField(self, fid); if(m_impl == 0) { throw Exception("Java object doesn't point to a OCIO object"); } S * jni = reinterpret_cast (m_impl); if(!jni->isconst && jni->cppobj) { return *jni->cppobj; } throw Exception("Could not get an editable OCIO object"); } template inline T GetJEnum(JNIEnv * env, jobject j_enum) { jclass cls = env->GetObjectClass(j_enum); jfieldID fid = env->GetFieldID(cls, "m_enum", "I"); return (T)env->GetIntField(j_enum, fid); } template inline jobject BuildJEnum(JNIEnv * env, const char* ociotype, T val) { jclass cls = env->FindClass(ociotype); jmethodID mid = env->GetMethodID(cls, "", "(I)V"); return env->NewObject(cls, mid, (int)val); } template inline void CheckArrayLength(JNIEnv * env, const char* name, T ptr, int32_t length) { if(ptr == NULL) return; if(env->GetArrayLength(ptr) < length) { std::ostringstream err; err << name << " needs to have " << length; err << " elements but found only " << env->GetArrayLength(ptr); throw Exception(err.str().c_str()); } } class GetJFloatArrayValue { public: GetJFloatArrayValue(JNIEnv* env, jfloatArray val, const char* name, int32_t len) { CheckArrayLength(env, name, val, len); m_env = env; m_val = val; if(val != NULL) m_ptr = env->GetFloatArrayElements(val, JNI_FALSE); } ~GetJFloatArrayValue() { if(m_val != NULL) m_env->ReleaseFloatArrayElements(m_val, m_ptr, JNI_FALSE); m_val = NULL; m_ptr = NULL; } jfloat* operator() () { return m_ptr; } private: JNIEnv* m_env; jfloat* m_ptr; jfloatArray m_val; }; class SetJFloatArrayValue { public: SetJFloatArrayValue(JNIEnv* env, jfloatArray val, const char* name, int32_t len) { CheckArrayLength(env, name, val, len); m_env = env; m_val = val; if(val != NULL) m_tmp.resize(len); } ~SetJFloatArrayValue() { if(m_val != NULL) m_env->SetFloatArrayRegion(m_val, 0, m_tmp.size(), &m_tmp[0]); m_val = NULL; m_tmp.clear(); } float* operator() () { return &m_tmp[0]; } private: JNIEnv* m_env; std::vector m_tmp; jfloatArray m_val; }; class GetJIntArrayValue { public: GetJIntArrayValue(JNIEnv* env, jintArray val, const char* name, int32_t len) { CheckArrayLength(env, name, val, len); m_env = env; m_val = val; if(val != NULL) m_ptr = env->GetIntArrayElements(val, JNI_FALSE); } ~GetJIntArrayValue() { if(m_val != NULL) m_env->ReleaseIntArrayElements(m_val, m_ptr, JNI_FALSE); m_val = NULL; m_ptr = NULL; } jint* operator() () { return m_ptr; } private: JNIEnv* m_env; jint* m_ptr; jintArray m_val; }; class GetJStringValue { public: GetJStringValue(JNIEnv* env, jstring val) { m_env = env; m_val = val; if(val != NULL) m_tmp = env->GetStringUTFChars(m_val, 0); } ~GetJStringValue() { if(m_val != NULL) m_env->ReleaseStringUTFChars(m_val, m_tmp); m_val = NULL; m_tmp = NULL; } const char* operator() () { return m_tmp; } private: JNIEnv* m_env; const char* m_tmp; jstring m_val; }; jobject NewJFloatBuffer(JNIEnv * env, float* ptr, int32_t len); float* GetJFloatBuffer(JNIEnv * env, jobject buffer, int32_t len); const char* GetOCIOTClass(ConstTransformRcPtr tran); void JNI_Handle_Exception(JNIEnv * env); #define OCIO_JNITRY_ENTER() try { #define OCIO_JNITRY_EXIT(ret) } catch(...) { JNI_Handle_Exception(env); return ret; } } OCIO_NAMESPACE_EXIT #endif // INCLUDED_OCIO_JNIUTIL_H opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNIGlobals.cpp0000644000175000017500000003600213223553423021143 0ustar mfvmfv/* 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 "OpenColorIO/OpenColorIO.h" #include "OpenColorIOJNI.h" #include "JNIUtil.h" OCIO_NAMESPACE_USING JNIEXPORT void JNICALL Java_org_OpenColorIO_Globals_create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() jfieldID fid; jclass wclass = env->GetObjectClass(self); fid = env->GetFieldID(wclass, "ROLE_DEFAULT", "Ljava/lang/String;"); env->SetObjectField(self, fid, env->NewStringUTF(ROLE_DEFAULT)); fid = env->GetFieldID(wclass, "ROLE_REFERENCE", "Ljava/lang/String;"); env->SetObjectField(self, fid, env->NewStringUTF(ROLE_REFERENCE)); fid = env->GetFieldID(wclass, "ROLE_DATA", "Ljava/lang/String;"); env->SetObjectField(self, fid, env->NewStringUTF(ROLE_DATA)); fid = env->GetFieldID(wclass, "ROLE_COLOR_PICKING", "Ljava/lang/String;"); env->SetObjectField(self, fid, env->NewStringUTF(ROLE_COLOR_PICKING)); fid = env->GetFieldID(wclass, "ROLE_SCENE_LINEAR", "Ljava/lang/String;"); env->SetObjectField(self, fid, env->NewStringUTF(ROLE_SCENE_LINEAR)); fid = env->GetFieldID(wclass, "ROLE_COMPOSITING_LOG", "Ljava/lang/String;"); env->SetObjectField(self, fid, env->NewStringUTF(ROLE_COMPOSITING_LOG)); fid = env->GetFieldID(wclass, "ROLE_COLOR_TIMING", "Ljava/lang/String;"); env->SetObjectField(self, fid, env->NewStringUTF(ROLE_COLOR_TIMING)); fid = env->GetFieldID(wclass, "ROLE_TEXTURE_PAINT", "Ljava/lang/String;"); env->SetObjectField(self, fid, env->NewStringUTF(ROLE_TEXTURE_PAINT)); fid = env->GetFieldID(wclass, "ROLE_MATTE_PAINT", "Ljava/lang/String;"); env->SetObjectField(self, fid, env->NewStringUTF(ROLE_MATTE_PAINT)); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_Globals_ClearAllCaches(JNIEnv * env, jobject) { OCIO_JNITRY_ENTER() ClearAllCaches(); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Globals_GetVersion(JNIEnv * env, jobject) { OCIO_JNITRY_ENTER() return env->NewStringUTF(GetVersion()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Globals_GetVersionHex(JNIEnv * env, jobject) { OCIO_JNITRY_ENTER() return (jint)GetVersionHex(); OCIO_JNITRY_EXIT(-1) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_GetLoggingLevel(JNIEnv * env, jobject) { OCIO_JNITRY_ENTER() return BuildJEnum(env, "org/OpenColorIO/LoggingLevel", GetLoggingLevel()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Globals_SetLoggingLevel(JNIEnv * env, jobject, jobject level) { OCIO_JNITRY_ENTER() SetLoggingLevel(GetJEnum(env, level)); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_GetCurrentConfig(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() jobject obj = BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Config"), GetCurrentConfig()); return obj; OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Globals_SetCurrentConfig(JNIEnv * env, jobject, jobject config) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, config); SetCurrentConfig(cfg); OCIO_JNITRY_EXIT() } // Bool JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Globals_BoolToString(JNIEnv * env, jobject, jboolean val) { OCIO_JNITRY_ENTER() return env->NewStringUTF(BoolToString((bool)val)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_Globals_BoolFromString(JNIEnv * env, jobject, jstring s) { OCIO_JNITRY_ENTER() return (jboolean)BoolFromString(GetJStringValue(env, s)()); OCIO_JNITRY_EXIT(false) } // LoggingLevel JNIEXPORT jstring JNICALL Java_org_OpenColorIO_LoggingLevel_toString(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return env->NewStringUTF( LoggingLevelToString(GetJEnum(env, self))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_LoggingLevel_equals(JNIEnv * env, jobject self, jobject obj) { OCIO_JNITRY_ENTER() return GetJEnum(env, self) == GetJEnum(env, obj); OCIO_JNITRY_EXIT(false) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Globals_LoggingLevelToString(JNIEnv * env, jobject, jobject level) { OCIO_JNITRY_ENTER() return env->NewStringUTF( LoggingLevelToString(GetJEnum(env, level))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_LoggingLevelFromString(JNIEnv * env, jobject, jstring s) { OCIO_JNITRY_ENTER() return BuildJEnum(env, "org/OpenColorIO/LoggingLevel", LoggingLevelFromString(GetJStringValue(env, s)())); OCIO_JNITRY_EXIT(NULL) } // TransformDirection JNIEXPORT jstring JNICALL Java_org_OpenColorIO_TransformDirection_toString(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return env->NewStringUTF( TransformDirectionToString(GetJEnum(env, self))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_TransformDirection_equals(JNIEnv * env, jobject self, jobject obj) { OCIO_JNITRY_ENTER() return GetJEnum(env, self) == GetJEnum(env, obj); OCIO_JNITRY_EXIT(false) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Globals_TransformDirectionToString(JNIEnv * env, jobject, jobject dir) { OCIO_JNITRY_ENTER() return env->NewStringUTF( TransformDirectionToString(GetJEnum(env, dir))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_TransformDirectionFromString(JNIEnv * env, jobject, jstring s) { OCIO_JNITRY_ENTER() return BuildJEnum(env, "org/OpenColorIO/TransformDirection", TransformDirectionFromString(GetJStringValue(env, s)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_GetInverseTransformDirection(JNIEnv * env, jobject, jobject dir) { OCIO_JNITRY_ENTER() return BuildJEnum(env, "org/OpenColorIO/TransformDirection", GetInverseTransformDirection(GetJEnum(env, dir))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_CombineTransformDirections(JNIEnv * env, jobject, jobject d1, jobject d2) { OCIO_JNITRY_ENTER() return BuildJEnum(env, "org/OpenColorIO/TransformDirection", CombineTransformDirections(GetJEnum(env, d1), GetJEnum(env, d2))); OCIO_JNITRY_EXIT(NULL) } // ColorSpaceDirection JNIEXPORT jstring JNICALL Java_org_OpenColorIO_ColorSpaceDirection_toString(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return env->NewStringUTF( ColorSpaceDirectionToString(GetJEnum(env, self))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_ColorSpaceDirection_equals(JNIEnv * env, jobject self, jobject obj) { OCIO_JNITRY_ENTER() return GetJEnum(env, self) == GetJEnum(env, obj); OCIO_JNITRY_EXIT(false) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Globals_ColorSpaceDirectionToString(JNIEnv * env, jobject, jobject dir) { OCIO_JNITRY_ENTER() return env->NewStringUTF( ColorSpaceDirectionToString(GetJEnum(env, dir))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_ColorSpaceDirectionFromString(JNIEnv * env, jobject, jstring s) { OCIO_JNITRY_ENTER() return BuildJEnum(env, "org/OpenColorIO/ColorSpaceDirection", ColorSpaceDirectionFromString(GetJStringValue(env, s)())); OCIO_JNITRY_EXIT(NULL) } // BitDepth JNIEXPORT jstring JNICALL Java_org_OpenColorIO_BitDepth_toString(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return env->NewStringUTF( BitDepthToString(GetJEnum(env, self))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_BitDepth_equals(JNIEnv * env, jobject self, jobject obj) { OCIO_JNITRY_ENTER() return GetJEnum(env, self) == GetJEnum(env, obj); OCIO_JNITRY_EXIT(false) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Globals_BitDepthToString(JNIEnv * env, jobject, jobject bitDepth) { OCIO_JNITRY_ENTER() return env->NewStringUTF( BitDepthToString(GetJEnum(env, bitDepth))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_BitDepthFromString(JNIEnv * env, jobject, jstring s) { OCIO_JNITRY_ENTER() return BuildJEnum(env, "org/OpenColorIO/BitDepth", BitDepthFromString(GetJStringValue(env, s)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_Globals_BitDepthIsFloat(JNIEnv * env, jobject, jobject bitDepth) { OCIO_JNITRY_ENTER() return (jboolean)BitDepthIsFloat(GetJEnum(env, bitDepth)); OCIO_JNITRY_EXIT(false) } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Globals_BitDepthToInt(JNIEnv * env, jobject, jobject bitDepth) { OCIO_JNITRY_ENTER() return (jint) BitDepthToInt(GetJEnum(env, bitDepth)); OCIO_JNITRY_EXIT(-1) } // Allocation JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Allocation_toString(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return env->NewStringUTF( AllocationToString(GetJEnum(env, self))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_Allocation_equals(JNIEnv * env, jobject self, jobject obj) { OCIO_JNITRY_ENTER() return GetJEnum(env, self) == GetJEnum(env, obj); OCIO_JNITRY_EXIT(false) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Globals_AllocationToString(JNIEnv * env, jobject, jobject allocation) { OCIO_JNITRY_ENTER() return env->NewStringUTF( AllocationToString(GetJEnum(env, allocation))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_AllocationFromString(JNIEnv * env, jobject, jstring s) { OCIO_JNITRY_ENTER() return BuildJEnum(env, "org/OpenColorIO/Allocation", AllocationFromString(GetJStringValue(env, s)())); OCIO_JNITRY_EXIT(NULL) } // Interpolation JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Interpolation_toString(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return env->NewStringUTF( InterpolationToString(GetJEnum(env, self))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_Interpolation_equals(JNIEnv * env, jobject self, jobject obj) { OCIO_JNITRY_ENTER() return GetJEnum(env, self) == GetJEnum(env, obj); OCIO_JNITRY_EXIT(false) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Globals_InterpolationToString(JNIEnv * env, jobject, jobject interp) { OCIO_JNITRY_ENTER() return env->NewStringUTF( InterpolationToString(GetJEnum(env, interp))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_InterpolationFromString(JNIEnv * env, jobject, jstring s) { OCIO_JNITRY_ENTER() return BuildJEnum(env, "org/OpenColorIO/Interpolation", InterpolationFromString(GetJStringValue(env, s)())); OCIO_JNITRY_EXIT(NULL) } // GpuLanguage JNIEXPORT jstring JNICALL Java_org_OpenColorIO_GpuLanguage_toString(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return env->NewStringUTF( GpuLanguageToString(GetJEnum(env, self))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_GpuLanguage_equals(JNIEnv * env, jobject self, jobject obj) { OCIO_JNITRY_ENTER() return GetJEnum(env, self) == GetJEnum(env, obj); OCIO_JNITRY_EXIT(false) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Globals_GpuLanguageToString(JNIEnv * env, jobject, jobject language) { OCIO_JNITRY_ENTER() return env->NewStringUTF( GpuLanguageToString(GetJEnum(env, language))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_GpuLanguageFromString(JNIEnv * env, jobject, jstring s) { OCIO_JNITRY_ENTER() return BuildJEnum(env, "org/OpenColorIO/GpuLanguage", GpuLanguageFromString(GetJStringValue(env, s)())); OCIO_JNITRY_EXIT(NULL) } // EnvironmentMode JNIEXPORT jstring JNICALL Java_org_OpenColorIO_EnvironmentMode_toString(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return env->NewStringUTF( EnvironmentModeToString(GetJEnum(env, self))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_EnvironmentMode_equals(JNIEnv * env, jobject self, jobject obj) { OCIO_JNITRY_ENTER() return GetJEnum(env, self) == GetJEnum(env, obj); OCIO_JNITRY_EXIT(false) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Globals_EnvironmentModeToString(JNIEnv * env, jobject, jobject mode) { OCIO_JNITRY_ENTER() return env->NewStringUTF( EnvironmentModeToString(GetJEnum(env, mode))); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Globals_EnvironmentModeFromString(JNIEnv * env, jobject, jstring s) { OCIO_JNITRY_ENTER() return BuildJEnum(env, "org/OpenColorIO/EnvironmentMode", EnvironmentModeFromString(GetJStringValue(env, s)())); OCIO_JNITRY_EXIT(NULL) } opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNIProcessor.cpp0000644000175000017500000001323213223553423021537 0ustar mfvmfv/* 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 #include #include #include "OpenColorIO/OpenColorIO.h" #include "OpenColorIOJNI.h" #include "JNIUtil.h" OCIO_NAMESPACE_USING JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Processor_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() jobject obj = BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Processor"), Processor::Create()); return obj; OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_Processor_isNoOp(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstProcessorRcPtr ptr = GetConstJOCIO(env, self); return (jboolean)ptr->isNoOp(); OCIO_JNITRY_EXIT(false) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_Processor_hasChannelCrosstalk(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstProcessorRcPtr ptr = GetConstJOCIO(env, self); return (jboolean)ptr->hasChannelCrosstalk(); OCIO_JNITRY_EXIT(false) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Processor_apply(JNIEnv * env, jobject self, jobject img) { OCIO_JNITRY_ENTER() ConstProcessorRcPtr ptr = GetConstJOCIO(env, self); ImageDescRcPtr _img = GetEditableJOCIO(env, img); ptr->apply(*_img.get()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_Processor_applyRGB(JNIEnv * env, jobject self, jfloatArray pixel) { OCIO_JNITRY_ENTER() ConstProcessorRcPtr ptr = GetConstJOCIO(env, self); ptr->applyRGB(GetJFloatArrayValue(env, pixel, "pixel", 3)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_Processor_applyRGBA(JNIEnv * env, jobject self, jfloatArray pixel) { OCIO_JNITRY_ENTER() ConstProcessorRcPtr ptr = GetConstJOCIO(env, self); ptr->applyRGBA(GetJFloatArrayValue(env, pixel, "pixel", 4)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Processor_getCpuCacheID(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstProcessorRcPtr ptr = GetConstJOCIO(env, self); return env->NewStringUTF(ptr->getCpuCacheID()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Processor_getGpuShaderText(JNIEnv * env, jobject self, jobject shaderDesc) { OCIO_JNITRY_ENTER() ConstProcessorRcPtr ptr = GetConstJOCIO(env, self); ConstGpuShaderDescRcPtr desc = GetConstJOCIO(env, shaderDesc); return env->NewStringUTF(ptr->getGpuShaderText(*desc.get())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Processor_getGpuShaderTextCacheID(JNIEnv * env, jobject self, jobject shaderDesc) { OCIO_JNITRY_ENTER() ConstProcessorRcPtr ptr = GetConstJOCIO(env, self); ConstGpuShaderDescRcPtr desc = GetConstJOCIO(env, shaderDesc); return env->NewStringUTF(ptr->getGpuShaderTextCacheID(*desc.get())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Processor_getGpuLut3D(JNIEnv * env, jobject self, jobject lut3d, jobject shaderDesc) { OCIO_JNITRY_ENTER() ConstProcessorRcPtr ptr = GetConstJOCIO(env, self); ConstGpuShaderDescRcPtr desc = GetConstJOCIO(env, shaderDesc); int len = desc->getLut3DEdgeLen(); int size = 3*len*len*len; float* _lut3d = GetJFloatBuffer(env, lut3d, size); ptr->getGpuLut3D(_lut3d, *desc.get()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Processor_getGpuLut3DCacheID(JNIEnv * env, jobject self, jobject shaderDesc) { OCIO_JNITRY_ENTER() ConstProcessorRcPtr ptr = GetConstJOCIO(env, self); ConstGpuShaderDescRcPtr desc = GetConstJOCIO(env, shaderDesc); return env->NewStringUTF(ptr->getGpuLut3DCacheID(*desc.get())); OCIO_JNITRY_EXIT(NULL) } opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNIColorSpace.cpp0000644000175000017500000002124513223553423021615 0ustar mfvmfv/* 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 #include #include #include "OpenColorIO/OpenColorIO.h" #include "OpenColorIOJNI.h" #include "JNIUtil.h" OCIO_NAMESPACE_USING JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpace_dispose(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() DisposeJOCIO(env, self); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_ColorSpace_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/ColorSpace"), ColorSpace::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_ColorSpace_createEditableCopy(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstColorSpaceRcPtr col = GetConstJOCIO(env, self); return BuildJObject(env, self, env->FindClass("org/OpenColorIO/ColorSpace"), col->createEditableCopy()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_ColorSpace_getName(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstColorSpaceRcPtr col = GetConstJOCIO(env, self); return env->NewStringUTF(col->getName()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpace_setName(JNIEnv * env, jobject self, jstring name) { OCIO_JNITRY_ENTER() ColorSpaceRcPtr col = GetEditableJOCIO(env, self); col->setName(GetJStringValue(env, name)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_ColorSpace_getFamily(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstColorSpaceRcPtr col = GetConstJOCIO(env, self); return env->NewStringUTF(col->getFamily()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpace_setFamily(JNIEnv * env, jobject self, jstring family) { OCIO_JNITRY_ENTER() ColorSpaceRcPtr col = GetEditableJOCIO(env, self); col->setFamily(GetJStringValue(env, family)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_ColorSpace_getEqualityGroup(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstColorSpaceRcPtr col = GetConstJOCIO(env, self); return env->NewStringUTF(col->getEqualityGroup()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpace_setEqualityGroup(JNIEnv * env, jobject self, jstring equalityGroup) { OCIO_JNITRY_ENTER() ColorSpaceRcPtr col = GetEditableJOCIO(env, self); col->setEqualityGroup(GetJStringValue(env, equalityGroup)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_ColorSpace_getDescription(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstColorSpaceRcPtr col = GetConstJOCIO(env, self); return env->NewStringUTF(col->getDescription()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpace_setDescription(JNIEnv * env, jobject self, jstring description) { OCIO_JNITRY_ENTER() ColorSpaceRcPtr col = GetEditableJOCIO(env, self); col->setDescription(GetJStringValue(env, description)()); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_ColorSpace_getBitDepth(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstColorSpaceRcPtr col = GetConstJOCIO(env, self); return BuildJEnum(env, "org/OpenColorIO/BitDepth", col->getBitDepth()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpace_setBitDepth(JNIEnv * env, jobject self, jobject bitDepth) { OCIO_JNITRY_ENTER() ColorSpaceRcPtr col = GetEditableJOCIO(env, self); col->setBitDepth(GetJEnum(env, bitDepth)); OCIO_JNITRY_EXIT() } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_ColorSpace_isData(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstColorSpaceRcPtr col = GetConstJOCIO(env, self); return (jboolean)col->isData(); OCIO_JNITRY_EXIT(false) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpace_setIsData(JNIEnv * env, jobject self, jboolean isData) { OCIO_JNITRY_ENTER() ColorSpaceRcPtr col = GetEditableJOCIO(env, self); col->setIsData((bool)isData); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_ColorSpace_getAllocation(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstColorSpaceRcPtr col = GetConstJOCIO(env, self); return BuildJEnum(env, "org/OpenColorIO/Allocation", col->getAllocation()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpace_setAllocation(JNIEnv * env, jobject self, jobject allocation) { OCIO_JNITRY_ENTER() ColorSpaceRcPtr col = GetEditableJOCIO(env, self); col->setAllocation(GetJEnum(env, allocation)); OCIO_JNITRY_EXIT() } JNIEXPORT jint JNICALL Java_org_OpenColorIO_ColorSpace_getAllocationNumVars(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstColorSpaceRcPtr col = GetConstJOCIO(env, self); return (jint)col->getAllocationNumVars(); OCIO_JNITRY_EXIT(0) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpace_getAllocationVars(JNIEnv * env, jobject self, jfloatArray vars) { OCIO_JNITRY_ENTER() ConstColorSpaceRcPtr col = GetConstJOCIO(env, self); col->getAllocationVars(SetJFloatArrayValue(env, vars, "vars", col->getAllocationNumVars())()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpace_setAllocationVars(JNIEnv * env, jobject self, jint numvars, jfloatArray vars) { OCIO_JNITRY_ENTER() ColorSpaceRcPtr col = GetEditableJOCIO(env, self); col->setAllocationVars((int)numvars, GetJFloatArrayValue(env, vars, "vars", numvars)()); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_ColorSpace_getTransform(JNIEnv * env, jobject self, jobject dir) { OCIO_JNITRY_ENTER() ConstColorSpaceRcPtr col = GetConstJOCIO(env, self); ColorSpaceDirection cd = GetJEnum(env, dir); ConstTransformRcPtr tr = col->getTransform(cd); return BuildJConstObject(env, self, env->FindClass(GetOCIOTClass(tr)), tr); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpace_setTransform(JNIEnv * env, jobject self, jobject transform, jobject dir) { OCIO_JNITRY_ENTER() ColorSpaceRcPtr col = GetEditableJOCIO(env, self); ColorSpaceDirection cd = GetJEnum(env, dir); ConstTransformRcPtr tran = GetConstJOCIO(env, transform); col->setTransform(tran, cd); OCIO_JNITRY_EXIT() } opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNIContext.cpp0000644000175000017500000001565613223553423021220 0ustar mfvmfv/* 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 #include #include "OpenColorIO/OpenColorIO.h" #include "OpenColorIOJNI.h" #include "JNIUtil.h" OCIO_NAMESPACE_USING JNIEXPORT void JNICALL Java_org_OpenColorIO_Context_dispose(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() DisposeJOCIO(env, self); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Context_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/Context"), Context::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Context_createEditableCopy(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstContextRcPtr con = GetConstJOCIO(env, self); return BuildJObject(env, self, env->FindClass("org/OpenColorIO/Context"), con->createEditableCopy()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Context_getCacheID(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstContextRcPtr con = GetConstJOCIO(env, self); return env->NewStringUTF(con->getCacheID()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Context_setSearchPath(JNIEnv * env, jobject self, jstring path) { OCIO_JNITRY_ENTER() ContextRcPtr con = GetEditableJOCIO(env, self); con->setSearchPath(GetJStringValue(env, path)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Context_getSearchPath(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstContextRcPtr con = GetConstJOCIO(env, self); return env->NewStringUTF(con->getSearchPath()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Context_setWorkingDir(JNIEnv * env, jobject self, jstring dirname) { OCIO_JNITRY_ENTER() ContextRcPtr con = GetEditableJOCIO(env, self); con->setWorkingDir(GetJStringValue(env, dirname)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Context_getWorkingDir(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstContextRcPtr con = GetConstJOCIO(env, self); return env->NewStringUTF(con->getWorkingDir()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Context_setStringVar(JNIEnv * env, jobject self, jstring name, jstring var) { OCIO_JNITRY_ENTER() ContextRcPtr con = GetEditableJOCIO(env, self); con->setStringVar(GetJStringValue(env, name)(), GetJStringValue(env, var)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Context_getStringVar(JNIEnv * env, jobject self, jstring name) { OCIO_JNITRY_ENTER() ConstContextRcPtr con = GetConstJOCIO(env, self); return env->NewStringUTF(con->getStringVar(GetJStringValue(env, name)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Context_getNumStringVars(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstContextRcPtr con = GetConstJOCIO(env, self); return (jint)con->getNumStringVars(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Context_getStringVarNameByIndex(JNIEnv * env, jobject self, jint index) { OCIO_JNITRY_ENTER() ConstContextRcPtr con = GetConstJOCIO(env, self); return env->NewStringUTF(con->getStringVarNameByIndex((int)index)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Context_clearStringVars(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ContextRcPtr con = GetEditableJOCIO(env, self); con->clearStringVars(); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_Context_setEnvironmentMode(JNIEnv * env, jobject self, jobject mode) { OCIO_JNITRY_ENTER() ContextRcPtr con = GetEditableJOCIO(env, self); con->setEnvironmentMode(GetJEnum(env, mode)); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Context_getEnvironmentMode(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstContextRcPtr con = GetConstJOCIO(env, self); return BuildJEnum(env, "org/OpenColorIO/EnvironmentMode", con->getEnvironmentMode()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Context_loadEnvironment(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ContextRcPtr con = GetEditableJOCIO(env, self); con->loadEnvironment(); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Context_resolveStringVar(JNIEnv * env, jobject self, jstring val) { OCIO_JNITRY_ENTER() ConstContextRcPtr con = GetConstJOCIO(env, self); return env->NewStringUTF(con->resolveStringVar(GetJStringValue(env, val)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Context_resolveFileLocation(JNIEnv * env, jobject self, jstring filename) { OCIO_JNITRY_ENTER() ConstContextRcPtr con = GetConstJOCIO(env, self); return env->NewStringUTF(con->resolveFileLocation(GetJStringValue(env, filename)())); OCIO_JNITRY_EXIT(NULL) } opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNIGpuShaderDesc.cpp0000644000175000017500000001142613223553423022244 0ustar mfvmfv/* 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 #include #include "OpenColorIO/OpenColorIO.h" #include "OpenColorIOJNI.h" #include "JNIUtil.h" OCIO_NAMESPACE_USING namespace { void GpuShaderDesc_deleter(GpuShaderDesc* d) { delete d; } }; // end anon namespace JNIEXPORT void JNICALL Java_org_OpenColorIO_GpuShaderDesc_create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() GpuShaderDescJNI * jnistruct = new GpuShaderDescJNI(); jnistruct->back_ptr = env->NewGlobalRef(self); jnistruct->constcppobj = new ConstGpuShaderDescRcPtr(); jnistruct->cppobj = new GpuShaderDescRcPtr(); *jnistruct->cppobj = GpuShaderDescRcPtr(new GpuShaderDesc(), &GpuShaderDesc_deleter); jnistruct->isconst = false; jclass wclass = env->GetObjectClass(self); jfieldID fid = env->GetFieldID(wclass, "m_impl", "J"); env->SetLongField(self, fid, (jlong)jnistruct); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_GpuShaderDesc_dispose(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() DisposeJOCIO(env, self); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_GpuShaderDesc_setLanguage(JNIEnv * env, jobject self, jobject lang) { OCIO_JNITRY_ENTER() GpuShaderDescRcPtr ptr = GetEditableJOCIO(env, self); ptr->setLanguage(GetJEnum(env, lang)); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_GpuShaderDesc_getLanguage(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstGpuShaderDescRcPtr ptr = GetConstJOCIO(env, self); return BuildJEnum(env, "org/OpenColorIO/GpuLanguage", ptr->getLanguage()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_GpuShaderDesc_setFunctionName(JNIEnv * env, jobject self, jstring name) { OCIO_JNITRY_ENTER() const char *_name = env->GetStringUTFChars(name, 0); GpuShaderDescRcPtr ptr = GetEditableJOCIO(env, self); ptr->setFunctionName(_name); env->ReleaseStringUTFChars(name, _name); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_GpuShaderDesc_getFunctionName(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstGpuShaderDescRcPtr ptr = GetConstJOCIO(env, self); return env->NewStringUTF(ptr->getFunctionName()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_GpuShaderDesc_setLut3DEdgeLen(JNIEnv * env, jobject self, jint len) { OCIO_JNITRY_ENTER() GpuShaderDescRcPtr ptr = GetEditableJOCIO(env, self); ptr->setLut3DEdgeLen((int)len); OCIO_JNITRY_EXIT() } JNIEXPORT jint JNICALL Java_org_OpenColorIO_GpuShaderDesc_getLut3DEdgeLen(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstGpuShaderDescRcPtr ptr = GetConstJOCIO(env, self); return (jint)ptr->getLut3DEdgeLen(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_GpuShaderDesc_getCacheID(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstGpuShaderDescRcPtr ptr = GetConstJOCIO(env, self); return env->NewStringUTF(ptr->getCacheID()); OCIO_JNITRY_EXIT(NULL) } opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNITransforms.cpp0000644000175000017500000012413313223553423021721 0ustar mfvmfv/* 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 "OpenColorIO/OpenColorIO.h" #include "OpenColorIOJNI.h" #include "JNIUtil.h" OCIO_NAMESPACE_USING // Transform JNIEXPORT void JNICALL Java_org_OpenColorIO_Transform_dispose(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() DisposeJOCIO(env, self); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Transform_createEditableCopy(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTransformRcPtr ctran = GetConstJOCIO(env, self); return BuildJObject(env, self, env->FindClass(GetOCIOTClass(ctran)), ctran->createEditableCopy()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Transform_getDirection(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTransformRcPtr ptr = GetConstJOCIO(env, self); return BuildJEnum(env, "org/OpenColorIO/TransformDirection", ptr->getDirection()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Transform_setDirection(JNIEnv * env, jobject self, jobject dir) { OCIO_JNITRY_ENTER() TransformRcPtr ptr = GetEditableJOCIO(env, self); ptr->setDirection(GetJEnum(env, dir)); OCIO_JNITRY_EXIT() } // AllocationTransform JNIEXPORT jobject JNICALL Java_org_OpenColorIO_AllocationTransform_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/AllocationTransform"), AllocationTransform::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_AllocationTransform_getAllocation(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstAllocationTransformRcPtr alctran = GetConstJOCIO(env, self); return BuildJEnum(env, "org/OpenColorIO/Allocation", alctran->getAllocation()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_AllocationTransform_setAllocation(JNIEnv * env, jobject self, jobject allocation) { OCIO_JNITRY_ENTER() AllocationTransformRcPtr alctran = GetEditableJOCIO(env, self); alctran->setAllocation(GetJEnum(env, allocation)); OCIO_JNITRY_EXIT() } JNIEXPORT jint JNICALL Java_org_OpenColorIO_AllocationTransform_getNumVars(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstAllocationTransformRcPtr alctran = GetConstJOCIO(env, self); return (jint)alctran->getNumVars(); OCIO_JNITRY_EXIT(0) } JNIEXPORT void JNICALL Java_org_OpenColorIO_AllocationTransform_getVars(JNIEnv * env, jobject self, jfloatArray vars) { OCIO_JNITRY_ENTER() ConstAllocationTransformRcPtr alctran = GetConstJOCIO(env, self); alctran->getVars(SetJFloatArrayValue(env, vars, "vars", alctran->getNumVars())()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_AllocationTransform_setVars(JNIEnv * env, jobject self, jint numvars, jfloatArray vars) { OCIO_JNITRY_ENTER() AllocationTransformRcPtr alctran = GetEditableJOCIO(env, self); alctran->setVars((int)numvars, GetJFloatArrayValue(env, vars, "vars", numvars)()); OCIO_JNITRY_EXIT() } // CDLTransform JNIEXPORT jobject JNICALL Java_org_OpenColorIO_CDLTransform_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/CDLTransform"), CDLTransform::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_CDLTransform_CreateFromFile(JNIEnv * env, jobject self, jstring src, jstring cccid) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/CDLTransform"), CDLTransform::CreateFromFile(GetJStringValue(env, src)(), GetJStringValue(env, cccid)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_CDLTransform_equals(JNIEnv * env, jobject self, jobject obj) { OCIO_JNITRY_ENTER() ConstCDLTransformRcPtr left = GetConstJOCIO(env, self); ConstCDLTransformRcPtr right = GetConstJOCIO(env, obj); return (jboolean)left->equals(right); OCIO_JNITRY_EXIT(false) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_CDLTransform_getXML(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstCDLTransformRcPtr cdltran = GetConstJOCIO(env, self); return env->NewStringUTF(cdltran->getXML()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_setXML(JNIEnv * env, jobject self, jstring xml) { OCIO_JNITRY_ENTER() CDLTransformRcPtr cdltran = GetEditableJOCIO(env, self); cdltran->setXML(GetJStringValue(env, xml)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_setSlope(JNIEnv * env, jobject self, jfloatArray rgb) { OCIO_JNITRY_ENTER() CDLTransformRcPtr cdltran = GetEditableJOCIO(env, self); cdltran->setSlope(GetJFloatArrayValue(env, rgb, "rgb", 3)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_getSlope(JNIEnv * env, jobject self, jfloatArray rgb) { OCIO_JNITRY_ENTER() ConstCDLTransformRcPtr cdltran = GetConstJOCIO(env, self); cdltran->getSlope(SetJFloatArrayValue(env, rgb, "rgb", 3)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_setOffset(JNIEnv * env, jobject self, jfloatArray rgb) { OCIO_JNITRY_ENTER() CDLTransformRcPtr cdltran = GetEditableJOCIO(env, self); cdltran->setOffset(GetJFloatArrayValue(env, rgb, "rgb", 3)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_getOffset(JNIEnv * env, jobject self, jfloatArray rgb) { OCIO_JNITRY_ENTER() ConstCDLTransformRcPtr cdltran = GetConstJOCIO(env, self); cdltran->getOffset(SetJFloatArrayValue(env, rgb, "rgb", 3)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_setPower(JNIEnv * env, jobject self, jfloatArray rgb) { OCIO_JNITRY_ENTER() CDLTransformRcPtr cdltran = GetEditableJOCIO(env, self); cdltran->setPower(GetJFloatArrayValue(env, rgb, "rgb", 3)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_getPower(JNIEnv * env, jobject self, jfloatArray rgb) { OCIO_JNITRY_ENTER() ConstCDLTransformRcPtr cdltran = GetConstJOCIO(env, self); cdltran->getPower(SetJFloatArrayValue(env, rgb, "rgb", 3)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_setSOP(JNIEnv * env, jobject self, jfloatArray vec9) { OCIO_JNITRY_ENTER() CDLTransformRcPtr cdltran = GetEditableJOCIO(env, self); cdltran->setSOP(GetJFloatArrayValue(env, vec9, "vec9", 9)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_getSOP(JNIEnv * env, jobject self, jfloatArray vec9) { OCIO_JNITRY_ENTER() ConstCDLTransformRcPtr cdltran = GetConstJOCIO(env, self); cdltran->getSOP(SetJFloatArrayValue(env, vec9, "vec9", 9)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_setSat(JNIEnv * env, jobject self, jfloat sat) { OCIO_JNITRY_ENTER() CDLTransformRcPtr cdltran = GetEditableJOCIO(env, self); cdltran->setSat((float)sat); OCIO_JNITRY_EXIT() } JNIEXPORT jfloat JNICALL Java_org_OpenColorIO_CDLTransform_getSat(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstCDLTransformRcPtr cdltran = GetConstJOCIO(env, self); return (jfloat)cdltran->getSat(); OCIO_JNITRY_EXIT(1.f) } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_getSatLumaCoefs(JNIEnv * env, jobject self, jfloatArray rgb) { OCIO_JNITRY_ENTER() ConstCDLTransformRcPtr cdltran = GetConstJOCIO(env, self); cdltran->getSatLumaCoefs(SetJFloatArrayValue(env, rgb, "rgb", 3)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_setID(JNIEnv * env, jobject self, jstring id) { OCIO_JNITRY_ENTER() CDLTransformRcPtr cdltran = GetEditableJOCIO(env, self); cdltran->setID(GetJStringValue(env, id)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_CDLTransform_getID(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstCDLTransformRcPtr cdltran = GetConstJOCIO(env, self); return env->NewStringUTF(cdltran->getID()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_CDLTransform_setDescription(JNIEnv * env, jobject self, jstring desc) { OCIO_JNITRY_ENTER() CDLTransformRcPtr cdltran = GetEditableJOCIO(env, self); cdltran->setDescription(GetJStringValue(env, desc)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_CDLTransform_getDescription(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstCDLTransformRcPtr cdltran = GetConstJOCIO(env, self); return env->NewStringUTF(cdltran->getDescription()); OCIO_JNITRY_EXIT(NULL) } // ColorSpaceTransform JNIEXPORT jobject JNICALL Java_org_OpenColorIO_ColorSpaceTransform_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/ColorSpaceTransform"), ColorSpaceTransform::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_ColorSpaceTransform_getSrc(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstColorSpaceTransformRcPtr coltran = GetConstJOCIO(env, self); return env->NewStringUTF(coltran->getSrc()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpaceTransform_setSrc(JNIEnv * env, jobject self, jstring src) { OCIO_JNITRY_ENTER() ColorSpaceTransformRcPtr coltran = GetEditableJOCIO(env, self); coltran->setSrc(GetJStringValue(env, src)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_ColorSpaceTransform_getDst(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstColorSpaceTransformRcPtr coltran = GetConstJOCIO(env, self); return env->NewStringUTF(coltran->getDst()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ColorSpaceTransform_setDst(JNIEnv * env, jobject self, jstring dst) { OCIO_JNITRY_ENTER() ColorSpaceTransformRcPtr coltran = GetEditableJOCIO(env, self); coltran->setDst(GetJStringValue(env, dst)()); OCIO_JNITRY_EXIT() } // DisplayTransform JNIEXPORT jobject JNICALL Java_org_OpenColorIO_DisplayTransform_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/DisplayTransform"), DisplayTransform::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_DisplayTransform_setInputColorSpaceName(JNIEnv * env, jobject self, jstring name) { OCIO_JNITRY_ENTER() DisplayTransformRcPtr dtran = GetEditableJOCIO(env, self); dtran->setInputColorSpaceName(GetJStringValue(env, name)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_DisplayTransform_getInputColorSpaceName(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstDisplayTransformRcPtr dtran = GetConstJOCIO(env, self); return env->NewStringUTF(dtran->getInputColorSpaceName()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_DisplayTransform_setLinearCC(JNIEnv * env, jobject self, jobject cc) { OCIO_JNITRY_ENTER() DisplayTransformRcPtr dtran = GetEditableJOCIO(env, self); ConstTransformRcPtr ptr = GetConstJOCIO(env, cc); dtran->setLinearCC(ptr); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_DisplayTransform_getLinearCC(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstDisplayTransformRcPtr dtran = GetConstJOCIO(env, self); ConstTransformRcPtr cctran = dtran->getLinearCC(); return BuildJObject(env, self, env->FindClass(GetOCIOTClass(cctran)), cctran->createEditableCopy()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_DisplayTransform_setColorTimingCC(JNIEnv * env, jobject self, jobject cc) { OCIO_JNITRY_ENTER() DisplayTransformRcPtr dtran = GetEditableJOCIO(env, self); ConstTransformRcPtr ptr = GetConstJOCIO(env, cc); dtran->setColorTimingCC(ptr); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_DisplayTransform_getColorTimingCC(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstDisplayTransformRcPtr dtran = GetConstJOCIO(env, self); ConstTransformRcPtr cctran = dtran->getColorTimingCC(); return BuildJObject(env, self, env->FindClass(GetOCIOTClass(cctran)), cctran->createEditableCopy()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_DisplayTransform_setChannelView(JNIEnv * env, jobject self, jobject transform) { OCIO_JNITRY_ENTER() DisplayTransformRcPtr dtran = GetEditableJOCIO(env, self); ConstTransformRcPtr ptr = GetConstJOCIO(env, transform); dtran->setChannelView(ptr); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_DisplayTransform_getChannelView(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstDisplayTransformRcPtr dtran = GetConstJOCIO(env, self); ConstTransformRcPtr cvtran = dtran->getChannelView(); return BuildJObject(env, self, env->FindClass(GetOCIOTClass(cvtran)), cvtran->createEditableCopy()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_DisplayTransform_setDisplay(JNIEnv * env, jobject self, jstring display) { OCIO_JNITRY_ENTER() DisplayTransformRcPtr dtran = GetEditableJOCIO(env, self); dtran->setDisplay(GetJStringValue(env, display)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_DisplayTransform_getDisplay(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstDisplayTransformRcPtr dtran = GetConstJOCIO(env, self); return env->NewStringUTF(dtran->getDisplay()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_DisplayTransform_setView(JNIEnv * env, jobject self, jstring view) { OCIO_JNITRY_ENTER() DisplayTransformRcPtr dtran = GetEditableJOCIO(env, self); dtran->setView(GetJStringValue(env, view)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_DisplayTransform_getView(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstDisplayTransformRcPtr dtran = GetConstJOCIO(env, self); return env->NewStringUTF(dtran->getView()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_DisplayTransform_setDisplayCC(JNIEnv * env, jobject self, jobject cc) { OCIO_JNITRY_ENTER() DisplayTransformRcPtr dtran = GetEditableJOCIO(env, self); ConstTransformRcPtr ptr = GetConstJOCIO(env, cc); dtran->setDisplayCC(ptr); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_DisplayTransform_getDisplayCC(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstDisplayTransformRcPtr dtran = GetConstJOCIO(env, self); ConstTransformRcPtr cctran = dtran->getDisplayCC(); return BuildJObject(env, self, env->FindClass(GetOCIOTClass(cctran)), cctran->createEditableCopy()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_DisplayTransform_setLooksOverride(JNIEnv * env, jobject self, jstring looks) { OCIO_JNITRY_ENTER() DisplayTransformRcPtr dtran = GetEditableJOCIO(env, self); dtran->setLooksOverride(GetJStringValue(env, looks)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_DisplayTransform_getLooksOverride(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstDisplayTransformRcPtr dtran = GetConstJOCIO(env, self); return env->NewStringUTF(dtran->getLooksOverride()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_DisplayTransform_setLooksOverrideEnabled(JNIEnv * env, jobject self, jboolean enabled) { OCIO_JNITRY_ENTER() DisplayTransformRcPtr dtran = GetEditableJOCIO(env, self); dtran->setLooksOverrideEnabled((bool)enabled); OCIO_JNITRY_EXIT() } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_DisplayTransform_getLooksOverrideEnabled(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstDisplayTransformRcPtr dtran = GetConstJOCIO(env, self); return (jboolean)dtran->getLooksOverrideEnabled(); OCIO_JNITRY_EXIT(false) } // ExponentTransform JNIEXPORT jobject JNICALL Java_org_OpenColorIO_ExponentTransform_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/ExponentTransform"), ExponentTransform::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_ExponentTransform_setValue(JNIEnv * env, jobject self, jfloatArray vec4) { OCIO_JNITRY_ENTER() ExponentTransformRcPtr exptran = GetEditableJOCIO(env, self); exptran->setValue(GetJFloatArrayValue(env, vec4, "vec4", 4)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_ExponentTransform_getValue(JNIEnv * env, jobject self, jfloatArray vec4) { OCIO_JNITRY_ENTER() ConstExponentTransformRcPtr exptran = GetConstJOCIO(env, self); exptran->getValue(SetJFloatArrayValue(env, vec4, "vec4", 4)()); OCIO_JNITRY_EXIT() } // FileTransform JNIEXPORT jobject JNICALL Java_org_OpenColorIO_FileTransform_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/FileTransform"), FileTransform::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_FileTransform_getSrc(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstFileTransformRcPtr filetran = GetConstJOCIO(env, self); return env->NewStringUTF(filetran->getSrc()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_FileTransform_setSrc(JNIEnv * env, jobject self, jstring src) { OCIO_JNITRY_ENTER() FileTransformRcPtr filetran = GetEditableJOCIO(env, self); filetran->setSrc(GetJStringValue(env, src)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_FileTransform_getCCCId(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstFileTransformRcPtr filetran = GetConstJOCIO(env, self); return env->NewStringUTF(filetran->getCCCId()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_FileTransform_setCCCId(JNIEnv * env, jobject self, jstring id) { OCIO_JNITRY_ENTER() FileTransformRcPtr filetran = GetEditableJOCIO(env, self); filetran->setCCCId(GetJStringValue(env, id)()); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_FileTransform_getInterpolation(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstFileTransformRcPtr filetran = GetConstJOCIO(env, self); return BuildJEnum(env, "org/OpenColorIO/Interpolation", filetran->getInterpolation()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_FileTransform_setInterpolation(JNIEnv * env, jobject self, jobject interp) { OCIO_JNITRY_ENTER() FileTransformRcPtr filetran = GetEditableJOCIO(env, self); filetran->setInterpolation(GetJEnum(env, interp)); OCIO_JNITRY_EXIT() } JNIEXPORT jint JNICALL Java_org_OpenColorIO_FileTransform_getNumFormats(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstFileTransformRcPtr filetran = GetConstJOCIO(env, self); return (jint)filetran->getNumFormats(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_FileTransform_getFormatNameByIndex(JNIEnv * env, jobject self, jint index) { OCIO_JNITRY_ENTER() ConstFileTransformRcPtr filetran = GetConstJOCIO(env, self); return env->NewStringUTF(filetran->getFormatNameByIndex((int)index)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_FileTransform_getFormatExtensionByIndex(JNIEnv * env, jobject self, jint index) { OCIO_JNITRY_ENTER() ConstFileTransformRcPtr filetran = GetConstJOCIO(env, self); return env->NewStringUTF(filetran->getFormatExtensionByIndex((int)index)); OCIO_JNITRY_EXIT(NULL) } // GroupTransform JNIEXPORT jobject JNICALL Java_org_OpenColorIO_GroupTransform_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/GroupTransform"), GroupTransform::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_GroupTransform_getTransform(JNIEnv * env, jobject self, jint index) { OCIO_JNITRY_ENTER() ConstGroupTransformRcPtr gtran = GetConstJOCIO(env, self); ConstTransformRcPtr ctran = gtran->getTransform((int)index); return BuildJObject(env, self, env->FindClass(GetOCIOTClass(ctran)), ctran->createEditableCopy()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jint JNICALL Java_org_OpenColorIO_GroupTransform_size(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstGroupTransformRcPtr gtran = GetConstJOCIO(env, self); return (jint)gtran->size(); OCIO_JNITRY_EXIT(0) } JNIEXPORT void JNICALL Java_org_OpenColorIO_GroupTransform_push_1back(JNIEnv * env, jobject self, jobject transform) { OCIO_JNITRY_ENTER() GroupTransformRcPtr gtran = GetEditableJOCIO(env, self); ConstTransformRcPtr ptr = GetConstJOCIO(env, transform); gtran->push_back(ptr); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_GroupTransform_clear(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() GroupTransformRcPtr gtran = GetEditableJOCIO(env, self); gtran->clear(); OCIO_JNITRY_EXIT() } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_GroupTransform_empty(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstGroupTransformRcPtr gtran = GetConstJOCIO(env, self); return (jboolean)gtran->empty(); OCIO_JNITRY_EXIT(false) } // LogTransform JNIEXPORT jobject JNICALL Java_org_OpenColorIO_LogTransform_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/LogTransform"), LogTransform::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_LogTransform_setBase(JNIEnv * env, jobject self, jfloat val) { OCIO_JNITRY_ENTER() LogTransformRcPtr ltran = GetEditableJOCIO(env, self); ltran->setBase((float)val); OCIO_JNITRY_EXIT() } JNIEXPORT jfloat JNICALL Java_org_OpenColorIO_LogTransform_getBase(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstLogTransformRcPtr ltran = GetConstJOCIO(env, self); return (jfloat)ltran->getBase(); OCIO_JNITRY_EXIT(0.f) } // LookTransform JNIEXPORT jobject JNICALL Java_org_OpenColorIO_LookTransform_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/LookTransform"), LookTransform::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_LookTransform_getSrc(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstLookTransformRcPtr lktran = GetConstJOCIO(env, self); return env->NewStringUTF(lktran->getSrc()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_LookTransform_setSrc(JNIEnv * env, jobject self, jstring src) { OCIO_JNITRY_ENTER() LookTransformRcPtr lktran = GetEditableJOCIO(env, self); lktran->setSrc(GetJStringValue(env, src)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_LookTransform_getDst(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstLookTransformRcPtr lktran = GetConstJOCIO(env, self); return env->NewStringUTF(lktran->getDst()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_LookTransform_setDst(JNIEnv * env, jobject self, jstring dst) { OCIO_JNITRY_ENTER() LookTransformRcPtr lktran = GetEditableJOCIO(env, self); lktran->setDst(GetJStringValue(env, dst)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_LookTransform_setLooks(JNIEnv * env, jobject self, jstring looks) { OCIO_JNITRY_ENTER() LookTransformRcPtr lktran = GetEditableJOCIO(env, self); lktran->setLooks(GetJStringValue(env, looks)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_LookTransform_getLooks(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstLookTransformRcPtr lktran = GetConstJOCIO(env, self); return env->NewStringUTF(lktran->getLooks()); OCIO_JNITRY_EXIT(NULL) } // MatrixTransform JNIEXPORT jobject JNICALL Java_org_OpenColorIO_MatrixTransform_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/MatrixTransform"), MatrixTransform::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_MatrixTransform_equals(JNIEnv * env, jobject self, jobject obj) { OCIO_JNITRY_ENTER() ConstMatrixTransformRcPtr left = GetConstJOCIO(env, self); ConstMatrixTransformRcPtr right = GetConstJOCIO(env, obj); return (jboolean)left->equals(*right.get()); OCIO_JNITRY_EXIT(false) } JNIEXPORT void JNICALL Java_org_OpenColorIO_MatrixTransform_setValue(JNIEnv * env, jobject self, jfloatArray m44, jfloatArray offset4) { OCIO_JNITRY_ENTER() MatrixTransformRcPtr mtran = GetEditableJOCIO(env, self); mtran->setValue(GetJFloatArrayValue(env, m44, "m44", 16)(), GetJFloatArrayValue(env, offset4, "offset4", 4)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_MatrixTransform_getValue(JNIEnv * env, jobject self, jfloatArray m44, jfloatArray offset4) { OCIO_JNITRY_ENTER() ConstMatrixTransformRcPtr mtran = GetConstJOCIO(env, self); mtran->getValue(SetJFloatArrayValue(env, m44, "m44", 16)(), SetJFloatArrayValue(env, offset4, "offset4", 4)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_MatrixTransform_setMatrix(JNIEnv * env, jobject self, jfloatArray m44) { OCIO_JNITRY_ENTER() MatrixTransformRcPtr mtran = GetEditableJOCIO(env, self); mtran->setMatrix(GetJFloatArrayValue(env, m44, "m44", 16)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_MatrixTransform_getMatrix(JNIEnv * env, jobject self, jfloatArray m44) { OCIO_JNITRY_ENTER() ConstMatrixTransformRcPtr mtran = GetConstJOCIO(env, self); mtran->getMatrix(SetJFloatArrayValue(env, m44, "m44", 16)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_MatrixTransform_setOffset(JNIEnv * env, jobject self, jfloatArray offset4) { OCIO_JNITRY_ENTER() MatrixTransformRcPtr mtran = GetEditableJOCIO(env, self); mtran->setOffset(GetJFloatArrayValue(env, offset4, "offset4", 4)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_MatrixTransform_getOffset(JNIEnv * env, jobject self, jfloatArray offset4) { OCIO_JNITRY_ENTER() ConstMatrixTransformRcPtr mtran = GetConstJOCIO(env, self); mtran->getOffset(SetJFloatArrayValue(env, offset4, "offset4", 4)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_MatrixTransform_Fit(JNIEnv * env, jobject self, jfloatArray m44, jfloatArray offset4, jfloatArray oldmin4, jfloatArray oldmax4, jfloatArray newmin4, jfloatArray newmax4) { OCIO_JNITRY_ENTER() ConstMatrixTransformRcPtr mtran = GetConstJOCIO(env, self); mtran->Fit(GetJFloatArrayValue(env, m44, "m44", 16)(), GetJFloatArrayValue(env, offset4, "offset4", 4)(), GetJFloatArrayValue(env, oldmin4, "oldmin4", 4)(), GetJFloatArrayValue(env, oldmax4, "oldmax4", 4)(), GetJFloatArrayValue(env, newmin4, "newmin4", 4)(), GetJFloatArrayValue(env, newmax4, "newmax4", 4)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_MatrixTransform_Identity(JNIEnv * env, jobject self, jfloatArray m44, jfloatArray offset4) { OCIO_JNITRY_ENTER() ConstMatrixTransformRcPtr mtran = GetConstJOCIO(env, self); mtran->Identity(GetJFloatArrayValue(env, m44, "m44", 16)(), GetJFloatArrayValue(env, offset4, "offset4", 4)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_MatrixTransform_Sat(JNIEnv * env, jobject self, jfloatArray m44, jfloatArray offset4, jfloat sat, jfloatArray lumaCoef3) { OCIO_JNITRY_ENTER() ConstMatrixTransformRcPtr mtran = GetConstJOCIO(env, self); mtran->Sat(GetJFloatArrayValue(env, m44, "m44", 16)(), GetJFloatArrayValue(env, offset4, "offset4", 4)(), (float)sat, GetJFloatArrayValue(env, lumaCoef3, "lumaCoef3", 3)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_MatrixTransform_Scale(JNIEnv * env, jobject self, jfloatArray m44, jfloatArray offset4, jfloatArray scale4) { OCIO_JNITRY_ENTER() ConstMatrixTransformRcPtr mtran = GetConstJOCIO(env, self); mtran->Scale(GetJFloatArrayValue(env, m44, "m44", 16)(), GetJFloatArrayValue(env, offset4, "offset4", 4)(), GetJFloatArrayValue(env, scale4, "scale4", 4)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_MatrixTransform_View(JNIEnv * env, jobject self, jfloatArray m44, jfloatArray offset4, jintArray channelHot4, jfloatArray lumaCoef3) { OCIO_JNITRY_ENTER() ConstMatrixTransformRcPtr mtran = GetConstJOCIO(env, self); mtran->View(GetJFloatArrayValue(env, m44, "m44", 16)(), GetJFloatArrayValue(env, offset4, "offset4", 4)(), GetJIntArrayValue(env, channelHot4, "channelHot4", 4)(), GetJFloatArrayValue(env, lumaCoef3, "lumaCoef3", 3)()); OCIO_JNITRY_EXIT() } // TruelightTransform JNIEXPORT jobject JNICALL Java_org_OpenColorIO_TruelightTransform_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/TruelightTransform"), TruelightTransform::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_TruelightTransform_setConfigRoot(JNIEnv * env, jobject self, jstring configroot) { OCIO_JNITRY_ENTER() TruelightTransformRcPtr ttran = GetEditableJOCIO(env, self); ttran->setConfigRoot(GetJStringValue(env, configroot)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_TruelightTransform_getConfigRoot(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTruelightTransformRcPtr ttran = GetConstJOCIO(env, self); return env->NewStringUTF(ttran->getConfigRoot()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_TruelightTransform_setProfile(JNIEnv * env, jobject self, jstring profile) { OCIO_JNITRY_ENTER() TruelightTransformRcPtr ttran = GetEditableJOCIO(env, self); ttran->setProfile(GetJStringValue(env, profile)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_TruelightTransform_getProfile(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTruelightTransformRcPtr ttran = GetConstJOCIO(env, self); return env->NewStringUTF(ttran->getProfile()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_TruelightTransform_setCamera(JNIEnv * env, jobject self, jstring camera) { OCIO_JNITRY_ENTER() TruelightTransformRcPtr ttran = GetEditableJOCIO(env, self); ttran->setCamera(GetJStringValue(env, camera)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_TruelightTransform_getCamera(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTruelightTransformRcPtr ttran = GetConstJOCIO(env, self); return env->NewStringUTF(ttran->getCamera()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_TruelightTransform_setInputDisplay(JNIEnv * env, jobject self, jstring display) { OCIO_JNITRY_ENTER() TruelightTransformRcPtr ttran = GetEditableJOCIO(env, self); ttran->setInputDisplay(GetJStringValue(env, display)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_TruelightTransform_getInputDisplay(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTruelightTransformRcPtr ttran = GetConstJOCIO(env, self); return env->NewStringUTF(ttran->getInputDisplay()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_TruelightTransform_setRecorder(JNIEnv * env, jobject self, jstring recorder) { OCIO_JNITRY_ENTER() TruelightTransformRcPtr ttran = GetEditableJOCIO(env, self); ttran->setRecorder(GetJStringValue(env, recorder)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_TruelightTransform_getRecorder(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTruelightTransformRcPtr ttran = GetConstJOCIO(env, self); return env->NewStringUTF(ttran->getRecorder()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_TruelightTransform_setPrint(JNIEnv * env, jobject self, jstring print) { OCIO_JNITRY_ENTER() TruelightTransformRcPtr ttran = GetEditableJOCIO(env, self); ttran->setPrint(GetJStringValue(env, print)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_TruelightTransform_getPrint(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTruelightTransformRcPtr ttran = GetConstJOCIO(env, self); return env->NewStringUTF(ttran->getPrint()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_TruelightTransform_setLamp(JNIEnv * env, jobject self, jstring lamp) { OCIO_JNITRY_ENTER() TruelightTransformRcPtr ttran = GetEditableJOCIO(env, self); ttran->setLamp(GetJStringValue(env, lamp)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_TruelightTransform_getLamp(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTruelightTransformRcPtr ttran = GetConstJOCIO(env, self); return env->NewStringUTF(ttran->getLamp()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_TruelightTransform_setOutputCamera(JNIEnv * env, jobject self, jstring camera) { OCIO_JNITRY_ENTER() TruelightTransformRcPtr ttran = GetEditableJOCIO(env, self); ttran->setOutputCamera(GetJStringValue(env, camera)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_TruelightTransform_getOutputCamera(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTruelightTransformRcPtr ttran = GetConstJOCIO(env, self); return env->NewStringUTF(ttran->getOutputCamera()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_TruelightTransform_setDisplay(JNIEnv * env, jobject self, jstring display) { OCIO_JNITRY_ENTER() TruelightTransformRcPtr ttran = GetEditableJOCIO(env, self); ttran->setDisplay(GetJStringValue(env, display)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_TruelightTransform_getDisplay(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTruelightTransformRcPtr ttran = GetConstJOCIO(env, self); return env->NewStringUTF(ttran->getDisplay()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_TruelightTransform_setCubeInput(JNIEnv * env, jobject self, jstring type) { OCIO_JNITRY_ENTER() TruelightTransformRcPtr ttran = GetEditableJOCIO(env, self); ttran->setCubeInput(GetJStringValue(env, type)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_TruelightTransform_getCubeInput(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstTruelightTransformRcPtr ttran = GetConstJOCIO(env, self); return env->NewStringUTF(ttran->getCubeInput()); OCIO_JNITRY_EXIT(NULL) } opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNIBaker.cpp0000644000175000017500000002243413223553423020610 0ustar mfvmfv/* 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 #include #include "OpenColorIO/OpenColorIO.h" #include "OpenColorIOJNI.h" #include "JNIUtil.h" OCIO_NAMESPACE_USING JNIEXPORT void JNICALL Java_org_OpenColorIO_Baker_dispose(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() DisposeJOCIO(env, self); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Baker_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/Baker"), Baker::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Baker_createEditableCopy(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return BuildJObject(env, self, env->FindClass("org/OpenColorIO/Baker"), bake->createEditableCopy()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Baker_setConfig(JNIEnv * env, jobject self, jobject config) { OCIO_JNITRY_ENTER() BakerRcPtr bake = GetEditableJOCIO(env, self); ConstConfigRcPtr cfg = GetConstJOCIO(env, config); bake->setConfig(cfg); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Baker_getConfig(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Config"), bake->getConfig()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Baker_setFormat(JNIEnv * env, jobject self, jstring formatName) { OCIO_JNITRY_ENTER() BakerRcPtr bake = GetEditableJOCIO(env, self); bake->setFormat(GetJStringValue(env, formatName)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Baker_getFormat(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return env->NewStringUTF(bake->getFormat()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Baker_setType(JNIEnv * env, jobject self, jstring type) { OCIO_JNITRY_ENTER() BakerRcPtr bake = GetEditableJOCIO(env, self); bake->setType(GetJStringValue(env, type)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Baker_getType(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return env->NewStringUTF(bake->getType()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Baker_setMetadata(JNIEnv * env, jobject self, jstring metadata) { OCIO_JNITRY_ENTER() BakerRcPtr bake = GetEditableJOCIO(env, self); bake->setMetadata(GetJStringValue(env, metadata)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Baker_getMetadata(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return env->NewStringUTF(bake->getMetadata()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Baker_setInputSpace(JNIEnv * env, jobject self, jstring inputSpace) { OCIO_JNITRY_ENTER() BakerRcPtr bake = GetEditableJOCIO(env, self); bake->setInputSpace(GetJStringValue(env, inputSpace)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Baker_getInputSpace(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return env->NewStringUTF(bake->getInputSpace()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Baker_setShaperSpace(JNIEnv * env, jobject self, jstring shaperSpace) { OCIO_JNITRY_ENTER() BakerRcPtr bake = GetEditableJOCIO(env, self); bake->setShaperSpace(GetJStringValue(env, shaperSpace)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Baker_getShaperSpace(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return env->NewStringUTF(bake->getShaperSpace()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Baker_setLooks(JNIEnv * env, jobject self, jstring looks) { OCIO_JNITRY_ENTER() BakerRcPtr bake = GetEditableJOCIO(env, self); bake->setLooks(GetJStringValue(env, looks)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Baker_getLooks(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return env->NewStringUTF(bake->getLooks()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Baker_setTargetSpace(JNIEnv * env, jobject self, jstring targetSpace) { OCIO_JNITRY_ENTER() BakerRcPtr bake = GetEditableJOCIO(env, self); bake->setTargetSpace(GetJStringValue(env, targetSpace)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Baker_getTargetSpace(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return env->NewStringUTF(bake->getTargetSpace()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Baker_setShaperSize(JNIEnv * env, jobject self, jint shapersize) { OCIO_JNITRY_ENTER() BakerRcPtr bake = GetEditableJOCIO(env, self); return bake->setShaperSize((int)shapersize); OCIO_JNITRY_EXIT() } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Baker_getShaperSize(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return (jint)bake->getShaperSize(); OCIO_JNITRY_EXIT(0) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Baker_setCubeSize(JNIEnv * env, jobject self, jint cubesize) { OCIO_JNITRY_ENTER() BakerRcPtr bake = GetEditableJOCIO(env, self); return bake->setCubeSize((int)cubesize); OCIO_JNITRY_EXIT() } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Baker_getCubeSize(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return (jint)bake->getCubeSize(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Baker_bake(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); std::ostringstream os; bake->bake(os); return env->NewStringUTF(os.str().c_str()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Baker_getNumFormats(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return (jint)bake->getNumFormats(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Baker_getFormatNameByIndex(JNIEnv * env, jobject self, jint index) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return env->NewStringUTF(bake->getFormatNameByIndex((int)index)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Baker_getFormatExtensionByIndex(JNIEnv * env, jobject self, jint index) { OCIO_JNITRY_ENTER() ConstBakerRcPtr bake = GetConstJOCIO(env, self); return env->NewStringUTF(bake->getFormatExtensionByIndex((int)index)); OCIO_JNITRY_EXIT(NULL) } opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNIUtil.cpp0000644000175000017500000001237713223553423020506 0ustar mfvmfv/* 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 #include "JNIUtil.h" OCIO_NAMESPACE_ENTER { jobject NewJFloatBuffer(JNIEnv * env, float* ptr, int32_t len) { jobject byte_buf = env->NewDirectByteBuffer(ptr, len * sizeof(float)); jmethodID mid = env->GetMethodID(env->GetObjectClass(byte_buf), "asFloatBuffer", "()Ljava/nio/FloatBuffer;"); if (mid == 0) throw Exception("Could not find asFloatBuffer() method"); return env->CallObjectMethod(byte_buf, mid); } float* GetJFloatBuffer(JNIEnv * env, jobject buffer, int32_t len) { jmethodID mid = env->GetMethodID(env->GetObjectClass(buffer), "isDirect", "()Z"); if (mid == 0) throw Exception("Could not find isDirect() method"); if(!env->CallBooleanMethod(buffer, mid)) { std::ostringstream err; err << "the FloatBuffer object is not 'direct' it needs to be created "; err << "from a ByteBuffer.allocateDirect(..).asFloatBuffer() call."; throw Exception(err.str().c_str()); } if(env->GetDirectBufferCapacity(buffer) != len) { std::ostringstream err; err << "the FloatBuffer object is not allocated correctly it needs to "; err << "of size " << len << " but is "; err << env->GetDirectBufferCapacity(buffer) << "."; throw Exception(err.str().c_str()); } return (float*)env->GetDirectBufferAddress(buffer); } const char* GetOCIOTClass(ConstTransformRcPtr tran) { if(ConstAllocationTransformRcPtr at = DynamicPtrCast(tran)) return "org/OpenColorIO/AllocationTransform"; else if(ConstCDLTransformRcPtr ct = DynamicPtrCast(tran)) return "org/OpenColorIO/CDLTransform"; else if(ConstColorSpaceTransformRcPtr cst = DynamicPtrCast(tran)) return "org/OpenColorIO/ColorSpaceTransform"; else if(ConstDisplayTransformRcPtr dt = DynamicPtrCast(tran)) return "org/OpenColorIO/DisplayTransform"; else if(ConstExponentTransformRcPtr et = DynamicPtrCast(tran)) return "org/OpenColorIO/ExponentTransform"; else if(ConstFileTransformRcPtr ft = DynamicPtrCast(tran)) return "org/OpenColorIO/FileTransform"; else if(ConstGroupTransformRcPtr gt = DynamicPtrCast(tran)) return "org/OpenColorIO/GroupTransform"; else if(ConstLogTransformRcPtr lt = DynamicPtrCast(tran)) return "org/OpenColorIO/LogTransform"; else if(ConstLookTransformRcPtr lkt = DynamicPtrCast(tran)) return "org/OpenColorIO/LookTransform"; else if(ConstMatrixTransformRcPtr mt = DynamicPtrCast(tran)) return "org/OpenColorIO/MatrixTransform"; else if(ConstTruelightTransformRcPtr tt = DynamicPtrCast(tran)) return "org/OpenColorIO/TruelightTransform"; else return "org/OpenColorIO/Transform"; } void JNI_Handle_Exception(JNIEnv * env) { try { throw; } catch (ExceptionMissingFile & e) { jclass je = env->FindClass("org/OpenColorIO/ExceptionMissingFile"); env->ThrowNew(je, e.what()); env->DeleteLocalRef(je); } catch (Exception & e) { jclass je = env->FindClass("org/OpenColorIO/ExceptionBase"); env->ThrowNew(je, e.what()); env->DeleteLocalRef(je); } catch (std::exception& e) { jclass je = env->FindClass("java/lang/Exception"); env->ThrowNew(je, e.what()); env->DeleteLocalRef(je); } catch (...) { jclass je = env->FindClass("java/lang/Exception"); env->ThrowNew(je, "Unknown C++ exception caught."); env->DeleteLocalRef(je); } } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/jniglue/Manifest.txt.in0000644000175000017500000000050213223553423021423 0ustar mfvmfvName: org/OpenColorIO/ Specification-Title: OpenColorIO - Open Source Color Management Specification-Version: @OCIO_VERSION@ Specification-Vendor: Sony Pictures Imageworks Inc., et al. Implementation-Title: org.OpenColorIO Implementation-Version: @OCIO_VERSION@ Implementation-Vendor: Sony Pictures Imageworks Inc., et al.opencolorio-1.1.0~dfsg0.orig/src/jniglue/LoadLibrary.java.in0000644000175000017500000000336213223553423022172 0ustar mfvmfv/* 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. */ package org.OpenColorIO; public class LoadLibrary { public LoadLibrary() { } protected LoadLibrary(long impl) { m_impl = impl; } public long m_impl = 0; static { System.loadLibrary("OpenColorIO-JNI.@OCIO_VERSION@"); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNIImageDesc.cpp0000644000175000017500000003063513223553423021407 0ustar mfvmfv/* 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 "OpenColorIO/OpenColorIO.h" #include "OpenColorIOJNI.h" #include "JNIUtil.h" OCIO_NAMESPACE_USING namespace { void ImageDesc_deleter(ImageDesc* d) { delete d; } void ImageDesc_dispose(JNIEnv * env, jobject self) { DisposeJOCIO(env, self); } }; // end anon namespace // PackedImageDesc JNIEXPORT void JNICALL Java_org_OpenColorIO_PackedImageDesc_create__Ljava_nio_FloatBuffer_2JJJ(JNIEnv * env, jobject self, jobject data, jlong width, jlong height, jlong numChannels) { OCIO_JNITRY_ENTER() float* _data = GetJFloatBuffer(env, data, width * height * numChannels); if(!_data) throw Exception("Could not find direct buffer address for data"); ImageDescJNI * jnistruct = new ImageDescJNI(); jnistruct->back_ptr = env->NewGlobalRef(self); jnistruct->constcppobj = new ConstImageDescRcPtr(); jnistruct->cppobj = new ImageDescRcPtr(); *jnistruct->cppobj = ImageDescRcPtr(new PackedImageDesc(_data, (long)width, (long)height, (long)numChannels), &ImageDesc_deleter); jnistruct->isconst = false; jclass wclass = env->GetObjectClass(self); jfieldID fid = env->GetFieldID(wclass, "m_impl", "J"); env->SetLongField(self, fid, (jlong)jnistruct); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_PackedImageDesc_create__Ljava_nio_FloatBuffer_2JJJJJJ(JNIEnv * env, jobject self, jobject data, jlong width, jlong height, jlong numChannels, jlong chanStrideBytes, jlong xStrideBytes, jlong yStrideBytes) { OCIO_JNITRY_ENTER() float* _data = GetJFloatBuffer(env, data, width * height * numChannels); if(!_data) throw Exception("Could not find direct buffer address for data"); ImageDescJNI * jnistruct = new ImageDescJNI(); jnistruct->back_ptr = env->NewGlobalRef(self); jnistruct->constcppobj = new ConstImageDescRcPtr(); jnistruct->cppobj = new ImageDescRcPtr(); *jnistruct->cppobj = ImageDescRcPtr(new PackedImageDesc(_data, (long)width, (long)height, (long)numChannels, (long)chanStrideBytes, (long) xStrideBytes, (long)yStrideBytes), &ImageDesc_deleter); jnistruct->isconst = false; jclass wclass = env->GetObjectClass(self); jfieldID fid = env->GetFieldID(wclass, "m_impl", "J"); env->SetLongField(self, fid, (jlong)jnistruct); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_PackedImageDesc_dispose(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ImageDesc_dispose(env, self); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_PackedImageDesc_getData(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPackedImageDescRcPtr ptr = DynamicPtrCast(img); int size = ptr->getWidth() * ptr->getHeight() * ptr->getNumChannels(); return NewJFloatBuffer(env, ptr->getData(), size); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jlong JNICALL Java_org_OpenColorIO_PackedImageDesc_getWidth(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPackedImageDescRcPtr ptr = DynamicPtrCast(img); return (jlong)ptr->getWidth(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jlong JNICALL Java_org_OpenColorIO_PackedImageDesc_getHeight(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPackedImageDescRcPtr ptr = DynamicPtrCast(img); return (jlong)ptr->getHeight(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jlong JNICALL Java_org_OpenColorIO_PackedImageDesc_getNumChannels(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPackedImageDescRcPtr ptr = DynamicPtrCast(img); return (jlong)ptr->getNumChannels(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jlong JNICALL Java_org_OpenColorIO_PackedImageDesc_getChanStrideBytes(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPackedImageDescRcPtr ptr = DynamicPtrCast(img); return (jlong)ptr->getChanStrideBytes(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jlong JNICALL Java_org_OpenColorIO_PackedImageDesc_getXStrideBytes(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPackedImageDescRcPtr ptr = DynamicPtrCast(img); return (jlong)ptr->getXStrideBytes(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jlong JNICALL Java_org_OpenColorIO_PackedImageDesc_getYStrideBytes(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPackedImageDescRcPtr ptr = DynamicPtrCast(img); return (jlong)ptr->getYStrideBytes(); OCIO_JNITRY_EXIT(0) } // PlanarImageDesc JNIEXPORT void JNICALL Java_org_OpenColorIO_PlanarImageDesc_dispose(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ImageDesc_dispose(env, self); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_PlanarImageDesc_create__Ljava_nio_FloatBuffer_2Ljava_nio_FloatBuffer_2Ljava_nio_FloatBuffer_2Ljava_nio_FloatBuffer_2JJ (JNIEnv * env, jobject self, jobject rData, jobject gData, jobject bData, jobject aData, jlong width, jlong height) { OCIO_JNITRY_ENTER() int32_t size = width * height; float* _rdata = GetJFloatBuffer(env, rData, size); if(!_rdata) throw Exception("Could not find direct buffer address for rData"); float* _gdata = GetJFloatBuffer(env, gData, size); if(!_gdata) throw Exception("Could not find direct buffer address for gData"); float* _bdata = GetJFloatBuffer(env, bData, size); if(!_bdata) throw Exception("Could not find direct buffer address for bData"); float* _adata = GetJFloatBuffer(env, aData, size); if(!_adata) throw Exception("Could not find direct buffer address for aData"); ImageDescJNI * jnistruct = new ImageDescJNI(); jnistruct->back_ptr = env->NewGlobalRef(self); jnistruct->constcppobj = new ConstImageDescRcPtr(); jnistruct->cppobj = new ImageDescRcPtr(); *jnistruct->cppobj = ImageDescRcPtr(new PlanarImageDesc(_rdata, _gdata, _bdata, _adata, (long)width, (long)height), &ImageDesc_deleter); jnistruct->isconst = false; jclass wclass = env->GetObjectClass(self); jfieldID fid = env->GetFieldID(wclass, "m_impl", "J"); env->SetLongField(self, fid, (jlong)jnistruct); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_PlanarImageDesc_create__Ljava_nio_FloatBuffer_2Ljava_nio_FloatBuffer_2Ljava_nio_FloatBuffer_2Ljava_nio_FloatBuffer_2JJJ (JNIEnv * env, jobject self, jobject rData, jobject gData, jobject bData, jobject aData, jlong width, jlong height, jlong yStrideBytes) { OCIO_JNITRY_ENTER() int32_t size = width * height; float* _rdata = GetJFloatBuffer(env, rData, size); if(!_rdata) throw Exception("Could not find direct buffer address for rData"); float* _gdata = GetJFloatBuffer(env, gData, size); if(!_gdata) throw Exception("Could not find direct buffer address for gData"); float* _bdata = GetJFloatBuffer(env, bData, size); if(!_bdata) throw Exception("Could not find direct buffer address for bData"); float* _adata = GetJFloatBuffer(env, aData, size); if(!_adata) throw Exception("Could not find direct buffer address for aData"); ImageDescJNI * jnistruct = new ImageDescJNI(); jnistruct->back_ptr = env->NewGlobalRef(self); jnistruct->constcppobj = new ConstImageDescRcPtr(); jnistruct->cppobj = new ImageDescRcPtr(); *jnistruct->cppobj = ImageDescRcPtr(new PlanarImageDesc(_rdata, _gdata, _bdata, _adata, (long)width, (long)height, (long)yStrideBytes), &ImageDesc_deleter); jnistruct->isconst = false; jclass wclass = env->GetObjectClass(self); jfieldID fid = env->GetFieldID(wclass, "m_impl", "J"); env->SetLongField(self, fid, (jlong)jnistruct); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_PlanarImageDesc_getRData(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPlanarImageDescRcPtr ptr = DynamicPtrCast(img); int size = ptr->getWidth() * ptr->getHeight(); return NewJFloatBuffer(env, ptr->getRData(), size); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_PlanarImageDesc_getGData(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPlanarImageDescRcPtr ptr = DynamicPtrCast(img); int size = ptr->getWidth() * ptr->getHeight(); return NewJFloatBuffer(env, ptr->getGData(), size); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_PlanarImageDesc_getBData(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPlanarImageDescRcPtr ptr = DynamicPtrCast(img); int size = ptr->getWidth() * ptr->getHeight(); return NewJFloatBuffer(env, ptr->getBData(), size); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_PlanarImageDesc_getAData(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPlanarImageDescRcPtr ptr = DynamicPtrCast(img); int size = ptr->getWidth() * ptr->getHeight(); return NewJFloatBuffer(env, ptr->getAData(), size); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jlong JNICALL Java_org_OpenColorIO_PlanarImageDesc_getWidth(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPlanarImageDescRcPtr ptr = DynamicPtrCast(img); return (jlong)ptr->getWidth(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jlong JNICALL Java_org_OpenColorIO_PlanarImageDesc_getHeight(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPlanarImageDescRcPtr ptr = DynamicPtrCast(img); return (jlong)ptr->getHeight(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jlong JNICALL Java_org_OpenColorIO_PlanarImageDesc_getYStrideBytes(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstImageDescRcPtr img = GetConstJOCIO(env, self); ConstPlanarImageDescRcPtr ptr = DynamicPtrCast(img); return (jlong)ptr->getYStrideBytes(); OCIO_JNITRY_EXIT(0) } opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNIConfig.cpp0000644000175000017500000005770413223553423021001 0ustar mfvmfv/* 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 #include #include #include "OpenColorIO/OpenColorIO.h" #include "OpenColorIOJNI.h" #include "JNIUtil.h" OCIO_NAMESPACE_USING JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_dispose(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() DisposeJOCIO(env, self); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/Config"), Config::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_CreateFromEnv(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Config"), Config::CreateFromEnv()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_CreateFromFile(JNIEnv * env, jobject self, jstring filename) { OCIO_JNITRY_ENTER() return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Config"), Config::CreateFromFile(GetJStringValue(env, filename)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_CreateFromStream(JNIEnv * env, jobject self, jstring istream) { OCIO_JNITRY_ENTER() std::istringstream is; is.str(std::string(GetJStringValue(env, istream)())); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Config"), Config::CreateFromStream(is)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_createEditableCopy(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return BuildJObject(env, self, env->FindClass("org/OpenColorIO/Config"), cfg->createEditableCopy()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_sanityCheck(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); cfg->sanityCheck(); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getDescription(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getDescription()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_setDescription(JNIEnv * env, jobject self, jstring description) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->setDescription(GetJStringValue(env, description)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_serialize(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); std::ostringstream os; cfg->serialize(os); return env->NewStringUTF(os.str().c_str()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getCacheID__(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getCacheID()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getCacheID__Lorg_OpenColorIO_Context_2(JNIEnv * env, jobject self, jobject context) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); ConstContextRcPtr con = GetConstJOCIO(env, context); return env->NewStringUTF(cfg->getCacheID(con)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_getCurrentContext(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Context"), cfg->getCurrentContext()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_addEnvironmentVar(JNIEnv * env, jobject self, jstring name, jstring defaultValue) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->addEnvironmentVar(GetJStringValue(env, name)(), GetJStringValue(env, defaultValue)()); OCIO_JNITRY_EXIT() } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Config_getNumEnvironmentVars(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return (jint)cfg->getNumEnvironmentVars(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getEnvironmentVarNameByIndex(JNIEnv * env, jobject self, jint index) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getEnvironmentVarNameByIndex((int)index)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getEnvironmentVarDefault(JNIEnv * env, jobject self, jstring name) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getEnvironmentVarDefault(GetJStringValue(env, name)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_clearEnvironmentVars(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->clearEnvironmentVars(); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getSearchPath(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getSearchPath()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_setSearchPath(JNIEnv * env, jobject self, jstring path) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->setSearchPath(GetJStringValue(env, path)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getWorkingDir(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getWorkingDir()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_setWorkingDir(JNIEnv * env, jobject self, jstring dirname) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->setWorkingDir(GetJStringValue(env, dirname)()); OCIO_JNITRY_EXIT() } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Config_getNumColorSpaces(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return (jint)cfg->getNumColorSpaces(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getColorSpaceNameByIndex(JNIEnv * env, jobject self, jint index) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getColorSpaceNameByIndex((int)index)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_getColorSpace(JNIEnv * env, jobject self, jstring name) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/ColorSpace"), cfg->getColorSpace(GetJStringValue(env, name)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Config_getIndexForColorSpace(JNIEnv * env, jobject self, jstring name) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return (jint)cfg->getIndexForColorSpace(GetJStringValue(env, name)()); OCIO_JNITRY_EXIT(0) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_addColorSpace(JNIEnv * env, jobject self, jobject cs) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); ConstColorSpaceRcPtr space = GetConstJOCIO(env, cs); cfg->addColorSpace(space); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_clearColorSpaces(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->clearColorSpaces(); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_parseColorSpaceFromString(JNIEnv * env, jobject self, jstring str) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); return env->NewStringUTF(cfg->parseColorSpaceFromString(GetJStringValue(env, str)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_Config_isStrictParsingEnabled(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return (jboolean)cfg->isStrictParsingEnabled(); OCIO_JNITRY_EXIT(false) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_setStrictParsingEnabled(JNIEnv * env, jobject self, jboolean enabled) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->setStrictParsingEnabled((bool)enabled); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_setRole(JNIEnv * env, jobject self, jstring role, jstring colorSpaceName) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->setRole(GetJStringValue(env, role)(), GetJStringValue(env, colorSpaceName)()); OCIO_JNITRY_EXIT() } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Config_getNumRoles(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return (jint)cfg->getNumRoles(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jboolean JNICALL Java_org_OpenColorIO_Config_hasRole(JNIEnv * env, jobject self, jstring role) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return (jboolean)cfg->hasRole(GetJStringValue(env, role)()); OCIO_JNITRY_EXIT(false) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getRoleName(JNIEnv * env, jobject self, jint index) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getRoleName((int)index)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getDefaultDisplay(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getDefaultDisplay()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Config_getNumDisplays(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return (jint)cfg->getNumDisplays(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getDisplay(JNIEnv * env, jobject self, jint index) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getDisplay((int)index)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getDefaultView(JNIEnv * env, jobject self, jstring display) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getDefaultView(GetJStringValue(env, display)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Config_getNumViews(JNIEnv * env, jobject self, jstring display) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return (jint)cfg->getNumViews(GetJStringValue(env, display)()); OCIO_JNITRY_EXIT(0) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getView(JNIEnv * env, jobject self, jstring display, jint index) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getView(GetJStringValue(env, display)(), (int)index)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getDisplayColorSpaceName(JNIEnv * env, jobject self, jstring display, jstring view) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getDisplayColorSpaceName(GetJStringValue(env, display)(), GetJStringValue(env, view)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getDisplayLooks(JNIEnv * env, jobject self, jstring display, jstring view) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getDisplayLooks(GetJStringValue(env, display)(), GetJStringValue(env, view)())); OCIO_JNITRY_EXIT(NULL) } // TODO: seems that 4 string params causes a memory error in the JNI layer? /* JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_addDisplay(JNIEnv * env, jobject self, jstring display, jstring view, jstring colorSpaceName, jstring looks) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->addDisplay(GetJStringValue(env, display)(), GetJStringValue(env, view)(), GetJStringValue(env, colorSpaceName)(), GetJStringValue(env, looks)()); OCIO_JNITRY_EXIT() } */ JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_clearDisplays(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->clearDisplays(); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_setActiveDisplays(JNIEnv * env, jobject self, jstring displays) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->setActiveDisplays(GetJStringValue(env, displays)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getActiveDisplays(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getActiveDisplays()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_setActiveViews(JNIEnv * env, jobject self, jstring views) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->setActiveViews(GetJStringValue(env, views)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getActiveViews(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getActiveViews()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_getDefaultLumaCoefs(JNIEnv * env, jobject self, jfloatArray rgb) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); cfg->getDefaultLumaCoefs(SetJFloatArrayValue(env, rgb, "rgb", 3)()); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_setDefaultLumaCoefs(JNIEnv * env, jobject self, jfloatArray rgb) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->setDefaultLumaCoefs(GetJFloatArrayValue(env, rgb, "rgb", 3)()); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_getLook(JNIEnv * env, jobject self, jstring name) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Look"), cfg->getLook(GetJStringValue(env, name)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jint JNICALL Java_org_OpenColorIO_Config_getNumLooks(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return (jint)cfg->getNumLooks(); OCIO_JNITRY_EXIT(0) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Config_getLookNameByIndex(JNIEnv * env, jobject self, jint index) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return env->NewStringUTF(cfg->getLookNameByIndex((int)index)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_addLook(JNIEnv * env, jobject self, jobject look) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); ConstLookRcPtr lok = GetConstJOCIO(env, look); cfg->addLook(lok); OCIO_JNITRY_EXIT() } JNIEXPORT void JNICALL Java_org_OpenColorIO_Config_clearLooks(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConfigRcPtr cfg = GetEditableJOCIO(env, self); cfg->clearLooks(); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_getProcessor__Lorg_OpenColorIO_Context_2Lorg_OpenColorIO_ColorSpace_2Lorg_OpenColorIO_ColorSpace_2 (JNIEnv * env, jobject self, jobject context, jobject srcColorSpace, jobject dstColorSpace) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); ConstContextRcPtr con = GetConstJOCIO(env, context); ConstColorSpaceRcPtr src = GetConstJOCIO(env, srcColorSpace); ConstColorSpaceRcPtr dst = GetConstJOCIO(env, dstColorSpace); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Processor"), cfg->getProcessor(con, src, dst)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_getProcessor__Lorg_OpenColorIO_ColorSpace_2Lorg_OpenColorIO_ColorSpace_2 (JNIEnv * env, jobject self, jobject srcColorSpace, jobject dstColorSpace) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); ConstColorSpaceRcPtr src = GetConstJOCIO(env, srcColorSpace); ConstColorSpaceRcPtr dst = GetConstJOCIO(env, dstColorSpace); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Processor"), cfg->getProcessor(src, dst)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_getProcessor__Ljava_lang_String_2Ljava_lang_String_2 (JNIEnv * env, jobject self, jstring srcName, jstring dstName) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Processor"), cfg->getProcessor( GetJStringValue(env, srcName)(), GetJStringValue(env, dstName)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_getProcessor__Lorg_OpenColorIO_Context_2Ljava_lang_String_2Ljava_lang_String_2 (JNIEnv * env, jobject self, jobject context, jstring srcName, jstring dstName) { OCIO_JNITRY_ENTER() ConstContextRcPtr con = GetConstJOCIO(env, context); ConstConfigRcPtr cfg = GetConstJOCIO(env, self); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Processor"), cfg->getProcessor(con, GetJStringValue(env, srcName)(), GetJStringValue(env, dstName)())); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_getProcessor__Lorg_OpenColorIO_Transform_2 (JNIEnv * env, jobject self, jobject transform) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); ConstTransformRcPtr tran = GetConstJOCIO(env, transform); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Processor"), cfg->getProcessor(tran)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_getProcessor__Lorg_OpenColorIO_Transform_2Lorg_OpenColorIO_TransformDirection_2 (JNIEnv * env, jobject self, jobject transform, jobject direction) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); ConstTransformRcPtr tran = GetConstJOCIO(env, transform); TransformDirection dir = GetJEnum(env, direction); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Processor"), cfg->getProcessor(tran, dir)); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Config_getProcessor__Lorg_OpenColorIO_Context_2Lorg_OpenColorIO_Transform_2Lorg_OpenColorIO_TransformDirection_2 (JNIEnv * env, jobject self, jobject context, jobject transform, jobject direction) { OCIO_JNITRY_ENTER() ConstConfigRcPtr cfg = GetConstJOCIO(env, self); ConstContextRcPtr con = GetConstJOCIO(env, context); ConstTransformRcPtr tran = GetConstJOCIO(env, transform); TransformDirection dir = GetJEnum(env, direction); return BuildJConstObject(env, self, env->FindClass("org/OpenColorIO/Processor"), cfg->getProcessor(con, tran, dir)); OCIO_JNITRY_EXIT(NULL) } opencolorio-1.1.0~dfsg0.orig/src/jniglue/JNILook.cpp0000644000175000017500000001237313223553423020471 0ustar mfvmfv/* 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 #include #include #include "OpenColorIO/OpenColorIO.h" #include "OpenColorIOJNI.h" #include "JNIUtil.h" OCIO_NAMESPACE_USING JNIEXPORT void JNICALL Java_org_OpenColorIO_Look_dispose(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() DisposeJOCIO(env, self); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Look_Create(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() return BuildJObject(env, self, env->FindClass("org/OpenColorIO/Look"), Look::Create()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Look_getName(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstLookRcPtr lok = GetConstJOCIO(env, self); return env->NewStringUTF(lok->getName()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Look_setName(JNIEnv * env, jobject self, jstring name) { OCIO_JNITRY_ENTER() LookRcPtr lok = GetEditableJOCIO(env, self); lok->setName(GetJStringValue(env, name)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Look_getProcessSpace(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstLookRcPtr lok = GetConstJOCIO(env, self); return env->NewStringUTF(lok->getProcessSpace()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Look_setProcessSpace(JNIEnv * env, jobject self, jstring processSpace) { OCIO_JNITRY_ENTER() LookRcPtr lok = GetEditableJOCIO(env, self); lok->setProcessSpace(GetJStringValue(env, processSpace)()); OCIO_JNITRY_EXIT() } JNIEXPORT jstring JNICALL Java_org_OpenColorIO_Look_getDescription(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstLookRcPtr lok = GetConstJOCIO(env, self); return env->NewStringUTF(lok->getDescription()); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Look_setDescription(JNIEnv * env, jobject self, jstring processSpace) { OCIO_JNITRY_ENTER() LookRcPtr lok = GetEditableJOCIO(env, self); lok->setDescription(GetJStringValue(env, processSpace)()); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Look_getTransform(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstLookRcPtr lok = GetConstJOCIO(env, self); ConstTransformRcPtr tr = lok->getTransform(); return BuildJConstObject(env, self, env->FindClass(GetOCIOTClass(tr)), tr); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Look_setTransform(JNIEnv * env, jobject self, jobject transform) { OCIO_JNITRY_ENTER() LookRcPtr lok = GetEditableJOCIO(env, self); ConstTransformRcPtr tran = GetConstJOCIO(env, transform); lok->setTransform(tran); OCIO_JNITRY_EXIT() } JNIEXPORT jobject JNICALL Java_org_OpenColorIO_Look_getInverseTransform(JNIEnv * env, jobject self) { OCIO_JNITRY_ENTER() ConstLookRcPtr lok = GetConstJOCIO(env, self); ConstTransformRcPtr tr = lok->getInverseTransform(); return BuildJConstObject(env, self, env->FindClass(GetOCIOTClass(tr)), tr); OCIO_JNITRY_EXIT(NULL) } JNIEXPORT void JNICALL Java_org_OpenColorIO_Look_setInverseTransform(JNIEnv * env, jobject self, jobject transform) { OCIO_JNITRY_ENTER() LookRcPtr lok = GetEditableJOCIO(env, self); ConstTransformRcPtr tran = GetConstJOCIO(env, transform); lok->setInverseTransform(tran); OCIO_JNITRY_EXIT() } opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/0000755000175000017500000000000013223553423017654 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/0000755000175000017500000000000013223553423020443 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/0000755000175000017500000000000013223553423022573 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/OpenColorIOTestSuite.java0000644000175000017500000000152613223553423027444 0ustar mfvmfv import junit.framework.Test; import junit.framework.TestSuite; public class OpenColorIOTestSuite { public static Test suite() { TestSuite suite = new TestSuite(); // Core suite.addTestSuite(GlobalsTest.class); suite.addTestSuite(ConfigTest.class); suite.addTestSuite(ColorSpaceTest.class); suite.addTestSuite(LookTest.class); suite.addTestSuite(BakerTest.class); suite.addTestSuite(PackedImageDescTest.class); suite.addTestSuite(PlanarImageDescTest.class); suite.addTestSuite(GpuShaderDescTest.class); suite.addTestSuite(ContextTest.class); suite.addTestSuite(TransformsTest.class); return suite; } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/PlanarImageDescTest.java0000644000175000017500000000323013223553423027253 0ustar mfvmfv import junit.framework.TestCase; import org.OpenColorIO.*; import java.nio.*; public class PlanarImageDescTest extends TestCase { protected void setUp() { } protected void tearDown() { } public void test_interface() { int width = 2; int height = 2; int channels = 4; // float rpix[] = new float[]{0.1f, 0.2f, 0.3f, 0.4f}; float gpix[] = new float[]{0.1f, 0.2f, 0.3f, 0.4f}; float bpix[] = new float[]{0.1f, 0.2f, 0.3f, 0.4f}; float apix[] = new float[]{1.0f, 1.0f, 1.0f, 1.0f}; int alloc = width * height * Float.SIZE / 8; // FloatBuffer rbuf = ByteBuffer.allocateDirect(alloc).asFloatBuffer(); rbuf.put(rpix); FloatBuffer gbuf = ByteBuffer.allocateDirect(alloc).asFloatBuffer(); gbuf.put(gpix); FloatBuffer bbuf = ByteBuffer.allocateDirect(alloc).asFloatBuffer(); bbuf.put(bpix); FloatBuffer abuf = ByteBuffer.allocateDirect(alloc).asFloatBuffer(); abuf.put(apix); // PlanarImageDesc foo = new PlanarImageDesc(rbuf, gbuf, bbuf, abuf, width, height); FloatBuffer trb = foo.getRData(); FloatBuffer tgb = foo.getGData(); FloatBuffer tbb = foo.getBData(); FloatBuffer tab = foo.getAData(); assertEquals(0.1f, trb.get(0)); assertEquals(0.2f, tgb.get(1)); assertEquals(0.3f, tbb.get(2)); assertEquals(1.0f, tab.get(3)); assertEquals(2, foo.getWidth()); assertEquals(2, foo.getHeight()); assertEquals(8, foo.getYStrideBytes()); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/ConfigTest.java0000644000175000017500000002427113223553423025511 0ustar mfvmfv import junit.framework.TestCase; import org.OpenColorIO.*; import java.nio.*; public class ConfigTest extends TestCase { String SIMPLE_PROFILE = "" + "ocio_profile_version: 1\n" + "\n" + "search_path: luts\n" + "strictparsing: false\n" + "luma: [0.2126, 0.7152, 0.0722]\n" + "\n" + "roles:\n" + " default: raw\n" + " scene_linear: lnh\n" + "\n" + "displays:\n" + " sRGB:\n" + " - ! {name: Film1D, colorspace: vd8}\n" + " - ! {name: Raw, colorspace: raw}\n" + "\n" + "active_displays: []\n" + "active_views: []\n" + "\n" + "colorspaces:\n" + " - !\n" + " name: raw\n" + " family: raw\n" + " bitdepth: 32f\n" + " description: |\n" + " A raw color space. Conversions to and from this space are no-ops.\n" + " \n" + " isdata: true\n" + " allocation: uniform\n" + "\n" + " - !\n" + " name: lnh\n" + " family: ln\n" + " bitdepth: 16f\n" + " description: |\n" + " The show reference space. This is a sensor referred linear\n" + " representation of the scene with primaries that correspond to\n" + " scanned film. 0.18 in this space corresponds to a properly\n" + " exposed 18% grey card.\n" + " \n" + " isdata: false\n" + " allocation: lg2\n" + "\n" + " - !\n" + " name: vd8\n" + " family: vd8\n" + " bitdepth: 8ui\n" + " description: |\n" + " how many transforms can we use?\n" + " \n" + " isdata: false\n" + " allocation: uniform\n" + " to_reference: !\n" + " children:\n" + " - ! {value: [2.2, 2.2, 2.2, 1]}\n" + " - ! {matrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], offset: [0, 0, 0, 0]}\n" + " - ! {slope: [1, 1, 1], offset: [0.1, 0.3, 0.4], power: [1.1, 1.1, 1.1], saturation: 0.9}\n"; String GLSLResult = "" + "\n" + "// Generated by OpenColorIO\n" + "\n" + "vec4 jnitestocio(in vec4 inPixel, \n" + " const sampler3D lut3d) \n" + "{\n" + "vec4 out_pixel = inPixel; \n" + "out_pixel = out_pixel * mat4(1.08749, -0.0794667, -0.00802222, 0, -0.0236222, 1.03164, -0.00802222, 0, -0.0236222, -0.0794667, 1.10309, 0, 0, 0, 0, 1);\n" + "out_pixel = pow(max(out_pixel, vec4(0, 0, 0, 0)), vec4(0.909091, 0.909091, 0.909091, 1));\n" + "out_pixel = vec4(-0.1, -0.3, -0.4, -0) + out_pixel;\n" + "out_pixel = pow(max(out_pixel, vec4(0, 0, 0, 0)), vec4(0.454545, 0.454545, 0.454545, 1));\n" + "// OSX segfault work-around: Force a no-op sampling of the 3d lut.\n" + "texture3D(lut3d, 0.96875 * out_pixel.rgb + 0.015625).rgb;\n" + "return out_pixel;\n" + "}\n" + "\n"; protected void setUp() { } protected void tearDown() { } public void test_interface() { Config _cfg = new Config().CreateFromStream(SIMPLE_PROFILE); Config _cfge = _cfg.createEditableCopy(); _cfge.clearEnvironmentVars(); assertEquals(0, _cfge.getNumEnvironmentVars()); _cfge.addEnvironmentVar("FOO", "test1"); _cfge.addEnvironmentVar("FOO2", "test2${FOO}"); assertEquals(2, _cfge.getNumEnvironmentVars()); assertEquals("FOO", _cfge.getEnvironmentVarNameByIndex(0)); assertEquals("FOO2", _cfge.getEnvironmentVarNameByIndex(1)); assertEquals("test1", _cfge.getEnvironmentVarDefault("FOO")); assertEquals("test2${FOO}", _cfge.getEnvironmentVarDefault("FOO2")); assertEquals("test2test1", _cfge.getCurrentContext().resolveStringVar("${FOO2}")); //self.assertEqual({'FOO': 'test1', 'FOO2': 'test2${FOO}'}, _cfge.getEnvironmentVarDefaults()) _cfge.clearEnvironmentVars(); assertEquals(0, _cfge.getNumEnvironmentVars()); assertEquals("luts", _cfge.getSearchPath()); _cfge.setSearchPath("otherdir"); assertEquals("otherdir", _cfge.getSearchPath()); _cfge.sanityCheck(); _cfge.setDescription("testdesc"); assertEquals("testdesc", _cfge.getDescription()); //assertEquals(SIMPLE_PROFILE, _cfg.serialize()); //assertEquals("$07d1fb1509eeae1837825fd4242f8a69:$885ad1683add38a11f7bbe34e8bf9ac0", // _cfg.getCacheID()); Context con = _cfg.getCurrentContext(); assertNotSame(0, con.getNumStringVars()); //assertEquals("", _cfg.getCacheID(con)); // test env makes this fail //assertEquals("", _cfge.getWorkingDir()); _cfge.setWorkingDir("/foobar"); assertEquals("/foobar", _cfge.getWorkingDir()); assertEquals(3, _cfge.getNumColorSpaces()); assertEquals("lnh", _cfge.getColorSpaceNameByIndex(1)); //public native ColorSpace getColorSpace(String name); assertEquals(0, _cfge.getIndexForColorSpace("foobar")); //public native void addColorSpace(ColorSpace cs); //public native void clearColorSpaces(); //public native String parseColorSpaceFromString(String str); if(_cfg.isStrictParsingEnabled()) fail("strict parsing should be off"); _cfge.setStrictParsingEnabled(true); if(!_cfge.isStrictParsingEnabled()) fail("strict parsing should be on"); assertEquals(2, _cfge.getNumRoles()); if(_cfg.hasRole("foo")) fail("shouldn't have role foo"); _cfge.setRole("foo", "dfadfadf"); assertEquals(3, _cfge.getNumRoles()); if(!_cfge.hasRole("foo")) fail("should have role foo"); assertEquals("foo", _cfge.getRoleName(1)); assertEquals("sRGB", _cfge.getDefaultDisplay()); assertEquals(1, _cfge.getNumDisplays()); assertEquals("sRGB", _cfge.getDisplay(0)); assertEquals("Film1D", _cfge.getDefaultView("sRGB")); assertEquals(2, _cfge.getNumViews("sRGB")); assertEquals("Raw", _cfge.getView("sRGB", 1)); assertEquals("vd8", _cfge.getDisplayColorSpaceName("sRGB", "Film1D")); assertEquals("", _cfg.getDisplayLooks("sRGB", "Film1D")); // TODO: seems that 4 string params causes a memory error in the JNI layer? //_cfge.addDisplay("foo", "bar", "foo", 0); _cfge.clearDisplays(); _cfge.setActiveDisplays("sRGB"); assertEquals("sRGB", _cfge.getActiveDisplays()); _cfge.setActiveViews("Film1D"); assertEquals("Film1D", _cfge.getActiveViews()); float luma[] = new float[3]; _cfge.getDefaultLumaCoefs(luma); assertEquals(0.2126, luma[0], 1e-8); float[] newluma = new float[]{0.1f, 0.2f, 0.3f}; _cfge.setDefaultLumaCoefs(newluma); float tnewluma[] = new float[3]; _cfge.getDefaultLumaCoefs(tnewluma); assertEquals(0.1f, tnewluma[0], 1e-8); assertEquals(0, _cfge.getNumLooks()); Look lk = new Look().Create(); lk.setName("coollook"); lk.setProcessSpace("somespace"); ExponentTransform et = new ExponentTransform().Create(); et.setValue(new float[]{0.1f, 0.2f, 0.3f, 0.4f}); lk.setTransform(et); ExponentTransform iet = new ExponentTransform().Create(); iet.setValue(new float[]{-0.1f, -0.2f, -0.3f, -0.4f}); lk.setInverseTransform(iet); _cfge.addLook(lk); assertEquals(1, _cfge.getNumLooks()); assertEquals("coollook", _cfge.getLookNameByIndex(0)); Look glk = _cfge.getLook("coollook"); assertEquals("somespace", glk.getProcessSpace()); _cfge.clearLooks(); assertEquals(0, _cfge.getNumLooks()); //public native Processor getProcessor(Context context, ColorSpace srcColorSpace, ColorSpace dstColorSpace); Processor _proc = _cfg.getProcessor("lnh", "vd8"); assertEquals(false, _proc.isNoOp()); assertEquals(true, _proc.hasChannelCrosstalk()); float packedpix[] = new float[]{0.48f, 0.18f, 0.9f, 1.0f, 0.48f, 0.18f, 0.18f, 1.0f, 0.48f, 0.18f, 0.18f, 1.0f, 0.48f, 0.18f, 0.18f, 1.0f }; FloatBuffer buf = ByteBuffer.allocateDirect(2 * 2 * 4 * Float.SIZE / 8).asFloatBuffer(); buf.put(packedpix); PackedImageDesc foo = new PackedImageDesc(buf, 2, 2, 4); _proc.apply(foo); FloatBuffer wee = foo.getData(); assertEquals(-2.4307251581696764E-35f, wee.get(2), 1e-8); float rgbfoo[] = new float[]{0.48f, 0.18f, 0.18f}; _proc.applyRGB(rgbfoo); assertEquals(0.6875247f, rgbfoo[0], 1e-8); float rgbafoo[] = new float[]{0.48f, 0.18f, 0.18f, 1.f}; _proc.applyRGBA(rgbafoo); assertEquals(1.f, rgbafoo[3], 1e-8); //assertEquals("$a92ef63abd9edf61ad5a7855da064648", _proc.getCpuCacheID()); GpuShaderDesc desc = new GpuShaderDesc(); desc.setLanguage(GpuLanguage.GPU_LANGUAGE_GLSL_1_3); desc.setFunctionName("jnitestocio"); desc.setLut3DEdgeLen(32); String glsl = _proc.getGpuShaderText(desc); //assertEquals(GLSLResult, glsl); //assertEquals("$1dead2bf42974cd1769164e45a0c9e40", _proc.getGpuShaderTextCacheID(desc)); int len = desc.getLut3DEdgeLen(); int size = 3 * len * len * len; FloatBuffer lut3d = ByteBuffer.allocateDirect(size * Float.SIZE / 8).asFloatBuffer(); _proc.getGpuLut3D(lut3d, desc); assertEquals(0.0f, lut3d.get(size-1)); assertEquals("", _proc.getGpuLut3DCacheID(desc)); //public native Processor getProcessor(Context context, String srcName, String dstName); //public native Processor getProcessor(Transform transform); //public native Processor getProcessor(Transform transform, TransformDirection direction); //public native Processor getProcessor(Context context, Transform transform, TransformDirection direction); _cfge.dispose(); _cfg.dispose(); //System.out.println(_cfge.serialize()); //_cfge.sanityCheck(); //System.out.println(_cfge.getNumColorSpaces()); //System.out.println(_cfg.getCacheID()); //System.out.println(_cfge.serialize()); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/ContextTest.java0000644000175000017500000000310513223553423025721 0ustar mfvmfv import junit.framework.TestCase; import org.OpenColorIO.*; public class ContextTest extends TestCase { protected void setUp() { } protected void tearDown() { } public void test_interface() { Context cont = new Context().Create(); cont.setSearchPath("testing123"); cont.setWorkingDir("/dir/123"); assertEquals("$4c2d66a612fc25ddd509591e1dead57b", cont.getCacheID()); assertEquals("testing123", cont.getSearchPath()); assertEquals("/dir/123", cont.getWorkingDir()); cont.setStringVar("TeSt", "foobar"); assertEquals("foobar", cont.getStringVar("TeSt")); assertEquals(1, cont.getNumStringVars()); assertEquals("TeSt", cont.getStringVarNameByIndex(0)); cont.loadEnvironment(); assertNotSame(0, cont.getNumStringVars()); cont.setStringVar("TEST1", "foobar"); assertEquals("/foo/foobar/bar", cont.resolveStringVar("/foo/${TEST1}/bar")); cont.clearStringVars(); assertEquals(0, cont.getNumStringVars()); assertEquals(EnvironmentMode.ENV_ENVIRONMENT_LOAD_PREDEFINED, cont.getEnvironmentMode()); cont.setEnvironmentMode(EnvironmentMode.ENV_ENVIRONMENT_LOAD_ALL); assertEquals(EnvironmentMode.ENV_ENVIRONMENT_LOAD_ALL, cont.getEnvironmentMode()); try { cont.setSearchPath("testing123"); String foo = cont.resolveFileLocation("test.lut"); System.out.println(foo); } catch (ExceptionMissingFile e) { //System.out.println(e); } } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/LookTest.java0000644000175000017500000000234013223553423025201 0ustar mfvmfv import junit.framework.TestCase; import org.OpenColorIO.*; public class LookTest extends TestCase { protected void setUp() { } protected void tearDown() { } public void test_interface() { Look lk = new Look().Create(); lk.setName("coollook"); assertEquals("coollook", lk.getName()); lk.setProcessSpace("somespace"); assertEquals("somespace", lk.getProcessSpace()); lk.setDescription("this is a test"); assertEquals("this is a test", lk.getDescription()); ExponentTransform et = new ExponentTransform().Create(); et.setValue(new float[]{0.1f, 0.2f, 0.3f, 0.4f}); lk.setTransform(et); ExponentTransform oet = (ExponentTransform)lk.getTransform(); float vals[] = new float[4]; oet.getValue(vals); assertEquals(0.2f, vals[1], 1e-8); ExponentTransform iet = new ExponentTransform().Create(); iet.setValue(new float[]{-0.1f, -0.2f, -0.3f, -0.4f}); lk.setInverseTransform(iet); ExponentTransform ioet = (ExponentTransform)lk.getInverseTransform(); float vals2[] = new float[4]; ioet.getValue(vals2); assertEquals(-0.2f, vals2[1], 1e-8); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/BakerTest.java0000644000175000017500000000604713223553423025331 0ustar mfvmfv import junit.framework.TestCase; import org.OpenColorIO.*; public class BakerTest extends TestCase { String SIMPLE_PROFILE = "" + "ocio_profile_version: 1\n" + "\n" + "strictparsing: false\n" + "\n" + "colorspaces:\n" + "\n" + " - !\n" + " name: lnh\n" + " bitdepth: 16f\n" + " isdata: false\n" + " allocation: lg2\n" + "\n" + " - !\n" + " name: test\n" + " bitdepth: 8ui\n" + " isdata: false\n" + " allocation: uniform\n" + " to_reference: ! {value: [2.2, 2.2, 2.2, 1]}\n"; String EXPECTED_LUT = "" + "CSPLUTV100\n" + "3D\n" + "BEGIN METADATA\n" + "this is some metadata!\n" + "END METADATA\n" + "\n" + "4\n" + "0.000977 0.039373 1.587401 64.000000\n" + "0.000000 0.333333 0.666667 1.000000\n" + "4\n" + "0.000977 0.039373 1.587401 64.000000\n" + "0.000000 0.333333 0.666667 1.000000\n" + "4\n" + "0.000977 0.039373 1.587401 64.000000\n" + "0.000000 0.333333 0.666667 1.000000\n" + "\n" + "2 2 2\n" + "0.042823 0.042823 0.042823\n" + "6.622026 0.042823 0.042823\n" + "0.042823 6.622026 0.042823\n" + "6.622026 6.622026 0.042823\n" + "0.042823 0.042823 6.622026\n" + "6.622026 0.042823 6.622026\n" + "0.042823 6.622026 6.622026\n" + "6.622026 6.622026 6.622026\n" + "\n"; protected void setUp() { } protected void tearDown() { } public void test_interface() { Baker bake = new Baker().Create(); Baker bakee = bake.createEditableCopy(); Config _cfg = new Config().CreateFromStream(SIMPLE_PROFILE); Config cfg = _cfg.createEditableCopy(); assertEquals(2, cfg.getNumColorSpaces()); Look foo = new Look().Create(); foo.setName("foo"); cfg.addLook(foo); Look bar = new Look().Create(); bar.setName("bar"); cfg.addLook(bar); bakee.setConfig(cfg); cfg = bakee.getConfig(); assertEquals(2, cfg.getNumColorSpaces()); bakee.setFormat("cinespace"); assertEquals("cinespace", bakee.getFormat()); bakee.setType("3D"); assertEquals("3D", bakee.getType()); bakee.setMetadata("this is some metadata!"); assertEquals("this is some metadata!", bakee.getMetadata()); bakee.setInputSpace("lnh"); assertEquals("lnh", bakee.getInputSpace()); bakee.setLooks("foo, -bar"); assertEquals("foo, -bar", bakee.getLooks()); bakee.setTargetSpace("test"); assertEquals("test", bakee.getTargetSpace()); bakee.setShaperSize(4); assertEquals(4, bakee.getShaperSize()); bakee.setCubeSize(2); assertEquals(2, bakee.getCubeSize()); String output = bakee.bake(); assertEquals(EXPECTED_LUT, output); assertEquals(5, bakee.getNumFormats()); assertEquals("cinespace", bakee.getFormatNameByIndex(2)); assertEquals("3dl", bakee.getFormatExtensionByIndex(1)); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/GlobalsTest.java0000644000175000017500000002314313223553423025664 0ustar mfvmfv import junit.framework.TestCase; import org.OpenColorIO.*; public class GlobalsTest extends TestCase { String FOO = "" + "ocio_profile_version: 1\n" + "\n" + "search_path: \"\"\n" + "strictparsing: false\n" + "luma: [0.2126, 0.7152, 0.0722]\n" + "\n" + "roles:\n" + " default: raw\n" + "\n" + "displays:\n" + " sRGB:\n" + " - ! {name: Raw, colorspace: raw}\n" + "\n" + "active_displays: []\n" + "active_views: []\n" + "\n" + "colorspaces:\n" + " - !\n" + " name: raw\n" + " family: raw\n" + " equalitygroup: \"\"\n" + " bitdepth: 32f\n" + " description: |\n" + " A raw color space. Conversions to and from this space are no-ops.\n" + " isdata: true\n" + " allocation: uniform\n"; protected void setUp() { } public void test_interface() { Globals globals = new Globals(); // Globals globals.ClearAllCaches(); //assertEquals("1.0.1", globals.GetVersion()); //assertEquals(16777472, globals.GetVersionHex()); assertEquals(LoggingLevel.LOGGING_LEVEL_INFO, globals.GetLoggingLevel()); globals.SetLoggingLevel(LoggingLevel.LOGGING_LEVEL_NONE); assertEquals(LoggingLevel.LOGGING_LEVEL_NONE, globals.GetLoggingLevel()); Config foo = globals.GetCurrentConfig(); assertEquals(FOO, foo.serialize()); globals.SetLoggingLevel(LoggingLevel.LOGGING_LEVEL_INFO); Config bar = new Config().CreateFromStream(foo.serialize()); globals.SetCurrentConfig(bar); Config wee = globals.GetCurrentConfig(); // LoggingLevel assertEquals(globals.LoggingLevelToString(LoggingLevel.LOGGING_LEVEL_NONE), "none"); assertEquals(globals.LoggingLevelFromString("none"), LoggingLevel.LOGGING_LEVEL_NONE); assertEquals(globals.LoggingLevelToString(LoggingLevel.LOGGING_LEVEL_WARNING), "warning"); assertEquals(globals.LoggingLevelFromString("warning"), LoggingLevel.LOGGING_LEVEL_WARNING); assertEquals(globals.LoggingLevelToString(LoggingLevel.LOGGING_LEVEL_INFO), "info"); assertEquals(globals.LoggingLevelFromString("info"), LoggingLevel.LOGGING_LEVEL_INFO); assertEquals(globals.LoggingLevelToString(LoggingLevel.LOGGING_LEVEL_DEBUG), "debug"); assertEquals(globals.LoggingLevelFromString("debug"), LoggingLevel.LOGGING_LEVEL_DEBUG); assertEquals(globals.LoggingLevelToString(LoggingLevel.LOGGING_LEVEL_UNKNOWN), "unknown"); assertEquals(globals.LoggingLevelFromString("unknown"), LoggingLevel.LOGGING_LEVEL_UNKNOWN); // TransformDirection assertEquals(globals.TransformDirectionToString(TransformDirection.TRANSFORM_DIR_UNKNOWN), "unknown"); assertEquals(globals.TransformDirectionFromString("unknown"), TransformDirection.TRANSFORM_DIR_UNKNOWN); assertEquals(globals.TransformDirectionToString(TransformDirection.TRANSFORM_DIR_FORWARD), "forward"); assertEquals(globals.TransformDirectionFromString("forward"), TransformDirection.TRANSFORM_DIR_FORWARD); assertEquals(globals.TransformDirectionToString(TransformDirection.TRANSFORM_DIR_INVERSE), "inverse"); assertEquals(globals.TransformDirectionFromString("inverse"), TransformDirection.TRANSFORM_DIR_INVERSE); assertEquals(globals.GetInverseTransformDirection(TransformDirection.TRANSFORM_DIR_UNKNOWN), TransformDirection.TRANSFORM_DIR_UNKNOWN); assertEquals(globals.GetInverseTransformDirection(TransformDirection.TRANSFORM_DIR_FORWARD), TransformDirection.TRANSFORM_DIR_INVERSE); assertEquals(globals.GetInverseTransformDirection(TransformDirection.TRANSFORM_DIR_INVERSE), TransformDirection.TRANSFORM_DIR_FORWARD); // ColorSpaceDirection assertEquals(globals.ColorSpaceDirectionToString(ColorSpaceDirection.COLORSPACE_DIR_UNKNOWN), "unknown"); assertEquals(globals.ColorSpaceDirectionFromString("unknown"), ColorSpaceDirection.COLORSPACE_DIR_UNKNOWN); assertEquals(globals.ColorSpaceDirectionToString(ColorSpaceDirection.COLORSPACE_DIR_TO_REFERENCE), "to_reference"); assertEquals(globals.ColorSpaceDirectionFromString("to_reference"), ColorSpaceDirection.COLORSPACE_DIR_TO_REFERENCE); assertEquals(globals.ColorSpaceDirectionToString(ColorSpaceDirection.COLORSPACE_DIR_FROM_REFERENCE), "from_reference"); assertEquals(globals.ColorSpaceDirectionFromString("from_reference"), ColorSpaceDirection.COLORSPACE_DIR_FROM_REFERENCE); // BitDepth assertEquals(globals.BitDepthToString(BitDepth.BIT_DEPTH_UNKNOWN), "unknown"); assertEquals(globals.BitDepthFromString("unknown"), BitDepth.BIT_DEPTH_UNKNOWN); assertEquals(globals.BitDepthToString(BitDepth.BIT_DEPTH_UINT8), "8ui"); assertEquals(globals.BitDepthFromString("8ui"), BitDepth.BIT_DEPTH_UINT8); assertEquals(globals.BitDepthToString(BitDepth.BIT_DEPTH_UINT10), "10ui"); assertEquals(globals.BitDepthFromString("10ui"), BitDepth.BIT_DEPTH_UINT10); assertEquals(globals.BitDepthToString(BitDepth.BIT_DEPTH_UINT12), "12ui"); assertEquals(globals.BitDepthFromString("12ui"), BitDepth.BIT_DEPTH_UINT12); assertEquals(globals.BitDepthToString(BitDepth.BIT_DEPTH_UINT14), "14ui"); assertEquals(globals.BitDepthFromString("14ui"), BitDepth.BIT_DEPTH_UINT14); assertEquals(globals.BitDepthToString(BitDepth.BIT_DEPTH_UINT16), "16ui"); assertEquals(globals.BitDepthFromString("16ui"), BitDepth.BIT_DEPTH_UINT16); assertEquals(globals.BitDepthToString(BitDepth.BIT_DEPTH_UINT32), "32ui"); assertEquals(globals.BitDepthFromString("32ui"), BitDepth.BIT_DEPTH_UINT32); assertEquals(globals.BitDepthToString(BitDepth.BIT_DEPTH_F16), "16f"); assertEquals(globals.BitDepthFromString("16f"), BitDepth.BIT_DEPTH_F16); assertEquals(globals.BitDepthToString(BitDepth.BIT_DEPTH_F32), "32f"); assertEquals(globals.BitDepthFromString("32f"), BitDepth.BIT_DEPTH_F32); // Allocation assertEquals(globals.AllocationToString(Allocation.ALLOCATION_UNKNOWN), "unknown"); assertEquals(globals.AllocationFromString("unknown"), Allocation.ALLOCATION_UNKNOWN); assertEquals(globals.AllocationToString(Allocation.ALLOCATION_UNIFORM), "uniform"); assertEquals(globals.AllocationFromString("uniform"), Allocation.ALLOCATION_UNIFORM); assertEquals(globals.AllocationToString(Allocation.ALLOCATION_LG2), "lg2"); assertEquals(globals.AllocationFromString("lg2"), Allocation.ALLOCATION_LG2); // Interpolation assertEquals(globals.InterpolationToString(Interpolation.INTERP_UNKNOWN), "unknown"); assertEquals(globals.InterpolationFromString("unknown"), Interpolation.INTERP_UNKNOWN); assertEquals(globals.InterpolationToString(Interpolation.INTERP_NEAREST), "nearest"); assertEquals(globals.InterpolationFromString("nearest"), Interpolation.INTERP_NEAREST); assertEquals(globals.InterpolationToString(Interpolation.INTERP_LINEAR), "linear"); assertEquals(globals.InterpolationFromString("linear"), Interpolation.INTERP_LINEAR); assertEquals(globals.InterpolationToString(Interpolation.INTERP_TETRAHEDRAL), "tetrahedral"); assertEquals(globals.InterpolationFromString("tetrahedral"), Interpolation.INTERP_TETRAHEDRAL); assertEquals(globals.InterpolationToString(Interpolation.INTERP_BEST), "best"); assertEquals(globals.InterpolationFromString("best"), Interpolation.INTERP_BEST); // GpuLanguage assertEquals(globals.GpuLanguageToString(GpuLanguage.GPU_LANGUAGE_UNKNOWN), "unknown"); assertEquals(globals.GpuLanguageFromString("unknown"), GpuLanguage.GPU_LANGUAGE_UNKNOWN); assertEquals(globals.GpuLanguageToString(GpuLanguage.GPU_LANGUAGE_CG), "cg"); assertEquals(globals.GpuLanguageFromString("cg"), GpuLanguage.GPU_LANGUAGE_CG); assertEquals(globals.GpuLanguageToString(GpuLanguage.GPU_LANGUAGE_GLSL_1_0), "glsl_1.0"); assertEquals(globals.GpuLanguageFromString("glsl_1.0"), GpuLanguage.GPU_LANGUAGE_GLSL_1_0); assertEquals(globals.GpuLanguageToString(GpuLanguage.GPU_LANGUAGE_GLSL_1_3), "glsl_1.3"); assertEquals(globals.GpuLanguageFromString("glsl_1.3"), GpuLanguage.GPU_LANGUAGE_GLSL_1_3); // EnvironmentMode assertEquals(globals.EnvironmentModeToString(EnvironmentMode.ENV_ENVIRONMENT_UNKNOWN), "unknown"); assertEquals(globals.EnvironmentModeFromString("unknown"), EnvironmentMode.ENV_ENVIRONMENT_UNKNOWN); assertEquals(globals.EnvironmentModeToString(EnvironmentMode.ENV_ENVIRONMENT_LOAD_PREDEFINED), "loadpredefined"); assertEquals(globals.EnvironmentModeFromString("loadpredefined"), EnvironmentMode.ENV_ENVIRONMENT_LOAD_PREDEFINED); assertEquals(globals.EnvironmentModeToString(EnvironmentMode.ENV_ENVIRONMENT_LOAD_ALL), "loadall"); assertEquals(globals.EnvironmentModeFromString("loadall"), EnvironmentMode.ENV_ENVIRONMENT_LOAD_ALL); // Roles assertEquals(globals.ROLE_DEFAULT, "default"); assertEquals(globals.ROLE_REFERENCE, "reference"); assertEquals(globals.ROLE_DATA, "data"); assertEquals(globals.ROLE_COLOR_PICKING, "color_picking"); assertEquals(globals.ROLE_SCENE_LINEAR, "scene_linear"); assertEquals(globals.ROLE_COMPOSITING_LOG, "compositing_log"); assertEquals(globals.ROLE_COLOR_TIMING, "color_timing"); assertEquals(globals.ROLE_TEXTURE_PAINT, "texture_paint"); assertEquals(globals.ROLE_MATTE_PAINT, "matte_paint"); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/ColorSpaceTest.java0000644000175000017500000000272313223553423026334 0ustar mfvmfv import junit.framework.TestCase; import org.OpenColorIO.*; public class ColorSpaceTest extends TestCase { protected void setUp() { } protected void tearDown() { } public void test_interface() { ColorSpace cs = new ColorSpace().Create(); cs.setName("mynewcolspace"); assertEquals("mynewcolspace", cs.getName()); cs.setFamily("fam1"); assertEquals("fam1", cs.getFamily()); cs.setEqualityGroup("match1"); assertEquals("match1", cs.getEqualityGroup()); cs.setDescription("this is a test"); assertEquals("this is a test", cs.getDescription()); cs.setBitDepth(BitDepth.BIT_DEPTH_F16); assertEquals(BitDepth.BIT_DEPTH_F16, cs.getBitDepth()); cs.setIsData(false); assertEquals(false, cs.isData()); cs.setAllocation(Allocation.ALLOCATION_LG2); assertEquals(Allocation.ALLOCATION_LG2, cs.getAllocation()); float test[] = new float[]{0.1f, 0.2f, 0.3f}; cs.setAllocationVars(3, test); assertEquals(3, cs.getAllocationNumVars()); float out[] = new float[3]; cs.getAllocationVars(out); LogTransform lt = new LogTransform().Create(); lt.setBase(10.f); cs.setTransform(lt, ColorSpaceDirection.COLORSPACE_DIR_TO_REFERENCE); LogTransform ott = (LogTransform)cs.getTransform(ColorSpaceDirection.COLORSPACE_DIR_TO_REFERENCE); assertEquals(10.f, ott.getBase()); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/test.cc0000644000175000017500000000042013223553423024055 0ustar mfvmfv this is a descipt 1.1 1.2 1.3 2.1 2.2 2.3 3.1 3.2 3.3 0.7 opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/PackedImageDescTest.java0000644000175000017500000000231013223553423027223 0ustar mfvmfv import junit.framework.TestCase; import org.OpenColorIO.*; import java.nio.*; public class PackedImageDescTest extends TestCase { protected void setUp() { } protected void tearDown() { } public void test_interface() { int width = 2; int height = 2; int channels = 4; float packedpix[] = new float[]{0.1f, 0.1f, 0.1f, 1.0f, 0.2f, 0.2f, 0.2f, 1.0f, 0.3f, 0.3f, 0.3f, 1.0f, 0.4f, 0.4f, 0.4f, 1.0f }; FloatBuffer buf = ByteBuffer.allocateDirect(width * height * channels * Float.SIZE / 8).asFloatBuffer(); buf.put(packedpix); // PackedImageDesc foo = new PackedImageDesc(buf, width, height, channels); FloatBuffer wee = foo.getData(); assertEquals(0.3f, wee.get(10)); assertEquals(2, foo.getWidth()); assertEquals(2, foo.getHeight()); assertEquals(4, foo.getNumChannels()); assertEquals(4, foo.getChanStrideBytes()); assertEquals(16, foo.getXStrideBytes()); assertEquals(32, foo.getYStrideBytes()); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/TransformsTest.java0000644000175000017500000002306013223553423026435 0ustar mfvmfv import junit.framework.TestCase; import org.OpenColorIO.*; public class TransformsTest extends TestCase { protected void setUp() { } protected void tearDown() { } public void test_interface() { //// AllocationTransform //// AllocationTransform at = new AllocationTransform().Create(); assertEquals(Allocation.ALLOCATION_UNIFORM, at.getAllocation()); at.setAllocation(Allocation.ALLOCATION_LG2); assertEquals(Allocation.ALLOCATION_LG2, at.getAllocation()); assertEquals(0, at.getNumVars()); float[] vars = new float[]{0.1f, 0.2f, 0.3f}; at.setVars(3, vars); assertEquals(3, at.getNumVars()); float newvars[] = new float[3]; at.getVars(newvars); assertEquals(0.2f, newvars[1], 1e-8); // Base Transform method tests assertEquals(TransformDirection.TRANSFORM_DIR_FORWARD, at.getDirection()); at.setDirection(TransformDirection.TRANSFORM_DIR_UNKNOWN); assertEquals(TransformDirection.TRANSFORM_DIR_UNKNOWN, at.getDirection()); //// CDLTransform //// CDLTransform cdl = new CDLTransform().Create(); String CC = "" +"" +"" +"this is a descipt" +"1.1 1.2 1.3" +"2.1 2.2 2.3" +"3.1 3.2 3.3" +"" +"0.7" +""; // Don't want to deal with getting the correct path so this runs //CDLTransform cdlfile = new CDLTransform().CreateFromFile("../OpenColorIO/src/jniglue/tests/org/OpenColorIO/test.cc", "foo"); //assertEquals(CC, cdlfile.getXML()); cdl.setXML(CC); assertEquals(CC, cdl.getXML()); //CDLTransform match = new CDLTransform().Create(); CDLTransform match = (CDLTransform)cdl.createEditableCopy(); match.setOffset(new float[]{1.0f, 1.0f, 1.f}); assertEquals(false, cdl.equals(match)); cdl.setSlope(new float[]{0.1f, 0.2f, 0.3f}); cdl.setOffset(new float[]{1.1f, 1.2f, 1.3f}); cdl.setPower(new float[]{2.1f, 2.2f, 2.3f}); cdl.setSat(0.5f); String CC2 = "" +"" +"" +"this is a descipt" +"0.1 0.2 0.3" +"1.1 1.2 1.3" +"2.1 2.2 2.3" +"" +"0.5" +""; assertEquals(CC2, cdl.getXML()); cdl.setSOP(new float[]{1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f}); float newsop[] = new float[9]; cdl.getSOP(newsop); assertEquals(1.5f, newsop[4], 1e-8); float slope[] = new float[3]; cdl.getSlope(slope); assertEquals(1.2f, slope[1], 1e-8); float offset[] = new float[3]; cdl.getOffset(offset); assertEquals(1.6f, offset[2], 1e-8); float power[] = new float[3]; cdl.getPower(power); assertEquals(1.7f, power[0], 1e-8); assertEquals(0.5f, cdl.getSat(), 1e-8); float luma[] = new float[3]; cdl.getSatLumaCoefs(luma); assertEquals(0.2126f, luma[0], 1e-8); assertEquals(0.7152f, luma[1], 1e-8); assertEquals(0.0722f, luma[2], 1e-8); cdl.setID("foobar123"); assertEquals("foobar123", cdl.getID()); cdl.setDescription("bar"); assertEquals("bar", cdl.getDescription()); //// ColorSpaceTransform //// ColorSpaceTransform ct = new ColorSpaceTransform().Create(); ct.setSrc("foo"); assertEquals("foo", ct.getSrc()); ct.setDst("bar"); assertEquals("bar", ct.getDst()); //// DisplayTransform //// DisplayTransform dt = new DisplayTransform().Create(); dt.setInputColorSpaceName("lin18"); assertEquals("lin18", dt.getInputColorSpaceName()); //public native void setLinearCC(Transform cc); //public native Transform getLinearCC(); //public native void setColorTimingCC(Transform cc); //public native Transform getColorTimingCC(); //public native void setChannelView(Transform transform); //public native Transform getChannelView(); dt.setDisplay("sRGB"); assertEquals("sRGB", dt.getDisplay()); dt.setView("foobar"); assertEquals("foobar", dt.getView()); cdl.setXML(CC); dt.setDisplayCC(cdl); CDLTransform cdldt = (CDLTransform)dt.getDisplayCC(); assertEquals(CC, cdldt.getXML()); dt.setLooksOverride("darkgrade"); assertEquals("darkgrade", dt.getLooksOverride()); dt.setLooksOverrideEnabled(true); assertEquals(true, dt.getLooksOverrideEnabled()); //// ExponentTransform //// ExponentTransform et = new ExponentTransform().Create(); et.setValue(new float[]{0.1f, 0.2f, 0.3f, 0.4f}); float evals[] = new float[4]; et.getValue(evals); assertEquals(0.3f, evals[2], 1e-8); //// FileTransform //// FileTransform ft = new FileTransform().Create(); ft.setSrc("foo"); assertEquals("foo", ft.getSrc()); ft.setCCCId("foobar"); assertEquals("foobar", ft.getCCCId()); ft.setInterpolation(Interpolation.INTERP_NEAREST); assertEquals(Interpolation.INTERP_NEAREST, ft.getInterpolation()); assertEquals(16, ft.getNumFormats()); assertEquals("flame", ft.getFormatNameByIndex(0)); assertEquals("3dl", ft.getFormatExtensionByIndex(0)); //// GroupTransform //// GroupTransform gt = new GroupTransform().Create(); gt.push_back(et); gt.push_back(ft); assertEquals(2, gt.size()); assertEquals(false, gt.empty()); Transform foo = gt.getTransform(0); assertEquals(TransformDirection.TRANSFORM_DIR_FORWARD, foo.getDirection()); gt.clear(); assertEquals(0, gt.size()); //// LogTransform //// LogTransform lt = new LogTransform().Create(); lt.setBase(10.f); assertEquals(10.f, lt.getBase()); //// LookTransform //// LookTransform lkt = new LookTransform().Create(); lkt.setSrc("foo"); assertEquals("foo", lkt.getSrc()); lkt.setDst("bar"); assertEquals("bar", lkt.getDst()); lkt.setLooks("bar;foo"); assertEquals("bar;foo", lkt.getLooks()); //// MatrixTransform //// MatrixTransform mt = new MatrixTransform().Create(); MatrixTransform mmt = (MatrixTransform)mt.createEditableCopy(); mt.setValue(new float[]{0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f}, new float[]{0.1f, 0.2f, 0.3f, 0.4f}); assertEquals(false, mt.equals(mmt)); float m44_1[] = new float[16]; float offset_1[] = new float[4]; mt.getValue(m44_1, offset_1); assertEquals(0.3f, m44_1[2]); assertEquals(0.2f, offset_1[1]); mt.setMatrix(new float[]{1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f}); float m44_2[] = new float[16]; mt.getMatrix(m44_2); assertEquals(1.3f, m44_2[2]); mt.setOffset(new float[]{1.1f, 1.2f, 1.3f, 1.4f}); float offset_2[] = new float[4]; mt.getOffset(offset_2); assertEquals(1.4f, offset_2[3]); mt.Fit(m44_2, offset_2, new float[]{0.1f, 0.1f, 0.1f, 0.1f}, new float[]{0.9f, 0.9f, 0.9f, 0.9f}, new float[]{0.0f, 0.0f, 0.0f, 0.0f}, new float[]{1.1f, 1.1f, 1.1f, 1.1f}); float m44_3[] = new float[16]; mt.getMatrix(m44_3); assertEquals(1.3f, m44_3[2]); mt.Identity(m44_3, offset_2); assertEquals(0.f, m44_3[1]); mt.Sat(m44_2, offset_2, 0.5f, new float[]{0.2126f, 0.7152f, 0.0722f}); assertEquals(0.3576f, m44_2[1]); mt.Scale(m44_2, offset_2, new float[]{0.9f, 0.8f, 0.7f, 1.f}); assertEquals(0.9f, m44_2[0]); mt.View(m44_2, offset_2, new int[]{1, 1, 1, 0}, new float[]{0.2126f, 0.7152f, 0.0722f}); assertEquals(0.0722f, m44_2[2]); //// TruelightTransform //// TruelightTransform tt = new TruelightTransform().Create(); tt.setConfigRoot("/some/path"); assertEquals("/some/path", tt.getConfigRoot()); tt.setProfile("profileA"); assertEquals("profileA", tt.getProfile()); tt.setCamera("incam"); assertEquals("incam", tt.getCamera()); tt.setInputDisplay("dellmon"); assertEquals("dellmon", tt.getInputDisplay()); tt.setRecorder("blah"); assertEquals("blah", tt.getRecorder()); tt.setPrint("kodasomething"); assertEquals("kodasomething", tt.getPrint()); tt.setLamp("foobar"); assertEquals("foobar", tt.getLamp()); tt.setOutputCamera("somecam"); assertEquals("somecam", tt.getOutputCamera()); tt.setDisplay("sRGB"); assertEquals("sRGB", tt.getDisplay()); tt.setCubeInput("log"); assertEquals("log", tt.getCubeInput()); try { } catch (Exception e) { System.out.println(e); } } }opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/org/OpenColorIO/GpuShaderDescTest.java0000644000175000017500000000124613223553423026762 0ustar mfvmfv import junit.framework.TestCase; import org.OpenColorIO.*; public class GpuShaderDescTest extends TestCase { protected void setUp() { } protected void tearDown() { } public void test_interface() { GpuShaderDesc desc = new GpuShaderDesc(); desc.setLanguage(GpuLanguage.GPU_LANGUAGE_GLSL_1_3); assertEquals(GpuLanguage.GPU_LANGUAGE_GLSL_1_3, desc.getLanguage()); desc.setFunctionName("foo123"); assertEquals("foo123", desc.getFunctionName()); desc.setLut3DEdgeLen(32); assertEquals(32, desc.getLut3DEdgeLen()); assertEquals("glsl_1.3 foo123 32", desc.getCacheID()); } } opencolorio-1.1.0~dfsg0.orig/src/jniglue/tests/CMakeLists.txt0000644000175000017500000000160713223553423022420 0ustar mfvmfv ############################################################################### ### JNI JUNIT TESTS ### file(GLOB _TESTS_FILES "org/OpenColorIO/*.java") set(_JCLASS_PATH "${CMAKE_CURRENT_BINARY_DIR}:${CMAKE_CURRENT_BINARY_DIR}/..:${CMAKE_SOURCE_DIR}/ext/junit-4.9b4.jar") set(_JLIB_PATH "${CMAKE_CURRENT_BINARY_DIR}/..") add_custom_target(JNITests COMMAND javac -cp ${_JCLASS_PATH} -d ${CMAKE_CURRENT_BINARY_DIR} ${_TESTS_FILES} COMMAND java -cp ${_JCLASS_PATH} -Djava.library.path=${_JLIB_PATH} junit.textui.TestRunner OpenColorIOTestSuite DEPENDS OpenColorIO-JNI WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Setting Up and Running JNI OCIO JUNIT tests") add_test(jniglue "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target JNITests) opencolorio-1.1.0~dfsg0.orig/src/photoshop/0000755000175000017500000000000013223553423017100 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/photoshop/win/0000755000175000017500000000000013223553423017675 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/photoshop/win/OpenColorIO_PS_Dialog.rc0000644000175000017500000000504313223553423024236 0ustar mfvmfv// Microsoft Visual C++ generated resource script. // #include "resource1.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource1.h\0" END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog // OCIODIALOG DIALOGEX 0, 0, 316, 168 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "OpenColorIO" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "OK",IDOK,205,147,50,14 PUSHBUTTON "Cancel",IDCANCEL,259,147,50,14 PUSHBUTTON "Export...",3,7,147,50,14 RTEXT "Configuration:",4,71,16,47,8 COMBOBOX 5,125,14,99,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Convert",6,"Button",BS_AUTORADIOBUTTON,84,40,42,10 CONTROL "Display",7,"Button",BS_AUTORADIOBUTTON,155,40,39,10 RTEXT "Input Space:",8,77,65,42,8 COMBOBOX 9,125,63,99,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP RTEXT "Output Space:",11,71,88,48,8 COMBOBOX 12,125,87,99,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP RTEXT "Transform:",14,83,112,36,8 COMBOBOX 15,125,111,99,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Invert",16,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,250,65,36,10 PUSHBUTTON ">",10,230,62,15,14 PUSHBUTTON ">",13,230,86,15,14 END #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED opencolorio-1.1.0~dfsg0.orig/src/photoshop/win/resource1.h0000644000175000017500000000062413223553423021760 0ustar mfvmfv//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by OpenColorIO_PS_Dialog.rc // // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1013 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif opencolorio-1.1.0~dfsg0.orig/src/photoshop/win/OpenColorIO_PS_Dialogs_Win.cpp0000644000175000017500000006366413223553423025431 0ustar mfvmfv #include "OpenColorIO_PS_Dialog.h" #include #include //#include //#include #include #include #include #include "OpenColorIO_PS_Context.h" #include "OpenColorIO_PS_Version.h" #include "OpenColorIO_AE_Dialogs.h" #include "ocioicc.h" static HINSTANCE hDllInstance = NULL; enum { DLOG_noUI = -1, DLOG_OK = IDOK, DLOG_Cancel = IDCANCEL, DLOG_Export = 3, DLOG_Configuration_Label, DLOG_Configuration_Menu, DLOG_Convert_Radio, DLOG_Display_Radio, DLOG_Menu1_Label, DLOG_Menu1_Menu, DLOG_Menu1_Button, DLOG_Menu2_Label, DLOG_Menu2_Menu, DLOG_Menu2_Button, DLOG_Menu3_Label, DLOG_Menu3_Menu, DLOG_Invert_Check }; static DialogSource g_source; static std::string g_config; // path when source == SOURCE_CUSTOM static DialogAction g_action; static bool g_invert; static DialogInterp g_interpolation; static std::string g_inputSpace; static std::string g_outputSpace; static std::string g_device; static std::string g_transform; static WORD g_item_clicked = 0; static OpenColorIO_PS_Context *g_context = NULL; static HWND g_configutationToolTip = NULL; // sensible Win macros #define GET_ITEM(ITEM) GetDlgItem(hwndDlg, (ITEM)) #define SET_LABEL_STRING(ITEM, STRING) SetDlgItemText(hwndDlg, (ITEM), (STRING)); #define SET_CHECK(ITEM, VAL) SendMessage(GET_ITEM(ITEM), BM_SETCHECK, (WPARAM)(VAL), (LPARAM)0) #define GET_CHECK(ITEM) SendMessage(GET_ITEM(ITEM), BM_GETCHECK, (WPARAM)0, (LPARAM)0) #define ADD_MENU_ITEM(MENU, INDEX, STRING, VALUE, SELECTED) \ SendMessage(GET_ITEM(MENU),( UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)(LPCTSTR)STRING ); \ SendMessage(GET_ITEM(MENU),(UINT)CB_SETITEMDATA, (WPARAM)INDEX, (LPARAM)(DWORD)VALUE); \ if(SELECTED) \ SendMessage(GET_ITEM(MENU), CB_SETCURSEL, (WPARAM)INDEX, (LPARAM)0); #define GET_NUMBER_MENU_ITEMS(MENU) SendMessage(GET_ITEM(MENU), CB_GETCOUNT , (WPARAM)0, (LPARAM)0); //#define GET_VALUE_OF_MENU_ITEM(MENU, INDEX) SendMessage(GET_ITEM(MENU), CB_GETITEMDATA, (WPARAM)(INDEX), (LPARAM)0); #define GET_STRING_OF_MENU_ITEM(MENU, INDEX, BUF) SendMessage(GET_ITEM(MENU), (UINT)CB_GETLBTEXT, (WPARAM)(INDEX), (LPARAM)(BUF)) #define GET_MENU_VALUE(MENU) SendMessage(GET_ITEM(MENU), (UINT)CB_GETITEMDATA, (WPARAM)SendMessage(GET_ITEM(MENU),(UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0), (LPARAM)0) #define GET_MENU_VALUE_STRING(MENU, BUF) SendMessage(GET_ITEM(MENU), (UINT)CB_GETLBTEXT, (WPARAM)SendMessage(GET_ITEM(MENU),(UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0), (LPARAM)(BUF)) #define SELECT_STRING_ITEM(MENU, STRING) SendMessage(GET_ITEM(MENU), CB_SELECTSTRING, (WPARAM)-1, (LPARAM)(STRING)); #define REMOVE_ALL_MENU_ITEMS(MENU) SendMessage(GET_ITEM(MENU), CB_RESETCONTENT, (WPARAM)0, (LPARAM)0); #define ENABLE_ITEM(ITEM, ENABLE) EnableWindow(GetDlgItem(hwndDlg, (ITEM)), (ENABLE)); #define SHOW_ITEM(ITEM, SHOW) ShowWindow(GetDlgItem(hwndDlg, (ITEM)), (SHOW) ? SW_SHOW : SW_HIDE) static void TrackInvert(HWND hwndDlg, bool readFromControl) { assert(readFromControl); // should always be from the control g_invert = GET_CHECK(DLOG_Invert_Check); } static void TrackMenu3(HWND hwndDlg, bool readFromControl) { assert(g_action == ACTION_DISPLAY); const int transformMenu = DLOG_Menu3_Menu; if(readFromControl) { char buf[256]; GET_MENU_VALUE_STRING(transformMenu, buf); g_transform = buf; } else { // set menu from value bool match = false; const int numberOfItems = GET_NUMBER_MENU_ITEMS(transformMenu); for(int i=0; i < numberOfItems && !match; i++) { char buf[256]; GET_STRING_OF_MENU_ITEM(transformMenu, i, buf); if(g_transform == buf) { match = true; SendMessage(GET_ITEM(transformMenu), CB_SETCURSEL, (WPARAM)i, (LPARAM)0); } } if(!match) { const std::string defaultTransform = g_context->getDefaultTransform(g_device); for(int i=0; i < numberOfItems && !match; i++) { char buf[256]; GET_STRING_OF_MENU_ITEM(transformMenu, i, buf); if(defaultTransform == buf) { SendMessage(GET_ITEM(transformMenu), CB_SETCURSEL, (WPARAM)i, (LPARAM)0); } } g_transform = defaultTransform; } } } static void TrackMenu2(HWND hwndDlg, bool readFromControl) { if(g_action == ACTION_DISPLAY) { const int deviceMenu = DLOG_Menu2_Menu; if(readFromControl) { char buf[256]; GET_MENU_VALUE_STRING(deviceMenu, buf); g_device = buf; } else { SELECT_STRING_ITEM(deviceMenu, g_device.c_str()); } } else { assert(g_action == ACTION_CONVERT); const int outputMenu = DLOG_Menu2_Menu; if(readFromControl) { char buf[256]; GET_MENU_VALUE_STRING(outputMenu, buf); g_outputSpace = buf; } else { SELECT_STRING_ITEM(outputMenu, g_outputSpace.c_str()); } } if(g_action == ACTION_DISPLAY) { const SpaceVec transforms = g_context->getTransforms(g_device); const int transformMenu = DLOG_Menu3_Menu; REMOVE_ALL_MENU_ITEMS(transformMenu); int index = 0; for(SpaceVec::const_iterator i = transforms.begin(); i != transforms.end(); ++i) { ADD_MENU_ITEM(transformMenu, index, i->c_str(), index, (g_transform == *i)); index++; } TrackMenu3(hwndDlg, false); } } static void TrackMenu1(HWND hwndDlg, bool readFromControl) { assert(readFromControl); // should always be from the control if(g_action == ACTION_LUT) { g_interpolation = (DialogInterp)GET_MENU_VALUE(DLOG_Menu1_Menu); } else { char buf[256] = { '\0' }; GET_MENU_VALUE_STRING(DLOG_Menu1_Menu, buf); g_inputSpace = buf; } } static void TrackMenu1Button(HWND hwndDlg) { if(g_context != NULL) { const bool chosen = ColorSpacePopUpMenu(g_context->getConfig(), g_inputSpace, false, hwndDlg); if(chosen) { const int inputSpaceMenu = DLOG_Menu1_Menu; const int numberOfItems = GET_NUMBER_MENU_ITEMS(inputSpaceMenu); for(int i=0; i < numberOfItems; i++) { char buf[256]; GET_STRING_OF_MENU_ITEM(inputSpaceMenu, i, buf); if(g_inputSpace == buf) { SendMessage(GET_ITEM(inputSpaceMenu), CB_SETCURSEL, (WPARAM)i, (LPARAM)0); } } } } } static void TrackMenu2Button(HWND hwndDlg) { if(g_context != NULL) { const bool chosen = ColorSpacePopUpMenu(g_context->getConfig(), g_outputSpace, false, hwndDlg); if(chosen) { const int outputSpaceMenu = DLOG_Menu2_Menu; const int numberOfItems = GET_NUMBER_MENU_ITEMS(outputSpaceMenu); for(int i=0; i < numberOfItems; i++) { char buf[256]; GET_STRING_OF_MENU_ITEM(outputSpaceMenu, i, buf); if(g_outputSpace == buf) { SendMessage(GET_ITEM(outputSpaceMenu), CB_SETCURSEL, (WPARAM)i, (LPARAM)0); } } } } } static void TrackActionRadios(HWND hwndDlg, bool readFromControl) { if(readFromControl) { if( GET_CHECK(DLOG_Display_Radio) ) { g_action = ACTION_DISPLAY; } else { g_action = ACTION_CONVERT; } } else { assert(g_action != ACTION_LUT); if(g_action == ACTION_DISPLAY) { SET_CHECK(DLOG_Convert_Radio, FALSE); SET_CHECK(DLOG_Display_Radio, TRUE); } else { SET_CHECK(DLOG_Convert_Radio, TRUE); SET_CHECK(DLOG_Display_Radio, FALSE); } } assert(g_context != NULL); const int inputLabel = DLOG_Menu1_Label; const int inputMenu = DLOG_Menu1_Menu; SET_LABEL_STRING(inputLabel, "Input Space:"); REMOVE_ALL_MENU_ITEMS(inputMenu); const SpaceVec &colorSpaces = g_context->getColorSpaces(); int index = 0; for(SpaceVec::const_iterator i = colorSpaces.begin(); i != colorSpaces.end(); ++i) { ADD_MENU_ITEM(inputMenu, index, i->c_str(), index, (g_inputSpace == *i)); index++; } SHOW_ITEM(DLOG_Menu1_Button, TRUE); if(g_action == ACTION_DISPLAY) { const int deviceLabel = DLOG_Menu2_Label; const int deviceMenu = DLOG_Menu2_Menu; const int transformLabel = DLOG_Menu3_Label; const int transformMenu = DLOG_Menu3_Menu; SET_LABEL_STRING(deviceLabel, "Device:"); SHOW_ITEM(deviceLabel, TRUE); SHOW_ITEM(deviceMenu, TRUE); REMOVE_ALL_MENU_ITEMS(deviceMenu); const SpaceVec &devices = g_context->getDevices(); index = 0; for(SpaceVec::const_iterator i = devices.begin(); i != devices.end(); ++i) { ADD_MENU_ITEM(deviceMenu, index, i->c_str(), index, (g_device == *i)); index++; } SHOW_ITEM(DLOG_Menu2_Button, FALSE); SET_LABEL_STRING(transformLabel, "Device:"); SHOW_ITEM(transformLabel, TRUE); SHOW_ITEM(transformMenu, TRUE); REMOVE_ALL_MENU_ITEMS(transformMenu); TrackMenu2(hwndDlg, false); } else { assert(g_action == ACTION_CONVERT); const int outputLabel = DLOG_Menu2_Label; const int outputMenu = DLOG_Menu2_Menu; SET_LABEL_STRING(outputLabel, "Output Space:"); SHOW_ITEM(outputLabel, TRUE); SHOW_ITEM(outputMenu, TRUE); REMOVE_ALL_MENU_ITEMS(outputMenu); index = 0; for(SpaceVec::const_iterator i = colorSpaces.begin(); i != colorSpaces.end(); ++i) { ADD_MENU_ITEM(outputMenu, index, i->c_str(), index, (g_outputSpace == *i)); index++; } SHOW_ITEM(DLOG_Menu2_Button, TRUE); SHOW_ITEM(DLOG_Menu3_Label, FALSE); SHOW_ITEM(DLOG_Menu3_Menu, FALSE); } } enum { CONFIG_ENVIRONMENT = 0, CONFIG_SEPERATOR, CONFIG_STANDARD, CONFIG_CUSTOM }; static void TrackConfigMenu(HWND hwndDlg, bool readFromControl) { std::string configPath; if(readFromControl) { const LRESULT source = GET_MENU_VALUE(DLOG_Configuration_Menu); if(source == CONFIG_SEPERATOR) { // invalid, read from params TrackConfigMenu(hwndDlg, false); return; } else if(source == CONFIG_ENVIRONMENT) { char *envFile = std::getenv("OCIO"); g_source = SOURCE_ENVIRONMENT; if(envFile != NULL) { configPath = envFile; } } else if(source == CONFIG_CUSTOM) { ExtensionMap extensions; for(int i=0; i < OCIO::FileTransform::getNumFormats(); ++i) { const std::string extension = OCIO::FileTransform::getFormatExtensionByIndex(i); const std::string format = OCIO::FileTransform::getFormatNameByIndex(i); if(extension != "ccc") // .ccc files require an ID parameter extensions[ extension ] = format; } extensions[ "ocio" ] = "OCIO Format"; char temp_path[256] = { '\0' }; const bool clickedOK = OpenFile(temp_path, 255, extensions, hwndDlg); if(clickedOK) { g_source = SOURCE_CUSTOM; g_config = temp_path; configPath = g_config; } else { // go back to whatever we had TrackConfigMenu(hwndDlg, false); return; } } else { assert(source == CONFIG_STANDARD); char menu_string[256] = { '\0' }; GET_MENU_VALUE_STRING(DLOG_Configuration_Menu, menu_string); g_source = SOURCE_STANDARD; g_config = menu_string; configPath = GetStdConfigPath(g_config); } } else { if(g_source == SOURCE_ENVIRONMENT) { char *envFile = std::getenv("OCIO"); SELECT_STRING_ITEM(DLOG_Configuration_Menu, "$OCIO"); if(envFile != NULL) { configPath = envFile; } } else if(g_source == SOURCE_CUSTOM) { SELECT_STRING_ITEM(DLOG_Configuration_Menu, "Custom..."); configPath = g_config; } else { assert(g_source == SOURCE_STANDARD); SELECT_STRING_ITEM(DLOG_Configuration_Menu, g_config.c_str()); configPath = GetStdConfigPath(g_config); } } if( !configPath.empty() ) { try { delete g_context; g_context = new OpenColorIO_PS_Context(configPath); if( g_context->isLUT() ) { g_action = ACTION_LUT; SHOW_ITEM(DLOG_Invert_Check, TRUE); if( g_context->canInvertLUT() ) { ENABLE_ITEM(DLOG_Invert_Check, TRUE); } else { ENABLE_ITEM(DLOG_Invert_Check, FALSE); g_invert = false; } SET_CHECK(DLOG_Invert_Check, g_invert); SHOW_ITEM(DLOG_Convert_Radio, FALSE); SHOW_ITEM(DLOG_Display_Radio, FALSE); const int interpLabel = DLOG_Menu1_Label; const int interpMenu = DLOG_Menu1_Menu; const bool canTetrahedral = !g_context->canInvertLUT(); SET_LABEL_STRING(interpLabel, "Interpolation:"); // interpolation menu REMOVE_ALL_MENU_ITEMS(interpMenu); ADD_MENU_ITEM(interpMenu, 0, "Nearest Neighbor", INTERPO_NEAREST, (g_interpolation == INTERPO_NEAREST)); ADD_MENU_ITEM(interpMenu, 1, "Linear", INTERPO_LINEAR, (g_interpolation == INTERPO_LINEAR)); if(canTetrahedral) ADD_MENU_ITEM(interpMenu, 2, "Tetrahedral", INTERPO_TETRAHEDRAL, (g_interpolation == INTERPO_TETRAHEDRAL)); ADD_MENU_ITEM(interpMenu, 3, "Best", INTERPO_BEST, (g_interpolation == INTERPO_BEST)); SHOW_ITEM(DLOG_Menu1_Button, FALSE); SHOW_ITEM(DLOG_Menu2_Label, FALSE); SHOW_ITEM(DLOG_Menu2_Menu, FALSE); SHOW_ITEM(DLOG_Menu2_Button, FALSE); SHOW_ITEM(DLOG_Menu3_Label, FALSE); SHOW_ITEM(DLOG_Menu3_Menu, FALSE); } else { SHOW_ITEM(DLOG_Invert_Check, FALSE); if(g_action == ACTION_LUT) { g_action = ACTION_CONVERT; } SHOW_ITEM(DLOG_Convert_Radio, TRUE); SHOW_ITEM(DLOG_Display_Radio, TRUE); const SpaceVec &colorSpaces = g_context->getColorSpaces(); if(-1 == FindSpace(colorSpaces, g_inputSpace)) { g_inputSpace = g_context->getDefaultColorSpace(); } if(-1 == FindSpace(colorSpaces, g_outputSpace)) { g_outputSpace = g_context->getDefaultColorSpace(); } const SpaceVec &devices = g_context->getDevices(); if(-1 == FindSpace(devices, g_device)) { g_device = g_context->getDefaultDevice(); } const SpaceVec transforms = g_context->getTransforms(g_device); if(-1 == FindSpace(transforms, g_transform)) { g_transform = g_context->getDefaultTransform(g_device); } TrackActionRadios(hwndDlg, false); } } catch(const std::exception &e) { MessageBox(hwndDlg, e.what(), "OpenColorIO error", MB_OK); if(g_source != SOURCE_ENVIRONMENT) { g_source = SOURCE_ENVIRONMENT; TrackConfigMenu(hwndDlg, false); } } catch(...) { MessageBox(hwndDlg, "Some unknown error", "OpenColorIO error", MB_OK); if(g_source != SOURCE_ENVIRONMENT) { g_source = SOURCE_ENVIRONMENT; TrackConfigMenu(hwndDlg, false); } } } else { delete g_context; g_context = NULL; REMOVE_ALL_MENU_ITEMS(DLOG_Menu1_Menu); REMOVE_ALL_MENU_ITEMS(DLOG_Menu2_Menu); REMOVE_ALL_MENU_ITEMS(DLOG_Menu3_Menu); } // set the tooltip char toolTipString[256]; strncpy(toolTipString, configPath.c_str(), 255); if(g_configutationToolTip != NULL) { DestroyWindow(g_configutationToolTip); g_configutationToolTip = NULL; } g_configutationToolTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_ALWAYSTIP, // TTS_BALLOON CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL, hDllInstance, NULL); assert(g_configutationToolTip != NULL); TOOLINFO toolInfo = { 0 }; toolInfo.cbSize = sizeof(toolInfo); toolInfo.hwnd = hwndDlg; toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS; toolInfo.uId = (UINT_PTR)GET_ITEM(DLOG_Configuration_Menu); toolInfo.lpszText = toolTipString; const LRESULT setTooltip = SendMessage(g_configutationToolTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo); assert(setTooltip); } static void DoExport(HWND hwndDlg) { if(g_context != NULL) { try { ExtensionMap extensions; for(int i=0; i < OCIO::Baker::getNumFormats(); ++i) { const char *extension = OCIO::Baker::getFormatExtensionByIndex(i); const char *format = OCIO::Baker::getFormatNameByIndex(i); extensions[ extension ] = format; } extensions[ "icc" ] = "ICC Profile"; char path[256] = { '\0' }; const bool result = SaveFile(path, 255, extensions, hwndDlg); if(result) { std::string the_path(path); std::string the_extension = the_path.substr( the_path.find_last_of('.') + 1 ); bool do_export = true; std::string monitor_icc_path; if(the_extension == "icc") { char monitor_path[256] = {'\0'}; do_export = GetMonitorProfile(monitor_path, 255, hwndDlg); if(do_export) { OCIO::ConstProcessorRcPtr processor; if(g_action == ACTION_CONVERT) { processor = g_context->getConvertProcessor(g_inputSpace, g_outputSpace); } else if(g_action == ACTION_DISPLAY) { processor = g_context->getDisplayProcessor(g_inputSpace, g_device, g_transform); } else { assert(g_action == ACTION_LUT); const OCIO::Interpolation interp = (g_interpolation == INTERPO_NEAREST ? OCIO::INTERP_NEAREST : g_interpolation == INTERPO_LINEAR ? OCIO::INTERP_LINEAR : g_interpolation == INTERPO_TETRAHEDRAL ? OCIO::INTERP_TETRAHEDRAL : OCIO::INTERP_BEST); const OCIO::TransformDirection direction = (g_invert ? OCIO::TRANSFORM_DIR_INVERSE : OCIO::TRANSFORM_DIR_FORWARD); processor = g_context->getLUTProcessor(interp, direction); } int cubesize = 32; int whitepointtemp = 6505; std::string copyright = "OpenColorIO, Sony Imageworks"; // create a description tag from the filename const char delimiter = '\\'; const size_t filename_start = the_path.find_last_of(delimiter) + 1; const size_t filename_end = the_path.find_last_of('.') - 1; std::string description = the_path.substr(the_path.find_last_of(delimiter) + 1, 1 + filename_end - filename_start); SaveICCProfileToFile(the_path, processor, cubesize, whitepointtemp, monitor_path, description, copyright, false); } } else { // need an extension->format map std::map extensions; for(int i=0; i < OCIO::Baker::getNumFormats(); ++i) { const char *extension = OCIO::Baker::getFormatExtensionByIndex(i); const char *format = OCIO::Baker::getFormatNameByIndex(i); extensions[ extension ] = format; } std::string format = extensions[ the_extension ]; OCIO::BakerRcPtr baker; if(g_action == ACTION_CONVERT) { baker = g_context->getConvertBaker(g_inputSpace, g_outputSpace); } else if(g_action == ACTION_DISPLAY) { baker = g_context->getDisplayBaker(g_inputSpace, g_device, g_transform); } else { assert(g_action == ACTION_LUT); const OCIO::Interpolation interp = (g_interpolation == INTERPO_NEAREST ? OCIO::INTERP_NEAREST : g_interpolation == INTERPO_LINEAR ? OCIO::INTERP_LINEAR : g_interpolation == INTERPO_TETRAHEDRAL ? OCIO::INTERP_TETRAHEDRAL : OCIO::INTERP_BEST); const OCIO::TransformDirection direction = (g_invert ? OCIO::TRANSFORM_DIR_INVERSE : OCIO::TRANSFORM_DIR_FORWARD); baker = g_context->getLUTBaker(interp, direction); } baker->setFormat( format.c_str() ); std::ofstream f(the_path.c_str()); baker->bake(f); } } } catch(const std::exception &e) { MessageBox(hwndDlg, e.what(), "OpenColorIO error", MB_OK); if(g_source != SOURCE_ENVIRONMENT) { g_source = SOURCE_ENVIRONMENT; TrackConfigMenu(hwndDlg, false); } } catch(...) { MessageBox(hwndDlg, "Some unknown error", "OpenColorIO error", MB_OK); if(g_source != SOURCE_ENVIRONMENT) { g_source = SOURCE_ENVIRONMENT; TrackConfigMenu(hwndDlg, false); } } } } static BOOL CALLBACK DialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { BOOL fError; switch (message) { case WM_INITDIALOG: do{ int index = 0; char *envFile = std::getenv("OCIO"); const DWORD envType = (envFile == NULL ? CONFIG_SEPERATOR : CONFIG_ENVIRONMENT); const bool envSelected = (envFile == NULL != NULL && g_source == SOURCE_ENVIRONMENT); ADD_MENU_ITEM(DLOG_Configuration_Menu, index, "$OCIO", CONFIG_ENVIRONMENT, envSelected); index++; ADD_MENU_ITEM(DLOG_Configuration_Menu, index, "-", CONFIG_SEPERATOR, FALSE); index++; ConfigVec standardConfigs; GetStdConfigs(standardConfigs); if(standardConfigs.size() > 0) { for(int i=0; i < standardConfigs.size(); i++) { const std::string &config = standardConfigs[i]; const bool selected = (g_source == SOURCE_STANDARD && config == g_config); ADD_MENU_ITEM(DLOG_Configuration_Menu, index, config.c_str(), CONFIG_STANDARD, selected); index++; } } else { std::string label = "No standard configs"; char appdata_path[MAX_PATH]; HRESULT result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdata_path); if(result == S_OK) { label = "(No configs in " + std::string(appdata_path) + "\\OpenColorIO\\)"; } ADD_MENU_ITEM(DLOG_Configuration_Menu, index, label.c_str(), CONFIG_SEPERATOR, FALSE); index++; } ADD_MENU_ITEM(DLOG_Configuration_Menu, index, "-", CONFIG_SEPERATOR, FALSE); index++; ADD_MENU_ITEM(DLOG_Configuration_Menu, index, "Custom...", CONFIG_CUSTOM, g_source == SOURCE_CUSTOM); index++; TrackConfigMenu(hwndDlg, false); }while(0); return TRUE; case WM_NOTIFY: return FALSE; case WM_COMMAND: g_item_clicked = LOWORD(wParam); const int menuParam = HIWORD(wParam); switch (LOWORD(wParam)) { case DLOG_OK: case DLOG_Cancel: // do the same thing, but g_item_clicked will be different delete g_context; g_context = NULL; DestroyWindow(g_configutationToolTip); g_configutationToolTip = NULL; // quit dialog //PostMessage((HWND)hwndDlg, WM_QUIT, (WPARAM)WA_ACTIVE, lParam); EndDialog(hwndDlg, 0); //DestroyWindow(hwndDlg); return TRUE; case DLOG_Export: DoExport(hwndDlg); return TRUE; case DLOG_Configuration_Menu: if(menuParam == CBN_SELCHANGE) TrackConfigMenu(hwndDlg, true); return TRUE; case DLOG_Convert_Radio: case DLOG_Display_Radio: TrackActionRadios(hwndDlg, true); return TRUE; case DLOG_Menu1_Menu: if(menuParam == CBN_SELCHANGE) TrackMenu1(hwndDlg, true); return TRUE; case DLOG_Menu1_Button: TrackMenu1Button(hwndDlg); return TRUE; case DLOG_Menu2_Menu: if(menuParam == CBN_SELCHANGE) TrackMenu2(hwndDlg, true); return TRUE; case DLOG_Menu2_Button: TrackMenu2Button(hwndDlg); return TRUE; case DLOG_Menu3_Menu: if(menuParam == CBN_SELCHANGE) TrackMenu3(hwndDlg, true); return TRUE; case DLOG_Invert_Check: TrackInvert(hwndDlg, true); return TRUE; } return FALSE; } return FALSE; } DialogResult OpenColorIO_PS_Dialog(DialogParams ¶ms, const void *plugHndl, const void *mwnd) { hDllInstance = (HINSTANCE)plugHndl; SetHInstance(hDllInstance); g_source = params.source; g_config = params.config; g_action = params.action; g_invert = params.invert; g_interpolation = params.interpolation; g_inputSpace = params.inputSpace; g_outputSpace = params.outputSpace; g_device = params.device; g_transform = params.transform; const int status = DialogBox((HINSTANCE)plugHndl, (LPSTR)"OCIODIALOG", (HWND)mwnd, (DLGPROC)DialogProc); if(g_item_clicked == IDOK) { params.source = g_source; params.config = g_config; params.action = g_action; params.invert = g_invert; params.interpolation = g_interpolation; params.inputSpace = g_inputSpace; params.outputSpace = g_outputSpace; params.device = g_device; params.transform = g_transform; return RESULT_OK; } else return RESULT_CANCEL; } void OpenColorIO_PS_About(const void *plugHndl, const void *mwnd) { const std::string ocioVersion = OCIO::GetVersion(); const std::string endl = "\n"; std::string text = std::string("OpenColorIO PS") + endl + OpenColorIO_PS_Beta_String + endl + __DATE__ + endl + endl + "OCIO version " + OCIO::GetVersion(); MessageBox((HWND)mwnd, text.c_str(), "OpenColorIO", MB_OK); } opencolorio-1.1.0~dfsg0.orig/src/photoshop/OpenColorIO_PS_Dialog.h0000644000175000017500000000531213223553423023263 0ustar mfvmfv/* Copyright (c) 2003-2017 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 _OPENCOLORIO_PS_DIALOG_H_ #define _OPENCOLORIO_PS_DIALOG_H_ #include enum DialogResult { RESULT_OK, RESULT_CANCEL, RESULT_EXPORT }; enum DialogSource { SOURCE_ENVIRONMENT, SOURCE_STANDARD, SOURCE_CUSTOM }; enum DialogAction { ACTION_LUT, ACTION_CONVERT, ACTION_DISPLAY }; enum DialogInterp { INTERPO_NEAREST, INTERPO_LINEAR, INTERPO_TETRAHEDRAL, INTERPO_BEST }; typedef struct DialogParams { DialogSource source; std::string config; // path when source == SOURCE_CUSTOM DialogAction action; bool invert; DialogInterp interpolation; std::string inputSpace; std::string outputSpace; std::string device; std::string transform; } DialogParams; // return true if user hit OK // if user hit OK, params block will have been modified // // send in block of parameters // plugHndl is bundle identifier string on Mac, hInstance on win // mwnd is the main window, Windows only (NULL on Mac) DialogResult OpenColorIO_PS_Dialog(DialogParams ¶ms, const void *plugHndl, const void *mwnd); void OpenColorIO_PS_About(const void *plugHndl, const void *mwnd); #endif // _OPENCOLORIO_PS_DIALOG_H_ opencolorio-1.1.0~dfsg0.orig/src/photoshop/xcode/0000755000175000017500000000000013223553423020202 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/photoshop/xcode/OpenColorIO_PS.xcodeproj/0000755000175000017500000000000013223553423024730 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/photoshop/xcode/OpenColorIO_PS.xcodeproj/project.pbxproj0000644000175000017500000054070513223553423030017 0ustar mfvmfv// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 42; objects = { /* Begin PBXBuildFile section */ 2A4150441E33FD6900E3954B /* OpenColorIO_PS_Context.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A4150431E33FD6900E3954B /* OpenColorIO_PS_Context.cpp */; }; 2A644C9D1E316E6C00AAEF84 /* OpenColorIO_PS_Dialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A644C9C1E316E6C00AAEF84 /* OpenColorIO_PS_Dialog.xib */; }; 2A644CB41E31731000AAEF84 /* OpenColorIO_PS_Dialog_Controller.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2A644CB31E31731000AAEF84 /* OpenColorIO_PS_Dialog_Controller.mm */; }; 2A644CBB1E31787500AAEF84 /* OpenColorIO_PS_Dialog_Cocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2A644CBA1E31787500AAEF84 /* OpenColorIO_PS_Dialog_Cocoa.mm */; }; 2A644DBA1E31FAAF00AAEF84 /* liblcms.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A644DB31E31FAA500AAEF84 /* liblcms.a */; }; 2A644DBB1E31FAB000AAEF84 /* libOpenColorIO.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A644DA71E31FA7800AAEF84 /* libOpenColorIO.a */; }; 2A644DBC1E31FAB000AAEF84 /* libtinyxml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A644DB61E31FAA500AAEF84 /* libtinyxml.a */; }; 2A644DBD1E31FAB100AAEF84 /* libyaml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A644DB91E31FAA500AAEF84 /* libyaml.a */; }; 2A7523751E3ECDEA00BB5897 /* ocioicc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A7523731E3ECDEA00BB5897 /* ocioicc.cpp */; }; 2A7523961E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser_Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A7523941E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser_Controller.m */; }; 2A7523971E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2A7523951E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser.xib */; }; 2A7529E21E3FB64000BB5897 /* OpenColorIO_AE_Dialogs_Cocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2A7529E11E3FB64000BB5897 /* OpenColorIO_AE_Dialogs_Cocoa.mm */; }; 2A7529E71E3FB66000BB5897 /* OpenColorIO_AE_Menu.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A7529E61E3FB66000BB5897 /* OpenColorIO_AE_Menu.m */; }; 2A7F211B1E2F4E57003428D7 /* OpenColorIO_PS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A7F21181E2F4E57003428D7 /* OpenColorIO_PS.cpp */; }; 2A7F211C1E2F4E57003428D7 /* OpenColorIO_PS.r in Rez */ = {isa = PBXBuildFile; fileRef = 2A7F211A1E2F4E57003428D7 /* OpenColorIO_PS.r */; }; 2AF20A8312065C87001E5E3F /* FilterBigDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AF20A8212065C87001E5E3F /* FilterBigDocument.cpp */; }; 2AF20AE712065E0E001E5E3F /* PIUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 64126C3409F97A19006DF4E6 /* PIUtilities.cpp */; }; 2AF20AEA12065E19001E5E3F /* DialogUtilitiesMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 64126C2F09F979F7006DF4E6 /* DialogUtilitiesMac.cpp */; }; 2AF20B9112066147001E5E3F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 646B5CA910D31664001A7C6E /* Cocoa.framework */; }; 2AF20B9C12066179001E5E3F /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */; }; 64126C2B09F979EA006DF4E6 /* PIUSuites.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 64126C2A09F979EA006DF4E6 /* PIUSuites.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 2A644DA61E31FA7800AAEF84 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2A644DA21E31FA7800AAEF84 /* OpenColorIO.xcodeproj */; proxyType = 2; remoteGlobalIDString = 2ACF567114776A0A00991ED5; remoteInfo = OpenColorIO; }; 2A644DB21E31FAA500AAEF84 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2A644DA81E31FAA500AAEF84 /* lcms.xcodeproj */; proxyType = 2; remoteGlobalIDString = 2ACF9E56147824F500991ED5; remoteInfo = lcms; }; 2A644DB51E31FAA500AAEF84 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2A644DAB1E31FAA500AAEF84 /* tinyxml.xcodeproj */; proxyType = 2; remoteGlobalIDString = 2ACF55441477682B00991ED5; remoteInfo = tinyxml; }; 2A644DB81E31FAA500AAEF84 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2A644DAE1E31FAA500AAEF84 /* yaml.xcodeproj */; proxyType = 2; remoteGlobalIDString = 2ACF559C1477692300991ED5; remoteInfo = yaml; }; 2A644DBE1E31FACE00AAEF84 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2A644DA81E31FAA500AAEF84 /* lcms.xcodeproj */; proxyType = 1; remoteGlobalIDString = 2ACF9E55147824F500991ED5; remoteInfo = lcms; }; 2A644DC01E31FACE00AAEF84 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2A644DAE1E31FAA500AAEF84 /* yaml.xcodeproj */; proxyType = 1; remoteGlobalIDString = 2ACF559B1477692300991ED5; remoteInfo = yaml; }; 2A644DC21E31FACE00AAEF84 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2A644DAB1E31FAA500AAEF84 /* tinyxml.xcodeproj */; proxyType = 1; remoteGlobalIDString = 2ACF55431477682B00991ED5; remoteInfo = tinyxml; }; 2A644DC41E31FACE00AAEF84 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 2A644DA21E31FA7800AAEF84 /* OpenColorIO.xcodeproj */; proxyType = 1; remoteGlobalIDString = 2ACF567014776A0A00991ED5; remoteInfo = OpenColorIO; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; 2A4150421E33FD6900E3954B /* OpenColorIO_PS_Context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_PS_Context.h; path = ../OpenColorIO_PS_Context.h; sourceTree = SOURCE_ROOT; }; 2A4150431E33FD6900E3954B /* OpenColorIO_PS_Context.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenColorIO_PS_Context.cpp; path = ../OpenColorIO_PS_Context.cpp; sourceTree = SOURCE_ROOT; }; 2A644C1A1E3166FC00AAEF84 /* OpenColorIO_PS_Dialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_PS_Dialog.h; path = ../OpenColorIO_PS_Dialog.h; sourceTree = SOURCE_ROOT; }; 2A644C9C1E316E6C00AAEF84 /* OpenColorIO_PS_Dialog.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = OpenColorIO_PS_Dialog.xib; path = ../mac/OpenColorIO_PS_Dialog.xib; sourceTree = SOURCE_ROOT; }; 2A644CB21E31731000AAEF84 /* OpenColorIO_PS_Dialog_Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_PS_Dialog_Controller.h; path = ../mac/OpenColorIO_PS_Dialog_Controller.h; sourceTree = SOURCE_ROOT; }; 2A644CB31E31731000AAEF84 /* OpenColorIO_PS_Dialog_Controller.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = OpenColorIO_PS_Dialog_Controller.mm; path = ../mac/OpenColorIO_PS_Dialog_Controller.mm; sourceTree = SOURCE_ROOT; }; 2A644CBA1E31787500AAEF84 /* OpenColorIO_PS_Dialog_Cocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = OpenColorIO_PS_Dialog_Cocoa.mm; path = ../mac/OpenColorIO_PS_Dialog_Cocoa.mm; sourceTree = SOURCE_ROOT; }; 2A644DA21E31FA7800AAEF84 /* OpenColorIO.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OpenColorIO.xcodeproj; path = ../../aftereffects/xcode/OpenColorIO.xcodeproj; sourceTree = SOURCE_ROOT; }; 2A644DA81E31FAA500AAEF84 /* lcms.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = lcms.xcodeproj; path = ../../aftereffects/xcode/ext/lcms.xcodeproj; sourceTree = SOURCE_ROOT; }; 2A644DAB1E31FAA500AAEF84 /* tinyxml.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = tinyxml.xcodeproj; path = ../../aftereffects/xcode/ext/tinyxml.xcodeproj; sourceTree = SOURCE_ROOT; }; 2A644DAE1E31FAA500AAEF84 /* yaml.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = yaml.xcodeproj; path = ../../aftereffects/xcode/ext/yaml.xcodeproj; sourceTree = SOURCE_ROOT; }; 2A7523731E3ECDEA00BB5897 /* ocioicc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ocioicc.cpp; path = ../../apps/ociobakelut/ocioicc.cpp; sourceTree = SOURCE_ROOT; }; 2A7523741E3ECDEA00BB5897 /* ocioicc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ocioicc.h; path = ../../apps/ociobakelut/ocioicc.h; sourceTree = SOURCE_ROOT; }; 2A7523931E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser_Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_AE_MonitorProfileChooser_Controller.h; path = ../../aftereffects/mac/OpenColorIO_AE_MonitorProfileChooser_Controller.h; sourceTree = SOURCE_ROOT; }; 2A7523941E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser_Controller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OpenColorIO_AE_MonitorProfileChooser_Controller.m; path = ../../aftereffects/mac/OpenColorIO_AE_MonitorProfileChooser_Controller.m; sourceTree = SOURCE_ROOT; }; 2A7523951E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = OpenColorIO_AE_MonitorProfileChooser.xib; path = ../../aftereffects/mac/OpenColorIO_AE_MonitorProfileChooser.xib; sourceTree = SOURCE_ROOT; }; 2A7529DF1E3FB61100BB5897 /* OpenColorIO_AE_Dialogs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_AE_Dialogs.h; path = ../../aftereffects/OpenColorIO_AE_Dialogs.h; sourceTree = SOURCE_ROOT; }; 2A7529E11E3FB64000BB5897 /* OpenColorIO_AE_Dialogs_Cocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = OpenColorIO_AE_Dialogs_Cocoa.mm; path = ../../aftereffects/mac/OpenColorIO_AE_Dialogs_Cocoa.mm; sourceTree = SOURCE_ROOT; }; 2A7529E51E3FB66000BB5897 /* OpenColorIO_AE_Menu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_AE_Menu.h; path = ../../aftereffects/mac/OpenColorIO_AE_Menu.h; sourceTree = SOURCE_ROOT; }; 2A7529E61E3FB66000BB5897 /* OpenColorIO_AE_Menu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OpenColorIO_AE_Menu.m; path = ../../aftereffects/mac/OpenColorIO_AE_Menu.m; sourceTree = SOURCE_ROOT; }; 2A7F21161E2F4E57003428D7 /* OpenColorIO_PS_Terminology.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_PS_Terminology.h; path = ../OpenColorIO_PS_Terminology.h; sourceTree = SOURCE_ROOT; }; 2A7F21171E2F4E57003428D7 /* OpenColorIO_PS_Version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_PS_Version.h; path = ../OpenColorIO_PS_Version.h; sourceTree = SOURCE_ROOT; }; 2A7F21181E2F4E57003428D7 /* OpenColorIO_PS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OpenColorIO_PS.cpp; path = ../OpenColorIO_PS.cpp; sourceTree = SOURCE_ROOT; }; 2A7F21191E2F4E57003428D7 /* OpenColorIO_PS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OpenColorIO_PS.h; path = ../OpenColorIO_PS.h; sourceTree = SOURCE_ROOT; }; 2A7F211A1E2F4E57003428D7 /* OpenColorIO_PS.r */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.rez; name = OpenColorIO_PS.r; path = ../OpenColorIO_PS.r; sourceTree = SOURCE_ROOT; }; 2AF20A8212065C87001E5E3F /* FilterBigDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FilterBigDocument.cpp; sourceTree = ""; }; 2AF20A8412065C91001E5E3F /* FilterBigDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilterBigDocument.h; sourceTree = ""; }; 2AF20A8D12065CC7001E5E3F /* ADMAGMTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMAGMTypes.h; sourceTree = ""; }; 2AF20A8E12065CC7001E5E3F /* ADMBasic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMBasic.h; sourceTree = ""; }; 2AF20A8F12065CC7001E5E3F /* ADMCustomResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMCustomResource.h; sourceTree = ""; }; 2AF20A9012065CC7001E5E3F /* ADMDialog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMDialog.h; sourceTree = ""; }; 2AF20A9112065CC7001E5E3F /* ADMDialogGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMDialogGroup.h; sourceTree = ""; }; 2AF20A9212065CC7001E5E3F /* ADMDrawer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMDrawer.h; sourceTree = ""; }; 2AF20A9312065CC7001E5E3F /* ADMEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMEntry.h; sourceTree = ""; }; 2AF20A9412065CC7001E5E3F /* ADMHierarchyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMHierarchyList.h; sourceTree = ""; }; 2AF20A9512065CC7001E5E3F /* ADMHost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMHost.h; sourceTree = ""; }; 2AF20A9612065CC7001E5E3F /* ADMHostInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMHostInit.h; sourceTree = ""; }; 2AF20A9712065CC7001E5E3F /* ADMHostInitUnicode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMHostInitUnicode.h; sourceTree = ""; }; 2AF20A9812065CC7001E5E3F /* ADMHostWin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMHostWin.h; sourceTree = ""; }; 2AF20A9912065CC7001E5E3F /* ADMIcon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMIcon.h; sourceTree = ""; }; 2AF20A9A12065CC7001E5E3F /* ADMImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMImage.h; sourceTree = ""; }; 2AF20A9B12065CC7001E5E3F /* ADMItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMItem.h; sourceTree = ""; }; 2AF20A9C12065CC7001E5E3F /* ADMList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMList.h; sourceTree = ""; }; 2AF20A9D12065CC7001E5E3F /* ADMListEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMListEntry.h; sourceTree = ""; }; 2AF20A9E12065CC7001E5E3F /* ADMNotifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMNotifier.h; sourceTree = ""; }; 2AF20A9F12065CC7001E5E3F /* ADMRadioGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMRadioGroup.h; sourceTree = ""; }; 2AF20AA012065CC7001E5E3F /* ADMResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMResource.h; sourceTree = ""; }; 2AF20AA112065CC7001E5E3F /* ADMStandardTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMStandardTypes.h; sourceTree = ""; }; 2AF20AA212065CC7001E5E3F /* ADMTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMTracker.h; sourceTree = ""; }; 2AF20AA312065CC7001E5E3F /* ADMTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMTypes.h; sourceTree = ""; }; 2AF20AA412065CC7001E5E3F /* ADMUITConversionSuite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMUITConversionSuite.h; sourceTree = ""; }; 2AF20AA512065CC7001E5E3F /* ADMVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMVersion.h; sourceTree = ""; }; 2AF20AA612065CC7001E5E3F /* ADMWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMWindow.h; sourceTree = ""; }; 2AF20AA812065CC7001E5E3F /* ADMBasicOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMBasicOld.h; sourceTree = ""; }; 2AF20AA912065CC7001E5E3F /* ADMCustomResourceOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMCustomResourceOld.h; sourceTree = ""; }; 2AF20AAA12065CC7001E5E3F /* ADMDialogGroupOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMDialogGroupOld.h; sourceTree = ""; }; 2AF20AAB12065CC7001E5E3F /* ADMDialogOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMDialogOld.h; sourceTree = ""; }; 2AF20AAC12065CC7001E5E3F /* ADMDrawerOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMDrawerOld.h; sourceTree = ""; }; 2AF20AAD12065CC7001E5E3F /* ADMEntryOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMEntryOld.h; sourceTree = ""; }; 2AF20AAE12065CC7001E5E3F /* ADMHierarchyListOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMHierarchyListOld.h; sourceTree = ""; }; 2AF20AAF12065CC7001E5E3F /* ADMHostInitOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMHostInitOld.h; sourceTree = ""; }; 2AF20AB012065CC7001E5E3F /* ADMHostOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMHostOld.h; sourceTree = ""; }; 2AF20AB112065CC7001E5E3F /* ADMIconOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMIconOld.h; sourceTree = ""; }; 2AF20AB212065CC7001E5E3F /* ADMImageOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMImageOld.h; sourceTree = ""; }; 2AF20AB312065CC7001E5E3F /* ADMItemOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMItemOld.h; sourceTree = ""; }; 2AF20AB412065CC7001E5E3F /* ADMListEntryOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMListEntryOld.h; sourceTree = ""; }; 2AF20AB512065CC7001E5E3F /* ADMListOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMListOld.h; sourceTree = ""; }; 2AF20AB612065CC7001E5E3F /* ADMNotifierOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADMNotifierOld.h; sourceTree = ""; }; 2AF20AB712065CC7001E5E3F /* PlatformConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformConfig.h; sourceTree = ""; }; 2AF20AB812065CC7001E5E3F /* PlatformPragma.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformPragma.h; sourceTree = ""; }; 6412691809F974D9006DF4E6 /* ADSP.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ADSP.h; path = /Developer/Headers/FlatCarbon/ADSP.h; sourceTree = ""; }; 6412691909F974D9006DF4E6 /* AEDataModel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AEDataModel.h; path = /Developer/Headers/FlatCarbon/AEDataModel.h; sourceTree = ""; }; 6412691A09F974D9006DF4E6 /* AEDataModel.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = AEDataModel.r; path = /Developer/Headers/FlatCarbon/AEDataModel.r; sourceTree = ""; }; 6412691B09F974D9006DF4E6 /* AEHelpers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AEHelpers.h; path = /Developer/Headers/FlatCarbon/AEHelpers.h; sourceTree = ""; }; 6412691C09F974D9006DF4E6 /* AEInteraction.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AEInteraction.h; path = /Developer/Headers/FlatCarbon/AEInteraction.h; sourceTree = ""; }; 6412691D09F974D9006DF4E6 /* AEMach.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AEMach.h; path = /Developer/Headers/FlatCarbon/AEMach.h; sourceTree = ""; }; 6412691E09F974D9006DF4E6 /* AEObjects.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AEObjects.h; path = /Developer/Headers/FlatCarbon/AEObjects.h; sourceTree = ""; }; 6412691F09F974D9006DF4E6 /* AEObjects.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = AEObjects.r; path = /Developer/Headers/FlatCarbon/AEObjects.r; sourceTree = ""; }; 6412692009F974D9006DF4E6 /* AEPackObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AEPackObject.h; path = /Developer/Headers/FlatCarbon/AEPackObject.h; sourceTree = ""; }; 6412692109F974D9006DF4E6 /* AERegistry.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AERegistry.h; path = /Developer/Headers/FlatCarbon/AERegistry.h; sourceTree = ""; }; 6412692209F974D9006DF4E6 /* AERegistry.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = AERegistry.r; path = /Developer/Headers/FlatCarbon/AERegistry.r; sourceTree = ""; }; 6412692309F974D9006DF4E6 /* AEUserTermTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AEUserTermTypes.h; path = /Developer/Headers/FlatCarbon/AEUserTermTypes.h; sourceTree = ""; }; 6412692409F974D9006DF4E6 /* AEUserTermTypes.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = AEUserTermTypes.r; path = /Developer/Headers/FlatCarbon/AEUserTermTypes.r; sourceTree = ""; }; 6412692509F974D9006DF4E6 /* AEWideUserTermTypes.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = AEWideUserTermTypes.r; path = /Developer/Headers/FlatCarbon/AEWideUserTermTypes.r; sourceTree = ""; }; 6412692609F974D9006DF4E6 /* AIFF.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AIFF.h; path = /Developer/Headers/FlatCarbon/AIFF.h; sourceTree = ""; }; 6412692709F974D9006DF4E6 /* Aliases.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Aliases.h; path = /Developer/Headers/FlatCarbon/Aliases.h; sourceTree = ""; }; 6412692809F974D9006DF4E6 /* Appearance.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Appearance.h; path = /Developer/Headers/FlatCarbon/Appearance.h; sourceTree = ""; }; 6412692909F974D9006DF4E6 /* Appearance.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Appearance.r; path = /Developer/Headers/FlatCarbon/Appearance.r; sourceTree = ""; }; 6412692A09F974D9006DF4E6 /* AppleDiskPartitions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AppleDiskPartitions.h; path = /Developer/Headers/FlatCarbon/AppleDiskPartitions.h; sourceTree = ""; }; 6412692B09F974D9006DF4E6 /* AppleEvents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AppleEvents.h; path = /Developer/Headers/FlatCarbon/AppleEvents.h; sourceTree = ""; }; 6412692C09F974D9006DF4E6 /* AppleEvents.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = AppleEvents.r; path = /Developer/Headers/FlatCarbon/AppleEvents.r; sourceTree = ""; }; 6412692D09F974D9006DF4E6 /* AppleGuide.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AppleGuide.h; path = /Developer/Headers/FlatCarbon/AppleGuide.h; sourceTree = ""; }; 6412692E09F974D9006DF4E6 /* AppleHelp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AppleHelp.h; path = /Developer/Headers/FlatCarbon/AppleHelp.h; sourceTree = ""; }; 6412692F09F974D9006DF4E6 /* AppleScript.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AppleScript.h; path = /Developer/Headers/FlatCarbon/AppleScript.h; sourceTree = ""; }; 6412693009F974D9006DF4E6 /* AppleTalk.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AppleTalk.h; path = /Developer/Headers/FlatCarbon/AppleTalk.h; sourceTree = ""; }; 6412693109F974D9006DF4E6 /* ApplicationServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ApplicationServices.h; path = /Developer/Headers/FlatCarbon/ApplicationServices.h; sourceTree = ""; }; 6412693209F974D9006DF4E6 /* ApplicationServices.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = ApplicationServices.r; path = /Developer/Headers/FlatCarbon/ApplicationServices.r; sourceTree = ""; }; 6412693309F974D9006DF4E6 /* ASDebugging.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ASDebugging.h; path = /Developer/Headers/FlatCarbon/ASDebugging.h; sourceTree = ""; }; 6412693409F974D9006DF4E6 /* ASRegistry.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ASRegistry.h; path = /Developer/Headers/FlatCarbon/ASRegistry.h; sourceTree = ""; }; 6412693509F974D9006DF4E6 /* ASRegistry.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = ASRegistry.r; path = /Developer/Headers/FlatCarbon/ASRegistry.r; sourceTree = ""; }; 6412693609F974D9006DF4E6 /* ATA.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ATA.h; path = /Developer/Headers/FlatCarbon/ATA.h; sourceTree = ""; }; 6412693709F974D9006DF4E6 /* ATSFont.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ATSFont.h; path = /Developer/Headers/FlatCarbon/ATSFont.h; sourceTree = ""; }; 6412693809F974D9006DF4E6 /* ATSLayoutTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ATSLayoutTypes.h; path = /Developer/Headers/FlatCarbon/ATSLayoutTypes.h; sourceTree = ""; }; 6412693909F974D9006DF4E6 /* ATSTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ATSTypes.h; path = /Developer/Headers/FlatCarbon/ATSTypes.h; sourceTree = ""; }; 6412693A09F974D9006DF4E6 /* ATSUnicode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ATSUnicode.h; path = /Developer/Headers/FlatCarbon/ATSUnicode.h; sourceTree = ""; }; 6412693B09F974D9006DF4E6 /* AVComponents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AVComponents.h; path = /Developer/Headers/FlatCarbon/AVComponents.h; sourceTree = ""; }; 6412693C09F974D9006DF4E6 /* AVComponents.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AVComponents.k.h; path = /Developer/Headers/FlatCarbon/AVComponents.k.h; sourceTree = ""; }; 6412693D09F974D9006DF4E6 /* AVComponents.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = AVComponents.r; path = /Developer/Headers/FlatCarbon/AVComponents.r; sourceTree = ""; }; 6412693E09F974D9006DF4E6 /* AVLTree.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AVLTree.h; path = /Developer/Headers/FlatCarbon/AVLTree.h; sourceTree = ""; }; 6412693F09F974D9006DF4E6 /* Balloons.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Balloons.h; path = /Developer/Headers/FlatCarbon/Balloons.h; sourceTree = ""; }; 6412694009F974D9006DF4E6 /* Balloons.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Balloons.r; path = /Developer/Headers/FlatCarbon/Balloons.r; sourceTree = ""; }; 6412694109F974D9006DF4E6 /* BalloonTypes.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = BalloonTypes.r; path = /Developer/Headers/FlatCarbon/BalloonTypes.r; sourceTree = ""; }; 6412694209F974D9006DF4E6 /* Carbon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Carbon.h; path = /Developer/Headers/FlatCarbon/Carbon.h; sourceTree = ""; }; 6412694309F974D9006DF4E6 /* Carbon.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Carbon.r; path = /Developer/Headers/FlatCarbon/Carbon.r; sourceTree = ""; }; 6412694409F974D9006DF4E6 /* CarbonEvents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CarbonEvents.h; path = /Developer/Headers/FlatCarbon/CarbonEvents.h; sourceTree = ""; }; 6412694509F974D9006DF4E6 /* CarbonEvents.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = CarbonEvents.r; path = /Developer/Headers/FlatCarbon/CarbonEvents.r; sourceTree = ""; }; 6412694609F974D9006DF4E6 /* CardServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CardServices.h; path = /Developer/Headers/FlatCarbon/CardServices.h; sourceTree = ""; }; 6412694709F974D9006DF4E6 /* CFArray.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFArray.h; path = /Developer/Headers/FlatCarbon/CFArray.h; sourceTree = ""; }; 6412694809F974D9006DF4E6 /* CFBag.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFBag.h; path = /Developer/Headers/FlatCarbon/CFBag.h; sourceTree = ""; }; 6412694909F974D9006DF4E6 /* CFBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFBase.h; path = /Developer/Headers/FlatCarbon/CFBase.h; sourceTree = ""; }; 6412694A09F974D9006DF4E6 /* CFBundle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFBundle.h; path = /Developer/Headers/FlatCarbon/CFBundle.h; sourceTree = ""; }; 6412694B09F974D9006DF4E6 /* CFCharacterSet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFCharacterSet.h; path = /Developer/Headers/FlatCarbon/CFCharacterSet.h; sourceTree = ""; }; 6412694C09F974D9006DF4E6 /* CFData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFData.h; path = /Developer/Headers/FlatCarbon/CFData.h; sourceTree = ""; }; 6412694D09F974D9006DF4E6 /* CFDate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFDate.h; path = /Developer/Headers/FlatCarbon/CFDate.h; sourceTree = ""; }; 6412694E09F974D9006DF4E6 /* CFDictionary.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFDictionary.h; path = /Developer/Headers/FlatCarbon/CFDictionary.h; sourceTree = ""; }; 6412694F09F974D9006DF4E6 /* CFNumber.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFNumber.h; path = /Developer/Headers/FlatCarbon/CFNumber.h; sourceTree = ""; }; 6412695009F974D9006DF4E6 /* CFPlugIn.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFPlugIn.h; path = /Developer/Headers/FlatCarbon/CFPlugIn.h; sourceTree = ""; }; 6412695109F974D9006DF4E6 /* CFPlugInCOM.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFPlugInCOM.h; path = /Developer/Headers/FlatCarbon/CFPlugInCOM.h; sourceTree = ""; }; 6412695209F974D9006DF4E6 /* CFPreferences.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFPreferences.h; path = /Developer/Headers/FlatCarbon/CFPreferences.h; sourceTree = ""; }; 6412695309F974D9006DF4E6 /* CFPropertyList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFPropertyList.h; path = /Developer/Headers/FlatCarbon/CFPropertyList.h; sourceTree = ""; }; 6412695409F974D9006DF4E6 /* CFSet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFSet.h; path = /Developer/Headers/FlatCarbon/CFSet.h; sourceTree = ""; }; 6412695509F974D9006DF4E6 /* CFString.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFString.h; path = /Developer/Headers/FlatCarbon/CFString.h; sourceTree = ""; }; 6412695609F974D9006DF4E6 /* CFStringEncodingExt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFStringEncodingExt.h; path = /Developer/Headers/FlatCarbon/CFStringEncodingExt.h; sourceTree = ""; }; 6412695709F974D9006DF4E6 /* CFTimeZone.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFTimeZone.h; path = /Developer/Headers/FlatCarbon/CFTimeZone.h; sourceTree = ""; }; 6412695809F974D9006DF4E6 /* CFTree.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFTree.h; path = /Developer/Headers/FlatCarbon/CFTree.h; sourceTree = ""; }; 6412695909F974D9006DF4E6 /* CFURL.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFURL.h; path = /Developer/Headers/FlatCarbon/CFURL.h; sourceTree = ""; }; 6412695A09F974D9006DF4E6 /* CFURLAccess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFURLAccess.h; path = /Developer/Headers/FlatCarbon/CFURLAccess.h; sourceTree = ""; }; 6412695B09F974D9006DF4E6 /* CFUUID.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFUUID.h; path = /Developer/Headers/FlatCarbon/CFUUID.h; sourceTree = ""; }; 6412695C09F974D9006DF4E6 /* CFXMLNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFXMLNode.h; path = /Developer/Headers/FlatCarbon/CFXMLNode.h; sourceTree = ""; }; 6412695D09F974D9006DF4E6 /* CFXMLParser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CFXMLParser.h; path = /Developer/Headers/FlatCarbon/CFXMLParser.h; sourceTree = ""; }; 6412695E09F974D9006DF4E6 /* CGAffineTransform.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGAffineTransform.h; path = /Developer/Headers/FlatCarbon/CGAffineTransform.h; sourceTree = ""; }; 6412695F09F974D9006DF4E6 /* CGBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGBase.h; path = /Developer/Headers/FlatCarbon/CGBase.h; sourceTree = ""; }; 6412696009F974D9006DF4E6 /* CGBitmapContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGBitmapContext.h; path = /Developer/Headers/FlatCarbon/CGBitmapContext.h; sourceTree = ""; }; 6412696109F974D9006DF4E6 /* CGColorSpace.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGColorSpace.h; path = /Developer/Headers/FlatCarbon/CGColorSpace.h; sourceTree = ""; }; 6412696209F974D9006DF4E6 /* CGContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGContext.h; path = /Developer/Headers/FlatCarbon/CGContext.h; sourceTree = ""; }; 6412696309F974D9006DF4E6 /* CGDataConsumer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGDataConsumer.h; path = /Developer/Headers/FlatCarbon/CGDataConsumer.h; sourceTree = ""; }; 6412696409F974D9006DF4E6 /* CGDataProvider.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGDataProvider.h; path = /Developer/Headers/FlatCarbon/CGDataProvider.h; sourceTree = ""; }; 6412696509F974D9006DF4E6 /* CGDirectDisplay.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGDirectDisplay.h; path = /Developer/Headers/FlatCarbon/CGDirectDisplay.h; sourceTree = ""; }; 6412696609F974D9006DF4E6 /* CGDirectPalette.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGDirectPalette.h; path = /Developer/Headers/FlatCarbon/CGDirectPalette.h; sourceTree = ""; }; 6412696709F974D9006DF4E6 /* CGError.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGError.h; path = /Developer/Headers/FlatCarbon/CGError.h; sourceTree = ""; }; 6412696809F974D9006DF4E6 /* CGFont.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGFont.h; path = /Developer/Headers/FlatCarbon/CGFont.h; sourceTree = ""; }; 6412696909F974D9006DF4E6 /* CGGeometry.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGGeometry.h; path = /Developer/Headers/FlatCarbon/CGGeometry.h; sourceTree = ""; }; 6412696A09F974D9006DF4E6 /* CGImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGImage.h; path = /Developer/Headers/FlatCarbon/CGImage.h; sourceTree = ""; }; 6412696B09F974D9006DF4E6 /* CGPattern.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGPattern.h; path = /Developer/Headers/FlatCarbon/CGPattern.h; sourceTree = ""; }; 6412696C09F974D9006DF4E6 /* CGPDFContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGPDFContext.h; path = /Developer/Headers/FlatCarbon/CGPDFContext.h; sourceTree = ""; }; 6412696D09F974D9006DF4E6 /* CGPDFDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGPDFDocument.h; path = /Developer/Headers/FlatCarbon/CGPDFDocument.h; sourceTree = ""; }; 6412696E09F974D9006DF4E6 /* CGRemoteOperation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGRemoteOperation.h; path = /Developer/Headers/FlatCarbon/CGRemoteOperation.h; sourceTree = ""; }; 6412696F09F974D9006DF4E6 /* CGWindowLevel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CGWindowLevel.h; path = /Developer/Headers/FlatCarbon/CGWindowLevel.h; sourceTree = ""; }; 6412697009F974D9006DF4E6 /* CMAcceleration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMAcceleration.h; path = /Developer/Headers/FlatCarbon/CMAcceleration.h; sourceTree = ""; }; 6412697109F974D9006DF4E6 /* CMApplication.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMApplication.h; path = /Developer/Headers/FlatCarbon/CMApplication.h; sourceTree = ""; }; 6412697209F974D9006DF4E6 /* CMCalibrator.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMCalibrator.h; path = /Developer/Headers/FlatCarbon/CMCalibrator.h; sourceTree = ""; }; 6412697309F974D9006DF4E6 /* CMComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMComponent.h; path = /Developer/Headers/FlatCarbon/CMComponent.h; sourceTree = ""; }; 6412697409F974D9006DF4E6 /* CMConversions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMConversions.h; path = /Developer/Headers/FlatCarbon/CMConversions.h; sourceTree = ""; }; 6412697509F974D9006DF4E6 /* CMDeviceIntegration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMDeviceIntegration.h; path = /Developer/Headers/FlatCarbon/CMDeviceIntegration.h; sourceTree = ""; }; 6412697609F974D9006DF4E6 /* CMICCProfile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMICCProfile.h; path = /Developer/Headers/FlatCarbon/CMICCProfile.h; sourceTree = ""; }; 6412697709F974D9006DF4E6 /* CMMComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMMComponent.h; path = /Developer/Headers/FlatCarbon/CMMComponent.h; sourceTree = ""; }; 6412697809F974D9006DF4E6 /* CMPRComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMPRComponent.h; path = /Developer/Headers/FlatCarbon/CMPRComponent.h; sourceTree = ""; }; 6412697909F974D9006DF4E6 /* CMScriptingPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMScriptingPlugin.h; path = /Developer/Headers/FlatCarbon/CMScriptingPlugin.h; sourceTree = ""; }; 6412697A09F974D9006DF4E6 /* CMTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CMTypes.h; path = /Developer/Headers/FlatCarbon/CMTypes.h; sourceTree = ""; }; 6412697B09F974D9006DF4E6 /* CodeFragments.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CodeFragments.h; path = /Developer/Headers/FlatCarbon/CodeFragments.h; sourceTree = ""; }; 6412697C09F974D9006DF4E6 /* CodeFragments.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = CodeFragments.r; path = /Developer/Headers/FlatCarbon/CodeFragments.r; sourceTree = ""; }; 6412697D09F974D9006DF4E6 /* CodeFragmentTypes.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = CodeFragmentTypes.r; path = /Developer/Headers/FlatCarbon/CodeFragmentTypes.r; sourceTree = ""; }; 6412697E09F974D9006DF4E6 /* Collections.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Collections.h; path = /Developer/Headers/FlatCarbon/Collections.h; sourceTree = ""; }; 6412697F09F974D9006DF4E6 /* Collections.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Collections.r; path = /Developer/Headers/FlatCarbon/Collections.r; sourceTree = ""; }; 6412698009F974D9006DF4E6 /* ColorPicker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ColorPicker.h; path = /Developer/Headers/FlatCarbon/ColorPicker.h; sourceTree = ""; }; 6412698109F974D9006DF4E6 /* ColorPickerComponents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ColorPickerComponents.h; path = /Developer/Headers/FlatCarbon/ColorPickerComponents.h; sourceTree = ""; }; 6412698209F974D9006DF4E6 /* CommResources.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CommResources.h; path = /Developer/Headers/FlatCarbon/CommResources.h; sourceTree = ""; }; 6412698309F974D9006DF4E6 /* CommResources.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = CommResources.r; path = /Developer/Headers/FlatCarbon/CommResources.r; sourceTree = ""; }; 6412698409F974D9006DF4E6 /* Components.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Components.h; path = /Developer/Headers/FlatCarbon/Components.h; sourceTree = ""; }; 6412698509F974D9006DF4E6 /* Components.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Components.k.h; path = /Developer/Headers/FlatCarbon/Components.k.h; sourceTree = ""; }; 6412698609F974D9006DF4E6 /* Components.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Components.r; path = /Developer/Headers/FlatCarbon/Components.r; sourceTree = ""; }; 6412698709F974D9006DF4E6 /* ConditionalMacros.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ConditionalMacros.h; path = /Developer/Headers/FlatCarbon/ConditionalMacros.h; sourceTree = ""; }; 6412698809F974D9006DF4E6 /* ConditionalMacros.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = ConditionalMacros.r; path = /Developer/Headers/FlatCarbon/ConditionalMacros.r; sourceTree = ""; }; 6412698909F974D9006DF4E6 /* Connections.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Connections.h; path = /Developer/Headers/FlatCarbon/Connections.h; sourceTree = ""; }; 6412698A09F974D9006DF4E6 /* ConnectionTools.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ConnectionTools.h; path = /Developer/Headers/FlatCarbon/ConnectionTools.h; sourceTree = ""; }; 6412698B09F974D9006DF4E6 /* ControlDefinitions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ControlDefinitions.h; path = /Developer/Headers/FlatCarbon/ControlDefinitions.h; sourceTree = ""; }; 6412698C09F974D9006DF4E6 /* ControlDefinitions.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = ControlDefinitions.r; path = /Developer/Headers/FlatCarbon/ControlDefinitions.r; sourceTree = ""; }; 6412698D09F974D9006DF4E6 /* Controls.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Controls.h; path = /Developer/Headers/FlatCarbon/Controls.h; sourceTree = ""; }; 6412698E09F974D9006DF4E6 /* Controls.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Controls.r; path = /Developer/Headers/FlatCarbon/Controls.r; sourceTree = ""; }; 6412698F09F974D9006DF4E6 /* ControlStrip.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ControlStrip.h; path = /Developer/Headers/FlatCarbon/ControlStrip.h; sourceTree = ""; }; 6412699009F974D9006DF4E6 /* CoreServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CoreServices.h; path = /Developer/Headers/FlatCarbon/CoreServices.h; sourceTree = ""; }; 6412699109F974D9006DF4E6 /* CoreServices.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = CoreServices.r; path = /Developer/Headers/FlatCarbon/CoreServices.r; sourceTree = ""; }; 6412699209F974D9006DF4E6 /* CRMSerialDevices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CRMSerialDevices.h; path = /Developer/Headers/FlatCarbon/CRMSerialDevices.h; sourceTree = ""; }; 6412699309F974D9006DF4E6 /* CryptoMessageSyntax.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CryptoMessageSyntax.h; path = /Developer/Headers/FlatCarbon/CryptoMessageSyntax.h; sourceTree = ""; }; 6412699409F974D9006DF4E6 /* CTBUtilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CTBUtilities.h; path = /Developer/Headers/FlatCarbon/CTBUtilities.h; sourceTree = ""; }; 6412699509F974D9006DF4E6 /* CursorDevices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CursorDevices.h; path = /Developer/Headers/FlatCarbon/CursorDevices.h; sourceTree = ""; }; 6412699609F974D9006DF4E6 /* DatabaseAccess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DatabaseAccess.h; path = /Developer/Headers/FlatCarbon/DatabaseAccess.h; sourceTree = ""; }; 6412699709F974D9006DF4E6 /* DatabaseAccess.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = DatabaseAccess.r; path = /Developer/Headers/FlatCarbon/DatabaseAccess.r; sourceTree = ""; }; 6412699809F974D9006DF4E6 /* DateTimeUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DateTimeUtils.h; path = /Developer/Headers/FlatCarbon/DateTimeUtils.h; sourceTree = ""; }; 6412699909F974D9006DF4E6 /* Debugging.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Debugging.h; path = /Developer/Headers/FlatCarbon/Debugging.h; sourceTree = ""; }; 6412699A09F974D9006DF4E6 /* DeskBus.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DeskBus.h; path = /Developer/Headers/FlatCarbon/DeskBus.h; sourceTree = ""; }; 6412699B09F974D9006DF4E6 /* DesktopPrinting.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DesktopPrinting.h; path = /Developer/Headers/FlatCarbon/DesktopPrinting.h; sourceTree = ""; }; 6412699C09F974D9006DF4E6 /* DesktopPrinting.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = DesktopPrinting.r; path = /Developer/Headers/FlatCarbon/DesktopPrinting.r; sourceTree = ""; }; 6412699D09F974D9006DF4E6 /* DeviceControl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DeviceControl.h; path = /Developer/Headers/FlatCarbon/DeviceControl.h; sourceTree = ""; }; 6412699E09F974D9006DF4E6 /* DeviceControl.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DeviceControl.k.h; path = /Developer/Headers/FlatCarbon/DeviceControl.k.h; sourceTree = ""; }; 6412699F09F974D9006DF4E6 /* Devices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Devices.h; path = /Developer/Headers/FlatCarbon/Devices.h; sourceTree = ""; }; 641269A009F974D9006DF4E6 /* Devices.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Devices.r; path = /Developer/Headers/FlatCarbon/Devices.r; sourceTree = ""; }; 641269A109F974D9006DF4E6 /* Dialogs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Dialogs.h; path = /Developer/Headers/FlatCarbon/Dialogs.h; sourceTree = ""; }; 641269A209F974D9006DF4E6 /* Dialogs.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Dialogs.r; path = /Developer/Headers/FlatCarbon/Dialogs.r; sourceTree = ""; }; 641269A309F974D9006DF4E6 /* Dictionary.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Dictionary.h; path = /Developer/Headers/FlatCarbon/Dictionary.h; sourceTree = ""; }; 641269A409F974D9006DF4E6 /* DiskInit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DiskInit.h; path = /Developer/Headers/FlatCarbon/DiskInit.h; sourceTree = ""; }; 641269A509F974D9006DF4E6 /* Disks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Disks.h; path = /Developer/Headers/FlatCarbon/Disks.h; sourceTree = ""; }; 641269A609F974D9006DF4E6 /* Displays.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Displays.h; path = /Developer/Headers/FlatCarbon/Displays.h; sourceTree = ""; }; 641269A709F974D9006DF4E6 /* Displays.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Displays.r; path = /Developer/Headers/FlatCarbon/Displays.r; sourceTree = ""; }; 641269A809F974D9006DF4E6 /* Drag.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Drag.h; path = /Developer/Headers/FlatCarbon/Drag.h; sourceTree = ""; }; 641269A909F974D9006DF4E6 /* DrawSprocket.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DrawSprocket.h; path = /Developer/Headers/FlatCarbon/DrawSprocket.h; sourceTree = ""; }; 641269AA09F974D9006DF4E6 /* DriverFamilyMatching.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DriverFamilyMatching.h; path = /Developer/Headers/FlatCarbon/DriverFamilyMatching.h; sourceTree = ""; }; 641269AB09F974D9006DF4E6 /* DriverGestalt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DriverGestalt.h; path = /Developer/Headers/FlatCarbon/DriverGestalt.h; sourceTree = ""; }; 641269AC09F974D9006DF4E6 /* DriverServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DriverServices.h; path = /Developer/Headers/FlatCarbon/DriverServices.h; sourceTree = ""; }; 641269AD09F974D9006DF4E6 /* DriverSupport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DriverSupport.h; path = /Developer/Headers/FlatCarbon/DriverSupport.h; sourceTree = ""; }; 641269AE09F974D9006DF4E6 /* DriverSynchronization.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DriverSynchronization.h; path = /Developer/Headers/FlatCarbon/DriverSynchronization.h; sourceTree = ""; }; 641269AF09F974D9006DF4E6 /* Editions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Editions.h; path = /Developer/Headers/FlatCarbon/Editions.h; sourceTree = ""; }; 641269B009F974D9006DF4E6 /* Endian.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Endian.h; path = /Developer/Headers/FlatCarbon/Endian.h; sourceTree = ""; }; 641269B109F974D9006DF4E6 /* ENET.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ENET.h; path = /Developer/Headers/FlatCarbon/ENET.h; sourceTree = ""; }; 641269B209F974D9006DF4E6 /* EPPC.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = EPPC.h; path = /Developer/Headers/FlatCarbon/EPPC.h; sourceTree = ""; }; 641269B309F974D9006DF4E6 /* EPPC.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = EPPC.r; path = /Developer/Headers/FlatCarbon/EPPC.r; sourceTree = ""; }; 641269B409F974D9006DF4E6 /* Errors.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Errors.h; path = /Developer/Headers/FlatCarbon/Errors.h; sourceTree = ""; }; 641269B509F974D9006DF4E6 /* Events.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Events.h; path = /Developer/Headers/FlatCarbon/Events.h; sourceTree = ""; }; 641269B609F974D9006DF4E6 /* Files.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Files.h; path = /Developer/Headers/FlatCarbon/Files.h; sourceTree = ""; }; 641269B709F974D9006DF4E6 /* FileSigning.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FileSigning.h; path = /Developer/Headers/FlatCarbon/FileSigning.h; sourceTree = ""; }; 641269B809F974D9006DF4E6 /* FileTransfers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FileTransfers.h; path = /Developer/Headers/FlatCarbon/FileTransfers.h; sourceTree = ""; }; 641269B909F974D9006DF4E6 /* FileTransferTools.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FileTransferTools.h; path = /Developer/Headers/FlatCarbon/FileTransferTools.h; sourceTree = ""; }; 641269BA09F974D9006DF4E6 /* FileTypesAndCreators.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FileTypesAndCreators.h; path = /Developer/Headers/FlatCarbon/FileTypesAndCreators.h; sourceTree = ""; }; 641269BB09F974D9006DF4E6 /* FileTypesAndCreators.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = FileTypesAndCreators.r; path = /Developer/Headers/FlatCarbon/FileTypesAndCreators.r; sourceTree = ""; }; 641269BC09F974D9006DF4E6 /* FindByContent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FindByContent.h; path = /Developer/Headers/FlatCarbon/FindByContent.h; sourceTree = ""; }; 641269BD09F974D9006DF4E6 /* Finder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Finder.h; path = /Developer/Headers/FlatCarbon/Finder.h; sourceTree = ""; }; 641269BE09F974D9006DF4E6 /* Finder.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Finder.r; path = /Developer/Headers/FlatCarbon/Finder.r; sourceTree = ""; }; 641269BF09F974D9006DF4E6 /* FinderRegistry.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FinderRegistry.h; path = /Developer/Headers/FlatCarbon/FinderRegistry.h; sourceTree = ""; }; 641269C009F974D9006DF4E6 /* FinderRegistry.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = FinderRegistry.r; path = /Developer/Headers/FlatCarbon/FinderRegistry.r; sourceTree = ""; }; 641269C109F974D9006DF4E6 /* FixMath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FixMath.h; path = /Developer/Headers/FlatCarbon/FixMath.h; sourceTree = ""; }; 641269C209F974D9006DF4E6 /* Folders.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Folders.h; path = /Developer/Headers/FlatCarbon/Folders.h; sourceTree = ""; }; 641269C309F974D9006DF4E6 /* Folders.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Folders.r; path = /Developer/Headers/FlatCarbon/Folders.r; sourceTree = ""; }; 641269C409F974D9006DF4E6 /* Fonts.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Fonts.h; path = /Developer/Headers/FlatCarbon/Fonts.h; sourceTree = ""; }; 641269C509F974D9006DF4E6 /* Fonts.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Fonts.r; path = /Developer/Headers/FlatCarbon/Fonts.r; sourceTree = ""; }; 641269C609F974D9006DF4E6 /* FontSync.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FontSync.h; path = /Developer/Headers/FlatCarbon/FontSync.h; sourceTree = ""; }; 641269C709F974D9006DF4E6 /* fp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = fp.h; path = /Developer/Headers/FlatCarbon/fp.h; sourceTree = ""; }; 641269C809F974D9006DF4E6 /* FSM.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = FSM.h; path = /Developer/Headers/FlatCarbon/FSM.h; sourceTree = ""; }; 641269C909F974D9006DF4E6 /* Gestalt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Gestalt.h; path = /Developer/Headers/FlatCarbon/Gestalt.h; sourceTree = ""; }; 641269CA09F974D9006DF4E6 /* Gestalt.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Gestalt.r; path = /Developer/Headers/FlatCarbon/Gestalt.r; sourceTree = ""; }; 641269CB09F974D9006DF4E6 /* GoggleSprocket.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GoggleSprocket.h; path = /Developer/Headers/FlatCarbon/GoggleSprocket.h; sourceTree = ""; }; 641269CC09F974D9006DF4E6 /* GXEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GXEnvironment.h; path = /Developer/Headers/FlatCarbon/GXEnvironment.h; sourceTree = ""; }; 641269CD09F974D9006DF4E6 /* GXErrors.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GXErrors.h; path = /Developer/Headers/FlatCarbon/GXErrors.h; sourceTree = ""; }; 641269CE09F974D9006DF4E6 /* GXFonts.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GXFonts.h; path = /Developer/Headers/FlatCarbon/GXFonts.h; sourceTree = ""; }; 641269CF09F974D9006DF4E6 /* GXGraphics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GXGraphics.h; path = /Developer/Headers/FlatCarbon/GXGraphics.h; sourceTree = ""; }; 641269D009F974D9006DF4E6 /* GXLayout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GXLayout.h; path = /Developer/Headers/FlatCarbon/GXLayout.h; sourceTree = ""; }; 641269D109F974D9006DF4E6 /* GXMath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GXMath.h; path = /Developer/Headers/FlatCarbon/GXMath.h; sourceTree = ""; }; 641269D209F974D9006DF4E6 /* GXMessages.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GXMessages.h; path = /Developer/Headers/FlatCarbon/GXMessages.h; sourceTree = ""; }; 641269D309F974D9006DF4E6 /* GXPrinterDrivers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GXPrinterDrivers.h; path = /Developer/Headers/FlatCarbon/GXPrinterDrivers.h; sourceTree = ""; }; 641269D409F974D9006DF4E6 /* GXPrinting.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GXPrinting.h; path = /Developer/Headers/FlatCarbon/GXPrinting.h; sourceTree = ""; }; 641269D509F974D9006DF4E6 /* GXTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GXTypes.h; path = /Developer/Headers/FlatCarbon/GXTypes.h; sourceTree = ""; }; 641269D609F974D9006DF4E6 /* HFSVolumes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = HFSVolumes.h; path = /Developer/Headers/FlatCarbon/HFSVolumes.h; sourceTree = ""; }; 641269D709F974D9006DF4E6 /* HID.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = HID.h; path = /Developer/Headers/FlatCarbon/HID.h; sourceTree = ""; }; 641269D809F974D9006DF4E6 /* HTMLRendering.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = HTMLRendering.h; path = /Developer/Headers/FlatCarbon/HTMLRendering.h; sourceTree = ""; }; 641269D909F974D9006DF4E6 /* HyperXCmd.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = HyperXCmd.h; path = /Developer/Headers/FlatCarbon/HyperXCmd.h; sourceTree = ""; }; 641269DA09F974D9006DF4E6 /* IAExtractor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = IAExtractor.h; path = /Developer/Headers/FlatCarbon/IAExtractor.h; sourceTree = ""; }; 641269DB09F974D9006DF4E6 /* IAExtractor.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = IAExtractor.r; path = /Developer/Headers/FlatCarbon/IAExtractor.r; sourceTree = ""; }; 641269DC09F974D9006DF4E6 /* IBCarbonRuntime.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = IBCarbonRuntime.h; path = /Developer/Headers/FlatCarbon/IBCarbonRuntime.h; sourceTree = ""; }; 641269DD09F974D9006DF4E6 /* ICAApplication.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ICAApplication.h; path = /Developer/Headers/FlatCarbon/ICAApplication.h; sourceTree = ""; }; 641269DE09F974D9006DF4E6 /* ICACamera.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ICACamera.h; path = /Developer/Headers/FlatCarbon/ICACamera.h; sourceTree = ""; }; 641269DF09F974D9006DF4E6 /* ICADevice.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ICADevice.h; path = /Developer/Headers/FlatCarbon/ICADevice.h; sourceTree = ""; }; 641269E009F974D9006DF4E6 /* Icons.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Icons.h; path = /Developer/Headers/FlatCarbon/Icons.h; sourceTree = ""; }; 641269E109F974D9006DF4E6 /* Icons.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Icons.r; path = /Developer/Headers/FlatCarbon/Icons.r; sourceTree = ""; }; 641269E209F974D9006DF4E6 /* ImageCodec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ImageCodec.h; path = /Developer/Headers/FlatCarbon/ImageCodec.h; sourceTree = ""; }; 641269E309F974D9006DF4E6 /* ImageCodec.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ImageCodec.k.h; path = /Developer/Headers/FlatCarbon/ImageCodec.k.h; sourceTree = ""; }; 641269E409F974D9006DF4E6 /* ImageCodec.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = ImageCodec.r; path = /Developer/Headers/FlatCarbon/ImageCodec.r; sourceTree = ""; }; 641269E509F974D9006DF4E6 /* ImageCompression.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ImageCompression.h; path = /Developer/Headers/FlatCarbon/ImageCompression.h; sourceTree = ""; }; 641269E609F974D9006DF4E6 /* ImageCompression.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ImageCompression.k.h; path = /Developer/Headers/FlatCarbon/ImageCompression.k.h; sourceTree = ""; }; 641269E709F974D9006DF4E6 /* ImageCompression.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = ImageCompression.r; path = /Developer/Headers/FlatCarbon/ImageCompression.r; sourceTree = ""; }; 641269E809F974D9006DF4E6 /* InputSprocket.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = InputSprocket.h; path = /Developer/Headers/FlatCarbon/InputSprocket.h; sourceTree = ""; }; 641269E909F974D9006DF4E6 /* InputSprocket.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = InputSprocket.r; path = /Developer/Headers/FlatCarbon/InputSprocket.r; sourceTree = ""; }; 641269EA09F974D9006DF4E6 /* InternetConfig.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = InternetConfig.h; path = /Developer/Headers/FlatCarbon/InternetConfig.h; sourceTree = ""; }; 641269EB09F974D9006DF4E6 /* Interrupts.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Interrupts.h; path = /Developer/Headers/FlatCarbon/Interrupts.h; sourceTree = ""; }; 641269EC09F974D9006DF4E6 /* IntlResources.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = IntlResources.h; path = /Developer/Headers/FlatCarbon/IntlResources.h; sourceTree = ""; }; 641269ED09F974D9006DF4E6 /* IntlResources.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = IntlResources.r; path = /Developer/Headers/FlatCarbon/IntlResources.r; sourceTree = ""; }; 641269EE09F974D9006DF4E6 /* IsochronousDataHandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = IsochronousDataHandler.h; path = /Developer/Headers/FlatCarbon/IsochronousDataHandler.h; sourceTree = ""; }; 641269EF09F974D9006DF4E6 /* IsochronousDataHandler.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = IsochronousDataHandler.k.h; path = /Developer/Headers/FlatCarbon/IsochronousDataHandler.k.h; sourceTree = ""; }; 641269F009F974D9006DF4E6 /* IsochronousDataHandler.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = IsochronousDataHandler.r; path = /Developer/Headers/FlatCarbon/IsochronousDataHandler.r; sourceTree = ""; }; 641269F109F974D9006DF4E6 /* JManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JManager.h; path = /Developer/Headers/FlatCarbon/JManager.h; sourceTree = ""; }; 641269F209F974D9006DF4E6 /* Kernel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Kernel.h; path = /Developer/Headers/FlatCarbon/Kernel.h; sourceTree = ""; }; 641269F309F974D9006DF4E6 /* Keyboards.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Keyboards.h; path = /Developer/Headers/FlatCarbon/Keyboards.h; sourceTree = ""; }; 641269F409F974D9006DF4E6 /* Keychain.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Keychain.h; path = /Developer/Headers/FlatCarbon/Keychain.h; sourceTree = ""; }; 641269F509F974D9006DF4E6 /* KeychainCore.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = KeychainCore.h; path = /Developer/Headers/FlatCarbon/KeychainCore.h; sourceTree = ""; }; 641269F609F974D9006DF4E6 /* KeychainHI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = KeychainHI.h; path = /Developer/Headers/FlatCarbon/KeychainHI.h; sourceTree = ""; }; 641269F709F974D9006DF4E6 /* LanguageAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = LanguageAnalysis.h; path = /Developer/Headers/FlatCarbon/LanguageAnalysis.h; sourceTree = ""; }; 641269F809F974D9006DF4E6 /* LaunchServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = LaunchServices.h; path = /Developer/Headers/FlatCarbon/LaunchServices.h; sourceTree = ""; }; 641269F909F974D9006DF4E6 /* Lists.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Lists.h; path = /Developer/Headers/FlatCarbon/Lists.h; sourceTree = ""; }; 641269FA09F974D9006DF4E6 /* LocationManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = LocationManager.h; path = /Developer/Headers/FlatCarbon/LocationManager.h; sourceTree = ""; }; 641269FB09F974D9006DF4E6 /* LocationManager.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = LocationManager.k.h; path = /Developer/Headers/FlatCarbon/LocationManager.k.h; sourceTree = ""; }; 641269FC09F974D9006DF4E6 /* LocationManager.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = LocationManager.r; path = /Developer/Headers/FlatCarbon/LocationManager.r; sourceTree = ""; }; 641269FD09F974D9006DF4E6 /* LowMem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = LowMem.h; path = /Developer/Headers/FlatCarbon/LowMem.h; sourceTree = ""; }; 641269FE09F974D9006DF4E6 /* MacApplication.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MacApplication.h; path = /Developer/Headers/FlatCarbon/MacApplication.h; sourceTree = ""; }; 641269FF09F974D9006DF4E6 /* MacErrors.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MacErrors.h; path = /Developer/Headers/FlatCarbon/MacErrors.h; sourceTree = ""; }; 64126A0009F974D9006DF4E6 /* MacHelp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MacHelp.h; path = /Developer/Headers/FlatCarbon/MacHelp.h; sourceTree = ""; }; 64126A0109F974D9006DF4E6 /* MachineExceptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MachineExceptions.h; path = /Developer/Headers/FlatCarbon/MachineExceptions.h; sourceTree = ""; }; 64126A0209F974D9006DF4E6 /* MacLocales.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MacLocales.h; path = /Developer/Headers/FlatCarbon/MacLocales.h; sourceTree = ""; }; 64126A0309F974D9006DF4E6 /* MacMemory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MacMemory.h; path = /Developer/Headers/FlatCarbon/MacMemory.h; sourceTree = ""; }; 64126A0409F974D9006DF4E6 /* MacTCP.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MacTCP.h; path = /Developer/Headers/FlatCarbon/MacTCP.h; sourceTree = ""; }; 64126A0509F974D9006DF4E6 /* MacTextEditor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MacTextEditor.h; path = /Developer/Headers/FlatCarbon/MacTextEditor.h; sourceTree = ""; }; 64126A0609F974D9006DF4E6 /* MacTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MacTypes.h; path = /Developer/Headers/FlatCarbon/MacTypes.h; sourceTree = ""; }; 64126A0709F974D9006DF4E6 /* MacTypes.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = MacTypes.r; path = /Developer/Headers/FlatCarbon/MacTypes.r; sourceTree = ""; }; 64126A0809F974D9006DF4E6 /* MacWindows.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MacWindows.h; path = /Developer/Headers/FlatCarbon/MacWindows.h; sourceTree = ""; }; 64126A0909F974D9006DF4E6 /* MacWindows.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = MacWindows.r; path = /Developer/Headers/FlatCarbon/MacWindows.r; sourceTree = ""; }; 64126A0A09F974D9006DF4E6 /* Math64.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Math64.h; path = /Developer/Headers/FlatCarbon/Math64.h; sourceTree = ""; }; 64126A0B09F974D9006DF4E6 /* MediaHandlers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MediaHandlers.h; path = /Developer/Headers/FlatCarbon/MediaHandlers.h; sourceTree = ""; }; 64126A0C09F974D9006DF4E6 /* MediaHandlers.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MediaHandlers.k.h; path = /Developer/Headers/FlatCarbon/MediaHandlers.k.h; sourceTree = ""; }; 64126A0D09F974D9006DF4E6 /* Memory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Memory.h; path = /Developer/Headers/FlatCarbon/Memory.h; sourceTree = ""; }; 64126A0E09F974D9006DF4E6 /* Menus.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Menus.h; path = /Developer/Headers/FlatCarbon/Menus.h; sourceTree = ""; }; 64126A0F09F974D9006DF4E6 /* Menus.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Menus.r; path = /Developer/Headers/FlatCarbon/Menus.r; sourceTree = ""; }; 64126A1009F974D9006DF4E6 /* MIDI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MIDI.h; path = /Developer/Headers/FlatCarbon/MIDI.h; sourceTree = ""; }; 64126A1109F974D9006DF4E6 /* MixedMode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MixedMode.h; path = /Developer/Headers/FlatCarbon/MixedMode.h; sourceTree = ""; }; 64126A1209F974D9006DF4E6 /* MixedMode.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = MixedMode.r; path = /Developer/Headers/FlatCarbon/MixedMode.r; sourceTree = ""; }; 64126A1309F974D9006DF4E6 /* Movies.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Movies.h; path = /Developer/Headers/FlatCarbon/Movies.h; sourceTree = ""; }; 64126A1409F974D9006DF4E6 /* Movies.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Movies.k.h; path = /Developer/Headers/FlatCarbon/Movies.k.h; sourceTree = ""; }; 64126A1509F974D9006DF4E6 /* MoviesFormat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MoviesFormat.h; path = /Developer/Headers/FlatCarbon/MoviesFormat.h; sourceTree = ""; }; 64126A1609F974D9006DF4E6 /* Multiprocessing.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Multiprocessing.h; path = /Developer/Headers/FlatCarbon/Multiprocessing.h; sourceTree = ""; }; 64126A1709F974D9006DF4E6 /* MultiprocessingInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MultiprocessingInfo.h; path = /Developer/Headers/FlatCarbon/MultiprocessingInfo.h; sourceTree = ""; }; 64126A1809F974D9006DF4E6 /* NameRegistry.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = NameRegistry.h; path = /Developer/Headers/FlatCarbon/NameRegistry.h; sourceTree = ""; }; 64126A1909F974D9006DF4E6 /* Navigation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Navigation.h; path = /Developer/Headers/FlatCarbon/Navigation.h; sourceTree = ""; }; 64126A1A09F974D9006DF4E6 /* NetSprocket.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = NetSprocket.h; path = /Developer/Headers/FlatCarbon/NetSprocket.h; sourceTree = ""; }; 64126A1B09F974D9006DF4E6 /* NetworkSetup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = NetworkSetup.h; path = /Developer/Headers/FlatCarbon/NetworkSetup.h; sourceTree = ""; }; 64126A1C09F974D9006DF4E6 /* NetworkSetup.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = NetworkSetup.r; path = /Developer/Headers/FlatCarbon/NetworkSetup.r; sourceTree = ""; }; 64126A1D09F974D9006DF4E6 /* Notification.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Notification.h; path = /Developer/Headers/FlatCarbon/Notification.h; sourceTree = ""; }; 64126A1E09F974D9006DF4E6 /* NSL.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = NSL.h; path = /Developer/Headers/FlatCarbon/NSL.h; sourceTree = ""; }; 64126A1F09F974D9006DF4E6 /* NSLCore.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = NSLCore.h; path = /Developer/Headers/FlatCarbon/NSLCore.h; sourceTree = ""; }; 64126A2009F974D9006DF4E6 /* NumberFormatting.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = NumberFormatting.h; path = /Developer/Headers/FlatCarbon/NumberFormatting.h; sourceTree = ""; }; 64126A2109F974D9006DF4E6 /* OpenTptAppleTalk.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptAppleTalk.h; path = /Developer/Headers/FlatCarbon/OpenTptAppleTalk.h; sourceTree = ""; }; 64126A2209F974D9006DF4E6 /* OpenTptClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptClient.h; path = /Developer/Headers/FlatCarbon/OpenTptClient.h; sourceTree = ""; }; 64126A2309F974D9006DF4E6 /* OpenTptCommon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptCommon.h; path = /Developer/Headers/FlatCarbon/OpenTptCommon.h; sourceTree = ""; }; 64126A2409F974D9006DF4E6 /* OpenTptConfig.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptConfig.h; path = /Developer/Headers/FlatCarbon/OpenTptConfig.h; sourceTree = ""; }; 64126A2509F974D9006DF4E6 /* OpenTptDevLinks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptDevLinks.h; path = /Developer/Headers/FlatCarbon/OpenTptDevLinks.h; sourceTree = ""; }; 64126A2609F974D9006DF4E6 /* OpenTptGlobalNew.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptGlobalNew.h; path = /Developer/Headers/FlatCarbon/OpenTptGlobalNew.h; sourceTree = ""; }; 64126A2709F974D9006DF4E6 /* OpenTptInternet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptInternet.h; path = /Developer/Headers/FlatCarbon/OpenTptInternet.h; sourceTree = ""; }; 64126A2809F974D9006DF4E6 /* OpenTptISDN.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptISDN.h; path = /Developer/Headers/FlatCarbon/OpenTptISDN.h; sourceTree = ""; }; 64126A2909F974D9006DF4E6 /* OpenTptLinks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptLinks.h; path = /Developer/Headers/FlatCarbon/OpenTptLinks.h; sourceTree = ""; }; 64126A2A09F974D9006DF4E6 /* OpenTptModule.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptModule.h; path = /Developer/Headers/FlatCarbon/OpenTptModule.h; sourceTree = ""; }; 64126A2B09F974D9006DF4E6 /* OpenTptPCISupport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptPCISupport.h; path = /Developer/Headers/FlatCarbon/OpenTptPCISupport.h; sourceTree = ""; }; 64126A2C09F974D9006DF4E6 /* OpenTptSerial.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptSerial.h; path = /Developer/Headers/FlatCarbon/OpenTptSerial.h; sourceTree = ""; }; 64126A2D09F974D9006DF4E6 /* OpenTptXTI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTptXTI.h; path = /Developer/Headers/FlatCarbon/OpenTptXTI.h; sourceTree = ""; }; 64126A2E09F974D9006DF4E6 /* OpenTransport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTransport.h; path = /Developer/Headers/FlatCarbon/OpenTransport.h; sourceTree = ""; }; 64126A2F09F974D9006DF4E6 /* OpenTransport.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = OpenTransport.r; path = /Developer/Headers/FlatCarbon/OpenTransport.r; sourceTree = ""; }; 64126A3009F974D9006DF4E6 /* OpenTransportKernel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTransportKernel.h; path = /Developer/Headers/FlatCarbon/OpenTransportKernel.h; sourceTree = ""; }; 64126A3109F974D9006DF4E6 /* OpenTransportKernel.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = OpenTransportKernel.r; path = /Developer/Headers/FlatCarbon/OpenTransportKernel.r; sourceTree = ""; }; 64126A3209F974D9006DF4E6 /* OpenTransportProtocol.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTransportProtocol.h; path = /Developer/Headers/FlatCarbon/OpenTransportProtocol.h; sourceTree = ""; }; 64126A3309F974D9006DF4E6 /* OpenTransportProtocol.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = OpenTransportProtocol.r; path = /Developer/Headers/FlatCarbon/OpenTransportProtocol.r; sourceTree = ""; }; 64126A3409F974D9006DF4E6 /* OpenTransportProviders.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTransportProviders.h; path = /Developer/Headers/FlatCarbon/OpenTransportProviders.h; sourceTree = ""; }; 64126A3509F974D9006DF4E6 /* OpenTransportProviders.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = OpenTransportProviders.r; path = /Developer/Headers/FlatCarbon/OpenTransportProviders.r; sourceTree = ""; }; 64126A3609F974D9006DF4E6 /* OpenTransportUNIX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OpenTransportUNIX.h; path = /Developer/Headers/FlatCarbon/OpenTransportUNIX.h; sourceTree = ""; }; 64126A3709F974D9006DF4E6 /* OSA.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OSA.h; path = /Developer/Headers/FlatCarbon/OSA.h; sourceTree = ""; }; 64126A3809F974D9006DF4E6 /* OSA.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OSA.k.h; path = /Developer/Headers/FlatCarbon/OSA.k.h; sourceTree = ""; }; 64126A3909F974D9006DF4E6 /* OSAComp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OSAComp.h; path = /Developer/Headers/FlatCarbon/OSAComp.h; sourceTree = ""; }; 64126A3A09F974D9006DF4E6 /* OSAGeneric.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OSAGeneric.h; path = /Developer/Headers/FlatCarbon/OSAGeneric.h; sourceTree = ""; }; 64126A3B09F974D9006DF4E6 /* OSUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = OSUtils.h; path = /Developer/Headers/FlatCarbon/OSUtils.h; sourceTree = ""; }; 64126A3C09F974D9006DF4E6 /* OSUtils.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = OSUtils.r; path = /Developer/Headers/FlatCarbon/OSUtils.r; sourceTree = ""; }; 64126A3D09F974D9006DF4E6 /* OTConfig.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = OTConfig.r; path = /Developer/Headers/FlatCarbon/OTConfig.r; sourceTree = ""; }; 64126A3E09F974D9006DF4E6 /* Packages.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Packages.h; path = /Developer/Headers/FlatCarbon/Packages.h; sourceTree = ""; }; 64126A3F09F974D9006DF4E6 /* Palettes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Palettes.h; path = /Developer/Headers/FlatCarbon/Palettes.h; sourceTree = ""; }; 64126A4009F974D9006DF4E6 /* Palettes.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Palettes.r; path = /Developer/Headers/FlatCarbon/Palettes.r; sourceTree = ""; }; 64126A4109F974D9006DF4E6 /* Patches.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Patches.h; path = /Developer/Headers/FlatCarbon/Patches.h; sourceTree = ""; }; 64126A4209F974D9006DF4E6 /* PCCard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PCCard.h; path = /Developer/Headers/FlatCarbon/PCCard.h; sourceTree = ""; }; 64126A4309F974D9006DF4E6 /* PCCardAdapterPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PCCardAdapterPlugin.h; path = /Developer/Headers/FlatCarbon/PCCardAdapterPlugin.h; sourceTree = ""; }; 64126A4409F974D9006DF4E6 /* PCCardEnablerPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PCCardEnablerPlugin.h; path = /Developer/Headers/FlatCarbon/PCCardEnablerPlugin.h; sourceTree = ""; }; 64126A4509F974D9006DF4E6 /* PCCardEnablerPlugin.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = PCCardEnablerPlugin.r; path = /Developer/Headers/FlatCarbon/PCCardEnablerPlugin.r; sourceTree = ""; }; 64126A4609F974D9006DF4E6 /* PCCardTuples.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PCCardTuples.h; path = /Developer/Headers/FlatCarbon/PCCardTuples.h; sourceTree = ""; }; 64126A4709F974D9006DF4E6 /* PCI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PCI.h; path = /Developer/Headers/FlatCarbon/PCI.h; sourceTree = ""; }; 64126A4809F974D9006DF4E6 /* PEFBinaryFormat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PEFBinaryFormat.h; path = /Developer/Headers/FlatCarbon/PEFBinaryFormat.h; sourceTree = ""; }; 64126A4909F974D9006DF4E6 /* Pict.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Pict.r; path = /Developer/Headers/FlatCarbon/Pict.r; sourceTree = ""; }; 64126A4A09F974D9006DF4E6 /* PictUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PictUtils.h; path = /Developer/Headers/FlatCarbon/PictUtils.h; sourceTree = ""; }; 64126A4B09F974D9006DF4E6 /* PictUtils.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = PictUtils.r; path = /Developer/Headers/FlatCarbon/PictUtils.r; sourceTree = ""; }; 64126A4C09F974D9006DF4E6 /* PLStringFuncs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PLStringFuncs.h; path = /Developer/Headers/FlatCarbon/PLStringFuncs.h; sourceTree = ""; }; 64126A4D09F974D9006DF4E6 /* PMApplication.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PMApplication.h; path = /Developer/Headers/FlatCarbon/PMApplication.h; sourceTree = ""; }; 64126A4E09F974D9006DF4E6 /* PMCore.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PMCore.h; path = /Developer/Headers/FlatCarbon/PMCore.h; sourceTree = ""; }; 64126A4F09F974D9006DF4E6 /* PMDefinitions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PMDefinitions.h; path = /Developer/Headers/FlatCarbon/PMDefinitions.h; sourceTree = ""; }; 64126A5009F974D9006DF4E6 /* Power.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Power.h; path = /Developer/Headers/FlatCarbon/Power.h; sourceTree = ""; }; 64126A5109F974D9006DF4E6 /* PPCToolbox.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PPCToolbox.h; path = /Developer/Headers/FlatCarbon/PPCToolbox.h; sourceTree = ""; }; 64126A5209F974D9006DF4E6 /* PPCToolbox.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = PPCToolbox.r; path = /Developer/Headers/FlatCarbon/PPCToolbox.r; sourceTree = ""; }; 64126A5309F974D9006DF4E6 /* Printing.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Printing.h; path = /Developer/Headers/FlatCarbon/Printing.h; sourceTree = ""; }; 64126A5409F974D9006DF4E6 /* Processes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Processes.h; path = /Developer/Headers/FlatCarbon/Processes.h; sourceTree = ""; }; 64126A5509F974D9006DF4E6 /* Processes.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Processes.r; path = /Developer/Headers/FlatCarbon/Processes.r; sourceTree = ""; }; 64126A5609F974D9006DF4E6 /* QD3D.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3D.h; path = /Developer/Headers/FlatCarbon/QD3D.h; sourceTree = ""; }; 64126A5709F974D9006DF4E6 /* QD3DAcceleration.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DAcceleration.h; path = /Developer/Headers/FlatCarbon/QD3DAcceleration.h; sourceTree = ""; }; 64126A5809F974D9006DF4E6 /* QD3DCamera.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DCamera.h; path = /Developer/Headers/FlatCarbon/QD3DCamera.h; sourceTree = ""; }; 64126A5909F974D9006DF4E6 /* QD3DController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DController.h; path = /Developer/Headers/FlatCarbon/QD3DController.h; sourceTree = ""; }; 64126A5A09F974D9006DF4E6 /* QD3DCustomElements.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DCustomElements.h; path = /Developer/Headers/FlatCarbon/QD3DCustomElements.h; sourceTree = ""; }; 64126A5B09F974D9006DF4E6 /* QD3DDrawContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DDrawContext.h; path = /Developer/Headers/FlatCarbon/QD3DDrawContext.h; sourceTree = ""; }; 64126A5C09F974D9006DF4E6 /* QD3DErrors.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DErrors.h; path = /Developer/Headers/FlatCarbon/QD3DErrors.h; sourceTree = ""; }; 64126A5D09F974D9006DF4E6 /* QD3DExtension.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DExtension.h; path = /Developer/Headers/FlatCarbon/QD3DExtension.h; sourceTree = ""; }; 64126A5E09F974D9006DF4E6 /* QD3DGeometry.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DGeometry.h; path = /Developer/Headers/FlatCarbon/QD3DGeometry.h; sourceTree = ""; }; 64126A5F09F974D9006DF4E6 /* QD3DGroup.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DGroup.h; path = /Developer/Headers/FlatCarbon/QD3DGroup.h; sourceTree = ""; }; 64126A6009F974D9006DF4E6 /* QD3DIO.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DIO.h; path = /Developer/Headers/FlatCarbon/QD3DIO.h; sourceTree = ""; }; 64126A6109F974D9006DF4E6 /* QD3DLight.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DLight.h; path = /Developer/Headers/FlatCarbon/QD3DLight.h; sourceTree = ""; }; 64126A6209F974D9006DF4E6 /* QD3DMath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DMath.h; path = /Developer/Headers/FlatCarbon/QD3DMath.h; sourceTree = ""; }; 64126A6309F974D9006DF4E6 /* QD3DPick.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DPick.h; path = /Developer/Headers/FlatCarbon/QD3DPick.h; sourceTree = ""; }; 64126A6409F974D9006DF4E6 /* QD3DRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DRenderer.h; path = /Developer/Headers/FlatCarbon/QD3DRenderer.h; sourceTree = ""; }; 64126A6509F974D9006DF4E6 /* QD3DSet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DSet.h; path = /Developer/Headers/FlatCarbon/QD3DSet.h; sourceTree = ""; }; 64126A6609F974D9006DF4E6 /* QD3DShader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DShader.h; path = /Developer/Headers/FlatCarbon/QD3DShader.h; sourceTree = ""; }; 64126A6709F974D9006DF4E6 /* QD3DStorage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DStorage.h; path = /Developer/Headers/FlatCarbon/QD3DStorage.h; sourceTree = ""; }; 64126A6809F974D9006DF4E6 /* QD3DString.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DString.h; path = /Developer/Headers/FlatCarbon/QD3DString.h; sourceTree = ""; }; 64126A6909F974D9006DF4E6 /* QD3DStyle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DStyle.h; path = /Developer/Headers/FlatCarbon/QD3DStyle.h; sourceTree = ""; }; 64126A6A09F974D9006DF4E6 /* QD3DTransform.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DTransform.h; path = /Developer/Headers/FlatCarbon/QD3DTransform.h; sourceTree = ""; }; 64126A6B09F974D9006DF4E6 /* QD3DView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DView.h; path = /Developer/Headers/FlatCarbon/QD3DView.h; sourceTree = ""; }; 64126A6C09F974D9006DF4E6 /* QD3DViewer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DViewer.h; path = /Developer/Headers/FlatCarbon/QD3DViewer.h; sourceTree = ""; }; 64126A6D09F974D9006DF4E6 /* QD3DWinViewer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QD3DWinViewer.h; path = /Developer/Headers/FlatCarbon/QD3DWinViewer.h; sourceTree = ""; }; 64126A6E09F974D9006DF4E6 /* QDOffscreen.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QDOffscreen.h; path = /Developer/Headers/FlatCarbon/QDOffscreen.h; sourceTree = ""; }; 64126A6F09F974D9006DF4E6 /* QTML.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QTML.h; path = /Developer/Headers/FlatCarbon/QTML.h; sourceTree = ""; }; 64126A7009F974D9006DF4E6 /* QTSMovie.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QTSMovie.h; path = /Developer/Headers/FlatCarbon/QTSMovie.h; sourceTree = ""; }; 64126A7109F974D9006DF4E6 /* QTSMovie.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QTSMovie.k.h; path = /Developer/Headers/FlatCarbon/QTSMovie.k.h; sourceTree = ""; }; 64126A7209F974D9006DF4E6 /* QTSMovie.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = QTSMovie.r; path = /Developer/Headers/FlatCarbon/QTSMovie.r; sourceTree = ""; }; 64126A7309F974D9006DF4E6 /* QTStreamingComponents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QTStreamingComponents.h; path = /Developer/Headers/FlatCarbon/QTStreamingComponents.h; sourceTree = ""; }; 64126A7409F974D9006DF4E6 /* QTStreamingComponents.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QTStreamingComponents.k.h; path = /Developer/Headers/FlatCarbon/QTStreamingComponents.k.h; sourceTree = ""; }; 64126A7509F974D9006DF4E6 /* QTStreamingComponents.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = QTStreamingComponents.r; path = /Developer/Headers/FlatCarbon/QTStreamingComponents.r; sourceTree = ""; }; 64126A7609F974D9006DF4E6 /* Quickdraw.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Quickdraw.h; path = /Developer/Headers/FlatCarbon/Quickdraw.h; sourceTree = ""; }; 64126A7709F974D9006DF4E6 /* Quickdraw.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Quickdraw.r; path = /Developer/Headers/FlatCarbon/Quickdraw.r; sourceTree = ""; }; 64126A7809F974D9006DF4E6 /* QuickdrawText.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QuickdrawText.h; path = /Developer/Headers/FlatCarbon/QuickdrawText.h; sourceTree = ""; }; 64126A7909F974D9006DF4E6 /* QuickTime.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QuickTime.h; path = /Developer/Headers/FlatCarbon/QuickTime.h; sourceTree = ""; }; 64126A7A09F974D9006DF4E6 /* QuickTime.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = QuickTime.r; path = /Developer/Headers/FlatCarbon/QuickTime.r; sourceTree = ""; }; 64126A7B09F974D9006DF4E6 /* QuickTimeComponents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QuickTimeComponents.h; path = /Developer/Headers/FlatCarbon/QuickTimeComponents.h; sourceTree = ""; }; 64126A7C09F974D9006DF4E6 /* QuickTimeComponents.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QuickTimeComponents.k.h; path = /Developer/Headers/FlatCarbon/QuickTimeComponents.k.h; sourceTree = ""; }; 64126A7D09F974D9006DF4E6 /* QuickTimeComponents.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = QuickTimeComponents.r; path = /Developer/Headers/FlatCarbon/QuickTimeComponents.r; sourceTree = ""; }; 64126A7E09F974D9006DF4E6 /* QuickTimeMusic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QuickTimeMusic.h; path = /Developer/Headers/FlatCarbon/QuickTimeMusic.h; sourceTree = ""; }; 64126A7F09F974D9006DF4E6 /* QuickTimeMusic.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QuickTimeMusic.k.h; path = /Developer/Headers/FlatCarbon/QuickTimeMusic.k.h; sourceTree = ""; }; 64126A8009F974D9006DF4E6 /* QuickTimeStreaming.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QuickTimeStreaming.h; path = /Developer/Headers/FlatCarbon/QuickTimeStreaming.h; sourceTree = ""; }; 64126A8109F974D9006DF4E6 /* QuickTimeVR.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QuickTimeVR.h; path = /Developer/Headers/FlatCarbon/QuickTimeVR.h; sourceTree = ""; }; 64126A8209F974D9006DF4E6 /* QuickTimeVRFormat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = QuickTimeVRFormat.h; path = /Developer/Headers/FlatCarbon/QuickTimeVRFormat.h; sourceTree = ""; }; 64126A8309F974D9006DF4E6 /* RAVE.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = RAVE.h; path = /Developer/Headers/FlatCarbon/RAVE.h; sourceTree = ""; }; 64126A8409F974D9006DF4E6 /* RAVESystem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = RAVESystem.h; path = /Developer/Headers/FlatCarbon/RAVESystem.h; sourceTree = ""; }; 64126A8509F974D9006DF4E6 /* Resources.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Resources.h; path = /Developer/Headers/FlatCarbon/Resources.h; sourceTree = ""; }; 64126A8609F974D9006DF4E6 /* Retrace.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Retrace.h; path = /Developer/Headers/FlatCarbon/Retrace.h; sourceTree = ""; }; 64126A8709F974D9006DF4E6 /* ROMDefs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ROMDefs.h; path = /Developer/Headers/FlatCarbon/ROMDefs.h; sourceTree = ""; }; 64126A8809F974D9006DF4E6 /* ScalerStreamTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ScalerStreamTypes.h; path = /Developer/Headers/FlatCarbon/ScalerStreamTypes.h; sourceTree = ""; }; 64126A8909F974D9006DF4E6 /* ScalerTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ScalerTypes.h; path = /Developer/Headers/FlatCarbon/ScalerTypes.h; sourceTree = ""; }; 64126A8A09F974D9006DF4E6 /* Scrap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Scrap.h; path = /Developer/Headers/FlatCarbon/Scrap.h; sourceTree = ""; }; 64126A8B09F974D9006DF4E6 /* Script.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Script.h; path = /Developer/Headers/FlatCarbon/Script.h; sourceTree = ""; }; 64126A8C09F974D9006DF4E6 /* Script.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Script.r; path = /Developer/Headers/FlatCarbon/Script.r; sourceTree = ""; }; 64126A8D09F974D9006DF4E6 /* SCSI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SCSI.h; path = /Developer/Headers/FlatCarbon/SCSI.h; sourceTree = ""; }; 64126A8E09F974D9006DF4E6 /* SegLoad.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SegLoad.h; path = /Developer/Headers/FlatCarbon/SegLoad.h; sourceTree = ""; }; 64126A8F09F974D9006DF4E6 /* Serial.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Serial.h; path = /Developer/Headers/FlatCarbon/Serial.h; sourceTree = ""; }; 64126A9009F974D9006DF4E6 /* SFNTLayoutTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SFNTLayoutTypes.h; path = /Developer/Headers/FlatCarbon/SFNTLayoutTypes.h; sourceTree = ""; }; 64126A9109F974D9006DF4E6 /* SFNTTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SFNTTypes.h; path = /Developer/Headers/FlatCarbon/SFNTTypes.h; sourceTree = ""; }; 64126A9209F974D9006DF4E6 /* ShutDown.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ShutDown.h; path = /Developer/Headers/FlatCarbon/ShutDown.h; sourceTree = ""; }; 64126A9309F974D9006DF4E6 /* Slots.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Slots.h; path = /Developer/Headers/FlatCarbon/Slots.h; sourceTree = ""; }; 64126A9409F974D9006DF4E6 /* Slots.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Slots.r; path = /Developer/Headers/FlatCarbon/Slots.r; sourceTree = ""; }; 64126A9509F974D9006DF4E6 /* SocketServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SocketServices.h; path = /Developer/Headers/FlatCarbon/SocketServices.h; sourceTree = ""; }; 64126A9609F974D9006DF4E6 /* Sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Sound.h; path = /Developer/Headers/FlatCarbon/Sound.h; sourceTree = ""; }; 64126A9709F974D9006DF4E6 /* Sound.k.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Sound.k.h; path = /Developer/Headers/FlatCarbon/Sound.k.h; sourceTree = ""; }; 64126A9809F974D9006DF4E6 /* Sound.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Sound.r; path = /Developer/Headers/FlatCarbon/Sound.r; sourceTree = ""; }; 64126A9909F974D9006DF4E6 /* SoundComponents.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SoundComponents.h; path = /Developer/Headers/FlatCarbon/SoundComponents.h; sourceTree = ""; }; 64126A9A09F974D9006DF4E6 /* SoundComponents.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = SoundComponents.r; path = /Developer/Headers/FlatCarbon/SoundComponents.r; sourceTree = ""; }; 64126A9B09F974D9006DF4E6 /* SoundInput.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SoundInput.h; path = /Developer/Headers/FlatCarbon/SoundInput.h; sourceTree = ""; }; 64126A9C09F974D9006DF4E6 /* SoundInput.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = SoundInput.r; path = /Developer/Headers/FlatCarbon/SoundInput.r; sourceTree = ""; }; 64126A9D09F974D9006DF4E6 /* SoundSprocket.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SoundSprocket.h; path = /Developer/Headers/FlatCarbon/SoundSprocket.h; sourceTree = ""; }; 64126A9E09F974D9006DF4E6 /* Speech.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Speech.h; path = /Developer/Headers/FlatCarbon/Speech.h; sourceTree = ""; }; 64126A9F09F974D9006DF4E6 /* SpeechRecognition.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SpeechRecognition.h; path = /Developer/Headers/FlatCarbon/SpeechRecognition.h; sourceTree = ""; }; 64126AA009F974D9006DF4E6 /* SpeechSynthesis.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SpeechSynthesis.h; path = /Developer/Headers/FlatCarbon/SpeechSynthesis.h; sourceTree = ""; }; 64126AA109F974D9006DF4E6 /* StandardFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = StandardFile.h; path = /Developer/Headers/FlatCarbon/StandardFile.h; sourceTree = ""; }; 64126AA209F974D9006DF4E6 /* Start.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Start.h; path = /Developer/Headers/FlatCarbon/Start.h; sourceTree = ""; }; 64126AA309F974D9006DF4E6 /* StringCompare.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = StringCompare.h; path = /Developer/Headers/FlatCarbon/StringCompare.h; sourceTree = ""; }; 64126AA409F974D9006DF4E6 /* Strings.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Strings.h; path = /Developer/Headers/FlatCarbon/Strings.h; sourceTree = ""; }; 64126AA509F974D9006DF4E6 /* SysTypes.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = SysTypes.r; path = /Developer/Headers/FlatCarbon/SysTypes.r; sourceTree = ""; }; 64126AA609F974D9006DF4E6 /* Telephones.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Telephones.h; path = /Developer/Headers/FlatCarbon/Telephones.h; sourceTree = ""; }; 64126AA709F974D9006DF4E6 /* Terminals.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Terminals.h; path = /Developer/Headers/FlatCarbon/Terminals.h; sourceTree = ""; }; 64126AA809F974D9006DF4E6 /* TerminalTools.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TerminalTools.h; path = /Developer/Headers/FlatCarbon/TerminalTools.h; sourceTree = ""; }; 64126AA909F974D9006DF4E6 /* TextCommon.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextCommon.h; path = /Developer/Headers/FlatCarbon/TextCommon.h; sourceTree = ""; }; 64126AAA09F974D9006DF4E6 /* TextCommon.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = TextCommon.r; path = /Developer/Headers/FlatCarbon/TextCommon.r; sourceTree = ""; }; 64126AAB09F974D9006DF4E6 /* TextEdit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextEdit.h; path = /Developer/Headers/FlatCarbon/TextEdit.h; sourceTree = ""; }; 64126AAC09F974D9006DF4E6 /* TextEncodingConverter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextEncodingConverter.h; path = /Developer/Headers/FlatCarbon/TextEncodingConverter.h; sourceTree = ""; }; 64126AAD09F974D9006DF4E6 /* TextEncodingPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextEncodingPlugin.h; path = /Developer/Headers/FlatCarbon/TextEncodingPlugin.h; sourceTree = ""; }; 64126AAE09F974D9006DF4E6 /* TextServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextServices.h; path = /Developer/Headers/FlatCarbon/TextServices.h; sourceTree = ""; }; 64126AAF09F974D9006DF4E6 /* TextUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TextUtils.h; path = /Developer/Headers/FlatCarbon/TextUtils.h; sourceTree = ""; }; 64126AB009F974D9006DF4E6 /* Threads.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Threads.h; path = /Developer/Headers/FlatCarbon/Threads.h; sourceTree = ""; }; 64126AB109F974D9006DF4E6 /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Timer.h; path = /Developer/Headers/FlatCarbon/Timer.h; sourceTree = ""; }; 64126AB209F974D9006DF4E6 /* ToolUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ToolUtils.h; path = /Developer/Headers/FlatCarbon/ToolUtils.h; sourceTree = ""; }; 64126AB309F974D9006DF4E6 /* Translation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Translation.h; path = /Developer/Headers/FlatCarbon/Translation.h; sourceTree = ""; }; 64126AB409F974D9006DF4E6 /* TranslationExtensions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TranslationExtensions.h; path = /Developer/Headers/FlatCarbon/TranslationExtensions.h; sourceTree = ""; }; 64126AB509F974D9006DF4E6 /* TranslationExtensions.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = TranslationExtensions.r; path = /Developer/Headers/FlatCarbon/TranslationExtensions.r; sourceTree = ""; }; 64126AB609F974D9006DF4E6 /* Traps.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Traps.h; path = /Developer/Headers/FlatCarbon/Traps.h; sourceTree = ""; }; 64126AB709F974D9006DF4E6 /* TSMTE.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TSMTE.h; path = /Developer/Headers/FlatCarbon/TSMTE.h; sourceTree = ""; }; 64126AB809F974D9006DF4E6 /* Types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Types.h; path = /Developer/Headers/FlatCarbon/Types.h; sourceTree = ""; }; 64126AB909F974D9006DF4E6 /* Types.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Types.r; path = /Developer/Headers/FlatCarbon/Types.r; sourceTree = ""; }; 64126ABA09F974D9006DF4E6 /* TypeSelect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = TypeSelect.h; path = /Developer/Headers/FlatCarbon/TypeSelect.h; sourceTree = ""; }; 64126ABB09F974D9006DF4E6 /* Unicode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Unicode.h; path = /Developer/Headers/FlatCarbon/Unicode.h; sourceTree = ""; }; 64126ABC09F974D9006DF4E6 /* UnicodeConverter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UnicodeConverter.h; path = /Developer/Headers/FlatCarbon/UnicodeConverter.h; sourceTree = ""; }; 64126ABD09F974D9006DF4E6 /* UnicodeConverter.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = UnicodeConverter.r; path = /Developer/Headers/FlatCarbon/UnicodeConverter.r; sourceTree = ""; }; 64126ABE09F974D9006DF4E6 /* UnicodeUtilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UnicodeUtilities.h; path = /Developer/Headers/FlatCarbon/UnicodeUtilities.h; sourceTree = ""; }; 64126ABF09F974D9006DF4E6 /* UnicodeUtilities.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = UnicodeUtilities.r; path = /Developer/Headers/FlatCarbon/UnicodeUtilities.r; sourceTree = ""; }; 64126AC009F974D9006DF4E6 /* URLAccess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = URLAccess.h; path = /Developer/Headers/FlatCarbon/URLAccess.h; sourceTree = ""; }; 64126AC109F974D9006DF4E6 /* USB.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = USB.h; path = /Developer/Headers/FlatCarbon/USB.h; sourceTree = ""; }; 64126AC209F974D9006DF4E6 /* UTCUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UTCUtils.h; path = /Developer/Headers/FlatCarbon/UTCUtils.h; sourceTree = ""; }; 64126AC309F974D9006DF4E6 /* vBasicOps.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = vBasicOps.h; path = /Developer/Headers/FlatCarbon/vBasicOps.h; sourceTree = ""; }; 64126AC409F974D9006DF4E6 /* vBigNum.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = vBigNum.h; path = /Developer/Headers/FlatCarbon/vBigNum.h; sourceTree = ""; }; 64126AC509F974D9006DF4E6 /* vBLAS.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = vBLAS.h; path = /Developer/Headers/FlatCarbon/vBLAS.h; sourceTree = ""; }; 64126AC609F974D9006DF4E6 /* vDSP.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = vDSP.h; path = /Developer/Headers/FlatCarbon/vDSP.h; sourceTree = ""; }; 64126AC709F974D9006DF4E6 /* vectorOps.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = vectorOps.h; path = /Developer/Headers/FlatCarbon/vectorOps.h; sourceTree = ""; }; 64126AC809F974D9006DF4E6 /* vfp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = vfp.h; path = /Developer/Headers/FlatCarbon/vfp.h; sourceTree = ""; }; 64126AC909F974D9006DF4E6 /* Video.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Video.h; path = /Developer/Headers/FlatCarbon/Video.h; sourceTree = ""; }; 64126ACA09F974D9006DF4E6 /* Video.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Video.r; path = /Developer/Headers/FlatCarbon/Video.r; sourceTree = ""; }; 64126ACB09F974D9006DF4E6 /* VideoServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VideoServices.h; path = /Developer/Headers/FlatCarbon/VideoServices.h; sourceTree = ""; }; 64126ACC09F974D9006DF4E6 /* Windows.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Windows.h; path = /Developer/Headers/FlatCarbon/Windows.h; sourceTree = ""; }; 64126ACD09F974D9006DF4E6 /* Windows.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = Windows.r; path = /Developer/Headers/FlatCarbon/Windows.r; sourceTree = ""; }; 64126ACE09F974D9006DF4E6 /* WorldScript.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = WorldScript.h; path = /Developer/Headers/FlatCarbon/WorldScript.h; sourceTree = ""; }; 64126ACF09F974D9006DF4E6 /* ZoomedVideo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ZoomedVideo.h; path = /Developer/Headers/FlatCarbon/ZoomedVideo.h; sourceTree = ""; }; 64126B2D09F9751D006DF4E6 /* ASPreInclude.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ASPreInclude.h; sourceTree = ""; }; 64126B2E09F9751D006DF4E6 /* PIAbout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIAbout.h; sourceTree = ""; }; 64126B2F09F9751D006DF4E6 /* PIAcquire.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIAcquire.h; sourceTree = ""; }; 64126B3009F9751D006DF4E6 /* PIActions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIActions.h; sourceTree = ""; }; 64126B3109F9751D006DF4E6 /* PIActionsPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIActionsPlugin.h; sourceTree = ""; }; 64126B3209F9751D006DF4E6 /* PIAliasSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIAliasSuite.h; sourceTree = ""; }; 64126B3309F9751D006DF4E6 /* PIBufferSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIBufferSuite.h; sourceTree = ""; }; 64126B3409F9751D006DF4E6 /* PIChannelPortOperations.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIChannelPortOperations.h; sourceTree = ""; }; 64126B3509F9751D006DF4E6 /* PIChannelPortsSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIChannelPortsSuite.h; sourceTree = ""; }; 64126B3609F9751D006DF4E6 /* PIColorSpaceSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIColorSpaceSuite.h; sourceTree = ""; }; 64126B3709F9751D006DF4E6 /* PIErrorSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIErrorSuite.h; sourceTree = ""; }; 64126B3809F9751D006DF4E6 /* PIExport.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIExport.h; sourceTree = ""; }; 64126B3909F9751D006DF4E6 /* PIFilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIFilter.h; sourceTree = ""; }; 64126B3A09F9751D006DF4E6 /* PIFormat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIFormat.h; sourceTree = ""; }; 64126B3B09F9751D006DF4E6 /* PIGeneral.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIGeneral.h; sourceTree = ""; }; 64126B3C09F9751D006DF4E6 /* PIGetFileListSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIGetFileListSuite.h; sourceTree = ""; }; 64126B3D09F9751D006DF4E6 /* PIGetPathSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIGetPathSuite.h; sourceTree = ""; }; 64126B3E09F9751D006DF4E6 /* PIHandleSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIHandleSuite.h; sourceTree = ""; }; 64126B3F09F9751D006DF4E6 /* PIPicker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIPicker.h; sourceTree = ""; }; 64126B4009F9751D006DF4E6 /* PIProgressSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIProgressSuite.h; sourceTree = ""; }; 64126B4109F9751D006DF4E6 /* PIProperties.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIProperties.h; sourceTree = ""; }; 64126B4209F9751D006DF4E6 /* PIResDefines.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIResDefines.h; sourceTree = ""; }; 64126B4309F9751D006DF4E6 /* PISelection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PISelection.h; sourceTree = ""; }; 64126B4409F9751D006DF4E6 /* PIStringTerminology.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIStringTerminology.h; sourceTree = ""; }; 64126B4509F9751D006DF4E6 /* PITerminology.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PITerminology.h; sourceTree = ""; }; 64126B4609F9751D006DF4E6 /* PITypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PITypes.h; sourceTree = ""; }; 64126B4709F9751D006DF4E6 /* PIUIHooksSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIUIHooksSuite.h; sourceTree = ""; }; 64126B4809F9751D006DF4E6 /* PSErrorDefines.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PSErrorDefines.h; sourceTree = ""; }; 64126B4A09F9751D006DF4E6 /* SPAccess.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPAccess.h; sourceTree = ""; }; 64126B4B09F9751D006DF4E6 /* SPAdapts.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPAdapts.h; sourceTree = ""; }; 64126B4C09F9751D006DF4E6 /* SPBasic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPBasic.h; sourceTree = ""; }; 64126B4D09F9751D006DF4E6 /* SPBckDbg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPBckDbg.h; sourceTree = ""; }; 64126B4E09F9751D006DF4E6 /* SPBlocks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPBlocks.h; sourceTree = ""; }; 64126B4F09F9751D006DF4E6 /* SPCaches.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPCaches.h; sourceTree = ""; }; 64126B5009F9751D006DF4E6 /* SPCOM.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPCOM.h; sourceTree = ""; }; 64126B5109F9751D006DF4E6 /* SPConfig.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPConfig.h; sourceTree = ""; }; 64126B5309F9751D006DF4E6 /* SPErrorCodes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPErrorCodes.h; sourceTree = ""; }; 64126B5409F9751D006DF4E6 /* SPErrors.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPErrors.h; sourceTree = ""; }; 64126B5509F9751D006DF4E6 /* SPFiles.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPFiles.h; sourceTree = ""; }; 64126B5609F9751D006DF4E6 /* SPHost.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPHost.h; sourceTree = ""; }; 64126B5709F9751D006DF4E6 /* SPInterf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPInterf.h; sourceTree = ""; }; 64126B5809F9751D006DF4E6 /* SPMData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPMData.h; sourceTree = ""; }; 64126B5909F9751D006DF4E6 /* SPObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPObject.h; sourceTree = ""; }; 64126B5A09F9751D006DF4E6 /* SPPiPL.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPPiPL.h; sourceTree = ""; }; 64126B5B09F9751D006DF4E6 /* SPPlugs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPPlugs.h; sourceTree = ""; }; 64126B5C09F9751D006DF4E6 /* SPProps.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPProps.h; sourceTree = ""; }; 64126B5D09F9751D006DF4E6 /* SPRuntme.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPRuntme.h; sourceTree = ""; }; 64126B5E09F9751D006DF4E6 /* SPStrngs.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPStrngs.h; sourceTree = ""; }; 64126B5F09F9751D006DF4E6 /* SPSTSPrp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPSTSPrp.h; sourceTree = ""; }; 64126B6009F9751D006DF4E6 /* SPSuites.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPSuites.h; sourceTree = ""; }; 64126B6109F9751D006DF4E6 /* SPTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SPTypes.h; sourceTree = ""; }; 64126B6309F9751D006DF4E6 /* PIGeneral.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; path = PIGeneral.r; sourceTree = ""; }; 64126B6409F9751D006DF4E6 /* PIMI.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; path = PIMI.r; sourceTree = ""; }; 64126B6509F9751D006DF4E6 /* PIPL.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; path = PIPL.r; sourceTree = ""; }; 64126B7409F97565006DF4E6 /* DialogUtilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DialogUtilities.h; sourceTree = ""; }; 64126B7B09F97565006DF4E6 /* MachOMacrezXcode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MachOMacrezXcode.h; sourceTree = ""; }; 64126B7F09F97565006DF4E6 /* PIDefines.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIDefines.h; sourceTree = ""; }; 64126B8109F97565006DF4E6 /* PIMachODebug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIMachODebug.h; sourceTree = ""; }; 64126B8209F97565006DF4E6 /* PIMachORelease.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIMachORelease.h; sourceTree = ""; }; 64126B8509F97565006DF4E6 /* PIRezMachO.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIRezMachO.h; sourceTree = ""; }; 64126B8709F97565006DF4E6 /* PIUActions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIUActions.h; sourceTree = ""; }; 64126B8909F97565006DF4E6 /* PIUFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIUFile.h; sourceTree = ""; }; 64126B8B09F97565006DF4E6 /* PIUI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIUI.h; sourceTree = ""; }; 64126B8E09F97565006DF4E6 /* PIUSuites.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIUSuites.h; sourceTree = ""; }; 64126B8F09F97565006DF4E6 /* PIUtilities.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PIUtilities.h; sourceTree = ""; }; 64126B9A09F97565006DF4E6 /* PIUtilities.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; path = PIUtilities.r; sourceTree = ""; }; 64126C2509F979E1006DF4E6 /* PIMacUI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PIMacUI.cpp; sourceTree = ""; }; 64126C2A09F979EA006DF4E6 /* PIUSuites.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PIUSuites.cpp; sourceTree = ""; }; 64126C2F09F979F7006DF4E6 /* DialogUtilitiesMac.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DialogUtilitiesMac.cpp; sourceTree = ""; }; 64126C3409F97A19006DF4E6 /* PIUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PIUtilities.cpp; sourceTree = ""; }; 646B5C9E10D3159B001A7C6E /* PSIntTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PSIntTypes.h; sourceTree = ""; }; 646B5CA910D31664001A7C6E /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 646B5D5E10D31674001A7C6E /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 64CC2EB3111CDDB200423B46 /* JSScriptingSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSScriptingSuite.h; sourceTree = ""; }; 64CF8EE60AA3A73400120C5A /* ASZStringSuite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ASZStringSuite.h; sourceTree = ""; }; 64CF8EE70AA3A73400120C5A /* ASTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ASTypes.h; sourceTree = ""; }; 64CF8EE80AA3A73400120C5A /* ASPragma.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ASPragma.h; sourceTree = ""; }; 64CF8EE90AA3A73400120C5A /* ASConfig.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ASConfig.h; sourceTree = ""; }; 8D01CCD20486CAD60068D4B7 /* OpenColorIO PS.plugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "OpenColorIO PS.plugin"; sourceTree = BUILT_PRODUCTS_DIR; }; E2880D630B0EECF5001C1C00 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 8D01CCCD0486CAD60068D4B7 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 2AF20B9112066147001E5E3F /* Cocoa.framework in Frameworks */, 2AF20B9C12066179001E5E3F /* Carbon.framework in Frameworks */, 2A644DBA1E31FAAF00AAEF84 /* liblcms.a in Frameworks */, 2A644DBB1E31FAB000AAEF84 /* libOpenColorIO.a in Frameworks */, 2A644DBC1E31FAB000AAEF84 /* libtinyxml.a in Frameworks */, 2A644DBD1E31FAB100AAEF84 /* libyaml.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 089C166AFE841209C02AAC07 /* SimpleFormat */ = { isa = PBXGroup; children = ( 2A7F21191E2F4E57003428D7 /* OpenColorIO_PS.h */, 2A7F21181E2F4E57003428D7 /* OpenColorIO_PS.cpp */, 2A7F21171E2F4E57003428D7 /* OpenColorIO_PS_Version.h */, 2A7F21161E2F4E57003428D7 /* OpenColorIO_PS_Terminology.h */, 2A4150421E33FD6900E3954B /* OpenColorIO_PS_Context.h */, 2A4150431E33FD6900E3954B /* OpenColorIO_PS_Context.cpp */, 2A644C1A1E3166FC00AAEF84 /* OpenColorIO_PS_Dialog.h */, 2A644CBA1E31787500AAEF84 /* OpenColorIO_PS_Dialog_Cocoa.mm */, 2A644C9C1E316E6C00AAEF84 /* OpenColorIO_PS_Dialog.xib */, 2A644CB21E31731000AAEF84 /* OpenColorIO_PS_Dialog_Controller.h */, 2A644CB31E31731000AAEF84 /* OpenColorIO_PS_Dialog_Controller.mm */, 2A7529DF1E3FB61100BB5897 /* OpenColorIO_AE_Dialogs.h */, 2A7529E11E3FB64000BB5897 /* OpenColorIO_AE_Dialogs_Cocoa.mm */, 2A7529E51E3FB66000BB5897 /* OpenColorIO_AE_Menu.h */, 2A7529E61E3FB66000BB5897 /* OpenColorIO_AE_Menu.m */, 2A7523931E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser_Controller.h */, 2A7523941E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser_Controller.m */, 2A7523951E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser.xib */, 2A7523741E3ECDEA00BB5897 /* ocioicc.h */, 2A7523731E3ECDEA00BB5897 /* ocioicc.cpp */, 2A7F211A1E2F4E57003428D7 /* OpenColorIO_PS.r */, 64126B7009F97565006DF4E6 /* SDK common */, 64126AD309F9751C006DF4E6 /* Photoshop common */, 6412691709F974D9006DF4E6 /* Mac OS common */, 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, 2A644DA21E31FA7800AAEF84 /* OpenColorIO.xcodeproj */, 2A644DA81E31FAA500AAEF84 /* lcms.xcodeproj */, 2A644DAB1E31FAA500AAEF84 /* tinyxml.xcodeproj */, 2A644DAE1E31FAA500AAEF84 /* yaml.xcodeproj */, 19C28FB4FE9D528D11CA2CBB /* Products */, ); name = SimpleFormat; sourceTree = ""; }; 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = { isa = PBXGroup; children = ( 646B5D5E10D31674001A7C6E /* AppKit.framework */, 08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */, 646B5CA910D31664001A7C6E /* Cocoa.framework */, ); name = "External Frameworks and Libraries"; sourceTree = ""; }; 19C28FB4FE9D528D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( 8D01CCD20486CAD60068D4B7 /* OpenColorIO PS.plugin */, ); name = Products; sourceTree = ""; }; 2A644DA31E31FA7800AAEF84 /* Products */ = { isa = PBXGroup; children = ( 2A644DA71E31FA7800AAEF84 /* libOpenColorIO.a */, ); name = Products; sourceTree = ""; }; 2A644DA91E31FAA500AAEF84 /* Products */ = { isa = PBXGroup; children = ( 2A644DB31E31FAA500AAEF84 /* liblcms.a */, ); name = Products; sourceTree = ""; }; 2A644DAC1E31FAA500AAEF84 /* Products */ = { isa = PBXGroup; children = ( 2A644DB61E31FAA500AAEF84 /* libtinyxml.a */, ); name = Products; sourceTree = ""; }; 2A644DAF1E31FAA500AAEF84 /* Products */ = { isa = PBXGroup; children = ( 2A644DB91E31FAA500AAEF84 /* libyaml.a */, ); name = Products; sourceTree = ""; }; 2AF20A8B12065CC6001E5E3F /* adm */ = { isa = PBXGroup; children = ( 2AF20A8D12065CC7001E5E3F /* ADMAGMTypes.h */, 2AF20A8E12065CC7001E5E3F /* ADMBasic.h */, 2AF20A8F12065CC7001E5E3F /* ADMCustomResource.h */, 2AF20A9012065CC7001E5E3F /* ADMDialog.h */, 2AF20A9112065CC7001E5E3F /* ADMDialogGroup.h */, 2AF20A9212065CC7001E5E3F /* ADMDrawer.h */, 2AF20A9312065CC7001E5E3F /* ADMEntry.h */, 2AF20A9412065CC7001E5E3F /* ADMHierarchyList.h */, 2AF20A9512065CC7001E5E3F /* ADMHost.h */, 2AF20A9612065CC7001E5E3F /* ADMHostInit.h */, 2AF20A9712065CC7001E5E3F /* ADMHostInitUnicode.h */, 2AF20A9812065CC7001E5E3F /* ADMHostWin.h */, 2AF20A9912065CC7001E5E3F /* ADMIcon.h */, 2AF20A9A12065CC7001E5E3F /* ADMImage.h */, 2AF20A9B12065CC7001E5E3F /* ADMItem.h */, 2AF20A9C12065CC7001E5E3F /* ADMList.h */, 2AF20A9D12065CC7001E5E3F /* ADMListEntry.h */, 2AF20A9E12065CC7001E5E3F /* ADMNotifier.h */, 2AF20A9F12065CC7001E5E3F /* ADMRadioGroup.h */, 2AF20AA012065CC7001E5E3F /* ADMResource.h */, 2AF20AA112065CC7001E5E3F /* ADMStandardTypes.h */, 2AF20AA212065CC7001E5E3F /* ADMTracker.h */, 2AF20AA312065CC7001E5E3F /* ADMTypes.h */, 2AF20AA412065CC7001E5E3F /* ADMUITConversionSuite.h */, 2AF20AA512065CC7001E5E3F /* ADMVersion.h */, 2AF20AA612065CC7001E5E3F /* ADMWindow.h */, 2AF20AA712065CC7001E5E3F /* legacy */, 2AF20AB712065CC7001E5E3F /* PlatformConfig.h */, 2AF20AB812065CC7001E5E3F /* PlatformPragma.h */, ); path = adm; sourceTree = ""; }; 2AF20AA712065CC7001E5E3F /* legacy */ = { isa = PBXGroup; children = ( 2AF20AA812065CC7001E5E3F /* ADMBasicOld.h */, 2AF20AA912065CC7001E5E3F /* ADMCustomResourceOld.h */, 2AF20AAA12065CC7001E5E3F /* ADMDialogGroupOld.h */, 2AF20AAB12065CC7001E5E3F /* ADMDialogOld.h */, 2AF20AAC12065CC7001E5E3F /* ADMDrawerOld.h */, 2AF20AAD12065CC7001E5E3F /* ADMEntryOld.h */, 2AF20AAE12065CC7001E5E3F /* ADMHierarchyListOld.h */, 2AF20AAF12065CC7001E5E3F /* ADMHostInitOld.h */, 2AF20AB012065CC7001E5E3F /* ADMHostOld.h */, 2AF20AB112065CC7001E5E3F /* ADMIconOld.h */, 2AF20AB212065CC7001E5E3F /* ADMImageOld.h */, 2AF20AB312065CC7001E5E3F /* ADMItemOld.h */, 2AF20AB412065CC7001E5E3F /* ADMListEntryOld.h */, 2AF20AB512065CC7001E5E3F /* ADMListOld.h */, 2AF20AB612065CC7001E5E3F /* ADMNotifierOld.h */, ); path = legacy; sourceTree = ""; }; 6412691709F974D9006DF4E6 /* Mac OS common */ = { isa = PBXGroup; children = ( 6412691809F974D9006DF4E6 /* ADSP.h */, 6412691909F974D9006DF4E6 /* AEDataModel.h */, 6412691A09F974D9006DF4E6 /* AEDataModel.r */, 6412691B09F974D9006DF4E6 /* AEHelpers.h */, 6412691C09F974D9006DF4E6 /* AEInteraction.h */, 6412691D09F974D9006DF4E6 /* AEMach.h */, 6412691E09F974D9006DF4E6 /* AEObjects.h */, 6412691F09F974D9006DF4E6 /* AEObjects.r */, 6412692009F974D9006DF4E6 /* AEPackObject.h */, 6412692109F974D9006DF4E6 /* AERegistry.h */, 6412692209F974D9006DF4E6 /* AERegistry.r */, 6412692309F974D9006DF4E6 /* AEUserTermTypes.h */, 6412692409F974D9006DF4E6 /* AEUserTermTypes.r */, 6412692509F974D9006DF4E6 /* AEWideUserTermTypes.r */, 6412692609F974D9006DF4E6 /* AIFF.h */, 6412692709F974D9006DF4E6 /* Aliases.h */, 6412692809F974D9006DF4E6 /* Appearance.h */, 6412692909F974D9006DF4E6 /* Appearance.r */, 6412692A09F974D9006DF4E6 /* AppleDiskPartitions.h */, 6412692B09F974D9006DF4E6 /* AppleEvents.h */, 6412692C09F974D9006DF4E6 /* AppleEvents.r */, 6412692D09F974D9006DF4E6 /* AppleGuide.h */, 6412692E09F974D9006DF4E6 /* AppleHelp.h */, 6412692F09F974D9006DF4E6 /* AppleScript.h */, 6412693009F974D9006DF4E6 /* AppleTalk.h */, 6412693109F974D9006DF4E6 /* ApplicationServices.h */, 6412693209F974D9006DF4E6 /* ApplicationServices.r */, 6412693309F974D9006DF4E6 /* ASDebugging.h */, 6412693409F974D9006DF4E6 /* ASRegistry.h */, 6412693509F974D9006DF4E6 /* ASRegistry.r */, 6412693609F974D9006DF4E6 /* ATA.h */, 6412693709F974D9006DF4E6 /* ATSFont.h */, 6412693809F974D9006DF4E6 /* ATSLayoutTypes.h */, 6412693909F974D9006DF4E6 /* ATSTypes.h */, 6412693A09F974D9006DF4E6 /* ATSUnicode.h */, 6412693B09F974D9006DF4E6 /* AVComponents.h */, 6412693C09F974D9006DF4E6 /* AVComponents.k.h */, 6412693D09F974D9006DF4E6 /* AVComponents.r */, 6412693E09F974D9006DF4E6 /* AVLTree.h */, 6412693F09F974D9006DF4E6 /* Balloons.h */, 6412694009F974D9006DF4E6 /* Balloons.r */, 6412694109F974D9006DF4E6 /* BalloonTypes.r */, 6412694209F974D9006DF4E6 /* Carbon.h */, 6412694309F974D9006DF4E6 /* Carbon.r */, 6412694409F974D9006DF4E6 /* CarbonEvents.h */, 6412694509F974D9006DF4E6 /* CarbonEvents.r */, 6412694609F974D9006DF4E6 /* CardServices.h */, 6412694709F974D9006DF4E6 /* CFArray.h */, 6412694809F974D9006DF4E6 /* CFBag.h */, 6412694909F974D9006DF4E6 /* CFBase.h */, 6412694A09F974D9006DF4E6 /* CFBundle.h */, 6412694B09F974D9006DF4E6 /* CFCharacterSet.h */, 6412694C09F974D9006DF4E6 /* CFData.h */, 6412694D09F974D9006DF4E6 /* CFDate.h */, 6412694E09F974D9006DF4E6 /* CFDictionary.h */, 6412694F09F974D9006DF4E6 /* CFNumber.h */, 6412695009F974D9006DF4E6 /* CFPlugIn.h */, 6412695109F974D9006DF4E6 /* CFPlugInCOM.h */, 6412695209F974D9006DF4E6 /* CFPreferences.h */, 6412695309F974D9006DF4E6 /* CFPropertyList.h */, 6412695409F974D9006DF4E6 /* CFSet.h */, 6412695509F974D9006DF4E6 /* CFString.h */, 6412695609F974D9006DF4E6 /* CFStringEncodingExt.h */, 6412695709F974D9006DF4E6 /* CFTimeZone.h */, 6412695809F974D9006DF4E6 /* CFTree.h */, 6412695909F974D9006DF4E6 /* CFURL.h */, 6412695A09F974D9006DF4E6 /* CFURLAccess.h */, 6412695B09F974D9006DF4E6 /* CFUUID.h */, 6412695C09F974D9006DF4E6 /* CFXMLNode.h */, 6412695D09F974D9006DF4E6 /* CFXMLParser.h */, 6412695E09F974D9006DF4E6 /* CGAffineTransform.h */, 6412695F09F974D9006DF4E6 /* CGBase.h */, 6412696009F974D9006DF4E6 /* CGBitmapContext.h */, 6412696109F974D9006DF4E6 /* CGColorSpace.h */, 6412696209F974D9006DF4E6 /* CGContext.h */, 6412696309F974D9006DF4E6 /* CGDataConsumer.h */, 6412696409F974D9006DF4E6 /* CGDataProvider.h */, 6412696509F974D9006DF4E6 /* CGDirectDisplay.h */, 6412696609F974D9006DF4E6 /* CGDirectPalette.h */, 6412696709F974D9006DF4E6 /* CGError.h */, 6412696809F974D9006DF4E6 /* CGFont.h */, 6412696909F974D9006DF4E6 /* CGGeometry.h */, 6412696A09F974D9006DF4E6 /* CGImage.h */, 6412696B09F974D9006DF4E6 /* CGPattern.h */, 6412696C09F974D9006DF4E6 /* CGPDFContext.h */, 6412696D09F974D9006DF4E6 /* CGPDFDocument.h */, 6412696E09F974D9006DF4E6 /* CGRemoteOperation.h */, 6412696F09F974D9006DF4E6 /* CGWindowLevel.h */, 6412697009F974D9006DF4E6 /* CMAcceleration.h */, 6412697109F974D9006DF4E6 /* CMApplication.h */, 6412697209F974D9006DF4E6 /* CMCalibrator.h */, 6412697309F974D9006DF4E6 /* CMComponent.h */, 6412697409F974D9006DF4E6 /* CMConversions.h */, 6412697509F974D9006DF4E6 /* CMDeviceIntegration.h */, 6412697609F974D9006DF4E6 /* CMICCProfile.h */, 6412697709F974D9006DF4E6 /* CMMComponent.h */, 6412697809F974D9006DF4E6 /* CMPRComponent.h */, 6412697909F974D9006DF4E6 /* CMScriptingPlugin.h */, 6412697A09F974D9006DF4E6 /* CMTypes.h */, 6412697B09F974D9006DF4E6 /* CodeFragments.h */, 6412697C09F974D9006DF4E6 /* CodeFragments.r */, 6412697D09F974D9006DF4E6 /* CodeFragmentTypes.r */, 6412697E09F974D9006DF4E6 /* Collections.h */, 6412697F09F974D9006DF4E6 /* Collections.r */, 6412698009F974D9006DF4E6 /* ColorPicker.h */, 6412698109F974D9006DF4E6 /* ColorPickerComponents.h */, 6412698209F974D9006DF4E6 /* CommResources.h */, 6412698309F974D9006DF4E6 /* CommResources.r */, 6412698409F974D9006DF4E6 /* Components.h */, 6412698509F974D9006DF4E6 /* Components.k.h */, 6412698609F974D9006DF4E6 /* Components.r */, 6412698709F974D9006DF4E6 /* ConditionalMacros.h */, 6412698809F974D9006DF4E6 /* ConditionalMacros.r */, 6412698909F974D9006DF4E6 /* Connections.h */, 6412698A09F974D9006DF4E6 /* ConnectionTools.h */, 6412698B09F974D9006DF4E6 /* ControlDefinitions.h */, 6412698C09F974D9006DF4E6 /* ControlDefinitions.r */, 6412698D09F974D9006DF4E6 /* Controls.h */, 6412698E09F974D9006DF4E6 /* Controls.r */, 6412698F09F974D9006DF4E6 /* ControlStrip.h */, 6412699009F974D9006DF4E6 /* CoreServices.h */, 6412699109F974D9006DF4E6 /* CoreServices.r */, 6412699209F974D9006DF4E6 /* CRMSerialDevices.h */, 6412699309F974D9006DF4E6 /* CryptoMessageSyntax.h */, 6412699409F974D9006DF4E6 /* CTBUtilities.h */, 6412699509F974D9006DF4E6 /* CursorDevices.h */, 6412699609F974D9006DF4E6 /* DatabaseAccess.h */, 6412699709F974D9006DF4E6 /* DatabaseAccess.r */, 6412699809F974D9006DF4E6 /* DateTimeUtils.h */, 6412699909F974D9006DF4E6 /* Debugging.h */, 6412699A09F974D9006DF4E6 /* DeskBus.h */, 6412699B09F974D9006DF4E6 /* DesktopPrinting.h */, 6412699C09F974D9006DF4E6 /* DesktopPrinting.r */, 6412699D09F974D9006DF4E6 /* DeviceControl.h */, 6412699E09F974D9006DF4E6 /* DeviceControl.k.h */, 6412699F09F974D9006DF4E6 /* Devices.h */, 641269A009F974D9006DF4E6 /* Devices.r */, 641269A109F974D9006DF4E6 /* Dialogs.h */, 641269A209F974D9006DF4E6 /* Dialogs.r */, 641269A309F974D9006DF4E6 /* Dictionary.h */, 641269A409F974D9006DF4E6 /* DiskInit.h */, 641269A509F974D9006DF4E6 /* Disks.h */, 641269A609F974D9006DF4E6 /* Displays.h */, 641269A709F974D9006DF4E6 /* Displays.r */, 641269A809F974D9006DF4E6 /* Drag.h */, 641269A909F974D9006DF4E6 /* DrawSprocket.h */, 641269AA09F974D9006DF4E6 /* DriverFamilyMatching.h */, 641269AB09F974D9006DF4E6 /* DriverGestalt.h */, 641269AC09F974D9006DF4E6 /* DriverServices.h */, 641269AD09F974D9006DF4E6 /* DriverSupport.h */, 641269AE09F974D9006DF4E6 /* DriverSynchronization.h */, 641269AF09F974D9006DF4E6 /* Editions.h */, 641269B009F974D9006DF4E6 /* Endian.h */, 641269B109F974D9006DF4E6 /* ENET.h */, 641269B209F974D9006DF4E6 /* EPPC.h */, 641269B309F974D9006DF4E6 /* EPPC.r */, 641269B409F974D9006DF4E6 /* Errors.h */, 641269B509F974D9006DF4E6 /* Events.h */, 641269B609F974D9006DF4E6 /* Files.h */, 641269B709F974D9006DF4E6 /* FileSigning.h */, 641269B809F974D9006DF4E6 /* FileTransfers.h */, 641269B909F974D9006DF4E6 /* FileTransferTools.h */, 641269BA09F974D9006DF4E6 /* FileTypesAndCreators.h */, 641269BB09F974D9006DF4E6 /* FileTypesAndCreators.r */, 641269BC09F974D9006DF4E6 /* FindByContent.h */, 641269BD09F974D9006DF4E6 /* Finder.h */, 641269BE09F974D9006DF4E6 /* Finder.r */, 641269BF09F974D9006DF4E6 /* FinderRegistry.h */, 641269C009F974D9006DF4E6 /* FinderRegistry.r */, 641269C109F974D9006DF4E6 /* FixMath.h */, 641269C209F974D9006DF4E6 /* Folders.h */, 641269C309F974D9006DF4E6 /* Folders.r */, 641269C409F974D9006DF4E6 /* Fonts.h */, 641269C509F974D9006DF4E6 /* Fonts.r */, 641269C609F974D9006DF4E6 /* FontSync.h */, 641269C709F974D9006DF4E6 /* fp.h */, 641269C809F974D9006DF4E6 /* FSM.h */, 641269C909F974D9006DF4E6 /* Gestalt.h */, 641269CA09F974D9006DF4E6 /* Gestalt.r */, 641269CB09F974D9006DF4E6 /* GoggleSprocket.h */, 641269CC09F974D9006DF4E6 /* GXEnvironment.h */, 641269CD09F974D9006DF4E6 /* GXErrors.h */, 641269CE09F974D9006DF4E6 /* GXFonts.h */, 641269CF09F974D9006DF4E6 /* GXGraphics.h */, 641269D009F974D9006DF4E6 /* GXLayout.h */, 641269D109F974D9006DF4E6 /* GXMath.h */, 641269D209F974D9006DF4E6 /* GXMessages.h */, 641269D309F974D9006DF4E6 /* GXPrinterDrivers.h */, 641269D409F974D9006DF4E6 /* GXPrinting.h */, 641269D509F974D9006DF4E6 /* GXTypes.h */, 641269D609F974D9006DF4E6 /* HFSVolumes.h */, 641269D709F974D9006DF4E6 /* HID.h */, 641269D809F974D9006DF4E6 /* HTMLRendering.h */, 641269D909F974D9006DF4E6 /* HyperXCmd.h */, 641269DA09F974D9006DF4E6 /* IAExtractor.h */, 641269DB09F974D9006DF4E6 /* IAExtractor.r */, 641269DC09F974D9006DF4E6 /* IBCarbonRuntime.h */, 641269DD09F974D9006DF4E6 /* ICAApplication.h */, 641269DE09F974D9006DF4E6 /* ICACamera.h */, 641269DF09F974D9006DF4E6 /* ICADevice.h */, 641269E009F974D9006DF4E6 /* Icons.h */, 641269E109F974D9006DF4E6 /* Icons.r */, 641269E209F974D9006DF4E6 /* ImageCodec.h */, 641269E309F974D9006DF4E6 /* ImageCodec.k.h */, 641269E409F974D9006DF4E6 /* ImageCodec.r */, 641269E509F974D9006DF4E6 /* ImageCompression.h */, 641269E609F974D9006DF4E6 /* ImageCompression.k.h */, 641269E709F974D9006DF4E6 /* ImageCompression.r */, 641269E809F974D9006DF4E6 /* InputSprocket.h */, 641269E909F974D9006DF4E6 /* InputSprocket.r */, 641269EA09F974D9006DF4E6 /* InternetConfig.h */, 641269EB09F974D9006DF4E6 /* Interrupts.h */, 641269EC09F974D9006DF4E6 /* IntlResources.h */, 641269ED09F974D9006DF4E6 /* IntlResources.r */, 641269EE09F974D9006DF4E6 /* IsochronousDataHandler.h */, 641269EF09F974D9006DF4E6 /* IsochronousDataHandler.k.h */, 641269F009F974D9006DF4E6 /* IsochronousDataHandler.r */, 641269F109F974D9006DF4E6 /* JManager.h */, 641269F209F974D9006DF4E6 /* Kernel.h */, 641269F309F974D9006DF4E6 /* Keyboards.h */, 641269F409F974D9006DF4E6 /* Keychain.h */, 641269F509F974D9006DF4E6 /* KeychainCore.h */, 641269F609F974D9006DF4E6 /* KeychainHI.h */, 641269F709F974D9006DF4E6 /* LanguageAnalysis.h */, 641269F809F974D9006DF4E6 /* LaunchServices.h */, 641269F909F974D9006DF4E6 /* Lists.h */, 641269FA09F974D9006DF4E6 /* LocationManager.h */, 641269FB09F974D9006DF4E6 /* LocationManager.k.h */, 641269FC09F974D9006DF4E6 /* LocationManager.r */, 641269FD09F974D9006DF4E6 /* LowMem.h */, 641269FE09F974D9006DF4E6 /* MacApplication.h */, 641269FF09F974D9006DF4E6 /* MacErrors.h */, 64126A0009F974D9006DF4E6 /* MacHelp.h */, 64126A0109F974D9006DF4E6 /* MachineExceptions.h */, 64126A0209F974D9006DF4E6 /* MacLocales.h */, 64126A0309F974D9006DF4E6 /* MacMemory.h */, 64126A0409F974D9006DF4E6 /* MacTCP.h */, 64126A0509F974D9006DF4E6 /* MacTextEditor.h */, 64126A0609F974D9006DF4E6 /* MacTypes.h */, 64126A0709F974D9006DF4E6 /* MacTypes.r */, 64126A0809F974D9006DF4E6 /* MacWindows.h */, 64126A0909F974D9006DF4E6 /* MacWindows.r */, 64126A0A09F974D9006DF4E6 /* Math64.h */, 64126A0B09F974D9006DF4E6 /* MediaHandlers.h */, 64126A0C09F974D9006DF4E6 /* MediaHandlers.k.h */, 64126A0D09F974D9006DF4E6 /* Memory.h */, 64126A0E09F974D9006DF4E6 /* Menus.h */, 64126A0F09F974D9006DF4E6 /* Menus.r */, 64126A1009F974D9006DF4E6 /* MIDI.h */, 64126A1109F974D9006DF4E6 /* MixedMode.h */, 64126A1209F974D9006DF4E6 /* MixedMode.r */, 64126A1309F974D9006DF4E6 /* Movies.h */, 64126A1409F974D9006DF4E6 /* Movies.k.h */, 64126A1509F974D9006DF4E6 /* MoviesFormat.h */, 64126A1609F974D9006DF4E6 /* Multiprocessing.h */, 64126A1709F974D9006DF4E6 /* MultiprocessingInfo.h */, 64126A1809F974D9006DF4E6 /* NameRegistry.h */, 64126A1909F974D9006DF4E6 /* Navigation.h */, 64126A1A09F974D9006DF4E6 /* NetSprocket.h */, 64126A1B09F974D9006DF4E6 /* NetworkSetup.h */, 64126A1C09F974D9006DF4E6 /* NetworkSetup.r */, 64126A1D09F974D9006DF4E6 /* Notification.h */, 64126A1E09F974D9006DF4E6 /* NSL.h */, 64126A1F09F974D9006DF4E6 /* NSLCore.h */, 64126A2009F974D9006DF4E6 /* NumberFormatting.h */, 64126A2109F974D9006DF4E6 /* OpenTptAppleTalk.h */, 64126A2209F974D9006DF4E6 /* OpenTptClient.h */, 64126A2309F974D9006DF4E6 /* OpenTptCommon.h */, 64126A2409F974D9006DF4E6 /* OpenTptConfig.h */, 64126A2509F974D9006DF4E6 /* OpenTptDevLinks.h */, 64126A2609F974D9006DF4E6 /* OpenTptGlobalNew.h */, 64126A2709F974D9006DF4E6 /* OpenTptInternet.h */, 64126A2809F974D9006DF4E6 /* OpenTptISDN.h */, 64126A2909F974D9006DF4E6 /* OpenTptLinks.h */, 64126A2A09F974D9006DF4E6 /* OpenTptModule.h */, 64126A2B09F974D9006DF4E6 /* OpenTptPCISupport.h */, 64126A2C09F974D9006DF4E6 /* OpenTptSerial.h */, 64126A2D09F974D9006DF4E6 /* OpenTptXTI.h */, 64126A2E09F974D9006DF4E6 /* OpenTransport.h */, 64126A2F09F974D9006DF4E6 /* OpenTransport.r */, 64126A3009F974D9006DF4E6 /* OpenTransportKernel.h */, 64126A3109F974D9006DF4E6 /* OpenTransportKernel.r */, 64126A3209F974D9006DF4E6 /* OpenTransportProtocol.h */, 64126A3309F974D9006DF4E6 /* OpenTransportProtocol.r */, 64126A3409F974D9006DF4E6 /* OpenTransportProviders.h */, 64126A3509F974D9006DF4E6 /* OpenTransportProviders.r */, 64126A3609F974D9006DF4E6 /* OpenTransportUNIX.h */, 64126A3709F974D9006DF4E6 /* OSA.h */, 64126A3809F974D9006DF4E6 /* OSA.k.h */, 64126A3909F974D9006DF4E6 /* OSAComp.h */, 64126A3A09F974D9006DF4E6 /* OSAGeneric.h */, 64126A3B09F974D9006DF4E6 /* OSUtils.h */, 64126A3C09F974D9006DF4E6 /* OSUtils.r */, 64126A3D09F974D9006DF4E6 /* OTConfig.r */, 64126A3E09F974D9006DF4E6 /* Packages.h */, 64126A3F09F974D9006DF4E6 /* Palettes.h */, 64126A4009F974D9006DF4E6 /* Palettes.r */, 64126A4109F974D9006DF4E6 /* Patches.h */, 64126A4209F974D9006DF4E6 /* PCCard.h */, 64126A4309F974D9006DF4E6 /* PCCardAdapterPlugin.h */, 64126A4409F974D9006DF4E6 /* PCCardEnablerPlugin.h */, 64126A4509F974D9006DF4E6 /* PCCardEnablerPlugin.r */, 64126A4609F974D9006DF4E6 /* PCCardTuples.h */, 64126A4709F974D9006DF4E6 /* PCI.h */, 64126A4809F974D9006DF4E6 /* PEFBinaryFormat.h */, 64126A4909F974D9006DF4E6 /* Pict.r */, 64126A4A09F974D9006DF4E6 /* PictUtils.h */, 64126A4B09F974D9006DF4E6 /* PictUtils.r */, 64126A4C09F974D9006DF4E6 /* PLStringFuncs.h */, 64126A4D09F974D9006DF4E6 /* PMApplication.h */, 64126A4E09F974D9006DF4E6 /* PMCore.h */, 64126A4F09F974D9006DF4E6 /* PMDefinitions.h */, 64126A5009F974D9006DF4E6 /* Power.h */, 64126A5109F974D9006DF4E6 /* PPCToolbox.h */, 64126A5209F974D9006DF4E6 /* PPCToolbox.r */, 64126A5309F974D9006DF4E6 /* Printing.h */, 64126A5409F974D9006DF4E6 /* Processes.h */, 64126A5509F974D9006DF4E6 /* Processes.r */, 64126A5609F974D9006DF4E6 /* QD3D.h */, 64126A5709F974D9006DF4E6 /* QD3DAcceleration.h */, 64126A5809F974D9006DF4E6 /* QD3DCamera.h */, 64126A5909F974D9006DF4E6 /* QD3DController.h */, 64126A5A09F974D9006DF4E6 /* QD3DCustomElements.h */, 64126A5B09F974D9006DF4E6 /* QD3DDrawContext.h */, 64126A5C09F974D9006DF4E6 /* QD3DErrors.h */, 64126A5D09F974D9006DF4E6 /* QD3DExtension.h */, 64126A5E09F974D9006DF4E6 /* QD3DGeometry.h */, 64126A5F09F974D9006DF4E6 /* QD3DGroup.h */, 64126A6009F974D9006DF4E6 /* QD3DIO.h */, 64126A6109F974D9006DF4E6 /* QD3DLight.h */, 64126A6209F974D9006DF4E6 /* QD3DMath.h */, 64126A6309F974D9006DF4E6 /* QD3DPick.h */, 64126A6409F974D9006DF4E6 /* QD3DRenderer.h */, 64126A6509F974D9006DF4E6 /* QD3DSet.h */, 64126A6609F974D9006DF4E6 /* QD3DShader.h */, 64126A6709F974D9006DF4E6 /* QD3DStorage.h */, 64126A6809F974D9006DF4E6 /* QD3DString.h */, 64126A6909F974D9006DF4E6 /* QD3DStyle.h */, 64126A6A09F974D9006DF4E6 /* QD3DTransform.h */, 64126A6B09F974D9006DF4E6 /* QD3DView.h */, 64126A6C09F974D9006DF4E6 /* QD3DViewer.h */, 64126A6D09F974D9006DF4E6 /* QD3DWinViewer.h */, 64126A6E09F974D9006DF4E6 /* QDOffscreen.h */, 64126A6F09F974D9006DF4E6 /* QTML.h */, 64126A7009F974D9006DF4E6 /* QTSMovie.h */, 64126A7109F974D9006DF4E6 /* QTSMovie.k.h */, 64126A7209F974D9006DF4E6 /* QTSMovie.r */, 64126A7309F974D9006DF4E6 /* QTStreamingComponents.h */, 64126A7409F974D9006DF4E6 /* QTStreamingComponents.k.h */, 64126A7509F974D9006DF4E6 /* QTStreamingComponents.r */, 64126A7609F974D9006DF4E6 /* Quickdraw.h */, 64126A7709F974D9006DF4E6 /* Quickdraw.r */, 64126A7809F974D9006DF4E6 /* QuickdrawText.h */, 64126A7909F974D9006DF4E6 /* QuickTime.h */, 64126A7A09F974D9006DF4E6 /* QuickTime.r */, 64126A7B09F974D9006DF4E6 /* QuickTimeComponents.h */, 64126A7C09F974D9006DF4E6 /* QuickTimeComponents.k.h */, 64126A7D09F974D9006DF4E6 /* QuickTimeComponents.r */, 64126A7E09F974D9006DF4E6 /* QuickTimeMusic.h */, 64126A7F09F974D9006DF4E6 /* QuickTimeMusic.k.h */, 64126A8009F974D9006DF4E6 /* QuickTimeStreaming.h */, 64126A8109F974D9006DF4E6 /* QuickTimeVR.h */, 64126A8209F974D9006DF4E6 /* QuickTimeVRFormat.h */, 64126A8309F974D9006DF4E6 /* RAVE.h */, 64126A8409F974D9006DF4E6 /* RAVESystem.h */, 64126A8509F974D9006DF4E6 /* Resources.h */, 64126A8609F974D9006DF4E6 /* Retrace.h */, 64126A8709F974D9006DF4E6 /* ROMDefs.h */, 64126A8809F974D9006DF4E6 /* ScalerStreamTypes.h */, 64126A8909F974D9006DF4E6 /* ScalerTypes.h */, 64126A8A09F974D9006DF4E6 /* Scrap.h */, 64126A8B09F974D9006DF4E6 /* Script.h */, 64126A8C09F974D9006DF4E6 /* Script.r */, 64126A8D09F974D9006DF4E6 /* SCSI.h */, 64126A8E09F974D9006DF4E6 /* SegLoad.h */, 64126A8F09F974D9006DF4E6 /* Serial.h */, 64126A9009F974D9006DF4E6 /* SFNTLayoutTypes.h */, 64126A9109F974D9006DF4E6 /* SFNTTypes.h */, 64126A9209F974D9006DF4E6 /* ShutDown.h */, 64126A9309F974D9006DF4E6 /* Slots.h */, 64126A9409F974D9006DF4E6 /* Slots.r */, 64126A9509F974D9006DF4E6 /* SocketServices.h */, 64126A9609F974D9006DF4E6 /* Sound.h */, 64126A9709F974D9006DF4E6 /* Sound.k.h */, 64126A9809F974D9006DF4E6 /* Sound.r */, 64126A9909F974D9006DF4E6 /* SoundComponents.h */, 64126A9A09F974D9006DF4E6 /* SoundComponents.r */, 64126A9B09F974D9006DF4E6 /* SoundInput.h */, 64126A9C09F974D9006DF4E6 /* SoundInput.r */, 64126A9D09F974D9006DF4E6 /* SoundSprocket.h */, 64126A9E09F974D9006DF4E6 /* Speech.h */, 64126A9F09F974D9006DF4E6 /* SpeechRecognition.h */, 64126AA009F974D9006DF4E6 /* SpeechSynthesis.h */, 64126AA109F974D9006DF4E6 /* StandardFile.h */, 64126AA209F974D9006DF4E6 /* Start.h */, 64126AA309F974D9006DF4E6 /* StringCompare.h */, 64126AA409F974D9006DF4E6 /* Strings.h */, 64126AA509F974D9006DF4E6 /* SysTypes.r */, 64126AA609F974D9006DF4E6 /* Telephones.h */, 64126AA709F974D9006DF4E6 /* Terminals.h */, 64126AA809F974D9006DF4E6 /* TerminalTools.h */, 64126AA909F974D9006DF4E6 /* TextCommon.h */, 64126AAA09F974D9006DF4E6 /* TextCommon.r */, 64126AAB09F974D9006DF4E6 /* TextEdit.h */, 64126AAC09F974D9006DF4E6 /* TextEncodingConverter.h */, 64126AAD09F974D9006DF4E6 /* TextEncodingPlugin.h */, 64126AAE09F974D9006DF4E6 /* TextServices.h */, 64126AAF09F974D9006DF4E6 /* TextUtils.h */, 64126AB009F974D9006DF4E6 /* Threads.h */, 64126AB109F974D9006DF4E6 /* Timer.h */, 64126AB209F974D9006DF4E6 /* ToolUtils.h */, 64126AB309F974D9006DF4E6 /* Translation.h */, 64126AB409F974D9006DF4E6 /* TranslationExtensions.h */, 64126AB509F974D9006DF4E6 /* TranslationExtensions.r */, 64126AB609F974D9006DF4E6 /* Traps.h */, 64126AB709F974D9006DF4E6 /* TSMTE.h */, 64126AB809F974D9006DF4E6 /* Types.h */, 64126AB909F974D9006DF4E6 /* Types.r */, 64126ABA09F974D9006DF4E6 /* TypeSelect.h */, 64126ABB09F974D9006DF4E6 /* Unicode.h */, 64126ABC09F974D9006DF4E6 /* UnicodeConverter.h */, 64126ABD09F974D9006DF4E6 /* UnicodeConverter.r */, 64126ABE09F974D9006DF4E6 /* UnicodeUtilities.h */, 64126ABF09F974D9006DF4E6 /* UnicodeUtilities.r */, 64126AC009F974D9006DF4E6 /* URLAccess.h */, 64126AC109F974D9006DF4E6 /* USB.h */, 64126AC209F974D9006DF4E6 /* UTCUtils.h */, 64126AC309F974D9006DF4E6 /* vBasicOps.h */, 64126AC409F974D9006DF4E6 /* vBigNum.h */, 64126AC509F974D9006DF4E6 /* vBLAS.h */, 64126AC609F974D9006DF4E6 /* vDSP.h */, 64126AC709F974D9006DF4E6 /* vectorOps.h */, 64126AC809F974D9006DF4E6 /* vfp.h */, 64126AC909F974D9006DF4E6 /* Video.h */, 64126ACA09F974D9006DF4E6 /* Video.r */, 64126ACB09F974D9006DF4E6 /* VideoServices.h */, 64126ACC09F974D9006DF4E6 /* Windows.h */, 64126ACD09F974D9006DF4E6 /* Windows.r */, 64126ACE09F974D9006DF4E6 /* WorldScript.h */, 64126ACF09F974D9006DF4E6 /* ZoomedVideo.h */, ); name = "Mac OS common"; path = /Developer/Headers/FlatCarbon; sourceTree = ""; }; 64126AD309F9751C006DF4E6 /* Photoshop common */ = { isa = PBXGroup; children = ( 2AF20A8B12065CC6001E5E3F /* adm */, 64126B2C09F9751D006DF4E6 /* photoshop */, 64126B4909F9751D006DF4E6 /* pica_sp */, 64126B6209F9751D006DF4E6 /* resources */, ); name = "Photoshop common"; path = ../../../ext/adobe_photoshop_cs5_sdk_mac/pluginsdk/photoshopapi; sourceTree = SOURCE_ROOT; }; 64126B2C09F9751D006DF4E6 /* photoshop */ = { isa = PBXGroup; children = ( 64CC2EB3111CDDB200423B46 /* JSScriptingSuite.h */, 646B5C9E10D3159B001A7C6E /* PSIntTypes.h */, 64CF8EE60AA3A73400120C5A /* ASZStringSuite.h */, 64CF8EE70AA3A73400120C5A /* ASTypes.h */, 64CF8EE80AA3A73400120C5A /* ASPragma.h */, 64CF8EE90AA3A73400120C5A /* ASConfig.h */, 64126B2D09F9751D006DF4E6 /* ASPreInclude.h */, 64126B2E09F9751D006DF4E6 /* PIAbout.h */, 64126B2F09F9751D006DF4E6 /* PIAcquire.h */, 64126B3009F9751D006DF4E6 /* PIActions.h */, 64126B3109F9751D006DF4E6 /* PIActionsPlugin.h */, 64126B3209F9751D006DF4E6 /* PIAliasSuite.h */, 64126B3309F9751D006DF4E6 /* PIBufferSuite.h */, 64126B3409F9751D006DF4E6 /* PIChannelPortOperations.h */, 64126B3509F9751D006DF4E6 /* PIChannelPortsSuite.h */, 64126B3609F9751D006DF4E6 /* PIColorSpaceSuite.h */, 64126B3709F9751D006DF4E6 /* PIErrorSuite.h */, 64126B3809F9751D006DF4E6 /* PIExport.h */, 64126B3909F9751D006DF4E6 /* PIFilter.h */, 64126B3A09F9751D006DF4E6 /* PIFormat.h */, 64126B3B09F9751D006DF4E6 /* PIGeneral.h */, 64126B3C09F9751D006DF4E6 /* PIGetFileListSuite.h */, 64126B3D09F9751D006DF4E6 /* PIGetPathSuite.h */, 64126B3E09F9751D006DF4E6 /* PIHandleSuite.h */, 64126B3F09F9751D006DF4E6 /* PIPicker.h */, 64126B4009F9751D006DF4E6 /* PIProgressSuite.h */, 64126B4109F9751D006DF4E6 /* PIProperties.h */, 64126B4209F9751D006DF4E6 /* PIResDefines.h */, 64126B4309F9751D006DF4E6 /* PISelection.h */, 64126B4409F9751D006DF4E6 /* PIStringTerminology.h */, 64126B4509F9751D006DF4E6 /* PITerminology.h */, 64126B4609F9751D006DF4E6 /* PITypes.h */, 64126B4709F9751D006DF4E6 /* PIUIHooksSuite.h */, 64126B4809F9751D006DF4E6 /* PSErrorDefines.h */, ); path = photoshop; sourceTree = ""; }; 64126B4909F9751D006DF4E6 /* pica_sp */ = { isa = PBXGroup; children = ( 64126B4A09F9751D006DF4E6 /* SPAccess.h */, 64126B4B09F9751D006DF4E6 /* SPAdapts.h */, 64126B4C09F9751D006DF4E6 /* SPBasic.h */, 64126B4D09F9751D006DF4E6 /* SPBckDbg.h */, 64126B4E09F9751D006DF4E6 /* SPBlocks.h */, 64126B4F09F9751D006DF4E6 /* SPCaches.h */, 64126B5009F9751D006DF4E6 /* SPCOM.h */, 64126B5109F9751D006DF4E6 /* SPConfig.h */, 64126B5309F9751D006DF4E6 /* SPErrorCodes.h */, 64126B5409F9751D006DF4E6 /* SPErrors.h */, 64126B5509F9751D006DF4E6 /* SPFiles.h */, 64126B5609F9751D006DF4E6 /* SPHost.h */, 64126B5709F9751D006DF4E6 /* SPInterf.h */, 64126B5809F9751D006DF4E6 /* SPMData.h */, 64126B5909F9751D006DF4E6 /* SPObject.h */, 64126B5A09F9751D006DF4E6 /* SPPiPL.h */, 64126B5B09F9751D006DF4E6 /* SPPlugs.h */, 64126B5C09F9751D006DF4E6 /* SPProps.h */, 64126B5D09F9751D006DF4E6 /* SPRuntme.h */, 64126B5E09F9751D006DF4E6 /* SPStrngs.h */, 64126B5F09F9751D006DF4E6 /* SPSTSPrp.h */, 64126B6009F9751D006DF4E6 /* SPSuites.h */, 64126B6109F9751D006DF4E6 /* SPTypes.h */, ); path = pica_sp; sourceTree = ""; }; 64126B6209F9751D006DF4E6 /* resources */ = { isa = PBXGroup; children = ( 64126B6309F9751D006DF4E6 /* PIGeneral.r */, 64126B6409F9751D006DF4E6 /* PIMI.r */, 64126B6509F9751D006DF4E6 /* PIPL.r */, ); path = resources; sourceTree = ""; }; 64126B7009F97565006DF4E6 /* SDK common */ = { isa = PBXGroup; children = ( 64126B7109F97565006DF4E6 /* includes */, 64126B9609F97565006DF4E6 /* resources */, 64126B9D09F97565006DF4E6 /* sources */, ); name = "SDK common"; path = ../../../ext/adobe_photoshop_cs5_sdk_mac/pluginsdk/samplecode/common; sourceTree = SOURCE_ROOT; }; 64126B7109F97565006DF4E6 /* includes */ = { isa = PBXGroup; children = ( 2AF20A8412065C91001E5E3F /* FilterBigDocument.h */, 64126B7409F97565006DF4E6 /* DialogUtilities.h */, 64126B7B09F97565006DF4E6 /* MachOMacrezXcode.h */, 64126B7F09F97565006DF4E6 /* PIDefines.h */, 64126B8109F97565006DF4E6 /* PIMachODebug.h */, 64126B8209F97565006DF4E6 /* PIMachORelease.h */, 64126B8509F97565006DF4E6 /* PIRezMachO.h */, 64126B8709F97565006DF4E6 /* PIUActions.h */, 64126B8909F97565006DF4E6 /* PIUFile.h */, 64126B8B09F97565006DF4E6 /* PIUI.h */, 64126B8E09F97565006DF4E6 /* PIUSuites.h */, 64126B8F09F97565006DF4E6 /* PIUtilities.h */, ); path = includes; sourceTree = ""; }; 64126B9609F97565006DF4E6 /* resources */ = { isa = PBXGroup; children = ( E2880D630B0EECF5001C1C00 /* Info.plist */, 64126B9A09F97565006DF4E6 /* PIUtilities.r */, ); path = resources; sourceTree = ""; }; 64126B9D09F97565006DF4E6 /* sources */ = { isa = PBXGroup; children = ( 2AF20A8212065C87001E5E3F /* FilterBigDocument.cpp */, 64126C2509F979E1006DF4E6 /* PIMacUI.cpp */, 64126C2A09F979EA006DF4E6 /* PIUSuites.cpp */, 64126C2F09F979F7006DF4E6 /* DialogUtilitiesMac.cpp */, 64126C3409F97A19006DF4E6 /* PIUtilities.cpp */, ); path = sources; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 8D01CCC60486CAD60068D4B7 /* OpenColorIO PS */ = { isa = PBXNativeTarget; buildConfigurationList = 4FADC23308B4156C00ABE55E /* Build configuration list for PBXNativeTarget "OpenColorIO PS" */; buildPhases = ( 8D01CCC90486CAD60068D4B7 /* Resources */, 8D01CCCB0486CAD60068D4B7 /* Sources */, 8D01CCCD0486CAD60068D4B7 /* Frameworks */, 64126BFC09F97704006DF4E6 /* Rez */, ); buildRules = ( ); dependencies = ( 2A644DBF1E31FACE00AAEF84 /* PBXTargetDependency */, 2A644DC11E31FACE00AAEF84 /* PBXTargetDependency */, 2A644DC31E31FACE00AAEF84 /* PBXTargetDependency */, 2A644DC51E31FACE00AAEF84 /* PBXTargetDependency */, ); name = "OpenColorIO PS"; productInstallPath = "$(HOME)/Library/Bundles"; productName = SimpleFormat; productReference = 8D01CCD20486CAD60068D4B7 /* OpenColorIO PS.plugin */; productType = "com.apple.product-type.bundle"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 089C1669FE841209C02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 4FADC23708B4156C00ABE55E /* Build configuration list for PBXProject "OpenColorIO_PS" */; compatibilityVersion = "Xcode 2.4"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, Japanese, French, German, ); mainGroup = 089C166AFE841209C02AAC07 /* SimpleFormat */; projectDirPath = ""; projectReferences = ( { ProductGroup = 2A644DA91E31FAA500AAEF84 /* Products */; ProjectRef = 2A644DA81E31FAA500AAEF84 /* lcms.xcodeproj */; }, { ProductGroup = 2A644DA31E31FA7800AAEF84 /* Products */; ProjectRef = 2A644DA21E31FA7800AAEF84 /* OpenColorIO.xcodeproj */; }, { ProductGroup = 2A644DAC1E31FAA500AAEF84 /* Products */; ProjectRef = 2A644DAB1E31FAA500AAEF84 /* tinyxml.xcodeproj */; }, { ProductGroup = 2A644DAF1E31FAA500AAEF84 /* Products */; ProjectRef = 2A644DAE1E31FAA500AAEF84 /* yaml.xcodeproj */; }, ); projectRoot = ""; targets = ( 8D01CCC60486CAD60068D4B7 /* OpenColorIO PS */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ 2A644DA71E31FA7800AAEF84 /* libOpenColorIO.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libOpenColorIO.a; remoteRef = 2A644DA61E31FA7800AAEF84 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; 2A644DB31E31FAA500AAEF84 /* liblcms.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = liblcms.a; remoteRef = 2A644DB21E31FAA500AAEF84 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; 2A644DB61E31FAA500AAEF84 /* libtinyxml.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libtinyxml.a; remoteRef = 2A644DB51E31FAA500AAEF84 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; 2A644DB91E31FAA500AAEF84 /* libyaml.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libyaml.a; remoteRef = 2A644DB81E31FAA500AAEF84 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ 8D01CCC90486CAD60068D4B7 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 2A644C9D1E316E6C00AAEF84 /* OpenColorIO_PS_Dialog.xib in Resources */, 2A7523971E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ 64126BFC09F97704006DF4E6 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; files = ( 2A7F211C1E2F4E57003428D7 /* OpenColorIO_PS.r in Rez */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXRezBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 8D01CCCB0486CAD60068D4B7 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 64126C2B09F979EA006DF4E6 /* PIUSuites.cpp in Sources */, 2AF20A8312065C87001E5E3F /* FilterBigDocument.cpp in Sources */, 2AF20AE712065E0E001E5E3F /* PIUtilities.cpp in Sources */, 2AF20AEA12065E19001E5E3F /* DialogUtilitiesMac.cpp in Sources */, 2A7F211B1E2F4E57003428D7 /* OpenColorIO_PS.cpp in Sources */, 2A644CB41E31731000AAEF84 /* OpenColorIO_PS_Dialog_Controller.mm in Sources */, 2A644CBB1E31787500AAEF84 /* OpenColorIO_PS_Dialog_Cocoa.mm in Sources */, 2A4150441E33FD6900E3954B /* OpenColorIO_PS_Context.cpp in Sources */, 2A7523751E3ECDEA00BB5897 /* ocioicc.cpp in Sources */, 2A7523961E3ED22600BB5897 /* OpenColorIO_AE_MonitorProfileChooser_Controller.m in Sources */, 2A7529E21E3FB64000BB5897 /* OpenColorIO_AE_Dialogs_Cocoa.mm in Sources */, 2A7529E71E3FB66000BB5897 /* OpenColorIO_AE_Menu.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 2A644DBF1E31FACE00AAEF84 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = lcms; targetProxy = 2A644DBE1E31FACE00AAEF84 /* PBXContainerItemProxy */; }; 2A644DC11E31FACE00AAEF84 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = yaml; targetProxy = 2A644DC01E31FACE00AAEF84 /* PBXContainerItemProxy */; }; 2A644DC31E31FACE00AAEF84 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = tinyxml; targetProxy = 2A644DC21E31FACE00AAEF84 /* PBXContainerItemProxy */; }; 2A644DC51E31FACE00AAEF84 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = OpenColorIO; targetProxy = 2A644DC41E31FACE00AAEF84 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 2A01738D112F17A8005CDE51 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { AE_SDK = "\"../../../../kits/Adobe After Effects CS3 SDK/Examples/Headers\""; ARCHS = "$(ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1)"; ARCHS_STANDARD_64_BIT_PRE_XCODE_3_1 = x86_64; COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 3; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = ( __PI__, PS_CS4_SDK, NDEBUG, ); GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; GENERATE_PKGINFO_FILE = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", ../../../export, ../../../src/core, ../../../ext/tinyxml, "../../../ext/yaml-cpp/include", "../../../ext/lcms2-2.1/include", ../../../src/aftereffects/xcode, ); ONLY_ACTIVE_ARCH = NO; PLUGIN_TYPE = 8BIF; PREBINDING = NO; REZ_PREFIX_FILE = "$(SRCROOT)/../../../ext/adobe_photoshop_cs5_sdk_mac/pluginsdk/samplecode/common/includes/MachOMacrezXcode.h"; SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; WRAPPER_EXTENSION = plugin; ZERO_LINK = NO; }; name = Release; }; 2A01738E112F17A8005CDE51 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { INFOPLIST_FILE = ../mac/OpenColorIO_PS_Info.plist; PRODUCT_NAME = "OpenColorIO PS"; WRAPPER_EXTENSION = plugin; }; name = Release; }; 4FADC23408B4156C00ABE55E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { INFOPLIST_FILE = ../mac/OpenColorIO_PS_Info.plist; PRODUCT_NAME = "OpenColorIO PS"; WRAPPER_EXTENSION = plugin; }; name = Debug; }; 4FADC23808B4156C00ABE55E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { AE_SDK = "\"../../../../kits/Adobe After Effects CS3 SDK/Examples/Headers\""; ARCHS = "$(ONLY_ACTIVE_ARCH_PRE_XCODE_3_1)"; COPY_PHASE_STRIP = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREPROCESSOR_DEFINITIONS = ( __PI__, PS_CS4_SDK, ); GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; GENERATE_PKGINFO_FILE = YES; HEADER_SEARCH_PATHS = ( "$(inherited)", ../../../export, ../../../src/core, ../../../ext/tinyxml, "../../../ext/yaml-cpp/include", "../../../ext/lcms2-2.1/include", ../../../src/aftereffects/xcode, ); ONLY_ACTIVE_ARCH_PRE_XCODE_3_1 = "$(NATIVE_ARCH_64)"; PLUGIN_TYPE = 8BIF; PREBINDING = NO; REZ_PREFIX_FILE = "$(SRCROOT)/../../../ext/adobe_photoshop_cs5_sdk_mac/pluginsdk/samplecode/common/includes/MachOMacrezXcode.h"; SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; STRIP_INSTALLED_PRODUCT = NO; WRAPPER_EXTENSION = plugin; ZERO_LINK = NO; }; name = Debug; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 4FADC23308B4156C00ABE55E /* Build configuration list for PBXNativeTarget "OpenColorIO PS" */ = { isa = XCConfigurationList; buildConfigurations = ( 4FADC23408B4156C00ABE55E /* Debug */, 2A01738E112F17A8005CDE51 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; 4FADC23708B4156C00ABE55E /* Build configuration list for PBXProject "OpenColorIO_PS" */ = { isa = XCConfigurationList; buildConfigurations = ( 4FADC23808B4156C00ABE55E /* Debug */, 2A01738D112F17A8005CDE51 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ }; rootObject = 089C1669FE841209C02AAC07 /* Project object */; } opencolorio-1.1.0~dfsg0.orig/src/photoshop/OpenColorIO_PS_Version.h0000644000175000017500000000412113223553423023506 0ustar mfvmfv/* Copyright (c) 2003-2017 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 _OPENCOLORIO_PS_VERSION_H_ #define _OPENCOLORIO_PS_VERSION_H_ #define OpenColorIO_PS_Major_Version 1 #define OpenColorIO_PS_Minor_Version 0 #define OpenColorIO_PS_Version_String "1.0" #define OpenColorIO_PS_Beta_String "Beta 4" #define OpenColorIO_PS_Build_Date __DATE__ #define OpenColorIO_PS_Build_Date_Manual "13 February 2017" #define OpenColorIO_PS_Build_Complete_Manual "v1.0 Beta 4 - " OpenColorIO_PS_Build_Date #define OpenColorIO_PS_Copyright_Year "2017" #define OpenColorIO_PS_Build_Year "2017" #define OpenColorIO_PS_Description "OpenColorIO" #endif // _OPENCOLORIO_PS_VERSION_H_ opencolorio-1.1.0~dfsg0.orig/src/photoshop/OpenColorIO_PS.r0000644000175000017500000002535413223553423022026 0ustar mfvmfv/* Copyright (c) 2003-2017 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 "OpenColorIO_PS_Version.h" // Definitions #define plugInName "OpenColorIO" #define plugInCopyrightYear OpenColorIO_PS_Copyright_Year #define plugInDescription OpenColorIO_PS_Description #define VersionString OpenColorIO_PS_Version_String #define ReleaseString OpenColorIO_PS_Build_Date_Manual #define CurrentYear OpenColorIO_PS_Build_Year // dictionary (aete) definitions #define vendorName "fnord" #define plugInAETEComment "OpenColorIO" #define plugInSuiteID 'ocio' #define plugInClassID plugInSuiteID #define plugInEventID plugInClassID #include "PIDefines.h" #ifdef __PIMac__ #include "Types.r" #include "SysTypes.r" #include "PIGeneral.r" #include "PIUtilities.r" #elif defined(__PIWin__) #define Rez #include "PIGeneral.h" #include "PIUtilities.r" #endif #include "PITerminology.h" #include "PIActions.h" #include "OpenColorIO_PS_Terminology.h" resource 'PiPL' ( 16000, "OpenColorIO", purgeable ) { { Kind { Filter }, Name { plugInName "..."}, Category { "OpenColorIO" }, Version { (latestFilterVersion << 16) | latestFilterSubVersion }, #ifdef __PIMac__ #if (defined(__x86_64__)) CodeMacIntel64 { "PluginMain" }, #endif #if (defined(__i386__)) CodeMacIntel32 { "PluginMain" }, #endif #if (defined(__ppc__)) CodeMachOPowerPC { 0, 0, "PluginMain" }, #endif #else #if defined(_WIN64) CodeWin64X86 { "PluginMain" }, #else CodeWin32X86 { "PluginMain" }, #endif #endif // ClassID, eventID, aete ID, uniqueString: HasTerminology { plugInClassID, plugInEventID, ResourceID, vendorName " " plugInName }, SupportedModes { noBitmap, noGrayScale, noIndexedColor, doesSupportRGBColor, noCMYKColor, noHSLColor, noHSBColor, noMultichannel, noDuotone, noLABColor }, EnableInfo { "in (PSHOP_ImageMode, RGBMode, RGB48Mode, RGB96Mode)" }, FilterLayerSupport {doesSupportFilterLayers}, // lets us work on smart objects PlugInMaxSize { 2000000, 2000000 }, FilterCaseInfo { { /* array: 7 elements */ /* Flat data, no selection */ inStraightData, outStraightData, doNotWriteOutsideSelection, doesNotFilterLayerMasks, doesNotWorkWithBlankData, copySourceToDestination, /* Flat data with selection */ inStraightData, outStraightData, doNotWriteOutsideSelection, doesNotFilterLayerMasks, doesNotWorkWithBlankData, copySourceToDestination, /* Floating selection */ inStraightData, outStraightData, doNotWriteOutsideSelection, doesNotFilterLayerMasks, doesNotWorkWithBlankData, copySourceToDestination, /* Editable transparency, no selection */ inStraightData, outStraightData, doNotWriteOutsideSelection, doesNotFilterLayerMasks, doesNotWorkWithBlankData, copySourceToDestination, /* Editable transparency, with selection */ inStraightData, outStraightData, doNotWriteOutsideSelection, doesNotFilterLayerMasks, doesNotWorkWithBlankData, copySourceToDestination, /* Preserved transparency, no selection */ inStraightData, outStraightData, doNotWriteOutsideSelection, doesNotFilterLayerMasks, doesNotWorkWithBlankData, copySourceToDestination, /* Preserved transparency, with selection */ inStraightData, outStraightData, doNotWriteOutsideSelection, doesNotFilterLayerMasks, doesNotWorkWithBlankData, copySourceToDestination } } } }; resource 'aete' (ResourceID, plugInName " dictionary", purgeable) { 1, 0, english, roman, /* aete version and language specifiers */ { vendorName, /* vendor suite name */ "OpenColorIO", /* optional description */ plugInSuiteID, /* suite ID */ 1, /* suite code, must be 1 */ 1, /* suite level, must be 1 */ { /* structure for filters */ plugInName, /* unique filter name */ plugInAETEComment, /* optional description */ plugInClassID, /* class ID, must be unique or Suite ID */ plugInEventID, /* event ID, must be unique */ NO_REPLY, /* never a reply */ IMAGE_DIRECT_PARAMETER, /* direct parameter, used by Photoshop */ { /* parameters here, if any */ "Source", /* parameter name */ ocioKeySource, /* parameter key ID */ typeSource, /* parameter type ID */ "Source of the OCIO configuration", /* optional description */ flagsEnumeratedParameter, /* parameter flags */ "Configuration", ocioKeyConfigName, typeChar, "OCIO Configuration Name", flagsSingleParameter, "File", ocioKeyConfigFileHandle, typePlatformFilePath, "OCIO Configuration File", flagsSingleParameter, "Action", ocioKeyAction, typeAction, "OCIO Action", flagsEnumeratedParameter, "Invert", ocioKeyInvert, typeBoolean, "Invert LUT", flagsSingleParameter, "Interpolation", ocioKeyInterpolation, typeInterpolation, "OCIO Interpolation", flagsEnumeratedParameter, "Input Space", ocioKeyInputSpace, typeChar, "OCIO Input Space", flagsSingleParameter, "Output Space", ocioKeyOutputSpace, typeChar, "OCIO Output Space", flagsSingleParameter, "Transform", ocioKeyTransform, typeChar, "OCIO Transform", flagsSingleParameter, "Device", ocioKeyDevice, typeChar, "OCIO Device", flagsSingleParameter } }, {}, /* non-filter plug-in class here */ {}, /* comparison ops (not supported) */ { /* any enumerations */ typeSource, { "Environment", sourceEnvironment, "$OCIO Environment Variable", "Standard", sourceStandard, "Standard OCIO Configuration", "Custom", sourceCustom, "Custom Configuration Path" }, typeAction, { "LUT", actionLUT, "Apply a LUT", "Convert", actionConvert, "Convert Transform", "Display", actionDisplay, "Display Transform" }, typeInterpolation, { "Nearest", interpNearest, "Nearest Interpolation", "Linear", interpLinear, "Linear Interpolation", "Tetrahedral", interpTetrahedral, "Tetrahedral Interpolation", "Best", interpBest, "Best Interpolation" } } } }; opencolorio-1.1.0~dfsg0.orig/src/photoshop/OpenColorIO_PS.h0000644000175000017500000000667413223553423022020 0ustar mfvmfv/* Copyright (c) 2003-2017 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 _OPENCOLORIO_PS_H_ #define _OPENCOLORIO_PS_H_ //#include "PIDefines.h" #include "PIFilter.h" #include "PIUtilities.h" #include "FilterBigDocument.h" enum { OCIO_SOURCE_NONE = 0, OCIO_SOURCE_ENVIRONMENT, OCIO_SOURCE_STANDARD, OCIO_SOURCE_CUSTOM }; typedef uint8 OCIO_Source; enum { OCIO_ACTION_NONE = 0, OCIO_ACTION_LUT, OCIO_ACTION_CONVERT, OCIO_ACTION_DISPLAY }; typedef uint8 OCIO_Action; enum { OCIO_INTERP_UNKNOWN = 0, OCIO_INTERP_NEAREST = 1, OCIO_INTERP_LINEAR = 2, OCIO_INTERP_TETRAHEDRAL = 3, OCIO_INTERP_BEST = 255 }; typedef uint8 OCIO_Interp; // this stuff would usually be in a header file typedef struct Globals { short *result; // Must always be first in Globals. FilterRecord *filterParamBlock; // Must always be second in Globals. Boolean do_dialog; OCIO_Source source; Str255 configName; PIPlatformFileHandle configFileHandle; OCIO_Action action; Boolean invert; OCIO_Interp interpolation; Str255 inputSpace; Str255 outputSpace; Str255 device; Str255 transform; } Globals, *GPtr, **GHdl; // some of the lame-ass supporting code needs this extern SPBasicSuite *sSPBasic; extern FilterRecord *gFilterRecord; #define gResult (*(globals->result)) #define gStuff (globals->filterParamBlock) #ifdef PS_CS4_SDK typedef intptr_t entryData; typedef void * allocateGlobalsPointer; #else typedef long entryData; typedef uint32 allocateGlobalsPointer; #endif // our entry function DLLExport SPAPI void PluginMain(const int16 selector, FilterRecord * filterRecord, entryData * data, int16 * result); #endif // _OPENCOLORIO_PS_H_ opencolorio-1.1.0~dfsg0.orig/src/photoshop/OpenColorIO_PS.cpp0000644000175000017500000007255313223553423022352 0ustar mfvmfv/* Copyright (c) 2003-2017 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 "OpenColorIO_PS.h" #include "OpenColorIO_PS_Dialog.h" #include "OpenColorIO_PS_Terminology.h" #include "OpenColorIO_PS_Context.h" #ifdef __PIWin__ //#include #include // DLLInstance for Windows HINSTANCE hDllInstance = NULL; #endif // some of the lame-ass supporting code needs this SPBasicSuite * sSPBasic = NULL; FilterRecord * gFilterRecord = NULL; typedef struct { long sig; OCIO_Source source; Str255 configName; Str255 configPath; OCIO_Action action; Boolean invert; OCIO_Interp interpolation; Str255 inputSpace; Str255 outputSpace; Str255 transform; Str255 device; } Param; #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) #endif /* MIN */ #ifndef MAX #define MAX(a,b) (((a)>(b))?(a):(b)) #endif /* MAX */ static void myC2PString(Str255 &pstr, const char *cstr) { const size_t len = MIN(strlen(cstr), 254); strncpy((char *)&pstr[1], cstr, len); pstr[0] = len; pstr[len + 1] = '\0'; } static const char * myP2CString(Str255 &pstr) { size_t len = pstr[0]; pstr[len + 1] = '\0'; return (const char *)&pstr[1]; } static void myP2PString(Str255 &dest, const Str255 &src) { memcpy(&dest[0], &src[0], 256); } static void ReportException(GPtr globals, const std::exception &e) { Str255 p_str; myC2PString(p_str, e.what()); PIReportError(p_str); gResult = errReportString; } static Boolean ReadScriptParams(GPtr globals) { PIReadDescriptor token = NULL; DescriptorKeyID key = 0; DescriptorTypeID type = 0; DescriptorKeyIDArray array = { NULLID }; int32 flags = 0; OSErr stickyError = noErr; Boolean returnValue = true; if(DescriptorAvailable(NULL)) { token = OpenReader(array); if(token) { while(PIGetKey(token, &key, &type, &flags)) { if(key == ocioKeySource) { DescriptorEnumID ostypeStoreValue; PIGetEnum(token, &ostypeStoreValue); globals->source = (ostypeStoreValue == sourceEnvironment ? OCIO_SOURCE_ENVIRONMENT : ostypeStoreValue == sourceCustom ? OCIO_SOURCE_CUSTOM : OCIO_SOURCE_STANDARD); } else if(key == ocioKeyConfigName) { PIGetStr(token, &globals->configName); } else if(key == ocioKeyConfigFileHandle) { PIGetAlias(token, (Handle *)&globals->configFileHandle); } else if(key == ocioKeyAction) { DescriptorEnumID ostypeStoreValue; PIGetEnum(token, &ostypeStoreValue); globals->action = (ostypeStoreValue == actionLUT ? OCIO_ACTION_LUT : ostypeStoreValue == actionDisplay ? OCIO_ACTION_DISPLAY : OCIO_ACTION_CONVERT); } else if(key == ocioKeyInvert) { PIGetBool(token, &globals->invert); } else if(key == ocioKeyInterpolation) { DescriptorEnumID ostypeStoreValue; PIGetEnum(token, &ostypeStoreValue); globals->action = (ostypeStoreValue == interpNearest ? OCIO_INTERP_NEAREST : ostypeStoreValue == interpLinear ? OCIO_INTERP_LINEAR : ostypeStoreValue == interpTetrahedral ? OCIO_INTERP_TETRAHEDRAL : OCIO_INTERP_BEST); } else if(key == ocioKeyInputSpace) { PIGetStr(token, &globals->inputSpace); } else if(key == ocioKeyOutputSpace) { PIGetStr(token, &globals->outputSpace); } else if(key == ocioKeyDevice) { PIGetStr(token, &globals->device); } else if(key == ocioKeyTransform) { PIGetStr(token, &globals->transform); } } stickyError = CloseReader(&token); // closes & disposes. } returnValue = PlayDialog(); } return returnValue; } static OSErr WriteScriptParams(GPtr globals) { PIWriteDescriptor token = nil; OSErr gotErr = noErr; if(DescriptorAvailable(NULL)) { token = OpenWriter(); if(token) { PIPutEnum(token, ocioKeySource, typeSource, (globals->source == OCIO_SOURCE_ENVIRONMENT ? sourceEnvironment : globals->source == OCIO_SOURCE_CUSTOM ? sourceCustom : sourceStandard)); if(globals->source == OCIO_SOURCE_STANDARD) { PIPutStr(token, ocioKeyConfigName, globals->configName); } else if(globals->source == OCIO_SOURCE_CUSTOM) { PIPutAlias(token, ocioKeyConfigFileHandle, (Handle)globals->configFileHandle); } PIPutEnum(token, ocioKeyAction, typeAction, (globals->action == OCIO_ACTION_LUT ? actionLUT : globals->action == OCIO_ACTION_DISPLAY ? actionDisplay : actionConvert)); if(globals->action == OCIO_ACTION_LUT) { PIPutBool(token, ocioKeyInvert, globals->invert); PIPutEnum(token, ocioKeyInterpolation, typeInterpolation, (globals->interpolation == OCIO_INTERP_NEAREST ? interpNearest : globals->interpolation == OCIO_INTERP_LINEAR ? interpLinear : globals->interpolation == OCIO_INTERP_TETRAHEDRAL ? interpTetrahedral : interpBest)); } else if(globals->action == OCIO_ACTION_DISPLAY) { PIPutStr(token, ocioKeyInputSpace, globals->inputSpace); PIPutStr(token, ocioKeyDevice, globals->device); PIPutStr(token, ocioKeyTransform, globals->transform); } else { assert(globals->action == OCIO_ACTION_CONVERT); PIPutStr(token, ocioKeyInputSpace, globals->inputSpace); PIPutStr(token, ocioKeyOutputSpace, globals->outputSpace); } gotErr = CloseWriter(&token); // closes and sets dialog optional } } return gotErr; } #pragma mark- static void DoAbout(AboutRecordPtr aboutRecord) { #ifdef __PIMac__ const char *plugHndl = "org.OpenColorIO.Photoshop"; const void *hwnd = NULL; #else // get platform handles const void *plugHndl = hDllInstance; HWND hwnd = (HWND)HostGetPlatformWindowPtr(aboutRecord); #endif OpenColorIO_PS_About(plugHndl, hwnd); } void ValidateParameters(GPtr globals) { if(gStuff->parameters == NULL) { gStuff->parameters = PINewHandle(sizeof(Param)); if(gStuff->parameters != NULL) { Param *param = (Param *)PILockHandle(gStuff->parameters, FALSE); if(param) { param->sig = OpenColorIOSignature; param->source = globals->source; myP2PString(param->configName, globals->configName); myC2PString(param->configPath, "dummyPath"); param->action = globals->action; param->invert = globals->invert; param->interpolation = globals->interpolation; myP2PString(param->inputSpace, globals->inputSpace); myP2PString(param->outputSpace, globals->outputSpace); myP2PString(param->device, globals->device); myP2PString(param->transform, globals->transform); PIUnlockHandle(gStuff->parameters); } } else { gResult = memFullErr; return; } } } static void InitGlobals(Ptr globalPtr) { GPtr globals = (GPtr)globalPtr; globals->do_dialog = FALSE; globals->source = OCIO_SOURCE_ENVIRONMENT; myC2PString(globals->configName, ""); globals->configFileHandle = NULL; globals->action = OCIO_ACTION_NONE; globals->invert = FALSE; globals->interpolation = OCIO_INTERP_LINEAR; myC2PString(globals->inputSpace, ""); myC2PString(globals->outputSpace, ""); myC2PString(globals->transform, ""); myC2PString(globals->device, ""); // set default with environment variable if it's set char *file = std::getenv("OCIO"); if(file) { std::string path = file; if( !path.empty() ) { try { OpenColorIO_PS_Context context(path); if( context.isLUT() ) { globals->source = OCIO_SOURCE_ENVIRONMENT; globals->action = OCIO_ACTION_LUT; } else { const std::string &defaultInputName = context.getDefaultColorSpace(); const std::string &defaultOutputName = defaultInputName; const std::string &defaultDevice = context.getDefaultDevice(); const std::string defaultTransform = context.getDefaultTransform(defaultDevice); globals->source = OCIO_SOURCE_ENVIRONMENT; globals->action = OCIO_ACTION_CONVERT; myC2PString(globals->inputSpace, defaultInputName.c_str()); myC2PString(globals->outputSpace, defaultOutputName.c_str()); myC2PString(globals->device, defaultDevice.c_str()); myC2PString(globals->transform, defaultTransform.c_str()); } } catch(const std::exception &e) { ReportException(globals, e); } catch(...) { gResult = formatCannotRead; } } } ValidateParameters(globals); } static void DoParameters(GPtr globals) { Boolean do_dialog = ReadScriptParams(globals); if(do_dialog) { // in the modern era, we always do dialogs in the render function globals->do_dialog = TRUE; } } static void DoPrepare(GPtr globals) { gStuff->bufferSpace = 0; gStuff->maxSpace = 0; } static inline float Clamp(const float &f) { return (f < 0.f ? 0.f : f > 1.f ? 1.f : f); } template static void ConvertRow(T *row, int len, OCIO::ConstProcessorRcPtr processor) { float *floatRow = NULL; if(max == 1) { floatRow = (float *)row; } else { floatRow = (float *)malloc(sizeof(float) * len * 3); if(floatRow == NULL) return; const T *in = row; float *out = floatRow; for(int x=0; x < len; x++) { *out++ = ((float)*in++ / (float)max); *out++ = ((float)*in++ / (float)max); *out++ = ((float)*in++ / (float)max); } } OCIO::PackedImageDesc img(floatRow, len, 1, 3); processor->apply(img); if(max != 1) { const float *in = floatRow; T *out = row; assert(round && clamp); for(int x=0; x < len; x++) { *out++ = (Clamp(*in++) * (float)max) + 0.5f; *out++ = (Clamp(*in++) * (float)max) + 0.5f; *out++ = (Clamp(*in++) * (float)max) + 0.5f; } free(floatRow); } } static void ProcessTile(GPtr globals, void *tileData, VRect &tileRect, int32 rowBytes, OCIO::ConstProcessorRcPtr processor) { const uint32 rectHeight = tileRect.bottom - tileRect.top; const uint32 rectWidth = tileRect.right - tileRect.left; unsigned char *row = (unsigned char *)tileData; for(uint32 pixelY = 0; pixelY < rectHeight; pixelY++) { if(gStuff->depth == 32) ConvertRow((float *)row, rectWidth, processor); else if(gStuff->depth == 16) ConvertRow((uint16 *)row, rectWidth, processor); else if(gStuff->depth == 8) ConvertRow((uint8 *)row, rectWidth, processor); row += rowBytes; } } static void DoStart(GPtr globals) { // legacy paramaters part if(gStuff->parameters) { Param *param = (Param *)PILockHandle(gStuff->parameters, FALSE); if(param && param->sig == OpenColorIOSignature) { // copy params (or not - seems to monkey with my dialog when I edit an action) PIUnlockHandle(gStuff->parameters); } } // modern scripting part Boolean do_dialog = ReadScriptParams(globals); if(do_dialog || globals->do_dialog) { DialogParams dialogParams; dialogParams.source = (globals->source == OCIO_SOURCE_ENVIRONMENT ? SOURCE_ENVIRONMENT : globals->source == OCIO_SOURCE_CUSTOM ? SOURCE_CUSTOM : SOURCE_STANDARD); if(globals->source == OCIO_SOURCE_CUSTOM) { #ifdef __PIMac__ assert(globals->configFileHandle != NULL); FSRef fsref; Boolean wasChanged; if(noErr == FSResolveAlias(NULL, globals->configFileHandle, &fsref, &wasChanged)) { char file_path[256]; file_path[0] = '\0'; FSRefMakePath(&fsref, (UInt8 *)file_path, 255); dialogParams.config = file_path; } else { dialogParams.source = SOURCE_ENVIRONMENT; } #else assert(globals->configFileHandle != NULL); dialogParams.config = PILockHandle(globals->configFileHandle, true); PIUnlockHandle(globals->configFileHandle); #endif } else if(globals->source == OCIO_SOURCE_STANDARD) { dialogParams.config = myP2CString(globals->configName); } dialogParams.action = (globals->action == OCIO_ACTION_LUT ? ACTION_LUT : globals->action == OCIO_ACTION_DISPLAY ? ACTION_DISPLAY : ACTION_CONVERT); dialogParams.invert = globals->invert; dialogParams.interpolation = (globals->interpolation == OCIO_INTERP_NEAREST ? INTERPO_NEAREST : globals->interpolation == OCIO_INTERP_LINEAR ? INTERPO_LINEAR : globals->interpolation == OCIO_INTERP_TETRAHEDRAL ? INTERPO_TETRAHEDRAL : INTERPO_BEST); dialogParams.inputSpace = myP2CString(globals->inputSpace); dialogParams.outputSpace = myP2CString(globals->outputSpace); dialogParams.device = myP2CString(globals->device); dialogParams.transform = myP2CString(globals->transform); #ifdef __PIMac__ const char *plugHndl = "org.OpenColorIO.Photoshop"; const void *hwnd = NULL; #else // get platform handles const void *plugHndl = hDllInstance; HWND hwnd = (HWND)((PlatformData *)gStuff->platformData)->hwnd; #endif const DialogResult dialogResult = OpenColorIO_PS_Dialog(dialogParams, plugHndl, hwnd); if(dialogResult == RESULT_OK || dialogResult == RESULT_EXPORT) { globals->source = (dialogParams.source == SOURCE_ENVIRONMENT ? OCIO_SOURCE_ENVIRONMENT : dialogParams.source == SOURCE_CUSTOM ? OCIO_SOURCE_CUSTOM : OCIO_SOURCE_STANDARD); if(dialogParams.source == SOURCE_CUSTOM) { #ifdef __PIMac__ FSRef temp_fsref; if(noErr == FSPathMakeRef((UInt8 *)dialogParams.config.c_str(), &temp_fsref, NULL) ) { FSNewAlias(NULL, &temp_fsref, &globals->configFileHandle); } else { globals->source = OCIO_SOURCE_NONE; } #else if(globals->configFileHandle) PISetHandleSize(globals->configFileHandle, (dialogParams.config.length() + 1) * sizeof(char)); else globals->configFileHandle = PINewHandle((dialogParams.config.length() + 1) * sizeof(char)); char *path_buf = PILockHandle(globals->configFileHandle, true); strcpy(path_buf, dialogParams.config.c_str()); PIUnlockHandle(globals->configFileHandle); #endif } else if(dialogParams.source == SOURCE_STANDARD) { myC2PString(globals->configName, dialogParams.config.c_str()); } globals->action = (dialogParams.action == ACTION_LUT ? OCIO_ACTION_LUT : dialogParams.action == ACTION_DISPLAY ? OCIO_ACTION_DISPLAY : OCIO_ACTION_CONVERT); globals->invert = dialogParams.invert; globals->interpolation = (dialogParams.interpolation == INTERPO_NEAREST ? OCIO_INTERP_NEAREST : dialogParams.interpolation == INTERPO_LINEAR ? OCIO_INTERP_LINEAR : dialogParams.interpolation == INTERPO_TETRAHEDRAL ? OCIO_INTERP_TETRAHEDRAL : OCIO_INTERP_BEST); myC2PString(globals->inputSpace, dialogParams.inputSpace.c_str()); myC2PString(globals->outputSpace, dialogParams.outputSpace.c_str()); myC2PString(globals->device, dialogParams.device.c_str()); myC2PString(globals->transform, dialogParams.transform.c_str()); } else gResult = userCanceledErr; globals->do_dialog = FALSE; if(gResult == noErr) { // this will copy values to parameters ValidateParameters(globals); } } std::string path; if(gResult == noErr) { if(globals->source == OCIO_SOURCE_ENVIRONMENT) { char *envFile = std::getenv("OCIO"); if(envFile != NULL && strlen(envFile) > 0) { path = envFile; } } else if(globals->source == OCIO_SOURCE_CUSTOM) { #ifdef __PIMac__ assert(globals->configFileHandle != NULL); FSRef fsref; Boolean wasChanged; if(noErr == FSResolveAlias(NULL, globals->configFileHandle, &fsref, &wasChanged)) { char file_path[256]; file_path[0] = '\0'; FSRefMakePath(&fsref, (UInt8 *)file_path, 255); path = file_path; } #else assert(globals->configFileHandle != NULL); path = PILockHandle(globals->configFileHandle, true); PIUnlockHandle(globals->configFileHandle); #endif } else { assert(globals->source == OCIO_SOURCE_STANDARD); #ifdef __PIMac__ const char *standardDirectory = "/Library/Application Support/OpenColorIO"; const std::string pathSeperator = "/"; #else const std::string pathSeperator = "\\"; char appdata_path[MAX_PATH]; HRESULT result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdata_path); const std::string standardDirectory = std::string(appdata_path) + pathSeperator + "OpenColorIO"; #endif path = standardDirectory; path += pathSeperator; path += myP2CString(globals->configName); path += pathSeperator + "config.ocio"; } if( path.empty() ) gResult = filterBadParameters; } if(gResult == noErr) { try { OpenColorIO_PS_Context context(path); OCIO::ConstProcessorRcPtr processor; if( context.isLUT() ) { assert(globals->action == OCIO_ACTION_LUT); const OCIO::Interpolation interpolation = (globals->interpolation == OCIO_INTERP_NEAREST ? OCIO::INTERP_NEAREST : globals->interpolation == OCIO_INTERP_LINEAR ? OCIO::INTERP_LINEAR : globals->interpolation == OCIO_INTERP_TETRAHEDRAL ? OCIO::INTERP_TETRAHEDRAL : OCIO::INTERP_BEST); const OCIO::TransformDirection direction = (globals->invert ? OCIO::TRANSFORM_DIR_INVERSE : OCIO::TRANSFORM_DIR_FORWARD); processor = context.getLUTProcessor(interpolation, direction); } else { if(globals->action == OCIO_ACTION_DISPLAY) { processor = context.getDisplayProcessor(myP2CString(globals->inputSpace), myP2CString(globals->device), myP2CString(globals->transform)); } else { assert(globals->action == OCIO_ACTION_CONVERT); processor = context.getConvertProcessor(myP2CString(globals->inputSpace), myP2CString(globals->outputSpace)); } } // now the Photoshop part int16 tileHeight = gStuff->outTileHeight; int16 tileWidth = gStuff->outTileWidth; if(tileWidth == 0 || tileHeight == 0 || gStuff->advanceState == NULL) { gResult = filterBadParameters; } VRect outRect = GetOutRect(); VRect filterRect = GetFilterRect(); int32 imageVert = filterRect.bottom - filterRect.top; int32 imageHor = filterRect.right - filterRect.left; uint32 tilesVert = (tileHeight - 1 + imageVert) / tileHeight; uint32 tilesHoriz = (tileWidth - 1 + imageHor) / tileWidth; int32 progress_total = tilesVert; int32 progress_complete = 0; gStuff->outLoPlane = 0; gStuff->outHiPlane = 2; for(uint16 vertTile = 0; vertTile < tilesVert && gResult == noErr; vertTile++) { for(uint16 horizTile = 0; horizTile < tilesHoriz && gResult == noErr; horizTile++) { outRect.top = filterRect.top + ( vertTile * tileHeight ); outRect.left = filterRect.left + ( horizTile * tileWidth ); outRect.bottom = outRect.top + tileHeight; outRect.right = outRect.left + tileWidth; if (outRect.bottom > filterRect.bottom) outRect.bottom = filterRect.bottom; if (outRect.right > filterRect.right) outRect.right = filterRect.right; SetOutRect(outRect); gResult = AdvanceState(); if(gResult == kNoErr) { outRect = GetOutRect(); ProcessTile(globals, gStuff->outData, outRect, gStuff->outRowBytes, processor); } } PIUpdateProgress(++progress_complete, progress_total); if( TestAbort() ) { gResult = userCanceledErr; } } } catch(const std::exception &e) { ReportException(globals, e); } catch(...) { gResult = filterBadParameters; } } VRect nullRect = {0,0,0,0}; SetOutRect(nullRect); if(gResult == noErr) WriteScriptParams(globals); } static void DoContinue(GPtr globals) { VRect outRect = { 0, 0, 0, 0}; SetOutRect(outRect); } static void DoFinish(GPtr globals) { } DLLExport SPAPI void PluginMain(const int16 selector, FilterRecord * filterRecord, entryData * data, int16 * result) { if (selector == filterSelectorAbout) { sSPBasic = ((AboutRecordPtr)filterRecord)->sSPBasic; #ifdef __PIWin__ if(hDllInstance == NULL) hDllInstance = GetDLLInstance((SPPluginRef)((AboutRecordPtr)filterRecord)->plugInRef); #endif DoAbout((AboutRecordPtr)filterRecord); } else { gFilterRecord = filterRecord; sSPBasic = filterRecord->sSPBasic; #ifdef __PIWin__ if(hDllInstance == NULL) hDllInstance = GetDLLInstance((SPPluginRef)filterRecord->plugInRef); #endif Ptr globalPtr = NULL; // Pointer for global structure GPtr globals = NULL; // actual globals globalPtr = AllocateGlobals ((allocateGlobalsPointer)result, (allocateGlobalsPointer)filterRecord, filterRecord->handleProcs, sizeof(Globals), data, InitGlobals); if(globalPtr == NULL) { *result = memFullErr; return; } globals = (GPtr)globalPtr; if (gStuff->bigDocumentData != NULL) gStuff->bigDocumentData->PluginUsing32BitCoordinates = true; switch (selector) { case filterSelectorParameters: DoParameters(globals); break; case filterSelectorPrepare: DoPrepare(globals); break; case filterSelectorStart: DoStart(globals); break; case filterSelectorContinue: DoContinue(globals); break; case filterSelectorFinish: DoFinish(globals); break; default: gResult = filterBadParameters; break; } if ((Handle)*data != NULL) PIUnlockHandle((Handle)*data); } } opencolorio-1.1.0~dfsg0.orig/src/photoshop/vc/0000755000175000017500000000000013223553423017510 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/photoshop/vc/vc9/0000755000175000017500000000000013223553423020211 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/photoshop/vc/vc9/OpenColorIO_PS.sln0000644000175000017500000001114313223553423023461 0ustar mfvmfv Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenColorIO_PS", "OpenColorIO_PS.vcproj", "{7C8F25C0-1ADD-4A2B-961E-2FCFDF5E6D2B}" ProjectSection(ProjectDependencies) = postProject {069FB60C-57CE-4D0F-9EC2-068E2A3F2930} = {069FB60C-57CE-4D0F-9EC2-068E2A3F2930} {8B308357-C548-49D9-9134-8A61D57D524C} = {8B308357-C548-49D9-9134-8A61D57D524C} {A19BA95E-D8ED-4958-883B-32561AF905EA} = {A19BA95E-D8ED-4958-883B-32561AF905EA} {F1DAC6DE-348A-4215-87B2-7584578291AC} = {F1DAC6DE-348A-4215-87B2-7584578291AC} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenColorIO", "..\..\..\aftereffects\vc\vc9\OpenColorIO.vcproj", "{8B308357-C548-49D9-9134-8A61D57D524C}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lcms", "..\..\..\aftereffects\vc\vc9\ext\lcms.vcproj", "{069FB60C-57CE-4D0F-9EC2-068E2A3F2930}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxml", "..\..\..\aftereffects\vc\vc9\ext\tinyxml.vcproj", "{A19BA95E-D8ED-4958-883B-32561AF905EA}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml", "..\..\..\aftereffects\vc\vc9\ext\yaml.vcproj", "{F1DAC6DE-348A-4215-87B2-7584578291AC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {7C8F25C0-1ADD-4A2B-961E-2FCFDF5E6D2B}.Debug|Win32.ActiveCfg = Debug|Win32 {7C8F25C0-1ADD-4A2B-961E-2FCFDF5E6D2B}.Debug|Win32.Build.0 = Debug|Win32 {7C8F25C0-1ADD-4A2B-961E-2FCFDF5E6D2B}.Debug|x64.ActiveCfg = Debug|x64 {7C8F25C0-1ADD-4A2B-961E-2FCFDF5E6D2B}.Debug|x64.Build.0 = Debug|x64 {7C8F25C0-1ADD-4A2B-961E-2FCFDF5E6D2B}.Release|Win32.ActiveCfg = Release|Win32 {7C8F25C0-1ADD-4A2B-961E-2FCFDF5E6D2B}.Release|Win32.Build.0 = Release|Win32 {7C8F25C0-1ADD-4A2B-961E-2FCFDF5E6D2B}.Release|x64.ActiveCfg = Release|x64 {7C8F25C0-1ADD-4A2B-961E-2FCFDF5E6D2B}.Release|x64.Build.0 = Release|x64 {8B308357-C548-49D9-9134-8A61D57D524C}.Debug|Win32.ActiveCfg = Debug|Win32 {8B308357-C548-49D9-9134-8A61D57D524C}.Debug|Win32.Build.0 = Debug|Win32 {8B308357-C548-49D9-9134-8A61D57D524C}.Debug|x64.ActiveCfg = Debug|x64 {8B308357-C548-49D9-9134-8A61D57D524C}.Debug|x64.Build.0 = Debug|x64 {8B308357-C548-49D9-9134-8A61D57D524C}.Release|Win32.ActiveCfg = Release|Win32 {8B308357-C548-49D9-9134-8A61D57D524C}.Release|Win32.Build.0 = Release|Win32 {8B308357-C548-49D9-9134-8A61D57D524C}.Release|x64.ActiveCfg = Release|x64 {8B308357-C548-49D9-9134-8A61D57D524C}.Release|x64.Build.0 = Release|x64 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Debug|Win32.ActiveCfg = Debug|Win32 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Debug|Win32.Build.0 = Debug|Win32 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Debug|x64.ActiveCfg = Debug|x64 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Debug|x64.Build.0 = Debug|x64 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Release|Win32.ActiveCfg = Release|Win32 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Release|Win32.Build.0 = Release|Win32 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Release|x64.ActiveCfg = Release|x64 {069FB60C-57CE-4D0F-9EC2-068E2A3F2930}.Release|x64.Build.0 = Release|x64 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Debug|Win32.ActiveCfg = Debug|Win32 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Debug|Win32.Build.0 = Debug|Win32 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Debug|x64.ActiveCfg = Debug|x64 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Debug|x64.Build.0 = Debug|x64 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Release|Win32.ActiveCfg = Release|Win32 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Release|Win32.Build.0 = Release|Win32 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Release|x64.ActiveCfg = Release|x64 {A19BA95E-D8ED-4958-883B-32561AF905EA}.Release|x64.Build.0 = Release|x64 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Debug|Win32.ActiveCfg = Debug|Win32 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Debug|Win32.Build.0 = Debug|Win32 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Debug|x64.ActiveCfg = Debug|x64 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Debug|x64.Build.0 = Debug|x64 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Release|Win32.ActiveCfg = Release|Win32 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Release|Win32.Build.0 = Release|Win32 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Release|x64.ActiveCfg = Release|x64 {F1DAC6DE-348A-4215-87B2-7584578291AC}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal opencolorio-1.1.0~dfsg0.orig/src/photoshop/vc/vc9/OpenColorIO_PS.vcproj0000644000175000017500000010050413223553423024170 0ustar mfvmfv opencolorio-1.1.0~dfsg0.orig/src/photoshop/OpenColorIO_PS_Terminology.h0000644000175000017500000000455513223553423024404 0ustar mfvmfv/* Copyright (c) 2003-2017 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. */ #define OpenColorIOSignature 'ocio' #define ocioKeySource 'oSrc' #define ocioKeyConfigName 'oCfN' #define ocioKeyConfigFileHandle 'oCfH' #define ocioKeyAction 'oAct' #define ocioKeyInvert 'oInv' #define ocioKeyInterpolation 'oInt' #define ocioKeyInputSpace 'oInp' #define ocioKeyOutputSpace 'oOut' #define ocioKeyTransform 'oTrn' #define ocioKeyDevice 'oDev' #define typeSource 'tSrc' #define sourceEnvironment 'sEnv' #define sourceStandard 'sStd' #define sourceCustom 'sCus' #define typeAction 'tAct' #define actionLUT 'aLUT' #define actionConvert 'aCvt' #define actionDisplay 'aDis' #define typeInterpolation 'tInt' #define interpNearest 'tNer' #define interpLinear 'tLin' #define interpTetrahedral 'tTet' #define interpBest 'tBst' opencolorio-1.1.0~dfsg0.orig/src/photoshop/OpenColorIO_PS_Context.cpp0000644000175000017500000002233713223553423024051 0ustar mfvmfv/* Copyright (c) 2003-2017 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 "OpenColorIO_PS_Context.h" int FindSpace(const SpaceVec &spaceVec, const std::string &space) { for(int i=0; i < spaceVec.size(); i++) { const std::string &s = spaceVec[i]; if(s == space) return i; } return -1; } OpenColorIO_PS_Context::OpenColorIO_PS_Context(const std::string &path) : _path(path) { const std::string extension = _path.substr( path.find_last_of('.') + 1 ); if(extension == "ocio") { _config = OCIO::Config::CreateFromFile( _path.c_str() ); _config->sanityCheck(); _isLUT = false; for(int i=0; i < _config->getNumColorSpaces(); ++i) { const std::string colorSpaceName = _config->getColorSpaceNameByIndex(i); OCIO::ConstColorSpaceRcPtr colorSpace = _config->getColorSpace( colorSpaceName.c_str() ); const std::string colorSpaceFamily = colorSpace->getFamily(); const std::string colorSpacePath = (colorSpaceFamily.empty() ? colorSpaceName : (colorSpaceFamily + "/" + colorSpaceName)); _colorSpaces.push_back(colorSpaceName); _colorSpacesFullPaths.push_back(colorSpacePath); } OCIO::ConstColorSpaceRcPtr defaultInput = _config->getColorSpace(OCIO::ROLE_SCENE_LINEAR); _defaultColorSpace = (defaultInput ? defaultInput->getName() : OCIO::ROLE_SCENE_LINEAR); for(int i=0; i < _config->getNumDisplays(); ++i) { const std::string deviceName = _config->getDisplay(i); _devices.push_back(deviceName); } _defaultDevice = _config->getDefaultDisplay(); } else { _config = OCIO::Config::Create(); OCIO::FileTransformRcPtr forwardTransform = OCIO::FileTransform::Create(); forwardTransform->setSrc( _path.c_str() ); forwardTransform->setInterpolation(OCIO::INTERP_LINEAR); forwardTransform->setDirection(OCIO::TRANSFORM_DIR_FORWARD); OCIO::ConstProcessorRcPtr forwardProcessor = _config->getProcessor(forwardTransform); _isLUT = true; _canInvertLUT = true; try { OCIO::FileTransformRcPtr inverseTransform = OCIO::FileTransform::Create(); inverseTransform->setSrc( _path.c_str() ); inverseTransform->setInterpolation(OCIO::INTERP_LINEAR); inverseTransform->setDirection(OCIO::TRANSFORM_DIR_INVERSE); OCIO::ConstProcessorRcPtr inverseProcessor = _config->getProcessor(inverseTransform); } catch(...) { _canInvertLUT = false; } } } OCIO::ConstProcessorRcPtr OpenColorIO_PS_Context::getConvertProcessor(const std::string &inputSpace, const std::string &outputSpace) const { assert( !isLUT() ); OCIO::ColorSpaceTransformRcPtr transform = OCIO::ColorSpaceTransform::Create(); transform->setSrc( inputSpace.c_str() ); transform->setDst( outputSpace.c_str() ); transform->setDirection(OCIO::TRANSFORM_DIR_FORWARD); OCIO::ConstProcessorRcPtr processor = _config->getProcessor(transform); return processor; } OCIO::ConstProcessorRcPtr OpenColorIO_PS_Context::getDisplayProcessor(const std::string &inputSpace, const std::string &device, const std::string &transform) const { assert( !isLUT() ); OCIO::DisplayTransformRcPtr ocio_transform = OCIO::DisplayTransform::Create(); ocio_transform->setInputColorSpaceName( inputSpace.c_str() ); ocio_transform->setDisplay( device.c_str() ); ocio_transform->setView( transform.c_str() ); OCIO::ConstProcessorRcPtr processor = _config->getProcessor(ocio_transform); return processor; } OCIO::ConstProcessorRcPtr OpenColorIO_PS_Context::getLUTProcessor(OCIO::Interpolation interpolation, OCIO::TransformDirection direction) const { assert( isLUT() ); OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create(); transform->setSrc( _path.c_str() ); transform->setInterpolation(interpolation); transform->setDirection(direction); OCIO::ConstProcessorRcPtr processor = _config->getProcessor(transform); return processor; } OCIO::BakerRcPtr OpenColorIO_PS_Context::getConvertBaker(const std::string &inputSpace, const std::string &outputSpace) const { assert( !isLUT() ); OCIO::BakerRcPtr baker = OCIO::Baker::Create(); baker->setConfig(_config); baker->setInputSpace( inputSpace.c_str() ); baker->setTargetSpace( outputSpace.c_str() ); return baker; } OCIO::BakerRcPtr OpenColorIO_PS_Context::getDisplayBaker(const std::string &inputSpace, const std::string &device, const std::string &transform) const { assert( !isLUT() ); OCIO::ConfigRcPtr editableConfig = _config->createEditableCopy(); OCIO::ColorSpaceRcPtr inputColorSpace = OCIO::ColorSpace::Create(); const std::string input_space = "RawInput"; inputColorSpace->setName( input_space.c_str() ); editableConfig->addColorSpace(inputColorSpace); OCIO::ColorSpaceRcPtr outputColorSpace = OCIO::ColorSpace::Create(); const std::string output_space = "ProcessedOutput"; outputColorSpace->setName( output_space.c_str() ); OCIO::DisplayTransformRcPtr transformPtr = OCIO::DisplayTransform::Create(); transformPtr->setInputColorSpaceName( inputSpace.c_str() ); transformPtr->setDisplay( device.c_str() ); transformPtr->setView( transform.c_str() ); outputColorSpace->setTransform(transformPtr, OCIO::COLORSPACE_DIR_FROM_REFERENCE); editableConfig->addColorSpace(outputColorSpace); OCIO::BakerRcPtr baker = OCIO::Baker::Create(); baker->setConfig(editableConfig); baker->setInputSpace( input_space.c_str() ); baker->setTargetSpace( output_space.c_str() ); return baker; } OCIO::BakerRcPtr OpenColorIO_PS_Context::getLUTBaker(OCIO::Interpolation interpolation, OCIO::TransformDirection direction) const { assert( isLUT() ); OCIO::ConfigRcPtr editableConfig = OCIO::Config::Create(); OCIO::ColorSpaceRcPtr inputColorSpace = OCIO::ColorSpace::Create(); std::string inputspace = "RawInput"; inputColorSpace->setName(inputspace.c_str()); editableConfig->addColorSpace(inputColorSpace); OCIO::ColorSpaceRcPtr outputColorSpace = OCIO::ColorSpace::Create(); std::string outputspace = "ProcessedOutput"; outputColorSpace->setName(outputspace.c_str()); OCIO::FileTransformRcPtr transform = OCIO::FileTransform::Create(); transform = OCIO::FileTransform::Create(); transform->setSrc(_path.c_str()); transform->setInterpolation(interpolation); transform->setDirection(direction); outputColorSpace->setTransform(transform, OCIO::COLORSPACE_DIR_FROM_REFERENCE); editableConfig->addColorSpace(outputColorSpace); OCIO::BakerRcPtr baker = OCIO::Baker::Create(); baker->setConfig(editableConfig); baker->setInputSpace(inputspace.c_str()); baker->setTargetSpace(outputspace.c_str()); return baker; } SpaceVec OpenColorIO_PS_Context::getTransforms(const std::string &device) const { SpaceVec transforms; for(int i=0; i < _config->getNumViews( device.c_str() ); ++i) { const std::string transformName = _config->getView(device.c_str(), i); transforms.push_back(transformName); } return transforms; } std::string OpenColorIO_PS_Context::getDefaultTransform(const std::string &device) const { return _config->getDefaultView( device.c_str() ); } opencolorio-1.1.0~dfsg0.orig/src/photoshop/mac/0000755000175000017500000000000013223553423017640 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/photoshop/mac/OpenColorIO_PS_Dialog.xib0000644000175000017500000025321113223553423024361 0ustar mfvmfv 1050 10K549 851 1038.36 461.00 com.apple.InterfaceBuilder.CocoaPlugin 851 YES YES com.apple.InterfaceBuilder.CocoaPlugin YES YES YES YES OpenColorIO_PS_Dialog_Controller FirstResponder NSApplication 1 2 {{196, 240}, {500, 270}} 544735232 OpenColorIO NSWindow {3.40282e+38, 3.40282e+38} 256 YES 268 {{206, 226}, {171, 26}} YES -2076049856 2048 LucidaGrande 13 1044 109199615 129 400 75 Item 1 1048576 2147483647 1 NSImage NSMenuCheckmark NSImage NSMenuMixedState _popUpItemAction: YES OtherViews YES Item 2 1048576 2147483647 _popUpItemAction: Item 3 1048576 2147483647 _popUpItemAction: 1 YES YES 2 268 {{109, 232}, {95, 17}} YES 68288064 71304192 Configuration: 6 System controlColor 3 MC42NjY2NjY2ODY1AA 6 System controlTextColor 3 MAA 268 {{134, 192}, {216, 18}} YES 1 2 YES -2080244224 0 Convert 1 1211912703 0 NSRadioButton 200 25 67239424 0 Display 1211912703 0 400 75 {106, 18} {4, 2} 1151868928 NSActionCell 67239424 0 Radio 1211912703 0 549453824 {18, 18} YES YES TU0AKgAABRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAADwRERGLJycnySsrK/A1NTXw IyMjyRwcHIsJCQk8AAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFRUVdVBQUOCoqKj/ 29vb//n5+f/6+vr/2tra/6qqqv9UVFTgHx8fdQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZGRl5 dXV198PDw//8/Pz////////////////////////////U1NT/fHx89yUlJXkAAAAFAAAAAAAAAAAAAAAA AAAAAxEREUZqamrmtbW1/+3t7f/+/v7//v7+//7+/v/9/f3//f39//39/f/39/f/xMTE/3d3d+YZGRlG AAAAAwAAAAAAAAAAAAAACkJCQqGtra3/xsbG/+vr6//y8vL/9fX1//X19f/z8/P/9fX1//Ly8v/u7u7/ 0tLS/6+vr/9KSkqhAAAACgAAAAAAAAAAAAAAF3h4eN2/v7//z8/P/93d3f/q6ur/7+/v/+/v7//w8PD/ 7e3t/+3t7f/i4uL/zs7O/8XFxf98fHzdAAAAFwAAAAAAAAADAAAAJKSkpPjOzs7/2dnZ/+Dg4P/i4uL/ 5eXl/+bm5v/n5+f/5eXl/+Li4v/e3t7/2tra/9DQ0P+srKz4AAAAJAAAAAMAAAADAAAALrCwsPrW1tb/ 3t7e/+Tk5P/p6en/6+vr/+zs7P/p6en/6+vr/+fn5//k5OT/4ODg/9nZ2f+zs7P6AAAALgAAAAMAAAAD AAAALp2dnezg4OD/5eXl/+rq6v/u7u7/8PDw//Dw8P/x8fH/8PDw/+7u7v/q6ur/5ubm/+Hh4f+ZmZns AAAALgAAAAMAAAADAAAAJG5ubs/l5eX/6enp/+/v7//y8vL/9vb2//r6+v/5+fn/9/f3//b29v/x8fH/ 6+vr/+Tk5P9ra2vPAAAAJAAAAAMAAAAAAAAAFy4uLpPCwsL67Ozs//Pz8//5+fn//v7+//7+/v/+/v7/ /v7+//v7+//19fX/8PDw/8LCwvosLCyTAAAAFwAAAAAAAAAAAAAACgAAAENfX1/S5OTk/vn5+f/+/v7/ ///////////////////////////8/Pz/5ubm/l9fX9IAAABDAAAACgAAAAAAAAAAAAAAAwAAABcAAABl YmJi3NLS0v3////////////////////////////////V1dX9ZGRk3AAAAGUAAAAXAAAAAwAAAAAAAAAA AAAAAAAAAAUAAAAfAAAAZTMzM8KAgIDwv7+//O3t7f/t7e3/v7+//ICAgPAzMzPCAAAAZQAAAB8AAAAF AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAFwAAAEMAAAB3AAAAnwAAALMAAACzAAAAnwAAAHcAAABD AAAAFwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAoAAAAXAAAAJAAAAC4AAAAu AAAAJAAAABcAAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQEAAAMAAAABABIAAAEB AAMAAAABABIAAAECAAMAAAAEAAAFugEDAAMAAAABAAEAAAEGAAMAAAABAAIAAAERAAQAAAABAAAACAES AAMAAAABAAEAAAEVAAMAAAABAAQAAAEWAAMAAAABABIAAAEXAAQAAAABAAAFEAEcAAMAAAABAAEAAAFS AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 3 MCAwAA 400 75 3 MQA 268 {{206, 146}, {171, 26}} YES -2076049856 2048 109199615 129 400 75 Item 1 1048576 2147483647 1 _popUpItemAction: YES OtherViews YES Item 2 1048576 2147483647 _popUpItemAction: Item 3 1048576 2147483647 _popUpItemAction: 1 YES YES 2 268 {{109, 152}, {95, 17}} YES 68288064 71304192 Input Space: 268 {{383, 12}, {103, 32}} YES 67239424 134217728 OK -2038284033 129 DQ 200 25 268 {{280, 12}, {103, 32}} YES 67239424 134217728 Cancel -2038284033 129 Gw 200 25 268 {{14, 12}, {111, 32}} YES 67239424 134217728 Export… -2038284033 129 Gw 200 25 268 {{205, 106}, {171, 26}} YES -2076049856 2048 109199615 129 400 75 Item 1 1048576 2147483647 1 _popUpItemAction: YES OtherViews YES Item 2 1048576 2147483647 _popUpItemAction: Item 3 1048576 2147483647 _popUpItemAction: 1 YES YES 2 268 {{108, 112}, {95, 17}} YES 68288064 71304192 Output Space: 268 {{205, 66}, {171, 26}} YES -2076049856 2048 109199615 129 400 75 Item 1 1048576 2147483647 1 _popUpItemAction: YES OtherViews YES Item 2 1048576 2147483647 _popUpItemAction: Item 3 1048576 2147483647 _popUpItemAction: 1 YES YES 2 268 {{108, 72}, {95, 17}} YES 68288064 71304192 Transform: 268 {{408, 151}, {74, 18}} YES -2080244224 0 Invert 1211912703 2 NSImage NSSwitch NSSwitch 200 25 268 {{377, 146}, {29, 26}} YES -2080244224 134217728 -2032910081 166 400 75 268 {{377, 106}, {29, 26}} YES -2080244224 134217728 -2032910081 166 400 75 {500, 270} {{0, 0}, {1680, 1028}} {3.40282e+38, 3.40282e+38} YES actionRadios 99 configurationMenu 100 invertCheck 104 window 108 clickedOK: 109 clickedExport: 110 clickedCancel: 111 trackConfigMenu: 112 menu1 150 menu2 151 menu3 152 label1 153 label2 154 label3 155 trackActionRadios: 156 trackMenu1: 157 trackMenu2: 158 trackMenu3: 159 inputSpaceButton 166 outputSpaceButton 167 popInputSpaceMenu: 168 popOutputSpaceMenu: 169 trackInvert: 170 YES 0 -2 File's Owner -1 First Responder -3 Application 1 YES 2 YES 3 YES 4 YES 5 YES 6 7 8 9 YES 10 11 YES 12 14 15 25 YES 26 YES 27 28 YES 29 YES 30 31 32 76 YES 77 95 YES 96 97 YES 98 134 YES 135 YES 136 137 YES 138 YES 139 140 141 142 YES 143 YES 144 145 YES 146 YES 147 148 149 41 YES 42 160 YES 161 164 YES 165 YES YES 1.IBEditorWindowLastContentRect 1.IBPluginDependency 1.IBWindowTemplateEditedContentRect 1.NSWindowTemplate.visibleAtLaunch 1.WindowOrigin 1.editorWindowContentRectSynchronizationRect 10.IBPluginDependency 11.IBPluginDependency 11.IBViewBoundsToFrameTransform 12.IBPluginDependency 134.IBPluginDependency 134.IBViewBoundsToFrameTransform 135.IBPluginDependency 135.IBViewBoundsToFrameTransform 136.IBPluginDependency 137.IBPluginDependency 138.IBEditorWindowLastContentRect 138.IBPluginDependency 139.IBPluginDependency 14.IBPluginDependency 140.IBPluginDependency 141.IBPluginDependency 142.IBPluginDependency 142.IBViewBoundsToFrameTransform 143.IBPluginDependency 143.IBViewBoundsToFrameTransform 144.IBPluginDependency 145.IBPluginDependency 146.IBEditorWindowLastContentRect 146.IBPluginDependency 147.IBPluginDependency 148.IBPluginDependency 149.IBPluginDependency 160.IBPluginDependency 160.IBViewBoundsToFrameTransform 161.IBPluginDependency 164.IBPluginDependency 164.IBViewBoundsToFrameTransform 165.IBPluginDependency 2.IBPluginDependency 25.IBPluginDependency 25.IBViewBoundsToFrameTransform 26.IBPluginDependency 26.IBViewBoundsToFrameTransform 27.IBPluginDependency 28.IBPluginDependency 29.IBEditorWindowLastContentRect 29.IBPluginDependency 3.IBPluginDependency 3.IBViewBoundsToFrameTransform 30.IBPluginDependency 31.IBPluginDependency 32.IBPluginDependency 4.IBPluginDependency 41.IBPluginDependency 41.IBViewBoundsToFrameTransform 42.IBPluginDependency 5.IBEditorWindowLastContentRect 5.IBPluginDependency 6.IBPluginDependency 7.IBPluginDependency 76.IBPluginDependency 76.IBViewBoundsToFrameTransform 77.IBPluginDependency 8.IBPluginDependency 9.IBPluginDependency 9.IBViewBoundsToFrameTransform 95.IBPluginDependency 95.IBViewBoundsToFrameTransform 96.IBPluginDependency 97.IBPluginDependency 97.IBViewBoundsToFrameTransform 98.IBPluginDependency YES {{463, 726}, {500, 270}} com.apple.InterfaceBuilder.CocoaPlugin {{463, 726}, {500, 270}} {196, 240} {{202, 428}, {480, 270}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDBgAAw0IAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDTQAAw8EAAA com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABC2AAAw7+AAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin {{804, 573}, {110, 63}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDTQAAw7QAAA com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABC2AAAw7KAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin {{804, 573}, {110, 63}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDvIAAwyoAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDvQAAwwIAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDTgAAw9UAAA com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABC2gAAw9OAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin {{804, 573}, {110, 63}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDTgAAw3oAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDzIAAwycAAA com.apple.InterfaceBuilder.CocoaPlugin {{658, 915}, {171, 63}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDv4AAwigAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABC2gAAw3cAAA com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABDjAAAwigAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin P4AAAL+AAABBYAAAwigAAA com.apple.InterfaceBuilder.CocoaPlugin YES YES YES YES 183 YES OpenColorIO_PS_Dialog_Controller NSObject YES YES clickedCancel: clickedExport: clickedOK: popInputSpaceMenu: popOutputSpaceMenu: trackActionRadios: trackConfigMenu: trackInvert: trackMenu1: trackMenu2: trackMenu3: YES id id id id id id id id id id id YES YES clickedCancel: clickedExport: clickedOK: popInputSpaceMenu: popOutputSpaceMenu: trackActionRadios: trackConfigMenu: trackInvert: trackMenu1: trackMenu2: trackMenu3: YES clickedCancel: id clickedExport: id clickedOK: id popInputSpaceMenu: id popOutputSpaceMenu: id trackActionRadios: id trackConfigMenu: id trackInvert: id trackMenu1: id trackMenu2: id trackMenu3: id YES YES actionRadios configurationMenu inputSpaceButton invertCheck label1 label2 label3 menu1 menu2 menu3 outputSpaceButton window YES NSMatrix NSPopUpButton NSButton NSButton NSTextField NSTextField NSTextField NSPopUpButton NSPopUpButton NSPopUpButton NSButton NSWindow YES YES actionRadios configurationMenu inputSpaceButton invertCheck label1 label2 label3 menu1 menu2 menu3 outputSpaceButton window YES actionRadios NSMatrix configurationMenu NSPopUpButton inputSpaceButton NSButton invertCheck NSButton label1 NSTextField label2 NSTextField label3 NSTextField menu1 NSPopUpButton menu2 NSPopUpButton menu3 NSPopUpButton outputSpaceButton NSButton window NSWindow IBProjectSource ../mac/OpenColorIO_PS_Dialog_Controller.h YES NSActionCell NSCell IBFrameworkSource AppKit.framework/Headers/NSActionCell.h NSApplication NSResponder IBFrameworkSource AppKit.framework/Headers/NSApplication.h NSApplication IBFrameworkSource AppKit.framework/Headers/NSApplicationScripting.h NSApplication IBFrameworkSource AppKit.framework/Headers/NSColorPanel.h NSApplication IBFrameworkSource AppKit.framework/Headers/NSHelpManager.h NSApplication IBFrameworkSource AppKit.framework/Headers/NSPageLayout.h NSApplication IBFrameworkSource AppKit.framework/Headers/NSUserInterfaceItemSearching.h NSButton NSControl IBFrameworkSource AppKit.framework/Headers/NSButton.h NSButtonCell NSActionCell IBFrameworkSource AppKit.framework/Headers/NSButtonCell.h NSCell NSObject IBFrameworkSource AppKit.framework/Headers/NSCell.h NSControl NSView IBFrameworkSource AppKit.framework/Headers/NSControl.h NSMatrix NSControl IBFrameworkSource AppKit.framework/Headers/NSMatrix.h NSMenu NSObject IBFrameworkSource AppKit.framework/Headers/NSMenu.h NSMenuItem NSObject IBFrameworkSource AppKit.framework/Headers/NSMenuItem.h NSMenuItemCell NSButtonCell IBFrameworkSource AppKit.framework/Headers/NSMenuItemCell.h NSObject IBFrameworkSource AppKit.framework/Headers/NSAccessibility.h NSObject NSObject NSObject NSObject NSObject IBFrameworkSource AppKit.framework/Headers/NSDictionaryController.h NSObject IBFrameworkSource AppKit.framework/Headers/NSDragging.h NSObject IBFrameworkSource AppKit.framework/Headers/NSFontManager.h NSObject IBFrameworkSource AppKit.framework/Headers/NSFontPanel.h NSObject IBFrameworkSource AppKit.framework/Headers/NSKeyValueBinding.h NSObject NSObject IBFrameworkSource AppKit.framework/Headers/NSNibLoading.h NSObject IBFrameworkSource AppKit.framework/Headers/NSOutlineView.h NSObject IBFrameworkSource AppKit.framework/Headers/NSPasteboard.h NSObject IBFrameworkSource AppKit.framework/Headers/NSSavePanel.h NSObject IBFrameworkSource AppKit.framework/Headers/NSTableView.h NSObject IBFrameworkSource AppKit.framework/Headers/NSToolbarItem.h NSObject IBFrameworkSource AppKit.framework/Headers/NSView.h NSPopUpButton NSButton IBFrameworkSource AppKit.framework/Headers/NSPopUpButton.h NSPopUpButtonCell NSMenuItemCell IBFrameworkSource AppKit.framework/Headers/NSPopUpButtonCell.h NSResponder IBFrameworkSource AppKit.framework/Headers/NSInterfaceStyle.h NSResponder NSObject IBFrameworkSource AppKit.framework/Headers/NSResponder.h NSTextField NSControl IBFrameworkSource AppKit.framework/Headers/NSTextField.h NSTextFieldCell NSActionCell IBFrameworkSource AppKit.framework/Headers/NSTextFieldCell.h NSView IBFrameworkSource AppKit.framework/Headers/NSClipView.h NSView NSView IBFrameworkSource AppKit.framework/Headers/NSRulerView.h NSView NSResponder NSWindow IBFrameworkSource AppKit.framework/Headers/NSDrawer.h NSWindow NSResponder IBFrameworkSource AppKit.framework/Headers/NSWindow.h NSWindow IBFrameworkSource AppKit.framework/Headers/NSWindowScripting.h 0 IBCocoaFramework com.apple.InterfaceBuilder.CocoaPlugin.macosx com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 YES ../xcode/OpenColorIO_PS.xcodeproj 3 YES YES NSMenuCheckmark NSMenuMixedState NSSwitch YES {9, 8} {7, 2} {15, 15} opencolorio-1.1.0~dfsg0.orig/src/photoshop/mac/OpenColorIO_PS_Info.plist0000755000175000017500000000120013223553423024416 0ustar mfvmfv CFBundleExecutable $(PRODUCT_NAME) CFBundleName $(PRODUCT_NAME) CFBundleIdentifier org.OpenColorIO.Photoshop CFBundleSignature 8BIM CFBundlePackageType $(PLUGIN_TYPE) CFBundleGetInfoString ©2017 OpenColorIO CFBundleDevelopmentRegion English opencolorio-1.1.0~dfsg0.orig/src/photoshop/mac/OpenColorIO_PS_Dialog_Cocoa.mm0000644000175000017500000001771313223553423025321 0ustar mfvmfv/* Copyright (c) 2003-2017 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 "OpenColorIO_PS_Dialog.h" #import "OpenColorIO_PS_Dialog_Controller.h" #include namespace OCIO = OCIO_NAMESPACE; #include "OpenColorIO_PS_Version.h" // ========== // Only building this on 64-bit (Cocoa) architectures // ========== #if __LP64__ || defined(COCOA_ON_32BIT) DialogResult OpenColorIO_PS_Dialog(DialogParams ¶ms, const void *plugHndl, const void *mwnd) { DialogResult result = RESULT_OK; NSApplicationLoad(); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *bundle_id = [NSString stringWithUTF8String:(const char *)plugHndl]; Class ui_controller_class = [[NSBundle bundleWithIdentifier:bundle_id] classNamed:@"OpenColorIO_PS_Dialog_Controller"]; if(ui_controller_class) { ControllerSource source = (params.source == SOURCE_ENVIRONMENT ? CSOURCE_ENVIRONMENT : params.source == SOURCE_CUSTOM ? CSOURCE_CUSTOM: CSOURCE_STANDARD); ControllerAction action = (params.action == ACTION_LUT ? CACTION_LUT : params.action == ACTION_DISPLAY ? CACTION_DISPLAY : CACTION_CONVERT); ControllerInterp interpolation = (params.interpolation == INTERPO_NEAREST ? CINTERP_NEAREST : params.interpolation == INTERPO_LINEAR ? CINTERP_LINEAR : params.interpolation == INTERPO_TETRAHEDRAL ? CINTERP_TETRAHEDRAL : CINTERP_BEST); NSString *configuration = (params.config.empty() ? nil : [NSString stringWithUTF8String:params.config.c_str()]); const BOOL invert = params.invert; NSString *inputSpace = (params.inputSpace.empty() ? nil : [NSString stringWithUTF8String:params.inputSpace.c_str()]); NSString *outputSpace = (params.outputSpace.empty() ? nil : [NSString stringWithUTF8String:params.outputSpace.c_str()]); NSString *transform = (params.transform.empty() ? nil : [NSString stringWithUTF8String:params.transform.c_str()]); NSString *device = (params.device.empty() ? nil : [NSString stringWithUTF8String:params.device.c_str()]); OpenColorIO_PS_Dialog_Controller *controller = [[ui_controller_class alloc] initWithSource:source configuration:configuration action:action invert:invert interpolation:interpolation inputSpace:inputSpace outputSpace:outputSpace device:device transform:transform]; if(controller) { NSWindow *window = [controller window]; const NSUInteger modalResult = [NSApp runModalForWindow:window]; if(modalResult == NSRunStoppedResponse) { source = [controller source]; action = [controller action]; interpolation = [controller interpolation]; params.source = (source == CSOURCE_ENVIRONMENT ? SOURCE_ENVIRONMENT : source == CSOURCE_CUSTOM ? SOURCE_CUSTOM : SOURCE_STANDARD); params.action = (action == CACTION_LUT ? ACTION_LUT : action == CACTION_DISPLAY ? ACTION_DISPLAY : ACTION_CONVERT); params.interpolation = (interpolation == CINTERP_NEAREST ? INTERPO_NEAREST : interpolation == CINTERP_LINEAR ? INTERPO_LINEAR : interpolation == CINTERP_TETRAHEDRAL ? INTERPO_TETRAHEDRAL : INTERPO_BEST); if([controller configuration] != nil) params.config = [[controller configuration] UTF8String]; params.invert = [controller invert]; if([controller inputSpace] != nil) params.inputSpace = [[controller inputSpace] UTF8String]; if([controller outputSpace] != nil) params.outputSpace = [[controller outputSpace] UTF8String]; if([controller transform] != nil) params.transform = [[controller transform] UTF8String]; if([controller device] != nil) params.device = [[controller device] UTF8String]; result = RESULT_OK; } else result = RESULT_CANCEL; [window close]; [controller release]; } } [pool release]; return result; } void OpenColorIO_PS_About(const void *plugHndl, const void *mwnd) { NSApplicationLoad(); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; const std::string endl = "\n"; std::string text = std::string("OpenColorIO PS") + endl + OpenColorIO_PS_Beta_String + endl + __DATE__ + endl + endl + "OCIO version " + OCIO::GetVersion(); NSString *informativeText = [NSString stringWithUTF8String:text.c_str()]; NSAlert *alert = [NSAlert alertWithMessageText:@"OpenColorIO" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", informativeText]; [alert setAlertStyle:NSInformationalAlertStyle]; [alert runModal]; [pool release]; } #endif // __LP64__ opencolorio-1.1.0~dfsg0.orig/src/photoshop/mac/OpenColorIO_PS_Dialog_Controller.h0000644000175000017500000000733513223553423026235 0ustar mfvmfv/* Copyright (c) 2003-2017 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. */ #import typedef enum ControllerSource { CSOURCE_ENVIRONMENT, CSOURCE_STANDARD, CSOURCE_CUSTOM }; typedef enum ControllerAction { CACTION_LUT, CACTION_CONVERT, CACTION_DISPLAY }; typedef enum ControllerInterp { CINTERP_NEAREST, CINTERP_LINEAR, CINTERP_TETRAHEDRAL, CINTERP_BEST }; @class OpenColorIO_AE_MonitorProfileChooser_Controller; @interface OpenColorIO_PS_Dialog_Controller : NSObject { IBOutlet NSPopUpButton *configurationMenu; IBOutlet NSMatrix *actionRadios; IBOutlet NSTextField *label1; IBOutlet NSTextField *label2; IBOutlet NSTextField *label3; IBOutlet NSPopUpButton *menu1; IBOutlet NSPopUpButton *menu2; IBOutlet NSPopUpButton *menu3; IBOutlet NSButton *invertCheck; IBOutlet NSButton *inputSpaceButton; IBOutlet NSButton *outputSpaceButton; IBOutlet NSWindow *window; void *contextPtr; ControllerSource source; NSString *configuration; NSString *customPath; ControllerAction action; NSString *inputSpace; NSString *outputSpace; NSString *device; NSString *transform; ControllerInterp interpolation; BOOL invert; } - (id)initWithSource:(ControllerSource)source configuration:(NSString *)configuration action:(ControllerAction)action invert:(BOOL)invert interpolation:(ControllerInterp)interpolation inputSpace:(NSString *)inputSpace outputSpace:(NSString *)outputSpace device:(NSString *)device transform:(NSString *)transform; - (IBAction)clickedOK:(id)sender; - (IBAction)clickedCancel:(id)sender; - (IBAction)clickedExport:(id)sender; - (IBAction)trackConfigMenu:(id)sender; - (IBAction)trackActionRadios:(id)sender; - (IBAction)trackMenu1:(id)sender; - (IBAction)trackMenu2:(id)sender; - (IBAction)trackMenu3:(id)sender; - (IBAction)trackInvert:(id)sender; - (IBAction)popInputSpaceMenu:(id)sender; - (IBAction)popOutputSpaceMenu:(id)sender; - (NSWindow *)window; - (ControllerSource)source; - (NSString *)configuration; - (ControllerAction)action; - (BOOL)invert; - (ControllerInterp)interpolation; - (NSString *)inputSpace; - (NSString *)outputSpace; - (NSString *)device; - (NSString *)transform; @end opencolorio-1.1.0~dfsg0.orig/src/photoshop/mac/OpenColorIO_PS_Dialog_Controller.mm0000644000175000017500000011027113223553423026411 0ustar mfvmfv/* Copyright (c) 2003-2017 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. */ #import "OpenColorIO_PS_Dialog_Controller.h" #import "OpenColorIO_AE_MonitorProfileChooser_Controller.h" #include #include #include #include "OpenColorIO_PS_Context.h" #include "OpenColorIO_AE_Dialogs.h" #include "ocioicc.h" static NSString *standardPath = @"/Library/Application Support/OpenColorIO"; @implementation OpenColorIO_PS_Dialog_Controller - (NSString *)pathForStandardConfig:(NSString *)config { return [[standardPath stringByAppendingPathComponent:config] stringByAppendingPathComponent:@"config.ocio"]; } - (id)initWithSource:(ControllerSource)initSource configuration:(NSString *)initConfiguration action:(ControllerAction)initAction invert:(BOOL)initInvert interpolation:(ControllerInterp)initInterpolation inputSpace:(NSString *)initInputSpace outputSpace:(NSString *)initOutputSpace device:(NSString *)initDevice transform:(NSString *)initTransform { self = [super init]; if(self) { if(!([NSBundle loadNibNamed:@"OpenColorIO_PS_Dialog" owner:self])) return nil; source = initSource; if(source == CSOURCE_CUSTOM) { customPath = [initConfiguration retain]; } else if(source == CSOURCE_STANDARD) { configuration = [initConfiguration retain]; } action = initAction; inputSpace = [initInputSpace retain]; outputSpace = [initOutputSpace retain]; device = [initDevice retain]; transform = [initTransform retain]; interpolation = initInterpolation; invert = initInvert; // configuration menu [configurationMenu removeAllItems]; [configurationMenu setAutoenablesItems:NO]; [configurationMenu addItemWithTitle:@"$OCIO"]; [[configurationMenu lastItem] setTag:CSOURCE_ENVIRONMENT]; char *envFile = std::getenv("OCIO"); if(envFile == NULL || strlen(envFile) == 0) [[configurationMenu lastItem] setEnabled:FALSE]; [[configurationMenu menu] addItem:[NSMenuItem separatorItem]]; NSArray *standardConfigs = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:standardPath error:NULL]; if([standardConfigs count] > 0) { for(NSString *configName in standardConfigs) { NSAssert([configName isKindOfClass:[NSString class]], @"expected NSString"); NSString *configFilePath = [self pathForStandardConfig:configName]; if([[NSFileManager defaultManager] isReadableFileAtPath:configFilePath]) { [configurationMenu addItemWithTitle:configName]; [[configurationMenu lastItem] setTag:CSOURCE_STANDARD]; } } } else { NSString *noConfigsMessage = [NSString stringWithFormat:@"No configs in %@", standardPath]; [configurationMenu addItemWithTitle:noConfigsMessage]; [[configurationMenu lastItem] setTag:CSOURCE_STANDARD]; [[configurationMenu lastItem] setEnabled:FALSE]; } [[configurationMenu menu] addItem:[NSMenuItem separatorItem]]; [configurationMenu addItemWithTitle:@"Custom…"]; [[configurationMenu lastItem] setTag:CSOURCE_CUSTOM]; [invertCheck setHidden:YES]; [menu1 removeAllItems]; [menu2 removeAllItems]; [menu3 removeAllItems]; [label3 setHidden:YES]; [menu3 setHidden:YES]; [self trackConfigMenu:nil]; } return self; } - (void)dealloc { OpenColorIO_PS_Context *context = (OpenColorIO_PS_Context *)contextPtr; delete context; [configuration release]; [customPath release]; [inputSpace release]; [outputSpace release]; [device release]; [transform release]; [super dealloc]; } - (IBAction)clickedOK:(id)sender { [NSApp stopModal]; } - (IBAction)clickedCancel:(id)sender { [NSApp abortModal]; } /* - (void)profileChooserDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { NSAssert(profileController != nil, @"profileController is nil"); [sheet orderOut:self]; if(returnCode == NSRunStoppedResponse) { NSString *path = (NSString *)contextInfo; NSAssert([path isKindOfClass:[NSString class]], @"expected NSString"); try { OpenColorIO_PS_Context *context = (OpenColorIO_PS_Context *)contextPtr; NSAssert(context != NULL, @"context was NULL"); char display_icc_path[256]; const BOOL gotICC = [profileController getMonitorProfile:display_icc_path bufferSize:255]; if(!gotICC) throw OCIO::Exception("Failed to get ICC profile"); OCIO::ConstProcessorRcPtr processor; if(action == CACTION_CONVERT) { processor = context->getConvertProcessor([inputSpace UTF8String], [outputSpace UTF8String]); } else if(action == CACTION_DISPLAY) { processor = context->getDisplayProcessor([inputSpace UTF8String], [device UTF8String], [transform UTF8String]); } else { NSAssert(action == CACTION_LUT, @"expected CACTION_LUT"); const OCIO::Interpolation interp = (interpolation == CINTERP_NEAREST ? OCIO::INTERP_NEAREST : interpolation == CINTERP_LINEAR ? OCIO::INTERP_LINEAR : interpolation == CINTERP_TETRAHEDRAL ? OCIO::INTERP_TETRAHEDRAL : OCIO::INTERP_BEST); const OCIO::TransformDirection direction = (invert ? OCIO::TRANSFORM_DIR_INVERSE : OCIO::TRANSFORM_DIR_FORWARD); processor = context->getLUTProcessor(interp, direction); } int cubesize = 32; int whitepointtemp = 6505; std::string copyright = "OpenColorIO, Sony Imageworks"; // create a description tag from the filename std::string description = [[[path lastPathComponent] stringByDeletingPathExtension] UTF8String]; SaveICCProfileToFile([path UTF8String], processor, cubesize, whitepointtemp, display_icc_path, description, copyright, false); } catch(const std::exception &e) { NSBeep(); NSString *ocioString = [NSString stringWithUTF8String:e.what()]; NSAlert *alert = [NSAlert alertWithMessageText:@"OpenColorIO error" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", ocioString]; [alert beginSheetModalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; } catch(...) { NSBeep(); NSString *ocioString = @"Some unknown error"; NSAlert *alert = [NSAlert alertWithMessageText:@"OpenColorIO error" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", ocioString]; [alert beginSheetModalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; } [path release]; } [profileController release]; profileController = nil; } */ - (void)exportPanelDidEnd:(NSSavePanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo { if(returnCode == NSOKButton) { OpenColorIO_PS_Context *context = (OpenColorIO_PS_Context *)contextPtr; NSAssert(context != NULL, @"context was NULL"); NSString *path = [[panel URL] path]; NSString *extension = [path pathExtension]; if([extension isEqualToString:@"icc"]) { OpenColorIO_AE_MonitorProfileChooser_Controller *profileController = [[OpenColorIO_AE_MonitorProfileChooser_Controller alloc] init]; // the sheet is still active, so can't run another one...will settle for modal const NSInteger modal_result = [NSApp runModalForWindow:[profileController getWindow]]; if(modal_result == NSRunStoppedResponse) { try { char display_icc_path[256]; const BOOL gotICC = [profileController getMonitorProfile:display_icc_path bufferSize:255]; if(!gotICC) throw OCIO::Exception("Failed to get ICC profile"); OCIO::ConstProcessorRcPtr processor; if(action == CACTION_CONVERT) { processor = context->getConvertProcessor([inputSpace UTF8String], [outputSpace UTF8String]); } else if(action == CACTION_DISPLAY) { processor = context->getDisplayProcessor([inputSpace UTF8String], [device UTF8String], [transform UTF8String]); } else { NSAssert(action == CACTION_LUT, @"expected CACTION_LUT"); const OCIO::Interpolation interp = (interpolation == CINTERP_NEAREST ? OCIO::INTERP_NEAREST : interpolation == CINTERP_LINEAR ? OCIO::INTERP_LINEAR : interpolation == CINTERP_TETRAHEDRAL ? OCIO::INTERP_TETRAHEDRAL : OCIO::INTERP_BEST); const OCIO::TransformDirection direction = (invert ? OCIO::TRANSFORM_DIR_INVERSE : OCIO::TRANSFORM_DIR_FORWARD); processor = context->getLUTProcessor(interp, direction); } int cubesize = 32; int whitepointtemp = 6505; std::string copyright = "OpenColorIO, Sony Imageworks"; // create a description tag from the filename std::string description = [[[path lastPathComponent] stringByDeletingPathExtension] UTF8String]; SaveICCProfileToFile([path UTF8String], processor, cubesize, whitepointtemp, display_icc_path, description, copyright, false); } catch(const std::exception &e) { NSBeep(); NSString *ocioString = [NSString stringWithUTF8String:e.what()]; NSAlert *alert = [NSAlert alertWithMessageText:@"OpenColorIO error" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", ocioString]; [alert beginSheetModalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; } catch(...) { NSBeep(); NSString *ocioString = @"Some unknown error"; NSAlert *alert = [NSAlert alertWithMessageText:@"OpenColorIO error" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", ocioString]; [alert beginSheetModalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; } } [[profileController getWindow] close]; [profileController release]; } else { try { // need an extension->format map std::map extensions; for(int i=0; i < OCIO::Baker::getNumFormats(); ++i) { const char *extension = OCIO::Baker::getFormatExtensionByIndex(i); const char *format = OCIO::Baker::getFormatNameByIndex(i); extensions[ extension ] = format; } const std::string the_extension = [extension UTF8String]; std::string format = extensions[ the_extension ]; OCIO::BakerRcPtr baker; if(action == CACTION_CONVERT) { baker = context->getConvertBaker([inputSpace UTF8String], [outputSpace UTF8String]); } else if(action == CACTION_DISPLAY) { baker = context->getDisplayBaker([inputSpace UTF8String], [device UTF8String], [transform UTF8String]); } else { NSAssert(action == CACTION_LUT, @"expected CACTION_LUT"); const OCIO::Interpolation interp = (interpolation == CINTERP_NEAREST ? OCIO::INTERP_NEAREST : interpolation == CINTERP_LINEAR ? OCIO::INTERP_LINEAR : interpolation == CINTERP_TETRAHEDRAL ? OCIO::INTERP_TETRAHEDRAL : OCIO::INTERP_BEST); const OCIO::TransformDirection direction = (invert ? OCIO::TRANSFORM_DIR_INVERSE : OCIO::TRANSFORM_DIR_FORWARD); baker = context->getLUTBaker(interp, direction); } baker->setFormat( format.c_str() ); std::ofstream f([path UTF8String]); baker->bake(f); } catch(const std::exception &e) { NSBeep(); NSString *ocioString = [NSString stringWithUTF8String:e.what()]; NSAlert *alert = [NSAlert alertWithMessageText:@"OpenColorIO error" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", ocioString]; [alert beginSheetModalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; } catch(...) { NSBeep(); NSString *ocioString = @"Some unknown error"; NSAlert *alert = [NSAlert alertWithMessageText:@"OpenColorIO error" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", ocioString]; [alert beginSheetModalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; } } } } - (IBAction)clickedExport:(id)sender { NSSavePanel *panel = [NSSavePanel savePanel]; NSMutableString *message = [NSMutableString stringWithString:@"Formats: ICC Profile (.icc)"]; NSMutableArray *extensionArray = [NSMutableArray arrayWithObject:@"icc"]; for(int i=0; i < OCIO::Baker::getNumFormats(); ++i) { const char *extension = OCIO::Baker::getFormatExtensionByIndex(i); const char *format = OCIO::Baker::getFormatNameByIndex(i); [extensionArray addObject:[NSString stringWithUTF8String:extension]]; [message appendFormat:@", %s (.%s)", format, extension]; } [panel setAllowedFileTypes:extensionArray]; [panel setMessage:message]; [panel beginSheetForDirectory:nil file:nil modalForWindow:window modalDelegate:self didEndSelector:@selector(exportPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL]; } - (void)openPanelDidEnd:(NSOpenPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo { if(returnCode == NSOKButton) { source = CSOURCE_CUSTOM; NSURL *url = [panel URL]; [customPath release]; customPath = [[url path] retain]; } [self trackConfigMenu:nil]; } - (IBAction)trackConfigMenu:(id)sender { const ControllerSource previousSource = source; if(sender == nil) { // set menu from values if(source == CSOURCE_STANDARD) { [configurationMenu selectItemWithTitle:configuration]; } else { [configurationMenu selectItemWithTag:source]; } } else { // set value from menu source = (ControllerSource)[[configurationMenu selectedItem] tag]; } NSString *configPath = nil; if(source == CSOURCE_ENVIRONMENT) { char *envFile = std::getenv("OCIO"); if(envFile != NULL && strlen(envFile) > 0) { configPath = [NSString stringWithUTF8String:envFile]; } } else if(source == CSOURCE_CUSTOM) { if(sender != nil) { source = previousSource; // we'll re-set to the previous source in case dialog is canceled // do file open dialog NSOpenPanel *panel = [NSOpenPanel openPanel]; [panel setCanChooseDirectories:NO]; [panel setAllowsMultipleSelection:NO]; NSMutableArray *extensions = [NSMutableArray arrayWithObject:@"ocio"]; for(int i=0; i < OCIO::FileTransform::getNumFormats(); ++i) { const char *extension = OCIO::FileTransform::getFormatExtensionByIndex(i); //const char *format = OCIO::FileTransform::getFormatNameByIndex(i); NSString *extensionString = [NSString stringWithUTF8String:extension]; if(![extensionString isEqualToString:@"ccc"]) // .ccc files require an ID parameter [extensions addObject:[NSString stringWithUTF8String:extension]]; } NSMutableString *message = [NSMutableString stringWithString:@"Formats: "]; for(int i=0; i < [extensions count]; i++) { NSString *extension = [extensions objectAtIndex:i]; if(i != 0) [message appendString:@", "]; [message appendString:@"."]; [message appendString:extension]; } [panel setMessage:message]; [panel setAllowedFileTypes:extensions]; [panel beginSheetForDirectory:nil file:nil modalForWindow:window modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL]; return; } else { configPath = customPath; } } else { NSAssert(source == CSOURCE_STANDARD, @"expected TAG_STANDARD"); [configuration release]; configuration = [[configurationMenu titleOfSelectedItem] retain]; configPath = [self pathForStandardConfig:configuration]; } if(configPath != nil && [[NSFileManager defaultManager] isReadableFileAtPath:configPath]) { try { OpenColorIO_PS_Context *oldContext = (OpenColorIO_PS_Context *)contextPtr; delete oldContext; OpenColorIO_PS_Context *context = new OpenColorIO_PS_Context([configPath UTF8String]); contextPtr = context; if( context->isLUT() ) { action = CACTION_LUT; [invertCheck setHidden:NO]; if( context->canInvertLUT() ) { [invertCheck setEnabled:YES]; } else { [invertCheck setEnabled:NO]; invert = NO; } [invertCheck setState:(invert ? NSOnState : NSOffState)]; [actionRadios setHidden:YES]; NSTextField *interpolationLabel = label1; NSPopUpButton *interpolationMenu = menu1; [interpolationLabel setStringValue:@"Interpolation"]; // interpolation menu [interpolationMenu removeAllItems]; [interpolationMenu addItemWithTitle:@"Nearest Neighbor"]; [[interpolationMenu lastItem] setTag:CINTERP_NEAREST]; [interpolationMenu addItemWithTitle:@"Linear"]; [[interpolationMenu lastItem] setTag:CINTERP_LINEAR]; [interpolationMenu addItemWithTitle:@"Tetrahedral"]; [[interpolationMenu lastItem] setTag:CINTERP_TETRAHEDRAL]; const bool canTetrahedral = !context->canInvertLUT(); if(!canTetrahedral) { [interpolationMenu setAutoenablesItems:NO]; [[interpolationMenu lastItem] setEnabled:NO]; if(interpolation == CINTERP_TETRAHEDRAL) interpolation = CINTERP_LINEAR; } [[interpolationMenu menu] addItem:[NSMenuItem separatorItem]]; [interpolationMenu addItemWithTitle:@"Best"]; [[interpolationMenu lastItem] setTag:CINTERP_BEST]; [interpolationMenu selectItemWithTag:interpolation]; [inputSpaceButton setHidden:YES]; [label2 setHidden:YES]; [menu2 setHidden:YES]; [outputSpaceButton setHidden:YES]; [label3 setHidden:YES]; [menu3 setHidden:YES]; } else { [invertCheck setHidden:YES]; if(action == CACTION_LUT) { action = CACTION_CONVERT; } [actionRadios setHidden:NO]; const SpaceVec &colorSpaces = context->getColorSpaces(); if(inputSpace == nil || -1 == FindSpace(colorSpaces, [inputSpace UTF8String])) { [inputSpace release]; inputSpace = [[NSString alloc] initWithUTF8String:context->getDefaultColorSpace().c_str()]; } if(outputSpace == nil || -1 == FindSpace(colorSpaces, [outputSpace UTF8String])) { [outputSpace release]; outputSpace = [[NSString alloc] initWithUTF8String:context->getDefaultColorSpace().c_str()]; } const SpaceVec &devices = context->getDevices(); if(device == nil || -1 == FindSpace(devices, [device UTF8String])) { [device release]; device = [[NSString alloc] initWithUTF8String:context->getDefaultDevice().c_str()]; } const SpaceVec transforms = context->getTransforms([device UTF8String]); if(transform == nil || -1 == FindSpace(transforms, [transform UTF8String])) { [transform release]; transform = [[NSString alloc] initWithUTF8String:context->getDefaultTransform([device UTF8String]).c_str()]; } [self trackActionRadios:nil]; } } catch(const std::exception &e) { NSBeep(); NSString *ocioString = [NSString stringWithUTF8String:e.what()]; NSAlert *alert = [NSAlert alertWithMessageText:@"OpenColorIO error" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", ocioString]; [alert beginSheetModalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; if(source != CSOURCE_ENVIRONMENT) { source = CSOURCE_ENVIRONMENT; [self trackConfigMenu:nil]; } } catch(...) { NSBeep(); NSString *ocioString = @"Some unknown error"; NSAlert *alert = [NSAlert alertWithMessageText:@"OpenColorIO error" defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", ocioString]; [alert beginSheetModalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL]; if(source != CSOURCE_ENVIRONMENT) { source = CSOURCE_ENVIRONMENT; [self trackConfigMenu:nil]; } } } [configurationMenu setToolTip:configPath]; } - (IBAction)trackActionRadios:(id)sender; { if(sender == nil) { // set radios from values NSAssert(action != CACTION_LUT, @"should not be a LUT"); const NSUInteger selectedColumn = (action == CACTION_DISPLAY ? 1 : 0); [actionRadios selectCellAtRow:0 column:selectedColumn]; } else { // set values from radios action = ([actionRadios selectedColumn] == 1 ? CACTION_DISPLAY : CACTION_CONVERT); } OpenColorIO_PS_Context *context = (OpenColorIO_PS_Context *)contextPtr; NSAssert(context != NULL, @"context was NULL"); NSTextField *inputLabel = label1; NSPopUpButton *inputMenu = menu1; [inputLabel setStringValue:@"Input Space:"]; [inputMenu removeAllItems]; const SpaceVec &colorSpaces = context->getColorSpaces(); for(SpaceVec::const_iterator i = colorSpaces.begin(); i != colorSpaces.end(); ++i) { NSString *colorSpace = [NSString stringWithUTF8String:i->c_str()]; [inputMenu addItemWithTitle:colorSpace]; } NSAssert([inputMenu itemWithTitle:inputSpace] != nil, @"don't have the input space"); [inputMenu selectItemWithTitle:inputSpace]; [inputSpaceButton setHidden:NO]; if(action == CACTION_DISPLAY) { NSTextField *deviceLabel = label2; NSPopUpButton *deviceMenu = menu2; NSTextField *transformLabel = label3; NSPopUpButton *transformMenu = menu3; [deviceLabel setStringValue:@"Device:"]; [deviceLabel setHidden:NO]; [deviceMenu setHidden:NO]; [deviceMenu removeAllItems]; const SpaceVec &devices = context->getDevices(); for(SpaceVec::const_iterator i = devices.begin(); i != devices.end(); ++i) { NSString *deviceName = [NSString stringWithUTF8String:i->c_str()]; [deviceMenu addItemWithTitle:deviceName]; } [outputSpaceButton setHidden:YES]; [transformLabel setStringValue:@"Transform:"]; [transformLabel setHidden:NO]; [transformMenu setHidden:NO]; [self trackMenu2:nil]; } else { NSAssert(action == CACTION_CONVERT, @"expected Convert"); NSTextField *outputLabel = label2; NSPopUpButton *outputMenu = menu2; [outputLabel setHidden:NO]; [outputLabel setStringValue:@"Output Space:"]; [outputMenu setHidden:NO]; [outputMenu removeAllItems]; for(SpaceVec::const_iterator i = colorSpaces.begin(); i != colorSpaces.end(); ++i) { NSString *colorSpace = [NSString stringWithUTF8String:i->c_str()]; [outputMenu addItemWithTitle:colorSpace]; } NSAssert([outputMenu itemWithTitle:outputSpace] != nil, @"don't have the input space"); [outputMenu selectItemWithTitle:outputSpace]; [outputSpaceButton setHidden:NO]; NSTextField *transformLabel = label3; NSPopUpButton *transformMenu = menu3; [transformLabel setHidden:YES]; [transformMenu setHidden:YES]; NSAssert([[transformLabel stringValue] isEqualToString:@"Transform:"], @"expected Transform:"); } } - (IBAction)trackMenu1:(id)sender { NSAssert(sender == menu1, @"always from the UI"); if(action == CACTION_LUT) { interpolation = (ControllerInterp)[[menu1 selectedItem] tag]; } else { [inputSpace release]; inputSpace = [[menu1 titleOfSelectedItem] retain]; } } - (IBAction)trackMenu2:(id)sender { if(action == CACTION_DISPLAY) { NSPopUpButton *deviceMenu = menu2; if(sender == nil) { // set menu from values NSAssert([deviceMenu itemWithTitle:device] != nil, @"don't have the device"); [deviceMenu selectItemWithTitle:device]; } else { // set values from menu [device release]; device = [[deviceMenu titleOfSelectedItem] retain]; } } else { NSAssert(action == CACTION_CONVERT, @"expected Convert"); NSPopUpButton *outputMenu = menu2; if(sender == nil) { // set menu from values NSAssert([outputMenu itemWithTitle:outputSpace] != nil, @"don't have the device"); [outputMenu selectItemWithTitle:outputSpace]; } else { // set values from menu [outputSpace release]; outputSpace = [[outputMenu titleOfSelectedItem] retain]; } } if(action == CACTION_DISPLAY) { OpenColorIO_PS_Context *context = (OpenColorIO_PS_Context *)contextPtr; NSAssert(context != NULL, @"context was NULL"); const SpaceVec transforms = context->getTransforms([device UTF8String]); NSPopUpButton *transformMenu = menu3; [transformMenu removeAllItems]; for(SpaceVec::const_iterator i = transforms.begin(); i != transforms.end(); ++i) { NSString *transformName = [NSString stringWithUTF8String:i->c_str()]; [transformMenu addItemWithTitle:transformName]; } [self trackMenu3:nil]; } } - (IBAction)trackMenu3:(id)sender { NSAssert(action == CACTION_DISPLAY, @"expected Display"); NSAssert([[label3 stringValue] isEqualToString:@"Transform:"], @"expected Transform:"); NSPopUpButton *transformMenu = menu3; if(sender == nil) { // set menu from value NSMenuItem *valueItem = [transformMenu itemWithTitle:transform]; if(valueItem != nil) { [transformMenu selectItem:valueItem]; } else { OpenColorIO_PS_Context *context = (OpenColorIO_PS_Context *)contextPtr; NSAssert(context != NULL, @"context was NULL"); const std::string defaultTransform = context->getDefaultTransform([device UTF8String]); NSMenuItem *defaultItem = [transformMenu itemWithTitle:[NSString stringWithUTF8String:defaultTransform.c_str()]]; NSAssert(defaultItem != nil, @"where's that default item?"); [transformMenu selectItem:defaultItem]; [transform release]; transform = [[transformMenu titleOfSelectedItem] retain]; } } else { // set value from menu [transform release]; transform = [[transformMenu titleOfSelectedItem] retain]; } } - (IBAction)trackInvert:(id)sender { NSAssert(sender == invertCheck, @"expected invertCheck"); invert = ([invertCheck state] == NSOnState); } - (IBAction)popInputSpaceMenu:(id)sender { OpenColorIO_PS_Context *context = (OpenColorIO_PS_Context *)contextPtr; if(context != NULL) { std::string colorSpace = [inputSpace UTF8String]; const bool chosen = ColorSpacePopUpMenu(context->getConfig(), colorSpace, false, NULL); if(chosen) { [inputSpace release]; inputSpace = [[NSString alloc] initWithUTF8String:colorSpace.c_str()]; [menu1 selectItemWithTitle:inputSpace]; } } } - (IBAction)popOutputSpaceMenu:(id)sender { OpenColorIO_PS_Context *context = (OpenColorIO_PS_Context *)contextPtr; if(context != NULL) { std::string colorSpace = [outputSpace UTF8String]; const bool chosen = ColorSpacePopUpMenu(context->getConfig(), colorSpace, false, NULL); if(chosen) { [outputSpace release]; outputSpace = [[NSString alloc] initWithUTF8String:colorSpace.c_str()]; [menu2 selectItemWithTitle:outputSpace]; } } } - (NSWindow *)window { return window; } - (ControllerSource)source { return source; } - (NSString *)configuration { if(source == CSOURCE_CUSTOM) { return customPath; } else { return configuration; } } - (ControllerAction)action { return action; } - (BOOL)invert { return invert; } - (ControllerInterp)interpolation { return interpolation; } - (NSString *)inputSpace { return inputSpace; } - (NSString *)outputSpace { return outputSpace; } - (NSString *)device { return device; } - (NSString *)transform { return transform; } @end opencolorio-1.1.0~dfsg0.orig/src/photoshop/OpenColorIO_PS_Context.h0000644000175000017500000000730413223553423023513 0ustar mfvmfv/* Copyright (c) 2003-2017 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 _OPENCOLORIO_PS_CONTEXT_H_ #define _OPENCOLORIO_PS_CONTEXT_H_ #include #include #include namespace OCIO = OCIO_NAMESPACE; typedef std::vector SpaceVec; int FindSpace(const SpaceVec &spaceVec, const std::string &space); // returns -1 if not found class OpenColorIO_PS_Context { public: OpenColorIO_PS_Context(const std::string &path); ~OpenColorIO_PS_Context() {} //const std::string getPath() const { return _path; } bool isLUT() const { return _isLUT; } bool canInvertLUT() const { return (isLUT() && _canInvertLUT); } OCIO::ConstConfigRcPtr getConfig() const { return _config; } OCIO::ConstProcessorRcPtr getConvertProcessor(const std::string &inputSpace, const std::string &outputSpace) const; OCIO::ConstProcessorRcPtr getDisplayProcessor(const std::string &inputSpace, const std::string &device, const std::string &transform) const; OCIO::ConstProcessorRcPtr getLUTProcessor(OCIO::Interpolation interpolation, OCIO::TransformDirection direction) const; OCIO::BakerRcPtr getConvertBaker(const std::string &inputSpace, const std::string &outputSpace) const; OCIO::BakerRcPtr getDisplayBaker(const std::string &inputSpace, const std::string &device, const std::string &transform) const; OCIO::BakerRcPtr getLUTBaker(OCIO::Interpolation interpolation, OCIO::TransformDirection direction) const; const SpaceVec & getColorSpaces(bool fullPath=false) const { return (fullPath ? _colorSpacesFullPaths : _colorSpaces); } const std::string & getDefaultColorSpace() const { return _defaultColorSpace; } const SpaceVec & getDevices() const { return _devices; }; const std::string & getDefaultDevice() const { return _defaultDevice; } SpaceVec getTransforms(const std::string &device) const; std::string getDefaultTransform(const std::string &device) const; private: std::string _path; OCIO::ConstConfigRcPtr _config; SpaceVec _colorSpaces; SpaceVec _colorSpacesFullPaths; std::string _defaultColorSpace; SpaceVec _devices; std::string _defaultDevice; bool _isLUT; bool _canInvertLUT; }; #endif // _OPENCOLORIO_PS_CONTEXT_H_opencolorio-1.1.0~dfsg0.orig/src/apps/0000755000175000017500000000000013223553423016020 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/apps/ociocheck/0000755000175000017500000000000013223553423017747 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/apps/ociocheck/CMakeLists.txt0000644000175000017500000000100513223553423022503 0ustar mfvmfvfile(GLOB_RECURSE share_src_files "${CMAKE_SOURCE_DIR}/src/apps/share/*.cpp") include_directories( ${CMAKE_SOURCE_DIR}/export/ ${CMAKE_BINARY_DIR}/export/ ${CMAKE_SOURCE_DIR}/src/apps/share/ ${Boost_INCLUDE_DIR} ) add_executable(ociocheck main.cpp ${share_src_files}) set_target_properties(ociocheck PROPERTIES COMPILE_FLAGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}) target_link_OCIO(ociocheck) install(TARGETS ociocheck EXPORT OpenColorIO DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/bin) opencolorio-1.1.0~dfsg0.orig/src/apps/ociocheck/main.cpp0000644000175000017500000002502413223553423021402 0ustar mfvmfv/* 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 #include #include #include #include #include namespace OCIO = OCIO_NAMESPACE; #include "argparse.h" const char * DESC_STRING = "\n\n" "ociocheck is useful to validate that the specified .ocio configuration\n" "is valid, and that all the color transforms are defined.\n" "For example, it is possible that the configuration may reference\n" "lookup tables that do not exist. ociocheck will find these cases.\n\n" "ociocheck can also be used to clean up formatting on an existing profile\n" "that has been manually edited, using the '-o' option.\n"; int main(int argc, const char **argv) { bool help = false; int errorcount = 0; std::string inputconfig; std::string outputconfig; ArgParse ap; ap.options("ociocheck -- validate an OpenColorIO configuration\n\n" "usage: ociocheck [options]\n", "--help", &help, "Print help message", "--iconfig %s", &inputconfig, "Input .ocio configuration file (default: $OCIO)", "--oconfig %s", &outputconfig, "Output .ocio file", NULL); if (ap.parse(argc, argv) < 0) { std::cout << ap.geterror() << std::endl; ap.usage(); std::cout << DESC_STRING; return 1; } if (help) { ap.usage(); std::cout << DESC_STRING; return 1; } try { OCIO::ConstConfigRcPtr config; std::cout << std::endl; std::cout << "OpenColorIO Library Version: " << OCIO::GetVersion() << std::endl; std::cout << "OpenColorIO Library VersionHex: " << OCIO::GetVersionHex() << std::endl; if(!inputconfig.empty()) { std::cout << "Loading " << inputconfig << std::endl; config = OCIO::Config::CreateFromFile(inputconfig.c_str()); } else if(getenv("OCIO")) { std::cout << "Loading $OCIO " << getenv("OCIO") << std::endl; config = OCIO::Config::CreateFromEnv(); } else { std::cout << "ERROR: You must specify an input ocio configuration "; std::cout << "(either with --iconfig or $OCIO).\n"; ap.usage (); std::cout << DESC_STRING; return 1; } std::cout << std::endl; std::cout << "** General **" << std::endl; std::cout << "Search Path: " << config->getSearchPath() << std::endl; std::cout << "Working Dir: " << config->getWorkingDir() << std::endl; std::cout << std::endl; std::cout << "Default Display: " << config->getDefaultDisplay() << std::endl; std::cout << "Default View: " << config->getDefaultView(config->getDefaultDisplay()) << std::endl; { std::cout << std::endl; std::cout << "** Roles **" << std::endl; std::set usedroles; const char * allroles[] = { OCIO::ROLE_DEFAULT, OCIO::ROLE_SCENE_LINEAR, OCIO::ROLE_DATA, OCIO::ROLE_REFERENCE, OCIO::ROLE_COMPOSITING_LOG, OCIO::ROLE_COLOR_TIMING, OCIO::ROLE_COLOR_PICKING, OCIO::ROLE_TEXTURE_PAINT, OCIO::ROLE_MATTE_PAINT, NULL }; int MAXROLES=256; for(int i=0;igetColorSpace(role); if(cs) { std::cout << cs->getName() << " (" << role << ")" << std::endl; } else { std::cout << "ERROR: NOT DEFINED" << " (" << role << ")" << std::endl; errorcount += 1; } } for(int i=0; igetNumRoles(); ++i) { const char * role = config->getRoleName(i); if(usedroles.find(role) != usedroles.end()) continue; OCIO::ConstColorSpaceRcPtr cs = config->getColorSpace(role); if(cs) { std::cout << cs->getName() << " (" << role << ": user)" << std::endl; } else { std::cout << "ERROR: NOT DEFINED" << " (" << role << ")" << std::endl; errorcount += 1; } } } std::cout << std::endl; std::cout << "** ColorSpaces **" << std::endl; OCIO::ConstColorSpaceRcPtr lin = config->getColorSpace(OCIO::ROLE_SCENE_LINEAR); if(!lin) { std::cout << "Error: scene_linear role must be defined." << std::endl; errorcount += 1; } else { for(int i=0; igetNumColorSpaces(); ++i) { OCIO::ConstColorSpaceRcPtr cs = config->getColorSpace(config->getColorSpaceNameByIndex(i)); bool convertsToLinear = true; std::string convertsToLinearErrorText; bool convertsFromLinear = true; std::string convertsFromLinearErrorText; try { OCIO::ConstProcessorRcPtr p = config->getProcessor(cs, lin); } catch(OCIO::Exception & exception) { convertsToLinear = false; convertsToLinearErrorText = exception.what(); } try { OCIO::ConstProcessorRcPtr p = config->getProcessor(lin, cs); } catch(OCIO::Exception & exception) { convertsFromLinear = false; convertsFromLinearErrorText = exception.what(); } if(convertsToLinear && convertsFromLinear) { std::cout << cs->getName() << std::endl; } else if(!convertsToLinear && !convertsFromLinear) { std::cout << cs->getName(); std::cout << " -- error" << std::endl; std::cout << "\t" << convertsToLinearErrorText << std::endl; std::cout << "\t" << convertsFromLinearErrorText << std::endl; errorcount += 1; } else if(convertsToLinear) { std::cout << cs->getName(); std::cout << " -- input only" << std::endl; } else if(convertsFromLinear) { std::cout << cs->getName(); std::cout << " -- output only" << std::endl; } } } std::cout << std::endl; std::cout << "** Looks **" << std::endl; if(config->getNumLooks()>0) { for(int i=0; igetNumLooks(); ++i) { std::cout << config->getLookNameByIndex(i) << std::endl; } } else { std::cout << "no looks defined" << std::endl; } std::cout << std::endl; std::cout << "** Sanity Check **" << std::endl; try { config->sanityCheck(); std::cout << "passed" << std::endl; } catch(OCIO::Exception & exception) { std::cout << "ERROR" << std::endl; errorcount += 1; std::cout << exception.what() << std::endl; } if(!outputconfig.empty()) { std::ofstream output; output.open(outputconfig.c_str()); if(!output.is_open()) { std::cout << "Error opening " << outputconfig << " for writing." << std::endl; } else { config->serialize(output); output.close(); std::cout << "Wrote " << outputconfig << std::endl; } } } catch(OCIO::Exception & exception) { std::cout << "ERROR: " << exception.what() << std::endl; return 1; } catch (std::exception& exception) { std::cout << "ERROR: " << exception.what() << "\n"; return 1; } catch(...) { std::cout << "Unknown error encountered." << std::endl; return 1; } std::cout << std::endl; if(errorcount == 0) { std::cout << "Tests complete." << std::endl << std::endl; return 0; } else { std::cout << errorcount << " tests failed." << std::endl << std::endl; return 1; } } opencolorio-1.1.0~dfsg0.orig/src/apps/ociodisplay/0000755000175000017500000000000013223553423020337 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/apps/ociodisplay/CMakeLists.txt0000644000175000017500000000133413223553423023100 0ustar mfvmfvif (OIIO_FOUND) include_directories( ${CMAKE_SOURCE_DIR}/export/ ${CMAKE_BINARY_DIR}/export/ ${OPENGL_INCLUDE_DIR} ${OIIO_INCLUDES} ${ILMBASE_INCLUDES} ${GLEW_INCLUDES} ${GLUT_INCLUDE_DIR} ) add_executable(ociodisplay main.cpp) # set_target_properties(ociodisplay PROPERTIES INSTALL_RPATH ${OIIO_LIBRARIES} ) set_target_properties(ociodisplay PROPERTIES COMPILE_FLAGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}) target_link_libraries(ociodisplay ${GLEW_LIBRARIES} ${GLUT_LIBRARY} ${OPENGL_LIBRARY} ${OIIO_LIBRARIES}) target_link_OCIO(ociodisplay) install(TARGETS ociodisplay EXPORT OpenColorIO DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/bin) endif() opencolorio-1.1.0~dfsg0.orig/src/apps/ociodisplay/main.cpp0000644000175000017500000005777613223553423022015 0ustar mfvmfv/* 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 #include #include #include #include #include #include #include #include namespace OCIO = OCIO_NAMESPACE; #include #include #if (OIIO_VERSION < 10100) namespace OIIO = OIIO_NAMESPACE; #endif #ifdef __APPLE__ #include #include #include #elif _WIN32 #include #include #else #include #include #include #include #endif bool g_verbose = false; std::string g_filename; GLint g_win = 0; int g_winWidth = 0; int g_winHeight = 0; GLuint g_fragShader = 0; GLuint g_program = 0; GLuint g_imageTexID; float g_imageAspect; GLuint g_lut3dTexID; const int LUT3D_EDGE_SIZE = 32; std::vector g_lut3d; std::string g_lut3dcacheid; std::string g_shadercacheid; std::string g_inputColorSpace; std::string g_display; std::string g_transformName; std::string g_look; float g_exposure_fstop = 0.0f; float g_display_gamma = 1.0f; int g_channelHot[4] = { 1, 1, 1, 1 }; // show rgb void UpdateOCIOGLState(); static void InitImageTexture(const char * filename) { glGenTextures(1, &g_imageTexID); std::vector img; int texWidth = 512; int texHeight = 512; int components = 4; if(filename && *filename) { std::cout << "loading: " << filename << std::endl; try { OIIO::ImageInput* f = OIIO::ImageInput::create(filename); if(!f) { std::cerr << "Could not create image input." << std::endl; exit(1); } OIIO::ImageSpec spec; f->open(filename, spec); std::string error = f->geterror(); if(!error.empty()) { std::cerr << "Error loading image " << error << std::endl; exit(1); } texWidth = spec.width; texHeight = spec.height; components = spec.nchannels; img.resize(texWidth*texHeight*components); memset(&img[0], 0, texWidth*texHeight*components*sizeof(float)); f->read_image( #if (OIIO_VERSION >= 10800) OIIO::TypeFloat, #else OIIO::TypeDesc::TypeFloat, #endif &img[0]); OIIO::ImageInput::destroy(f); } catch(...) { std::cerr << "Error loading file."; exit(1); } } // If no file is provided, use a default gradient texture else { std::cout << "No image specified, loading gradient." << std::endl; img.resize(texWidth*texHeight*components); memset(&img[0], 0, texWidth*texHeight*components*sizeof(float)); for(int y=0; ygetDefaultDisplay(); g_transformName = config->getDefaultView(g_display.c_str()); g_look = config->getDisplayLooks(g_display.c_str(), g_transformName.c_str()); g_inputColorSpace = OCIO::ROLE_SCENE_LINEAR; if(filename && *filename) { std::string cs = config->parseColorSpaceFromString(filename); if(!cs.empty()) { g_inputColorSpace = cs; std::cout << "colorspace: " << cs << std::endl; } else { std::cout << "colorspace: " << g_inputColorSpace << " \t(could not determine from filename, using default)" << std::endl; } } } static void AllocateLut3D() { glGenTextures(1, &g_lut3dTexID); int num3Dentries = 3*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE; g_lut3d.resize(num3Dentries); memset(&g_lut3d[0], 0, sizeof(float)*num3Dentries); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_3D, g_lut3dTexID); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, 0, GL_RGB,GL_FLOAT, &g_lut3d[0]); } /* static void Idle(void) { // + Do Work glutPostRedisplay(); } */ void Redisplay(void) { float windowAspect = 1.0; if(g_winHeight != 0) { windowAspect = (float)g_winWidth/(float)g_winHeight; } float pts[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; // x0,y0,x1,y1 if(windowAspect>g_imageAspect) { float imgWidthScreenSpace = g_imageAspect * (float)g_winHeight; pts[0] = (float)g_winWidth * 0.5f - (float)imgWidthScreenSpace * 0.5f; pts[2] = (float)g_winWidth * 0.5f + (float)imgWidthScreenSpace * 0.5f; pts[1] = 0.0f; pts[3] = (float)g_winHeight; } else { float imgHeightScreenSpace = (float)g_winWidth / g_imageAspect; pts[0] = 0.0f; pts[2] = (float)g_winWidth; pts[1] = (float)g_winHeight * 0.5f - imgHeightScreenSpace * 0.5f; pts[3] = (float)g_winHeight * 0.5f + imgHeightScreenSpace * 0.5f; } glEnable(GL_TEXTURE_2D); glClearColor(0.1f, 0.1f, 0.1f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1, 1, 1); glPushMatrix(); glBegin(GL_QUADS); glTexCoord2f(0.0f, 1.0f); glVertex2f(pts[0], pts[1]); glTexCoord2f(0.0f, 0.0f); glVertex2f(pts[0], pts[3]); glTexCoord2f(1.0f, 0.0f); glVertex2f(pts[2], pts[3]); glTexCoord2f(1.0f, 1.0f); glVertex2f(pts[2], pts[1]); glEnd(); glPopMatrix(); glDisable(GL_TEXTURE_2D); glutSwapBuffers(); } static void Reshape(int width, int height) { g_winWidth = width; g_winHeight = height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, g_winWidth, 0.0, g_winHeight, -100.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } static void CleanUp(void) { glDeleteShader(g_fragShader); glDeleteProgram(g_program); glutDestroyWindow(g_win); } static void Key(unsigned char key, int /*x*/, int /*y*/) { if(key == 'c' || key == 'C') { g_channelHot[0] = 1; g_channelHot[1] = 1; g_channelHot[2] = 1; g_channelHot[3] = 1; } else if(key == 'r' || key == 'R') { g_channelHot[0] = 1; g_channelHot[1] = 0; g_channelHot[2] = 0; g_channelHot[3] = 0; } else if(key == 'g' || key == 'G') { g_channelHot[0] = 0; g_channelHot[1] = 1; g_channelHot[2] = 0; g_channelHot[3] = 0; } else if(key == 'b' || key == 'B') { g_channelHot[0] = 0; g_channelHot[1] = 0; g_channelHot[2] = 1; g_channelHot[3] = 0; } else if(key == 'a' || key == 'A') { g_channelHot[0] = 0; g_channelHot[1] = 0; g_channelHot[2] = 0; g_channelHot[3] = 1; } else if(key == 'l' || key == 'L') { g_channelHot[0] = 1; g_channelHot[1] = 1; g_channelHot[2] = 1; g_channelHot[3] = 0; } else if(key == 27) { CleanUp(); exit(0); } UpdateOCIOGLState(); glutPostRedisplay(); } static void SpecialKey(int key, int x, int y) { (void) x; (void) y; int mod = glutGetModifiers(); if(key == GLUT_KEY_UP && (mod & GLUT_ACTIVE_CTRL)) { g_exposure_fstop += 0.25f; } else if(key == GLUT_KEY_DOWN && (mod & GLUT_ACTIVE_CTRL)) { g_exposure_fstop -= 0.25f; } else if(key == GLUT_KEY_HOME && (mod & GLUT_ACTIVE_CTRL)) { g_exposure_fstop = 0.0f; g_display_gamma = 1.0f; } else if(key == GLUT_KEY_UP && (mod & GLUT_ACTIVE_ALT)) { g_display_gamma *= 1.1f; } else if(key == GLUT_KEY_DOWN && (mod & GLUT_ACTIVE_ALT)) { g_display_gamma /= 1.1f; } else if(key == GLUT_KEY_HOME && (mod & GLUT_ACTIVE_ALT)) { g_exposure_fstop = 0.0f; g_display_gamma = 1.0f; } UpdateOCIOGLState(); glutPostRedisplay(); } GLuint CompileShaderText(GLenum shaderType, const char *text) { GLuint shader; GLint stat; shader = glCreateShader(shaderType); glShaderSource(shader, 1, (const GLchar **) &text, NULL); glCompileShader(shader); glGetShaderiv(shader, GL_COMPILE_STATUS, &stat); if (!stat) { GLchar log[1000]; GLsizei len; glGetShaderInfoLog(shader, 1000, &len, log); fprintf(stderr, "Error: problem compiling shader: %s\n", log); return 0; } return shader; } GLuint LinkShaders(GLuint fragShader) { if (!fragShader) return 0; GLuint program = glCreateProgram(); if (fragShader) glAttachShader(program, fragShader); glLinkProgram(program); /* check link */ { GLint stat; glGetProgramiv(program, GL_LINK_STATUS, &stat); if (!stat) { GLchar log[1000]; GLsizei len; glGetProgramInfoLog(program, 1000, &len, log); fprintf(stderr, "Shader link error:\n%s\n", log); return 0; } } return program; } const char * g_fragShaderText = "" "\n" "uniform sampler2D tex1;\n" "uniform sampler3D tex2;\n" "\n" "void main()\n" "{\n" " vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n" " gl_FragColor = OCIODisplay(col, tex2);\n" "}\n"; void UpdateOCIOGLState() { // Step 0: Get the processor using any of the pipelines mentioned above. OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create(); transform->setInputColorSpaceName( g_inputColorSpace.c_str() ); transform->setDisplay( g_display.c_str() ); transform->setView( g_transformName.c_str() ); transform->setLooksOverride( g_look.c_str() ); if(g_verbose) { std::cout << std::endl; std::cout << "Color transformation composed of:" << std::endl; std::cout << " Image ColorSpace is:\t" << g_inputColorSpace << std::endl; std::cout << " Transform is:\t\t" << g_transformName << std::endl; std::cout << " Device is:\t\t" << g_display << std::endl; std::cout << " Looks Override is:\t'" << g_look << "'" << std::endl; std::cout << " with:" << std::endl; std::cout << " exposure_fstop = " << g_exposure_fstop << std::endl; std::cout << " display_gamma = " << g_display_gamma << std::endl; std::cout << " channels = " << (g_channelHot[0] ? "R" : "") << (g_channelHot[1] ? "G" : "") << (g_channelHot[2] ? "B" : "") << (g_channelHot[3] ? "A" : "") << std::endl; } // Add optional transforms to create a full-featured, "canonical" display pipeline // Fstop exposure control (in SCENE_LINEAR) { float gain = powf(2.0f, g_exposure_fstop); const float slope4f[] = { gain, gain, gain, gain }; float m44[16]; float offset4[4]; OCIO::MatrixTransform::Scale(m44, offset4, slope4f); OCIO::MatrixTransformRcPtr mtx = OCIO::MatrixTransform::Create(); mtx->setValue(m44, offset4); transform->setLinearCC(mtx); } // Channel swizzling { float lumacoef[3]; config->getDefaultLumaCoefs(lumacoef); float m44[16]; float offset[4]; OCIO::MatrixTransform::View(m44, offset, g_channelHot, lumacoef); OCIO::MatrixTransformRcPtr swizzle = OCIO::MatrixTransform::Create(); swizzle->setValue(m44, offset); transform->setChannelView(swizzle); } // Post-display transform gamma { float exponent = 1.0f/std::max(1e-6f, static_cast(g_display_gamma)); const float exponent4f[] = { exponent, exponent, exponent, exponent }; OCIO::ExponentTransformRcPtr expTransform = OCIO::ExponentTransform::Create(); expTransform->setValue(exponent4f); transform->setDisplayCC(expTransform); } OCIO::ConstProcessorRcPtr processor; try { processor = config->getProcessor(transform); } catch(OCIO::Exception & e) { std::cerr << e.what() << std::endl; return; } catch(...) { return; } // Step 1: Create a GPU Shader Description OCIO::GpuShaderDesc shaderDesc; shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0); shaderDesc.setFunctionName("OCIODisplay"); shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE); // Step 2: Compute the 3D LUT std::string lut3dCacheID = processor->getGpuLut3DCacheID(shaderDesc); if(lut3dCacheID != g_lut3dcacheid) { //std::cerr << "Computing 3DLut " << g_lut3dcacheid << std::endl; g_lut3dcacheid = lut3dCacheID; processor->getGpuLut3D(&g_lut3d[0], shaderDesc); glBindTexture(GL_TEXTURE_3D, g_lut3dTexID); glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, GL_RGB,GL_FLOAT, &g_lut3d[0]); } // Step 3: Compute the Shader std::string shaderCacheID = processor->getGpuShaderTextCacheID(shaderDesc); if(g_program == 0 || shaderCacheID != g_shadercacheid) { //std::cerr << "Computing Shader " << g_shadercacheid << std::endl; g_shadercacheid = shaderCacheID; std::ostringstream os; os << processor->getGpuShaderText(shaderDesc) << "\n"; os << g_fragShaderText; //std::cerr << os.str() << std::endl; if(g_fragShader) glDeleteShader(g_fragShader); g_fragShader = CompileShaderText(GL_FRAGMENT_SHADER, os.str().c_str()); if(g_program) glDeleteProgram(g_program); g_program = LinkShaders(g_fragShader); } glUseProgram(g_program); glUniform1i(glGetUniformLocation(g_program, "tex1"), 1); glUniform1i(glGetUniformLocation(g_program, "tex2"), 2); } void menuCallback(int /*id*/) { glutPostRedisplay(); } void imageColorSpace_CB(int id) { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char * name = config->getColorSpaceNameByIndex(id); if(!name) return; g_inputColorSpace = name; UpdateOCIOGLState(); glutPostRedisplay(); } void displayDevice_CB(int id) { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char * display = config->getDisplay(id); if(!display) return; g_display = display; const char * csname = config->getDisplayColorSpaceName(g_display.c_str(), g_transformName.c_str()); if(!csname) { g_transformName = config->getDefaultView(g_display.c_str()); } g_look = config->getDisplayLooks(g_display.c_str(), g_transformName.c_str()); UpdateOCIOGLState(); glutPostRedisplay(); } void transform_CB(int id) { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char * transform = config->getView(g_display.c_str(), id); if(!transform) return; g_transformName = transform; g_look = config->getDisplayLooks(g_display.c_str(), g_transformName.c_str()); UpdateOCIOGLState(); glutPostRedisplay(); } void look_CB(int id) { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); const char * look = config->getLookNameByIndex(id); if(!look || !*look) return; g_look = look; UpdateOCIOGLState(); glutPostRedisplay(); } static void PopulateOCIOMenus() { OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); int csMenuID = glutCreateMenu(imageColorSpace_CB); std::map families; for(int i=0; igetNumColorSpaces(); ++i) { const char * csName = config->getColorSpaceNameByIndex(i); if(csName && *csName) { OCIO::ConstColorSpaceRcPtr cs = config->getColorSpace(csName); if(cs) { const char * family = cs->getFamily(); if(family && *family) { if(families.find(family)==families.end()) { families[family] = glutCreateMenu(imageColorSpace_CB); glutAddMenuEntry(csName, i); glutSetMenu(csMenuID); glutAddSubMenu(family, families[family]); } else { glutSetMenu(families[family]); glutAddMenuEntry(csName, i); } } else { glutSetMenu(csMenuID); glutAddMenuEntry(csName, i); } } } } int deviceMenuID = glutCreateMenu(displayDevice_CB); for(int i=0; igetNumDisplays(); ++i) { glutAddMenuEntry(config->getDisplay(i), i); } int transformMenuID = glutCreateMenu(transform_CB); const char * defaultDisplay = config->getDefaultDisplay(); for(int i=0; igetNumViews(defaultDisplay); ++i) { glutAddMenuEntry(config->getView(defaultDisplay, i), i); } int lookMenuID = glutCreateMenu(look_CB); for(int i=0; igetNumLooks(); ++i) { glutAddMenuEntry(config->getLookNameByIndex(i), i); } glutCreateMenu(menuCallback); glutAddSubMenu("Image ColorSpace", csMenuID); glutAddSubMenu("Transform", transformMenuID); glutAddSubMenu("Device", deviceMenuID); glutAddSubMenu("Looks Override", lookMenuID); glutAttachMenu(GLUT_RIGHT_BUTTON); } const char * USAGE_TEXT = "\n" "Keys:\n" "\tCtrl+Up: Exposure +1/4 stop (in scene linear)\n" "\tCtrl+Down: Exposure -1/4 stop (in scene linear)\n" "\tCtrl+Home: Reset Exposure + Gamma\n" "\n" "\tAlt+Up: Gamma up (post display transform)\n" "\tAlt+Down: Gamma down (post display transform)\n" "\tAlt+Home: Reset Exposure + Gamma\n" "\n" "\tC: View Color\n" "\tR: View Red \n" "\tG: View Green\n" "\tB: View Blue\n" "\tA: View Alpha\n" "\tL: View Luma\n" "\n" "\tRight-Mouse Button: Configure Display / Transform / ColorSpace / Looks\n" "\n" "\tEsc: Quit\n"; void parseArguments(int argc, char **argv) { for(int i=1; i #include #include #include #include namespace OCIO = OCIO_NAMESPACE; #include #include #if (OIIO_VERSION < 10100) namespace OIIO = OIIO_NAMESPACE; #endif #include "argparse.h" // array of non openimageIO arguments static std::vector args; // fill 'args' array with openimageIO arguments static int parse_end_args(int argc, const char *argv[]) { while(argc>0) { args.push_back(argv[0]); argc--; argv++; } return 0; } bool ParseNameValuePair(std::string& name, std::string& value, const std::string& input); bool StringToFloat(float * fval, const char * str); bool StringToInt(int * ival, const char * str); bool StringToVector(std::vector * ivector, const char * str); int main(int argc, const char **argv) { ArgParse ap; std::vector floatAttrs; std::vector intAttrs; std::vector stringAttrs; std::string keepChannels; bool croptofull = false; ap.options("ocioconvert -- apply colorspace transform to an image \n\n" "usage: ocioconvert [options] inputimage inputcolorspace outputimage outputcolorspace\n\n", "%*", parse_end_args, "", "", "OpenImageIO options", "--float-attribute %L", &floatAttrs, "name=float pair defining OIIO float attribute", "--int-attribute %L", &intAttrs, "name=int pair defining OIIO int attribute", "--string-attribute %L", &stringAttrs, "name=string pair defining OIIO string attribute", "--croptofull", &croptofull, "name=Crop or pad to make pixel data region match the \"full\" region", "--ch %s", &keepChannels, "name=Select channels (e.g., \"2,3,4\")", NULL ); if (ap.parse (argc, argv) < 0) { std::cerr << ap.geterror() << std::endl; ap.usage (); exit(1); } if(args.size()!=4) { ap.usage(); exit(1); } const char * inputimage = args[0].c_str(); const char * inputcolorspace = args[1].c_str(); const char * outputimage = args[2].c_str(); const char * outputcolorspace = args[3].c_str(); OIIO::ImageSpec spec; std::vector img; int imgwidth = 0; int imgheight = 0; int components = 0; // Load the image std::cerr << "Loading " << inputimage << std::endl; try { OIIO::ImageInput* f = OIIO::ImageInput::create(inputimage); if(!f) { std::cerr << "Could not create image input." << std::endl; exit(1); } f->open(inputimage, spec); std::string error = f->geterror(); if(!error.empty()) { std::cerr << "Error loading image " << error << std::endl; exit(1); } imgwidth = spec.width; imgheight = spec.height; components = spec.nchannels; img.resize(imgwidth*imgheight*components); memset(&img[0], 0, imgwidth*imgheight*components*sizeof(float)); f->read_image(OIIO::TypeDesc::TypeFloat, &img[0]); delete f; std::vector kchannels; //parse --ch argument if (keepChannels != "" && !StringToVector(&kchannels,keepChannels.c_str())) { std::cerr << "Error: --ch: '" << keepChannels << "' should be comma-seperated integers\n"; exit(1); } //if kchannels not specified, then keep all channels if (kchannels.size() == 0) { kchannels.resize(components); for (int channel=0; channel < components; channel++) { kchannels[channel] = channel; } } if (croptofull) { imgwidth = spec.full_width; imgheight = spec.full_height; std::cerr << "cropping to " << imgwidth; std::cerr << "x" << imgheight << std::endl; } if (croptofull || (int)kchannels.size() < spec.nchannels) { // crop down bounding box and ditch all but n channels // img is a flattened 3 dimensional matrix heightxwidthxchannels // fill croppedimg with only the needed pixels std::vector croppedimg; croppedimg.resize(imgwidth*imgheight*kchannels.size()); for (int y=0 ; y < spec.height ; y++) { for (int x=0 ; x < spec.width; x++) { for (int k=0; k < (int)kchannels.size(); k++) { int channel = kchannels[k]; int current_pixel_y = y + spec.y; int current_pixel_x = x + spec.x; if (current_pixel_y >= 0 && current_pixel_x >= 0 && current_pixel_y < imgheight && current_pixel_x < imgwidth) { // get the value at the desired pixel float current_pixel = img[(y*spec.width*components) + (x*components)+channel]; // put in croppedimg. croppedimg[(current_pixel_y*imgwidth*kchannels.size()) + (current_pixel_x*kchannels.size()) + channel] = current_pixel; } } } } // redefine the spec so it matches the new bounding box spec.x = 0; spec.y = 0; spec.height = imgheight; spec.width = imgwidth; spec.nchannels = (int)(kchannels.size()); components = (int)(kchannels.size()); img = croppedimg; } } catch(...) { std::cerr << "Error loading file."; exit(1); } // Process the image try { // Load the current config. OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); // Get the processor OCIO::ConstProcessorRcPtr processor = config->getProcessor(inputcolorspace, outputcolorspace); // Wrap the image in a light-weight ImageDescription OCIO::PackedImageDesc imageDesc(&img[0], imgwidth, imgheight, components); // Apply the color transformation (in place) processor->apply(imageDesc); } catch(OCIO::Exception & exception) { std::cerr << "OCIO Error: " << exception.what() << std::endl; exit(1); } catch(...) { std::cerr << "Unknown OCIO error encountered." << std::endl; exit(1); } // // set the provided OpenImageIO attributes // bool parseerror = false; for(unsigned int i=0; iopen(outputimage, spec); f->write_image(OIIO::TypeDesc::FLOAT, &img[0]); f->close(); delete f; } catch(...) { std::cerr << "Error loading file."; exit(1); } std::cerr << "Wrote " << outputimage << std::endl; return 0; } // Parse name=value parts // return true on success bool ParseNameValuePair(std::string& name, std::string& value, const std::string& input) { // split string into name=value size_t pos = input.find('='); if(pos==std::string::npos) return false; name = input.substr(0,pos); value = input.substr(pos+1); return true; } // return true on success bool StringToFloat(float * fval, const char * str) { if(!str) return false; std::istringstream inputStringstream(str); float x; if(!(inputStringstream >> x)) { return false; } if(fval) *fval = x; return true; } bool StringToInt(int * ival, const char * str) { if(!str) return false; std::istringstream inputStringstream(str); int x; if(!(inputStringstream >> x)) { return false; } if(ival) *ival = x; return true; } bool StringToVector(std::vector * ivector, const char * str) { std::stringstream ss(str); int i; while (ss >> i) { ivector->push_back(i); if (ss.peek() == ',') { ss.ignore(); } } return ivector->size() != 0; } opencolorio-1.1.0~dfsg0.orig/src/apps/ociolutimage/0000755000175000017500000000000013223553423020501 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/apps/ociolutimage/CMakeLists.txt0000644000175000017500000000130113223553423023234 0ustar mfvmfvif (OIIO_FOUND) include_directories( ${CMAKE_SOURCE_DIR}/export/ ${CMAKE_BINARY_DIR}/export/ ${CMAKE_SOURCE_DIR}/src/apps/share/ ${OIIO_INCLUDES} ${ILMBASE_INCLUDES} ) file(GLOB_RECURSE share_src_files "${CMAKE_SOURCE_DIR}/src/apps/share/*.cpp") add_executable(ociolutimage ${share_src_files} main.cpp) set_target_properties(ociolutimage PROPERTIES COMPILE_FLAGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}) target_link_libraries(ociolutimage ${OIIO_LIBRARIES} ${CMAKE_DL_LIBS}) target_link_OCIO(ociolutimage) install(TARGETS ociolutimage EXPORT OpenColorIO DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/bin) endif() opencolorio-1.1.0~dfsg0.orig/src/apps/ociolutimage/main.cpp0000644000175000017500000003015513223553423022135 0ustar mfvmfv/* 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 namespace OCIO = OCIO_NAMESPACE; OCIO_NAMESPACE_USING; #include #include #if (OIIO_VERSION < 10100) namespace OIIO = OIIO_NAMESPACE; #endif #include "argparse.h" #include #include #include #include #include #include "pystring.h" enum Lut3DOrder { LUT3DORDER_FAST_RED = 0, LUT3DORDER_FAST_BLUE }; void WriteLut3D(const std::string & filename, const float* lutdata, int edgeLen); void GenerateIdentityLut3D(float* img, int edgeLen, int numChannels, Lut3DOrder lut3DOrder); void GetLutImageSize(int & width, int & height, int cubesize, int maxwidth) { // Compute the image width / height width = cubesize*cubesize; if(maxwidth>0 && width>=maxwidth) { // TODO: Do something smarter here to find a better multiple, // to create a more pleasing gradient rendition. // Use prime divisors / lowest common denominator, if possible? width = std::min(maxwidth, width); } int numpixels = cubesize*cubesize*cubesize; height = (int)(ceilf((float)numpixels/(float)width)); } void Generate(int cubesize, int maxwidth, const std::string & outputfile, const std::string & configfile, const std::string & incolorspace, const std::string & outcolorspace) { int width = 0; int height = 0; int numchannels = 3; GetLutImageSize(width, height, cubesize, maxwidth); std::vector img; img.resize(width*height*numchannels, 0); GenerateIdentityLut3D(&img[0], cubesize, numchannels, LUT3DORDER_FAST_RED); if(!incolorspace.empty() || !outcolorspace.empty()) { OCIO::ConstConfigRcPtr config = OCIO::Config::Create(); if(!configfile.empty()) { config = OCIO::Config::CreateFromFile(configfile.c_str()); } else if(getenv("OCIO")) { config = OCIO::Config::CreateFromEnv(); } else { std::ostringstream os; os << "You must specify an ocio configuration "; os << "(either with --config or $OCIO)."; throw Exception(os.str().c_str()); } OCIO::ConstProcessorRcPtr processor = config->getProcessor(incolorspace.c_str(), outcolorspace.c_str()); OCIO::PackedImageDesc imgdesc(&img[0], width, height, 3); processor->apply(imgdesc); } OIIO::ImageOutput* f = OIIO::ImageOutput::create(outputfile); if(!f) { throw Exception( "Could not create output image."); } OIIO::ImageSpec spec(width, height, numchannels, OIIO::TypeDesc::TypeFloat); // TODO: If DPX, force 16-bit output? f->open(outputfile, spec); f->write_image(OIIO::TypeDesc::FLOAT, &img[0]); f->close(); delete f; } void Extract(int cubesize, int maxwidth, const std::string & inputfile, const std::string & outputfile) { // Read the image OIIO::ImageInput* f = OIIO::ImageInput::create(inputfile); if(!f) { throw Exception("Could not create input image."); } OIIO::ImageSpec spec; f->open(inputfile, spec); std::string error = f->geterror(); if(!error.empty()) { std::ostringstream os; os << "Error loading image " << error; throw Exception(os.str().c_str()); } int width = 0; int height = 0; GetLutImageSize(width, height, cubesize, maxwidth); if(spec.width != width || spec.height != height) { std::ostringstream os; os << "Image does not have expected dimensions. "; os << "Expected " << width << "x" << height << ", "; os << "Found " << spec.width << "x" << spec.height; throw Exception(os.str().c_str()); } if(spec.nchannels<3) { throw Exception("Image must have 3 or more channels."); } int lut3DNumPixels = cubesize*cubesize*cubesize; if(spec.width*spec.height img; img.resize(spec.width*spec.height*spec.nchannels, 0); f->read_image(OIIO::TypeDesc::TypeFloat, &img[0]); delete f; // Repack into rgb // Convert the RGB[...] image to an RGB image, in place. // Of course, this only works because we're doing it from left to right // so old pixels are read before they're written over if(spec.nchannels > 3) { for(int i=0; i\n\n" "example: ociolutimage --generate --output lut.exr\n" "example: ociolutimage --extract --input lut.exr --output output.spi3d\n", "", "", "--generate", &generate, "Generate a lattice image", "--extract", &extract, "Extract a 3dlut from an input image", "", "", "--cubesize %d", &cubesize, "Size of the cube (default: 32)", "--maxwidth %d", &maxwidth, "Specify maximum width of the image (default: 2048)", "--input %s", &inputfile, "Specify the input filename", "--output %s", &outputfile, "Specify the output filename", "", "", "--config %s", &config, ".ocio configuration file (default: $OCIO)", "--colorconvert %s %s", &incolorspace, &outcolorspace, "Apply a color space conversion to the image.", NULL); if (ap.parse(argc, argv) < 0) { std::cout << ap.geterror() << std::endl; ap.usage(); std::cout << "\n"; return 1; } if (argc == 1 ) { ap.usage(); std::cout << "\n"; return 1; } if(generate) { try { Generate(cubesize, maxwidth, outputfile, config, incolorspace, outcolorspace); } catch(std::exception & e) { std::cerr << "Error generating image: " << e.what() << std::endl; exit(1); } catch(...) { std::cerr << "Error generating image. An unknown error occurred.\n"; exit(1); } } else if(extract) { try { Extract(cubesize, maxwidth, inputfile, outputfile); } catch(std::exception & e) { std::cerr << "Error extracting lut: " << e.what() << std::endl; exit(1); } catch(...) { std::cerr << "Error extracting lut. An unknown error occurred.\n"; exit(1); } } else { std::cerr << "Must specify either --generate or --extract.\n"; exit(1); } return 0; } //////////////////////////////////////////////////////////////////////////////// // // TODO: These should be exposed from inside OCIO, in appropriate time. // inline int GetLut3DIndex_B(int indexR, int indexG, int indexB, int sizeR, int sizeG, int /*sizeB*/) { return 3 * (indexR + sizeR * (indexG + sizeG * indexB)); } inline int GetLut3DIndex_R(int indexR, int indexG, int indexB, int /*sizeR*/, int sizeG, int sizeB) { return 3 * (indexB + sizeB * (indexG + sizeG * indexR)); } void GenerateIdentityLut3D(float* img, int edgeLen, int numChannels, Lut3DOrder lut3DOrder) { if(!img) return; if(numChannels < 3) { throw Exception("Cannot generate idenitity 3d lut with less than 3 channels."); } float c = 1.0f / ((float)edgeLen - 1.0f); if(lut3DOrder == LUT3DORDER_FAST_RED) { for(int i=0; i #include namespace OCIO = OCIO_NAMESPACE; OCIO_NAMESPACE_ENTER { // // Build an ICC profile for doing soft proofing // // N-component LUT-based display profile required tags // ------------------------------------------------------------------------------ // Tag Name General Description // ------------------------------------------------------------------------------ // profileDescriptionTag Structure containing invariant and localizable // versions of the profile name for display // AToB0Tag Device to PCS: 8-bit or 16-bit data: intent of 0 // BToA0Tag PCS to Device space: 8-bit or 16-bit data: intent of 0 // mediaWhitePointTag Media XYZ white point // copyrightTag Profile copyright information // chromaticAdaptationTag Converts XYZ colour from the actual illumination // source to PCS illuminant. Required only if the actual // illumination source is not D50. void SaveICCProfileToFile(const std::string & outputfile, ConstProcessorRcPtr & processor, int cubesize, int whitepointtemp, const std::string & displayicc, const std::string & description, const std::string & copyright, bool verbose); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/apps/ociobakelut/ocioicc.cpp0000644000175000017500000002110613223553423022435 0ustar mfvmfv/* 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 #include #include #include #include #include #include #include #include "ocioicc.h" #include "lcms2.h" #include "lcms2_plugin.h" OCIO_NAMESPACE_ENTER { namespace { void ErrorHandler(cmsContext /*ContextID*/, cmsUInt32Number /*ErrorCode*/, const char *Text) { std::cerr << "OCIO Error: " << Text << "\n"; return; } typedef struct { cmsHTRANSFORM to_PCS16; cmsHTRANSFORM from_PCS16; //OCIO::ConstProcessorRcPtr shaper_processor; OCIO::ConstProcessorRcPtr processor; } SamplerData; static void Add3GammaCurves(cmsPipeline* lut, cmsFloat64Number Curve) { cmsToneCurve* id = cmsBuildGamma(NULL, Curve); cmsToneCurve* id3[3]; id3[0] = id; id3[1] = id; id3[2] = id; cmsPipelineInsertStage(lut, cmsAT_END, cmsStageAllocToneCurves(NULL, 3, id3)); cmsFreeToneCurve(id); } static void AddIdentityMatrix(cmsPipeline* lut) { const cmsFloat64Number Identity[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 }; cmsPipelineInsertStage(lut, cmsAT_END, cmsStageAllocMatrix(NULL, 3, 3, Identity, NULL)); } static cmsInt32Number Display2PCS_Sampler16(const cmsUInt16Number in[], cmsUInt16Number out[], void* userdata) { //std::cout << "r" << in[0] << " g" << in[1] << " b" << in[2] << "\n"; SamplerData* data = (SamplerData*) userdata; cmsFloat32Number pix[3] = { static_cast(in[0])/65535.f, static_cast(in[1])/65535.f, static_cast(in[2])/65535.f}; data->processor->applyRGB(pix); out[0] = (cmsUInt16Number)std::max(std::min(pix[0] * 65535.f, 65535.f), 0.f); out[1] = (cmsUInt16Number)std::max(std::min(pix[1] * 65535.f, 65535.f), 0.f); out[2] = (cmsUInt16Number)std::max(std::min(pix[2] * 65535.f, 65535.f), 0.f); cmsDoTransform(data->to_PCS16, out, out, 1); return 1; } static cmsInt32Number PCS2Display_Sampler16(const cmsUInt16Number in[], cmsUInt16Number out[], void* userdata) { //std::cout << "r" << in[0] << " g" << in[1] << " b" << in[2] << "\n"; SamplerData* data = (SamplerData*) userdata; cmsDoTransform(data->from_PCS16, in, out, 1); // we don't have a reverse Lab -> Display transform return 1; } } // anon namespace void SaveICCProfileToFile(const std::string & outputfile, ConstProcessorRcPtr & processor, int cubesize, int whitepointtemp, const std::string & displayicc, const std::string & description, const std::string & copyright, bool verbose) { // Create the ICC Profile // Setup the Error Handler cmsSetLogErrorHandler(ErrorHandler); // D65 white point cmsCIExyY whitePoint; cmsWhitePointFromTemp(&whitePoint, whitepointtemp); // LAB PCS cmsHPROFILE labProfile = cmsCreateLab4ProfileTHR(NULL, &whitePoint); // Display (OCIO sRGB cube -> LAB) cmsHPROFILE DisplayProfile; if(displayicc != "") DisplayProfile = cmsOpenProfileFromFile(displayicc.c_str(), "r"); else DisplayProfile = cmsCreate_sRGBProfileTHR(NULL); // Create an empty RGB Profile cmsHPROFILE hProfile = cmsCreateRGBProfileTHR(NULL, &whitePoint, NULL, NULL); if(verbose) std::cout << "[OpenColorIO INFO]: Setting up Profile: " << outputfile << "\n"; // Added Header fields cmsSetProfileVersion(hProfile, 4.2); cmsSetDeviceClass(hProfile, cmsSigDisplayClass); cmsSetColorSpace(hProfile, cmsSigRgbData); cmsSetPCS(hProfile, cmsSigLabData); cmsSetHeaderRenderingIntent(hProfile, INTENT_PERCEPTUAL); // cmsMLU* DescriptionMLU = cmsMLUalloc(NULL, 1); cmsMLU* CopyrightMLU = cmsMLUalloc(NULL, 1); cmsMLUsetASCII(DescriptionMLU, "en", "US", description.c_str()); cmsMLUsetASCII(CopyrightMLU, "en", "US", copyright.c_str()); cmsWriteTag(hProfile, cmsSigProfileDescriptionTag, DescriptionMLU); cmsWriteTag(hProfile, cmsSigCopyrightTag, CopyrightMLU); // SamplerData data; data.processor = processor; // 16Bit data.to_PCS16 = cmsCreateTransform(DisplayProfile, TYPE_RGB_16, labProfile, TYPE_LabV2_16, INTENT_PERCEPTUAL, cmsFLAGS_NOOPTIMIZE|cmsFLAGS_NOCACHE); data.from_PCS16 = cmsCreateTransform(labProfile, TYPE_LabV2_16, DisplayProfile, TYPE_RGB_16, INTENT_PERCEPTUAL, cmsFLAGS_NOOPTIMIZE|cmsFLAGS_NOCACHE); // // AToB0Tag - Device to PCS (16-bit) intent of 0 (perceptual) // // cmsSigCurveSetElemType // `- cmsSigCLutElemType // `- cmsSigCurveSetElemType // `- cmsSigMatrixElemType // `- cmsSigCurveSetElemType // if(verbose) std::cout << "[OpenColorIO INFO]: Adding AToB0Tag\n"; cmsPipeline* AToB0Tag = cmsPipelineAlloc(NULL, 3, 3); Add3GammaCurves(AToB0Tag, 1.f); // cmsSigCurveSetElemType // cmsSigCLutElemType cmsStage* AToB0Clut = cmsStageAllocCLut16bit(NULL, cubesize, 3, 3, NULL); if(verbose) std::cout << "[OpenColorIO INFO]: Sampling AToB0 CLUT from Display to Lab\n"; cmsStageSampleCLut16bit(AToB0Clut, Display2PCS_Sampler16, &data, 0); cmsPipelineInsertStage(AToB0Tag, cmsAT_END, AToB0Clut); Add3GammaCurves(AToB0Tag, 1.f); // cmsSigCurveSetElemType AddIdentityMatrix(AToB0Tag); // cmsSigMatrixElemType Add3GammaCurves(AToB0Tag, 1.f); // cmsSigCurveSetElemType // Add AToB0Tag cmsWriteTag(hProfile, cmsSigAToB0Tag, AToB0Tag); cmsPipelineFree(AToB0Tag); // // BToA0Tag - PCS to Device space (16-bit) intent of 0 (perceptual) // // cmsSigCurveSetElemType // `- cmsSigMatrixElemType // `- cmsSigCurveSetElemType // `- cmsSigCLutElemType // `- cmsSigCurveSetElemType // if(verbose) std::cout << "[OpenColorIO INFO]: Adding BToA0Tag\n"; cmsPipeline* BToA0Tag = cmsPipelineAlloc(NULL, 3, 3); Add3GammaCurves(BToA0Tag, 1.f); // cmsSigCurveSetElemType AddIdentityMatrix(BToA0Tag); // cmsSigMatrixElemType Add3GammaCurves(BToA0Tag, 1.f); // cmsSigCurveSetElemType // cmsSigCLutElemType cmsStage* BToA0Clut = cmsStageAllocCLut16bit(NULL, cubesize, 3, 3, NULL); if(verbose) std::cout << "[OpenColorIO INFO]: Sampling BToA0 CLUT from Lab to Display\n"; cmsStageSampleCLut16bit(BToA0Clut, PCS2Display_Sampler16, &data, 0); cmsPipelineInsertStage(BToA0Tag, cmsAT_END, BToA0Clut); Add3GammaCurves(BToA0Tag, 1.f); // cmsSigCurveSetElemType // Add BToA0Tag cmsWriteTag(hProfile, cmsSigBToA0Tag, BToA0Tag); cmsPipelineFree(BToA0Tag); // // D2Bx - Device to PCS (float) (Not Yet Impl) // // // B2Dx - PCS to Device (float) (Not Yet Impl) // // // Write // if(verbose) std::cout << "[OpenColorIO INFO]: Writing " << outputfile << std::endl; cmsSaveProfileToFile(hProfile, outputfile.c_str()); cmsCloseProfile(hProfile); if(verbose) std::cout << "[OpenColorIO INFO]: Finished\n"; } } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/apps/ociobakelut/main.cpp0000644000175000017500000004737113223553423021765 0ustar mfvmfv/* 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 #include #include #include #include #include #include namespace OCIO = OCIO_NAMESPACE; #include "argparse.h" #include "ocioicc.h" static std::string outputfile; static int parse_end_args(int argc, const char *argv[]) { if(argc>0) { outputfile = argv[0]; } return 0; } OCIO::GroupTransformRcPtr parse_luts(int argc, const char *argv[]); int main (int argc, const char* argv[]) { bool help = false; int cubesize = -1; int shapersize = -1; // cubsize^2 std::string format; std::string inputconfig; std::string inputspace; std::string shaperspace; std::string looks; std::string outputspace; bool usestdout = false; bool verbose = false; int whitepointtemp = 6505; std::string displayicc; std::string description; std::string copyright = "No copyright. Use freely."; // What are the allowed baker output formats? std::ostringstream formats; formats << "the lut format to bake: "; for(int i=0; i\n\n" "example: ociobakelut --inputspace lg10 --outputspace srgb8 --format flame lg_to_srgb.3dl\n" "example: ociobakelut --lut filmlut.3dl --lut calibration.3dl --format flame display.3dl\n" "example: ociobakelut --cccid 0 --lut cdlgrade.ccc --lut calibration.3dl --format flame graded_display.3dl\n" "example: ociobakelut --lut look.3dl --offset 0.01 -0.02 0.03 --lut display.3dl --format flame display_with_look.3dl\n" "example: ociobakelut --inputspace lg10 --outputspace srgb8 --format icc ~/Library/ColorSync/Profiles/test.icc\n" "example: ociobakelut --lut filmlut.3dl --lut calibration.3dl --format icc ~/Library/ColorSync/Profiles/test.icc\n\n", "%*", parse_end_args, "", "", "Using Existing OCIO Configurations", "--inputspace %s", &inputspace, "Input OCIO ColorSpace (or Role)", "--outputspace %s", &outputspace, "Output OCIO ColorSpace (or Role)", "--shaperspace %s", &shaperspace, "the OCIO ColorSpace or Role, for the shaper", "--looks %s", &looks, "the OCIO looks to apply", "--iconfig %s", &inputconfig, "Input .ocio configuration file (default: $OCIO)\n", "", "Config-Free LUT Baking", "", " (all options can be specified multiple times, each is applied in order)", "--cccid %s", &dummystr, "Specify a CCCId for any following luts", "--lut %s", &dummystr, "Specify a LUT (forward direction)", "--invlut %s", &dummystr, "Specify a LUT (inverse direction)", "--slope %f %f %f", &dummyf1, &dummyf2, &dummyf3, "slope", "--offset %f %f %f", &dummyf1, &dummyf2, &dummyf3, "offset (float)", "--offset10 %f %f %f", &dummyf1, &dummyf2, &dummyf3, "offset (10-bit)", "--power %f %f %f", &dummyf1, &dummyf2, &dummyf3, "power", "--sat %f", &dummyf1, "saturation (ASC-CDL luma coefficients)\n", "", "Baking Options", "--format %s", &format, formatstr.c_str(), "--shapersize %d", &shapersize, "size of the shaper (default: format specific)", "--cubesize %d", &cubesize, "size of the cube (default: format specific)", "--stdout", &usestdout, "Write to stdout (rather than file)", "--v", &verbose, "Verbose", "--help", &help, "Print help message\n", "", "ICC Options", //"--cubesize %d", &cubesize, "size of the icc CLUT cube (default: 32)", "--whitepoint %d", &whitepointtemp, "whitepoint for the profile (default: 6505)", "--displayicc %s", &displayicc , "an icc profile which matches the OCIO profiles target display", "--description %s", &description , "a meaningful description, this will show up in UI like photoshop (defaults to \"filename.icc\")", "--copyright %s", ©right , "a copyright field (default: \"No copyright. Use freely.\"\n", // TODO: add --metadata option NULL); if (ap.parse(argc, argv) < 0) { std::cout << ap.geterror() << std::endl; ap.usage(); std::cout << "\n"; return 1; } if (help || (argc == 1 )) { ap.usage(); std::cout << "\n"; return 1; } // If we're printing to stdout, disable verbose printouts if(usestdout) { verbose = false; } // Create the OCIO processor for the specified transform. OCIO::ConstConfigRcPtr config; OCIO::GroupTransformRcPtr groupTransform; try { groupTransform = parse_luts(argc, argv); } catch(const OCIO::Exception & e) { std::cerr << "\nERROR: " << e.what() << std::endl; std::cerr << "See --help for more info." << std::endl; return 1; } catch(...) { std::cerr << "\nERROR: An unknown error occurred in parse_luts" << std::endl; std::cerr << "See --help for more info." << std::endl; return 1; } if(!groupTransform) { std::cerr << "\nERROR: parse_luts returned null transform" << std::endl; std::cerr << "See --help for more info." << std::endl; return 1; } // If --luts have been specified, synthesize a new (temporary) configuration // with the transformation embedded in a colorspace. if(!groupTransform->empty()) { if(!inputspace.empty()) { std::cerr << "\nERROR: --inputspace is not allowed when using --lut\n\n"; std::cerr << "See --help for more info." << std::endl; return 1; } if(!outputspace.empty()) { std::cerr << "\nERROR: --outputspace is not allowed when using --lut\n\n"; std::cerr << "See --help for more info." << std::endl; return 1; } if(!looks.empty()) { std::cerr << "\nERROR: --looks is not allowed when using --lut\n\n"; std::cerr << "See --help for more info." << std::endl; return 1; } if(!shaperspace.empty()) { std::cerr << "\nERROR: --shaperspace is not allowed when using --lut\n\n"; std::cerr << "See --help for more info." << std::endl; return 1; } OCIO::ConfigRcPtr editableConfig = OCIO::Config::Create(); OCIO::ColorSpaceRcPtr inputColorSpace = OCIO::ColorSpace::Create(); inputspace = "RawInput"; inputColorSpace->setName(inputspace.c_str()); editableConfig->addColorSpace(inputColorSpace); OCIO::ColorSpaceRcPtr outputColorSpace = OCIO::ColorSpace::Create(); outputspace = "ProcessedOutput"; outputColorSpace->setName(outputspace.c_str()); outputColorSpace->setTransform(groupTransform, OCIO::COLORSPACE_DIR_FROM_REFERENCE); if(verbose) { std::cout << "[OpenColorIO DEBUG]: Specified Transform:"; std::cout << *groupTransform; std::cout << "\n"; } editableConfig->addColorSpace(outputColorSpace); config = editableConfig; } else { if(inputspace.empty()) { std::cerr << "\nERROR: You must specify the --inputspace.\n\n"; std::cerr << "See --help for more info." << std::endl; return 1; } if(outputspace.empty()) { std::cerr << "\nERROR: You must specify the --outputspace.\n\n"; std::cerr << "See --help for more info." << std::endl; return 1; } if(format.empty()) { std::cerr << "\nERROR: You must specify the lut format using --format.\n\n"; std::cerr << "See --help for more info." << std::endl; return 1; } if(!inputconfig.empty()) { if(!usestdout && verbose) std::cout << "[OpenColorIO INFO]: Loading " << inputconfig << std::endl; config = OCIO::Config::CreateFromFile(inputconfig.c_str()); } else if(getenv("OCIO")) { if(!usestdout && verbose) std::cout << "[OpenColorIO INFO]: Loading $OCIO " << getenv("OCIO") << std::endl; config = OCIO::Config::CreateFromEnv(); } else { std::cerr << "ERROR: You must specify an input ocio configuration "; std::cerr << "(either with --iconfig or $OCIO).\n\n"; ap.usage (); return 1; } } if(outputfile.empty() && !usestdout) { std::cerr << "\nERROR: You must specify the outputfile or --stdout.\n\n"; std::cerr << "See --help for more info." << std::endl; return 1; } try { if(format == "icc") { if(description.empty()) { description = outputfile; if(verbose) std::cout << "[OpenColorIO INFO]: \"--description\" set to default value of filename.icc: " << outputfile << "" << std::endl; } if(usestdout) { std::cerr << "\nERROR: --stdout not supported when writing icc profiles.\n\n"; std::cerr << "See --help for more info." << std::endl; return 1; } if(outputfile.empty()) { std::cerr << "ERROR: you need to specify a output icc path\n"; std::cerr << "See --help for more info." << std::endl; return 1; } if(cubesize<2) cubesize = 32; // default OCIO::ConstProcessorRcPtr processor; if (!looks.empty()) { OCIO::LookTransformRcPtr transform = OCIO::LookTransform::Create(); transform->setLooks(looks.c_str()); transform->setSrc(inputspace.c_str()); transform->setDst(outputspace.c_str()); processor = config->getProcessor(transform, OCIO::TRANSFORM_DIR_FORWARD); } else { processor = config->getProcessor(inputspace.c_str(), outputspace.c_str()); } SaveICCProfileToFile(outputfile, processor, cubesize, whitepointtemp, displayicc, description, copyright, verbose); } else { OCIO::BakerRcPtr baker = OCIO::Baker::Create(); // setup the baker for our lut type baker->setConfig(config); baker->setFormat(format.c_str()); baker->setInputSpace(inputspace.c_str()); baker->setShaperSpace(shaperspace.c_str()); baker->setLooks(looks.c_str()); baker->setTargetSpace(outputspace.c_str()); if(shapersize!=-1) baker->setShaperSize(shapersize); if(cubesize!=-1) baker->setCubeSize(cubesize); // output lut std::ostringstream output; if(!usestdout && verbose) std::cout << "[OpenColorIO INFO]: Baking '" << format << "' lut" << std::endl; if(usestdout) { baker->bake(std::cout); } else { std::ofstream f(outputfile.c_str()); baker->bake(f); if(verbose) std::cout << "[OpenColorIO INFO]: Wrote '" << outputfile << "'" << std::endl; } } } catch(OCIO::Exception & exception) { std::cerr << "OCIO Error: " << exception.what() << std::endl; std::cerr << "See --help for more info." << std::endl; return 1; } catch (std::exception& exception) { std::cerr << "Error: " << exception.what() << "\n"; std::cerr << "See --help for more info." << std::endl; return 1; } catch(...) { std::cerr << "Unknown OCIO error encountered." << std::endl; std::cerr << "See --help for more info." << std::endl; return 1; } return 0; } // TODO: Replace this dirty argument parsing code with a clean version // that leverages the same codepath for the standard arguments. If // the OIIO derived argparse does not suffice, options we may want to consider // include simpleopt, tclap, ultraopt // TODO: Use better input validation, instead of atof. // If too few arguments are provides for scale (let's say only two) and // the following argument is the start of another flag (let's say "--invlut") // then atof() will likely try to convert "--invlut" to its double equivalent, // resulting in an invalid (or at least undesired) scale value. OCIO::GroupTransformRcPtr parse_luts(int argc, const char *argv[]) { OCIO::GroupTransformRcPtr groupTransform = OCIO::GroupTransform::Create(); const char *lastCCCId = NULL; // Ugly to use this but using GroupTransform::getTransform() // returns a const object so we must set this // prior to using --lut for now. for(int i=0; i=argc) { throw OCIO::Exception("Error parsing --lut. Invalid num args"); } OCIO::FileTransformRcPtr t = OCIO::FileTransform::Create(); t->setSrc(argv[i+1]); t->setInterpolation(OCIO::INTERP_BEST); if (lastCCCId) { t->setCCCId(lastCCCId); } groupTransform->push_back(t); i += 1; } else if(arg == "--cccid" || arg == "-cccid") { if(i+1>=argc) { throw OCIO::Exception("Error parsing --cccid. Invalid num args"); } lastCCCId = argv[i+1]; i += 1; } else if(arg == "--invlut" || arg == "-invlut") { if(i+1>=argc) { throw OCIO::Exception("Error parsing --invlut. Invalid num args"); } OCIO::FileTransformRcPtr t = OCIO::FileTransform::Create(); t->setSrc(argv[i+1]); t->setInterpolation(OCIO::INTERP_BEST); t->setDirection(OCIO::TRANSFORM_DIR_INVERSE); groupTransform->push_back(t); i += 1; } else if(arg == "--slope" || arg == "-slope") { if(i+3>=argc) { throw OCIO::Exception("Error parsing --slope. Invalid num args"); } OCIO::CDLTransformRcPtr t = OCIO::CDLTransform::Create(); float scale[3]; scale[0] = (float) atof(argv[i+1]); scale[1] = (float) atof(argv[i+2]); scale[2] = (float) atof(argv[i+3]); t->setSlope(scale); groupTransform->push_back(t); i += 3; } else if(arg == "--offset" || arg == "-offset") { if(i+3>=argc) { throw OCIO::Exception("Error parsing --offset. Invalid num args"); } OCIO::CDLTransformRcPtr t = OCIO::CDLTransform::Create(); float offset[3]; offset[0] = (float) atof(argv[i+1]); offset[1] = (float) atof(argv[i+2]); offset[2] = (float) atof(argv[i+3]); t->setOffset(offset); groupTransform->push_back(t); i += 3; } else if(arg == "--offset10" || arg == "-offset10") { if(i+3>=argc) { throw OCIO::Exception("Error parsing --offset10. Invalid num args"); } OCIO::CDLTransformRcPtr t = OCIO::CDLTransform::Create(); float offset[3]; offset[0] = (float) atof(argv[i+1]) / 1023.0f; offset[1] = (float) atof(argv[i+2]) / 1023.0f; offset[2] = (float) atof(argv[i+3]) / 1023.0f; t->setOffset(offset); groupTransform->push_back(t); i += 3; } else if(arg == "--power" || arg == "-power") { if(i+3>=argc) { throw OCIO::Exception("Error parsing --power. Invalid num args"); } OCIO::CDLTransformRcPtr t = OCIO::CDLTransform::Create(); float power[3]; power[0] = (float) atof(argv[i+1]); power[1] = (float) atof(argv[i+2]); power[2] = (float) atof(argv[i+3]); t->setPower(power); groupTransform->push_back(t); i += 3; } else if(arg == "--sat" || arg == "-sat") { if(i+1>=argc) { throw OCIO::Exception("Error parsing --sat. Invalid num args"); } OCIO::CDLTransformRcPtr t = OCIO::CDLTransform::Create(); t->setSat((float) atof(argv[i+1])); groupTransform->push_back(t); i += 1; } } return groupTransform; } opencolorio-1.1.0~dfsg0.orig/src/apps/share/0000755000175000017500000000000013223553423017122 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/apps/share/strutil.h0000644000175000017500000000611113223553423021000 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. 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 the software's owners 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. (This is the Modified BSD License) */ ///////////////////////////////////////////////////////////////////////// /// @file strutil.h /// /// @brief String-related utilities, all in namespace Strutil. ///////////////////////////////////////////////////////////////////////// #ifndef OPENCOLORIO_STRUTIL_H #define OPENCOLORIO_STRUTIL_H #include #include #include #include #ifndef OPENCOLORIO_PRINTF_ARGS # ifndef __GNUC__ # define __attribute__(x) # endif // Enable printf-like warnings with gcc by attaching // OPENIMAGEIO_PRINTF_ARGS to printf-like functions. Eg: // // void foo (const char* fmt, ...) OPENCOLORIO_PRINTF_ARGS(1,2); // // The arguments specify the positions of the format string and the the // beginning of the varargs parameter list respectively. // // For member functions with arguments like the example above, you need // OPENCOLORIO_PRINTF_ARGS(2,3) instead. (gcc includes the implicit this // pointer when it counts member function arguments.) # define OPENCOLORIO_PRINTF_ARGS(fmtarg_pos, vararg_pos) \ __attribute__ ((format (printf, fmtarg_pos, vararg_pos) )) #endif /// @namespace Strutil /// /// @brief String-related utilities. namespace Strutil { /// Return a std::string formatted from printf-like arguments -- passed /// already as a va_list. std::string vformat (const char *fmt, va_list ap) OPENCOLORIO_PRINTF_ARGS(1,0); }; // namespace Strutil #endif // OPENCOLORIO_STRUTIL_H opencolorio-1.1.0~dfsg0.orig/src/apps/share/pystring.h0000644000175000017500000005602313223553423021160 0ustar mfvmfv/////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2008-2010, Sony Pictures Imageworks Inc // 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 the organization 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_OCIO_PYSTRING_H #define INCLUDED_OCIO_PYSTRING_H #include #include #include OCIO_NAMESPACE_ENTER { // Version 1.1.2 // https://github.com/imageworks/pystring/tarball/v1.1.2 namespace pystring { ////////////////////////////////////////////////////////////////////////////////////////////// /// @mainpage pystring /// /// This is a set of functions matching the interface and behaviors of python string methods /// (as of python 2.3) using std::string. /// /// Overlapping functionality ( such as index and slice/substr ) of std::string is included /// to match python interfaces. /// ////////////////////////////////////////////////////////////////////////////////////////////// /// @defgroup functions pystring /// @{ #define MAX_32BIT_INT 2147483647 ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with only its first character capitalized. /// std::string capitalize( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return centered in a string of length width. Padding is done using spaces. /// std::string center( const std::string & str, int width ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the number of occurrences of substring sub in string S[start:end]. Optional /// arguments start and end are interpreted as in slice notation. /// int count( const std::string & str, const std::string & substr, int start = 0, int end = MAX_32BIT_INT); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return True if the string ends with the specified suffix, otherwise return False. With /// optional start, test beginning at that position. With optional end, stop comparing at that position. /// bool endswith( const std::string & str, const std::string & suffix, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string where all tab characters are expanded using spaces. If tabsize /// is not given, a tab size of 8 characters is assumed. /// std::string expandtabs( const std::string & str, int tabsize = 8); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the lowest index in the string where substring sub is found, such that sub is /// contained in the range [start, end). Optional arguments start and end are interpreted as /// in slice notation. Return -1 if sub is not found. /// int find( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Synonym of find right now. Python version throws exceptions. This one currently doesn't /// int index( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all characters in the string are alphanumeric and there is at least one /// character, false otherwise. /// bool isalnum( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all characters in the string are alphabetic and there is at least one /// character, false otherwise /// bool isalpha( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all characters in the string are digits and there is at least one /// character, false otherwise. /// bool isdigit( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all cased characters in the string are lowercase and there is at least one /// cased character, false otherwise. /// bool islower( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if there are only whitespace characters in the string and there is at least /// one character, false otherwise. /// bool isspace( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if the string is a titlecased string and there is at least one character, /// i.e. uppercase characters may only follow uncased characters and lowercase characters only /// cased ones. Return false otherwise. /// bool istitle( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return true if all cased characters in the string are uppercase and there is at least one /// cased character, false otherwise. /// bool isupper( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a string which is the concatenation of the strings in the sequence seq. /// The separator between elements is the str argument /// std::string join( const std::string & str, const std::vector< std::string > & seq ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the string left justified in a string of length width. Padding is done using /// spaces. The original string is returned if width is less than str.size(). /// std::string ljust( const std::string & str, int width ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string converted to lowercase. /// std::string lower( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with leading characters removed. If chars is omitted or None, /// whitespace characters are removed. If given and not "", chars must be a string; the /// characters in the string will be stripped from the beginning of the string this method /// is called on (argument "str" ). /// std::string lstrip( const std::string & str, const std::string & chars = "" ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string, concatenated N times, together. /// Corresponds to the __mul__ operator. /// std::string mul( const std::string & str, int n); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the string around first occurance of sep. /// Three strings will always placed into result. If sep is found, the strings will /// be the text before sep, sep itself, and the remaining text. If sep is /// not found, the original string will be returned with two empty strings. /// void partition( const std::string & str, const std::string & sep, std::vector< std::string > & result ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with all occurrences of substring old replaced by new. If /// the optional argument count is given, only the first count occurrences are replaced. /// std::string replace( const std::string & str, const std::string & oldstr, const std::string & newstr, int count = -1); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the highest index in the string where substring sub is found, such that sub is /// contained within s[start,end]. Optional arguments start and end are interpreted as in /// slice notation. Return -1 on failure. /// int rfind( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Currently a synonym of rfind. The python version raises exceptions. This one currently /// does not /// int rindex( const std::string & str, const std::string & sub, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the string right justified in a string of length width. Padding is done using /// spaces. The original string is returned if width is less than str.size(). /// std::string rjust( const std::string & str, int width); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the string around last occurance of sep. /// Three strings will always placed into result. If sep is found, the strings will /// be the text before sep, sep itself, and the remaining text. If sep is /// not found, the original string will be returned with two empty strings. /// void rpartition( const std::string & str, const std::string & sep, std::vector< std::string > & result ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with trailing characters removed. If chars is "", whitespace /// characters are removed. If not "", the characters in the string will be stripped from the /// end of the string this method is called on. /// std::string rstrip( const std::string & str, const std::string & chars = "" ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Fills the "result" list with the words in the string, using sep as the delimiter string. /// If maxsplit is > -1, at most maxsplit splits are done. If sep is "", /// any whitespace string is a separator. /// void split( const std::string & str, std::vector< std::string > & result, const std::string & sep = "", int maxsplit = -1); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Fills the "result" list with the words in the string, using sep as the delimiter string. /// Does a number of splits starting at the end of the string, the result still has the /// split strings in their original order. /// If maxsplit is > -1, at most maxsplit splits are done. If sep is "", /// any whitespace string is a separator. /// void rsplit( const std::string & str, std::vector< std::string > & result, const std::string & sep = "", int maxsplit = -1); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a list of the lines in the string, breaking at line boundaries. Line breaks /// are not included in the resulting list unless keepends is given and true. /// void splitlines( const std::string & str, std::vector< std::string > & result, bool keepends = false ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return True if string starts with the prefix, otherwise return False. With optional start, /// test string beginning at that position. With optional end, stop comparing string at that /// position /// bool startswith( const std::string & str, const std::string & prefix, int start = 0, int end = MAX_32BIT_INT ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with leading and trailing characters removed. If chars is "", /// whitespace characters are removed. If given not "", the characters in the string will be /// stripped from the both ends of the string this method is called on. /// std::string strip( const std::string & str, const std::string & chars = "" ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string with uppercase characters converted to lowercase and vice versa. /// std::string swapcase( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a titlecased version of the string: words start with uppercase characters, /// all remaining cased characters are lowercase. /// std::string title( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string where all characters occurring in the optional argument /// deletechars are removed, and the remaining characters have been mapped through the given /// translation table, which must be a string of length 256. /// std::string translate( const std::string & str, const std::string & table, const std::string & deletechars = ""); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a copy of the string converted to uppercase. /// std::string upper( const std::string & str ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the numeric string left filled with zeros in a string of length width. The original /// string is returned if width is less than str.size(). /// std::string zfill( const std::string & str, int width ); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief function matching python's slice functionality. /// std::string slice( const std::string & str, int start = 0, int end = MAX_32BIT_INT); /// /// @ } /// namespace os { namespace path { // All of the function below have three versions. // Example: // join(...) // join_nt(...) // join_posix(...) // // The regular function dispatches to the other versions - based on the OS // at compile time - to match the result you'd get from the python // interepreter on the same operating system // // Should you want to 'lock off' to a particular version of the string // manipulation across *all* operating systems, use the version with the // _OS you are interested in. I.e., you can use posix style path joining, // even on Windows, with join_posix. // // The naming, (nt, posix) matches the cpython source implementation. ////////////////////////////////////////////////////////////////////////////////////////////// /// @defgroup functions pystring::os::path /// @{ ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the base name of pathname path. This is the second half of the pair returned /// by split(path). Note that the result of this function is different from the Unix basename /// program; where basename for '/foo/bar/' returns 'bar', the basename() function returns an /// empty string (''). std::string basename(const std::string & path); std::string basename_nt(const std::string & path); std::string basename_posix(const std::string & path); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return the directory name of pathname path. This is the first half of the pair /// returned by split(path). std::string dirname(const std::string & path); std::string dirname_nt(const std::string & path); std::string dirname_posix(const std::string & path); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return True if path is an absolute pathname. On Unix, that means it begins with a /// slash, on Windows that it begins with a (back)slash after chopping off a potential drive /// letter. bool isabs(const std::string & path); bool isabs_nt(const std::string & path); bool isabs_posix(const std::string & s); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Return a normalized absolutized version of the pathname path. /// /// NOTE: This differs from the interface of the python equivalent in that it requires you /// to pass in the current working directory as an argument. std::string abspath(const std::string & path, const std::string & cwd); std::string abspath_nt(const std::string & path, const std::string & cwd); std::string abspath_posix(const std::string & path, const std::string & cwd); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Join one or more path components intelligently. If any component is an absolute /// path, all previous components (on Windows, including the previous drive letter, if there /// was one) are thrown away, and joining continues. The return value is the concatenation of /// path1, and optionally path2, etc., with exactly one directory separator (os.sep) inserted /// between components, unless path2 is empty. Note that on Windows, since there is a current /// directory for each drive, os.path.join("c:", "foo") represents a path relative to the /// current directory on drive C: (c:foo), not c:\foo. /// This dispatches based on the compilation OS std::string join(const std::string & path1, const std::string & path2); std::string join_nt(const std::string & path1, const std::string & path2); std::string join_posix(const std::string & path1, const std::string & path2); std::string join(const std::vector< std::string > & paths); std::string join_nt(const std::vector< std::string > & paths); std::string join_posix(const std::vector< std::string > & paths); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Normalize a pathname. This collapses redundant separators and up-level references /// so that A//B, A/B/, A/./B and A/foo/../B all become A/B. It does not normalize the case /// (use normcase() for that). On Windows, it converts forward slashes to backward slashes. /// It should be understood that this may change the meaning of the path if it contains /// symbolic links! std::string normpath(const std::string & path); std::string normpath_nt(const std::string & path); std::string normpath_posix(const std::string & path); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the pathname path into a pair, (head, tail) where tail is the last pathname /// component and head is everything leading up to that. The tail part will never contain a /// slash; if path ends in a slash, tail will be empty. If there is no slash in path, head /// will be empty. If path is empty, both head and tail are empty. Trailing slashes are /// stripped from head unless it is the root (one or more slashes only). In all cases, /// join(head, tail) returns a path to the same location as path (but the strings may /// differ). void split(std::string & head, std::string & tail, const std::string & path); void split_nt(std::string & head, std::string & tail, const std::string & path); void split_posix(std::string & head, std::string & tail, const std::string & path); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the pathname path into a pair (drive, tail) where drive is either a drive /// specification or the empty string. On systems which do not use drive specifications, /// drive will always be the empty string. In all cases, drive + tail will be the same as /// path. void splitdrive(std::string & drivespec, std::string & pathspec, const std::string & path); void splitdrive_nt(std::string & drivespec, std::string & pathspec, const std::string & p); void splitdrive_posix(std::string & drivespec, std::string & pathspec, const std::string & path); ////////////////////////////////////////////////////////////////////////////////////////////// /// @brief Split the pathname path into a pair (root, ext) such that root + ext == path, and /// ext is empty or begins with a period and contains at most one period. Leading periods on /// the basename are ignored; splitext('.cshrc') returns ('.cshrc', ''). void splitext(std::string & root, std::string & ext, const std::string & path); void splitext_nt(std::string & root, std::string & ext, const std::string & path); void splitext_posix(std::string & root, std::string & ext, const std::string & path); /// /// @ } /// } // namespace path } // namespace os } // namespace pystring } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/src/apps/share/argparse.cpp0000644000175000017500000003550013223553423021435 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Based on BSD-licensed software Copyright 2004 NVIDIA Corp. 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 the software's owners 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. (This is the Modified BSD License) */ #include #include #include #include #include #include #include #include #include "strutil.h" #include "argparse.h" /* OIIO_NAMESPACE_ENTER { */ class ArgOption { public: typedef int (*callback_t) (int, const char**); ArgOption (const char *str); ~ArgOption () { } int initialize (); int parameter_count () const { return m_count; } const std::string & name() const { return m_flag; } const std::string & fmt() const { return m_format; } bool is_flag () const { return m_type == Flag; } bool is_sublist () const { return m_type == Sublist; } bool is_regular () const { return m_type == Regular; } void add_parameter (int i, void *p); void set_parameter (int i, const char *argv); void add_argument (const char *argv); int invoke_callback () const; int invoke_callback (int argc, const char **argv) const { return m_callback ? m_callback (argc, argv) : 0; } void set_callback (callback_t cb) { m_callback = cb; } void found_on_command_line () { m_repetitions++; } int parsed_count () const { return m_repetitions; } void description (const char *d) { m_descript = d; } const std::string & description() const { return m_descript; } private: enum OptionType { None, Regular, Flag, Sublist }; std::string m_format; // original format string std::string m_flag; // just the -flag_foo part std::string m_code; // paramter types, eg "df" std::string m_descript; OptionType m_type; int m_count; // number of parameters std::vector m_param; // pointers to app data vars callback_t m_callback; int m_repetitions; // number of times on cmd line std::vector m_argv; }; // Constructor. Does not do any parsing or error checking. // Make sure to call initialize() right after construction. ArgOption::ArgOption (const char *str) : m_format(str), m_type(None), m_count(0), m_callback(NULL), m_repetitions(0) { } // Parses the format string ("-option %s %d %f") to extract the // flag ("-option") and create a code string ("sdf"). After the // code string is created, the param list of void* pointers is // allocated to hold the argument variable pointers. int ArgOption::initialize() { size_t n; const char *s; if (m_format.empty() || m_format == "%*") { m_type = Sublist; m_count = 1; // sublist callback function pointer m_code = "*"; m_flag = ""; } else if (m_format == "") { } else { // extract the flag name s = &m_format[0]; assert(*s == '-'); assert(isalpha(s[1]) || (s[1] == '-' && isalpha(s[2]))); s++; if (*s == '-') s++; while (isalnum(*s) || *s == '_' || *s == '-') s++; if (! *s) { m_flag = m_format; m_type = Flag; m_count = 1; m_code = "b"; } else { n = s - (&m_format[0]); m_flag.assign (m_format.begin(), m_format.begin()+n); // Parse the scanf-like parameters m_type = Regular; n = (m_format.length() - n) / 2; // conservative estimate m_code.clear (); while (*s != '\0') { if (*s == '%') { s++; assert(*s != '\0'); m_count++; // adding another parameter switch (*s) { case 'd': // 32bit int case 'g': // float case 'f': // float case 'F': // double case 's': // string case 'L': // vector assert (m_type == Regular); m_code += *s; break; case '*': assert(m_count == 1); m_type = Sublist; break; default: std::cerr << "Programmer error: Unknown option "; std::cerr << "type string \"" << *s << "\"" << "\n"; abort(); } } s++; } } } // Allocate space for the parameter pointers and initialize to NULL m_param.resize (m_count, NULL); return 0; } // Stores the pointer to an argument in the param list and // initializes flag options to FALSE. // FIXME -- there is no such initialization. Bug? void ArgOption::add_parameter (int i, void *p) { assert (i >= 0 && i < m_count); m_param[i] = p; } // Given a string from argv, set the associated option parameter // at index i using the format conversion code in the code string. void ArgOption::set_parameter (int i, const char *argv) { assert(i < m_count); switch (m_code[i]) { case 'd': *(int *)m_param[i] = atoi(argv); break; case 'f': case 'g': *(float *)m_param[i] = (float)atof(argv); break; case 'F': *(double *)m_param[i] = atof(argv); break; case 's': *(std::string *)m_param[i] = argv; break; case 'S': *(std::string *)m_param[i] = argv; break; case 'L': ((std::vector *)m_param[i])->push_back (argv); break; case 'b': *(bool *)m_param[i] = true; break; case '*': default: abort(); } } // Call the sublist callback if any arguments have been parsed int ArgOption::invoke_callback () const { assert (m_count == 1); int argc = (int) m_argv.size(); if (argc == 0) return 0; // Convert the argv's to char*[] const char **myargv = (const char **) alloca (argc * sizeof(const char *)); for (int i = 0; i < argc; ++i) myargv[i] = m_argv[i].c_str(); return invoke_callback (argc, myargv); } // Add an argument to this sublist option void ArgOption::add_argument (const char *argv) { m_argv.push_back (argv); } ArgParse::ArgParse (int argc, const char **argv) : m_argc(argc), m_argv(argv), m_global(NULL) { } ArgParse::~ArgParse() { for (unsigned int i=0; ifound_on_command_line(); if (option->is_flag()) { option->set_parameter(0, NULL); } else { assert (option->is_regular()); for (int j = 0; j < option->parameter_count(); j++) { if (j+i+1 >= m_argc) { error ("Missing parameter %d from option " "\"%s\"", j+1, option->name().c_str()); return -1; } option->set_parameter (j, m_argv[i+j+1]); } i += option->parameter_count(); } } else { // not an option nor an option parameter, glob onto global list if (m_global) m_global->invoke_callback (1, m_argv+i); else { error ("Argument \"%s\" does not have an associated " "option", m_argv[i]); return -1; } } } return 0; } // Primary entry point. This function accepts a set of format strings // and variable pointers. Each string contains an option name and a // scanf-like format string to enumerate the arguments of that option // (eg. "-option %d %f %s"). The format string is followed by a list // of pointers to the argument variables, just like scanf. All format // strings and arguments are parsed to create a list of ArgOption objects. // After all ArgOptions are created, the command line is parsed and // the sublist option callbacks are invoked. int ArgParse::options (const char *intro, ...) { va_list ap; va_start (ap, intro); m_intro = intro; for (const char *cur = va_arg(ap, char *); cur; cur = va_arg(ap, char *)) { if (find_option (cur) && strcmp(cur, "")) { error ("Option \"%s\" is multiply defined", cur); return -1; } // Build a new option and then parse the values ArgOption *option = new ArgOption (cur); if (option->initialize() < 0) { return -1; } if (cur[0] == '\0' || (cur[0] == '%' && cur[1] == '*' && cur[2] == '\0')) { // set default global option m_global = option; } // Grab any parameters and store them with this option for (int i = 0; i < option->parameter_count(); i++) { void *p = va_arg (ap, void *); if (p == NULL) { error ("Missing argument parameter for \"%s\"", option->name().c_str()); return -1; } option->add_parameter (i, p); if (option == m_global) option->set_callback ((ArgOption::callback_t)p); } // Last argument is description option->description ((const char *) va_arg (ap, const char *)); m_option.push_back(option); } va_end (ap); return 0; } // Find an option by name in the option vector ArgOption * ArgParse::find_option (const char *name) { for (std::vector::const_iterator i = m_option.begin(); i != m_option.end(); i++) { const char *opt = (*i)->name().c_str(); if (! strcmp(name, opt)) return *i; // Match even if the user mixes up one dash or two if (name[0] == '-' && name[1] == '-' && opt[0] == '-' && opt[1] != '-') if (! strcmp (name+1, opt)) return *i; if (name[0] == '-' && name[1] != '-' && opt[0] == '-' && opt[1] == '-') if (! strcmp (name, opt+1)) return *i; } return NULL; } int ArgParse::found (const char *option_name) { ArgOption *option = find_option(option_name); if (option == NULL) return 0; return option->parsed_count(); } void ArgParse::error (const char *format, ...) { va_list ap; va_start (ap, format); m_errmessage = Strutil::vformat (format, ap); va_end (ap); } std::string ArgParse::geterror () const { std::string e = m_errmessage; m_errmessage.clear (); return e; } void ArgParse::usage () const { const size_t longline = 40; std::cout << m_intro << '\n'; size_t maxlen = 0; for (unsigned int i=0; ifmt().length(); // Option lists > 40 chars will be split into multiple lines if (fmtlen < longline) maxlen = std::max (maxlen, fmtlen); } for (unsigned int i=0; idescription().length()) { size_t fmtlen = opt->fmt().length(); if (opt->fmt() == "") std::cout << opt->description() << '\n'; else if (fmtlen < longline) std::cout << " " << opt->fmt() << std::string (maxlen + 2 - fmtlen, ' ') << opt->description() << '\n'; else std::cout << " " << opt->fmt() << "\n " << std::string (maxlen + 2, ' ') << opt->description() << '\n'; } } } std::string ArgParse::command_line () const { std::string s; for (int i = 0; i < m_argc; ++i) { if (strchr (m_argv[i], ' ')) { s += '\"'; s += m_argv[i]; s += '\"'; } else { s += m_argv[i]; } if (i < m_argc-1) s += ' '; } return s; } /* } OIIO_NAMESPACE_EXIT */ opencolorio-1.1.0~dfsg0.orig/src/apps/share/strutil.cpp0000644000175000017500000000611213223553423021334 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. 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 the software's owners 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. (This is the Modified BSD License) */ #include #include #include #include #include #include #include "strutil.h" std::string Strutil::vformat (const char *fmt, va_list ap) { // Allocate a buffer on the stack that's big enough for us almost // all the time. Be prepared to allocate dynamically if it doesn't fit. size_t size = 1024; char stackbuf[1024]; std::vector dynamicbuf; char *buf = &stackbuf[0]; while (1) { // Try to vsnprintf into our buffer. va_list apsave; #ifdef va_copy va_copy (apsave, ap); #else apsave = ap; #endif int needed = vsnprintf (buf, size, fmt, ap); va_end (ap); // NB. C99 (which modern Linux and OS X follow) says vsnprintf // failure returns the length it would have needed. But older // glibc and current Windows return -1 for failure, i.e., not // telling us how much was needed. if (needed < (int)size && needed >= 0) { // It fit fine so we're done. return std::string (buf, (size_t) needed); } // vsnprintf reported that it wanted to write more characters // than we allotted. So try again using a dynamic buffer. This // doesn't happen very often if we chose our initial size well. size = (needed > 0) ? (needed+1) : (size*2); dynamicbuf.resize (size); buf = &dynamicbuf[0]; #ifdef va_copy va_copy (ap, apsave); #else ap = apsave; #endif } } opencolorio-1.1.0~dfsg0.orig/src/apps/share/argparse.h0000644000175000017500000001513313223553423021102 0ustar mfvmfv/* Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Based on BSD-licensed software Copyright 2004 NVIDIA Corp. 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 the software's owners 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. (This is the Modified BSD License) */ /// \file /// \brief Simple parsing of program command-line arguments. #ifndef OPENCOLORIO_ARGPARSE_H #define OPENCOLORIO_ARGPARSE_H #include #ifndef OPENCOLORIO_PRINTF_ARGS /* See comments in strutil.h */ # ifndef __GNUC__ # define __attribute__(x) # endif # define OPENCOLORIO_PRINTF_ARGS(fmtarg_pos, vararg_pos) \ __attribute__ ((format (printf, fmtarg_pos, vararg_pos) )) #endif /* OIIO_NAMESPACE_ENTER { */ class ArgOption; // Forward declaration ///////////////////////////////////////////////////////////////////////////// /// /// \class ArgParse /// /// Argument Parsing /// /// The parse function takes a list of options and variables or functions /// for storing option values and return <0 on failure: /// /// \code /// static int /// parse_files (int argc, const char *argv[]) /// { /// for (int i = 0; i < argc; i++) /// filenames.push_back (argv[i]); /// return 0; /// } /// /// ... /// /// ArgParse ap; /// /// ap.options ("Usage: myapp [options] filename...", /// "%*", parse_objects, "", /// "-camera %f %f %f", &camera[0], &camera[1], &camera[2], /// "set the camera position", /// "-lookat %f %f %f", &lx, &ly, &lz, /// "set the position of interest", /// "-oversampling %d", &oversampling, "oversamping rate", /// "-passes %d", &passes, "number of passes", /// "-lens %f %f %f", &aperture, &focalDistance, &focalLength, /// "set aperture, focal distance, focal length", /// "-format %d %d %f", &width, &height, &aspect, /// "set width, height, aspect ratio", /// "-v", &flag, "verbose output", /// NULL); /// /// if (ap.parse (argc, argv) < 0) { /// std::cerr << ap.geterror() << std::endl; /// ap.usage (); /// return EXIT_FAILURE; /// } /// \endcode /// /// The available argument types are: /// - no \% argument - bool flag /// - \%d - 32bit integer /// - \%f - 32bit float /// - \%F - 64bit float (double) /// - \%s - std::string /// - \%L - std::vector (takes 1 arg, appends to list) /// - \%* - catch all non-options and pass individually as an (argc,argv) /// sublist to a callback, each immediately after it's found /// /// There are several special format tokens: /// - "" - not an option at all, just a description to print /// in the usage output. /// /// Notes: /// - If an option doesn't have any arguments, a flag argument is assumed. /// - Flags are initialized to false. No other variables are initialized. /// - The empty string, "", is used as a global sublist (ie. "%*"). /// - Sublist functions are all of the form "int func(int argc, char **argv)". /// - If a sublist function returns -1, parse() will terminate early. /// ///////////////////////////////////////////////////////////////////////////// class ArgParse { public: ArgParse (int argc=0, const char **argv=NULL); ~ArgParse (); /// Declare the command line options. After the introductory /// message, parameters are a set of format strings and variable /// pointers. Each string contains an option name and a scanf-like /// format string to enumerate the arguments of that option /// (eg. "-option %d %f %s"). The format string is followed by a /// list of pointers to the argument variables, just like scanf. A /// NULL terminates the list. int options (const char *intro, ...); /// With the options already set up, parse the command line. /// Return 0 if ok, -1 if it's a malformed command line. int parse (int argc, const char **argv); /// Return any error messages generated during the course of parse() /// (and clear any error flags). If no error has occurred since the /// last time geterror() was called, it will return an empty string. std::string geterror () const; /// Deprecated /// std::string error_message () const { return geterror (); } /// Print the usage message to stdout. The usage message is /// generated and formatted automatically based on the command and /// description arguments passed to parse(). void usage () const; /// Return the entire command-line as one string. /// std::string command_line () const; private: int m_argc; // a copy of the command line argc const char **m_argv; // a copy of the command line argv mutable std::string m_errmessage; // error message ArgOption *m_global; // option for extra cmd line arguments std::string m_intro; std::vector m_option; ArgOption *find_option(const char *name); void error (const char *format, ...) OPENCOLORIO_PRINTF_ARGS(2,3); int found (const char *option); // number of times option was parsed }; /* } OIIO_NAMESPACE_EXIT */ #endif // OPENCOLORIO_ARGPARSE_H opencolorio-1.1.0~dfsg0.orig/src/apps/share/pystring.cpp0000644000175000017500000011124313223553423021507 0ustar mfvmfv/////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2008-2010, Sony Pictures Imageworks Inc // 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 the organization 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 #include "pystring.h" #include #include #include #include #include OCIO_NAMESPACE_ENTER { namespace pystring { #if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) || defined(_MSC_VER) #ifndef WINDOWS #define WINDOWS #endif #endif // This definition codes from configure.in in the python src. // Strictly speaking this limits us to str sizes of 2**31. // Should we wish to handle this limit, we could use an architecture // specific #defines and read from ssize_t (unistd.h) if the header exists. // But in the meantime, the use of int assures maximum arch compatibility. // This must also equal the size used in the end = MAX_32BIT_INT default arg. typedef int Py_ssize_t; /* helper macro to fixup start/end slice values */ #define ADJUST_INDICES(start, end, len) \ if (end > len) \ end = len; \ else if (end < 0) { \ end += len; \ if (end < 0) \ end = 0; \ } \ if (start < 0) { \ start += len; \ if (start < 0) \ start = 0; \ } namespace { ////////////////////////////////////////////////////////////////////////////////////////////// /// why doesn't the std::reverse work? /// void reverse_strings( std::vector< std::string > & result) { for (std::vector< std::string >::size_type i = 0; i < result.size() / 2; i++ ) { std::swap(result[i], result[result.size() - 1 - i]); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void split_whitespace( const std::string & str, std::vector< std::string > & result, int maxsplit ) { std::string::size_type i, j, len = str.size(); for (i = j = 0; i < len; ) { while ( i < len && ::isspace( str[i] ) ) i++; j = i; while ( i < len && ! ::isspace( str[i]) ) i++; if (j < i) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( j, i - j )); while ( i < len && ::isspace( str[i])) i++; j = i; } } if (j < len) { result.push_back( str.substr( j, len - j )); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void rsplit_whitespace( const std::string & str, std::vector< std::string > & result, int maxsplit ) { std::string::size_type len = str.size(); std::string::size_type i, j; for (i = j = len; i > 0; ) { while ( i > 0 && ::isspace( str[i - 1] ) ) i--; j = i; while ( i > 0 && ! ::isspace( str[i - 1]) ) i--; if (j > i) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( i, j - i )); while ( i > 0 && ::isspace( str[i - 1])) i--; j = i; } } if (j > 0) { result.push_back( str.substr( 0, j )); } //std::reverse( result, result.begin(), result.end() ); reverse_strings( result ); } } //anonymous namespace ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void split( const std::string & str, std::vector< std::string > & result, const std::string & sep, int maxsplit ) { result.clear(); if ( maxsplit < 0 ) maxsplit = MAX_32BIT_INT;//result.max_size(); if ( sep.size() == 0 ) { split_whitespace( str, result, maxsplit ); return; } std::string::size_type i,j, len = str.size(), n = sep.size(); i = j = 0; while ( i+n <= len ) { if ( str[i] == sep[0] && str.substr( i, n ) == sep ) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( j, i - j ) ); i = j = i + n; } else { i++; } } result.push_back( str.substr( j, len-j ) ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void rsplit( const std::string & str, std::vector< std::string > & result, const std::string & sep, int maxsplit ) { if ( maxsplit < 0 ) { split( str, result, sep, 0 ); return; } result.clear(); if ( sep.size() == 0 ) { rsplit_whitespace( str, result, maxsplit ); return; } std::string::size_type i,j, len = str.size(), n = sep.size(); i = j = len; while ( i > n ) { if ( str[i - 1] == sep[n - 1] && str.substr( i - n, n ) == sep ) { if ( maxsplit-- <= 0 ) break; result.push_back( str.substr( i, j - i ) ); i = j = i - n; } else { i--; } } result.push_back( str.substr( 0, j ) ); reverse_strings( result ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// #define LEFTSTRIP 0 #define RIGHTSTRIP 1 #define BOTHSTRIP 2 ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string do_strip( const std::string & str, int striptype, const std::string & chars ) { Py_ssize_t len = (Py_ssize_t) str.size(), i, j, charslen = (Py_ssize_t) chars.size(); if ( charslen == 0 ) { i = 0; if ( striptype != RIGHTSTRIP ) { while ( i < len && ::isspace( str[i] ) ) { i++; } } j = len; if ( striptype != LEFTSTRIP ) { do { j--; } while (j >= i && ::isspace(str[j])); j++; } } else { const char * sep = chars.c_str(); i = 0; if ( striptype != RIGHTSTRIP ) { while ( i < len && memchr(sep, str[i], charslen) ) { i++; } } j = len; if (striptype != LEFTSTRIP) { do { j--; } while (j >= i && memchr(sep, str[j], charslen) ); j++; } } if ( i == 0 && j == len ) { return str; } else { return str.substr( i, j - i ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void partition( const std::string & str, const std::string & sep, std::vector< std::string > & result ) { result.resize(3); int index = find( str, sep ); if ( index < 0 ) { result[0] = str; result[1] = ""; result[2] = ""; } else { result[0] = str.substr( 0, index ); result[1] = sep; result[2] = str.substr( index + sep.size(), str.size() ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void rpartition( const std::string & str, const std::string & sep, std::vector< std::string > & result ) { result.resize(3); int index = rfind( str, sep ); if ( index < 0 ) { result[0] = ""; result[1] = ""; result[2] = str; } else { result[0] = str.substr( 0, index ); result[1] = sep; result[2] = str.substr( index + sep.size(), str.size() ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string strip( const std::string & str, const std::string & chars ) { return do_strip( str, BOTHSTRIP, chars ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string lstrip( const std::string & str, const std::string & chars ) { return do_strip( str, LEFTSTRIP, chars ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string rstrip( const std::string & str, const std::string & chars ) { return do_strip( str, RIGHTSTRIP, chars ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string join( const std::string & str, const std::vector< std::string > & seq ) { std::vector< std::string >::size_type seqlen = seq.size(), i; if ( seqlen == 0 ) return ""; if ( seqlen == 1 ) return seq[0]; std::string result( seq[0] ); for ( i = 1; i < seqlen; ++i ) { result += str + seq[i]; } return result; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// namespace { /* Matches the end (direction >= 0) or start (direction < 0) of self * against substr, using the start and end arguments. Returns * -1 on error, 0 if not found and 1 if found. */ int _string_tailmatch(const std::string & self, const std::string & substr, Py_ssize_t start, Py_ssize_t end, int direction) { Py_ssize_t len = (Py_ssize_t) self.size(); Py_ssize_t slen = (Py_ssize_t) substr.size(); const char* sub = substr.c_str(); const char* str = self.c_str(); ADJUST_INDICES(start, end, len); if (direction < 0) { // startswith if (start+slen > len) return 0; } else { // endswith if (end-start < slen || start > len) return 0; if (end-slen > start) start = end - slen; } if (end-start >= slen) return (!std::memcmp(str+start, sub, slen)); return 0; } } bool endswith( const std::string & str, const std::string & suffix, int start, int end ) { int result = _string_tailmatch(str, suffix, (Py_ssize_t) start, (Py_ssize_t) end, +1); //if (result == -1) // TODO: Error condition return result == 1; } bool startswith( const std::string & str, const std::string & prefix, int start, int end ) { int result = _string_tailmatch(str, prefix, (Py_ssize_t) start, (Py_ssize_t) end, -1); //if (result == -1) // TODO: Error condition return result == 1; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isalnum( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::isalnum( str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::isalnum( str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isalpha( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::isalpha( (int) str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::isalpha( (int) str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isdigit( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::isdigit( str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::isdigit( str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool islower( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::islower( str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::islower( str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isspace( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::isspace( str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::isspace( str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool istitle( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if ( len == 1 ) { return ::isupper( str[0] ) != 0; } bool cased = false, previous_is_cased = false; for ( i = 0; i < len; ++i ) { if ( ::isupper( str[i] ) ) { if ( previous_is_cased ) { return false; } previous_is_cased = true; cased = true; } else if ( ::islower( str[i] ) ) { if (!previous_is_cased) { return false; } previous_is_cased = true; cased = true; } else { previous_is_cased = false; } } return cased; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// bool isupper( const std::string & str ) { std::string::size_type len = str.size(), i; if ( len == 0 ) return false; if( len == 1 ) { return ::isupper( str[0] ) != 0; } for ( i = 0; i < len; ++i ) { if ( ::isupper( str[i] ) == 0 ) return false; } return true; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string capitalize( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; if ( len > 0) { if (::islower(s[0])) s[0] = (char) ::toupper( s[0] ); } for ( i = 1; i < len; ++i ) { if (::isupper(s[i])) s[i] = (char) ::tolower( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string lower( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; for ( i = 0; i < len; ++i ) { if ( ::isupper( s[i] ) ) s[i] = (char) ::tolower( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string upper( const std::string & str ) { std::string s( str ) ; std::string::size_type len = s.size(), i; for ( i = 0; i < len; ++i ) { if ( ::islower( s[i] ) ) s[i] = (char) ::toupper( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string swapcase( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; for ( i = 0; i < len; ++i ) { if ( ::islower( s[i] ) ) s[i] = (char) ::toupper( s[i] ); else if (::isupper( s[i] ) ) s[i] = (char) ::tolower( s[i] ); } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string title( const std::string & str ) { std::string s( str ); std::string::size_type len = s.size(), i; bool previous_is_cased = false; for ( i = 0; i < len; ++i ) { int c = s[i]; if ( ::islower(c) ) { if ( !previous_is_cased ) { s[i] = (char) ::toupper(c); } previous_is_cased = true; } else if ( ::isupper(c) ) { if ( previous_is_cased ) { s[i] = (char) ::tolower(c); } previous_is_cased = true; } else { previous_is_cased = false; } } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string translate( const std::string & str, const std::string & table, const std::string & deletechars ) { std::string s; std::string::size_type len = str.size(), dellen = deletechars.size(); if ( table.size() != 256 ) { // TODO : raise exception instead return str; } //if nothing is deleted, use faster code if ( dellen == 0 ) { s = str; for ( std::string::size_type i = 0; i < len; ++i ) { s[i] = table[ s[i] ]; } return s; } int trans_table[256]; for ( int i = 0; i < 256; i++) { trans_table[i] = table[i]; } for ( std::string::size_type i = 0; i < dellen; i++) { trans_table[(int) deletechars[i] ] = -1; } for ( std::string::size_type i = 0; i < len; ++i ) { if ( trans_table[ (int) str[i] ] != -1 ) { s += table[ str[i] ]; } } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string zfill( const std::string & str, int width ) { int len = (int)str.size(); if ( len >= width ) { return str; } std::string s( str ); int fill = width - len; s = std::string( fill, '0' ) + s; if ( s[fill] == '+' || s[fill] == '-' ) { s[0] = s[fill]; s[fill] = '0'; } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string ljust( const std::string & str, int width ) { std::string::size_type len = str.size(); if ( (( int ) len ) >= width ) return str; return str + std::string( width - len, ' ' ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string rjust( const std::string & str, int width ) { std::string::size_type len = str.size(); if ( (( int ) len ) >= width ) return str; return std::string( width - len, ' ' ) + str; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string center( const std::string & str, int width ) { int len = (int) str.size(); int marg, left; if ( len >= width ) return str; marg = width - len; left = marg / 2 + (marg & width & 1); return std::string( left, ' ' ) + str + std::string( marg - left, ' ' ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string slice( const std::string & str, int start, int end ) { ADJUST_INDICES(start, end, (int) str.size()); if ( start >= end ) return ""; return str.substr( start, end - start ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int find( const std::string & str, const std::string & sub, int start, int end ) { ADJUST_INDICES(start, end, (int) str.size()); std::string::size_type result = str.find( sub, start ); // If we cannot find the string, or if the end-point of our found substring is past // the allowed end limit, return that it can't be found. if( result == std::string::npos || (result + sub.size() > (std::string::size_type)end) ) { return -1; } return (int) result; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int index( const std::string & str, const std::string & sub, int start, int end ) { return find( str, sub, start, end ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int rfind( const std::string & str, const std::string & sub, int start, int end ) { ADJUST_INDICES(start, end, (int) str.size()); std::string::size_type result = str.rfind( sub, end ); if( result == std::string::npos || result < (std::string::size_type)start || (result + sub.size() > (std::string::size_type)end)) return -1; return (int)result; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int rindex( const std::string & str, const std::string & sub, int start, int end ) { return rfind( str, sub, start, end ); } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string expandtabs( const std::string & str, int tabsize ) { std::string s( str ); std::string::size_type len = str.size(), i = 0; int offset = 0; int j = 0; for ( i = 0; i < len; ++i ) { if ( str[i] == '\t' ) { if ( tabsize > 0 ) { int fillsize = tabsize - (j % tabsize); j += fillsize; s.replace( i + offset, 1, std::string( fillsize, ' ' )); offset += fillsize - 1; } else { s.replace( i + offset, 1, "" ); offset -= 1; } } else { j++; if (str[i] == '\n' || str[i] == '\r') { j = 0; } } } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// int count( const std::string & str, const std::string & substr, int start, int end ) { int nummatches = 0; int cursor = start; while ( 1 ) { cursor = find( str, substr, cursor, end ); if ( cursor < 0 ) break; cursor += (int) substr.size(); nummatches += 1; } return nummatches; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string replace( const std::string & str, const std::string & oldstr, const std::string & newstr, int count ) { int sofar = 0; int cursor = 0; std::string s( str ); std::string::size_type oldlen = oldstr.size(), newlen = newstr.size(); while ( ( cursor = find( s, oldstr, cursor ) ) != -1 ) { if ( count > -1 && sofar >= count ) { break; } s.replace( cursor, oldlen, newstr ); cursor += (int) newlen; ++sofar; } return s; } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// void splitlines( const std::string & str, std::vector< std::string > & result, bool keepends ) { result.clear(); std::string::size_type len = str.size(), i, j, eol; for (i = j = 0; i < len; ) { while (i < len && str[i] != '\n' && str[i] != '\r') i++; eol = i; if (i < len) { if (str[i] == '\r' && i + 1 < len && str[i+1] == '\n') { i += 2; } else { i++; } if (keepends) eol = i; } result.push_back( str.substr( j, eol - j ) ); j = i; } if (j < len) { result.push_back( str.substr( j, len - j ) ); } } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string mul( const std::string & str, int n ) { // Early exits if (n <= 0) return ""; if (n == 1) return str; std::ostringstream os; for(int i=0; i & paths) { if(paths.empty()) return ""; if(paths.size() == 1) return paths[0]; std::string path = paths[0]; for(unsigned int i=1; i3) || ((path.size()==3) && !pystring::endswith(path, "/") && !pystring::endswith(path, "\\"))) { b_nts = true; } } if(b_nts) { path = b; } else { // Join, and ensure there's a separator. // assert len(path) > 0 if( pystring::endswith(path, "/") || pystring::endswith(path, "\\")) { if(pystring::startswith(b,"/") || pystring::startswith(b,"\\")) { path += pystring::slice(b, 1); } else { path += b; } } else if(pystring::endswith(path, ":")) { path += b; } else if(!b.empty()) { if(pystring::startswith(b,"/") || pystring::startswith(b,"\\")) { path += b; } else { path += "\\" + b; } } else { // path is not empty and does not end with a backslash, // but b is empty; since, e.g., split('a/') produces // ('a', ''), it's best if join() adds a backslash in // this case. path += "\\"; } } } return path; } // Join two or more pathname components, inserting "\\" as needed. std::string join_nt(const std::string & a, const std::string & b) { std::vector< std::string > paths(2); paths[0] = a; paths[1] = b; return join_nt(paths); } // Join pathnames. // If any component is an absolute path, all previous path components // will be discarded. // Ignore the previous parts if a part is absolute. // Insert a '/' unless the first part is empty or already ends in '/'. std::string join_posix(const std::vector< std::string > & paths) { if(paths.empty()) return ""; if(paths.size() == 1) return paths[0]; std::string path = paths[0]; for(unsigned int i=1; i paths(2); paths[0] = a; paths[1] = b; return join_posix(paths); } std::string join(const std::string & path1, const std::string & path2) { #ifdef WINDOWS return join_nt(path1, path2); #else return join_posix(path1, path2); #endif } std::string join(const std::vector< std::string > & paths) { #ifdef WINDOWS return join_nt(paths); #else return join_posix(paths); #endif } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// // Split a pathname. // Return (head, tail) where tail is everything after the final slash. // Either part may be empty void split_nt(std::string & head, std::string & tail, const std::string & path) { std::string d, p; splitdrive_nt(d, p, path); // set i to index beyond p's last slash int i = (int)p.size(); while(i>0 && (p[i-1] != '\\') && (p[i-1] != '/')) { i = i - 1; } head = pystring::slice(p,0,i); tail = pystring::slice(p,i); // now tail has no slashes // remove trailing slashes from head, unless it's all slashes std::string head2 = head; while(!head2.empty() && ((pystring::slice(head2,-1) == "/") || (pystring::slice(head2,-1) == "\\"))) { head2 = pystring::slice(head,0,-1); } if(!head2.empty()) head = head2; head = d + head; } // Split a path in head (everything up to the last '/') and tail (the // rest). If the path ends in '/', tail will be empty. If there is no // '/' in the path, head will be empty. // Trailing '/'es are stripped from head unless it is the root. void split_posix(std::string & head, std::string & tail, const std::string & p) { int i = pystring::rfind(p, "/") + 1; head = pystring::slice(p,0,i); tail = pystring::slice(p,i); if(!head.empty() && (head != pystring::mul("/", (int) head.size()))) { head = pystring::rstrip(head, "/"); } } void split(std::string & head, std::string & tail, const std::string & path) { #ifdef WINDOWS return split_nt(head, tail, path); #else return split_posix(head, tail, path); #endif } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// std::string basename_nt(const std::string & path) { std::string head, tail; split_nt(head, tail, path); return tail; } std::string basename_posix(const std::string & path) { std::string head, tail; split_posix(head, tail, path); return tail; } std::string basename(const std::string & path) { #ifdef WINDOWS return basename_nt(path); #else return basename_posix(path); #endif } std::string dirname_nt(const std::string & path) { std::string head, tail; split_nt(head, tail, path); return head; } std::string dirname_posix(const std::string & path) { std::string head, tail; split_posix(head, tail, path); return head; } std::string dirname(const std::string & path) { #ifdef WINDOWS return dirname_nt(path); #else return dirname_posix(path); #endif } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// // Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B. std::string normpath_nt(const std::string & p) { std::string path = p; path = pystring::replace(path, "/","\\"); std::string prefix; splitdrive_nt(prefix, path, path); // We need to be careful here. If the prefix is empty, and the path starts // with a backslash, it could either be an absolute path on the current // drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It // is therefore imperative NOT to collapse multiple backslashes blindly in // that case. // The code below preserves multiple backslashes when there is no drive // letter. This means that the invalid filename \\\a\b is preserved // unchanged, where a\\\b is normalised to a\b. It's not clear that there // is any better behaviour for such edge cases. if(prefix.empty()) { // No drive letter - preserve initial backslashes while(pystring::slice(path,0,1) == "\\") { prefix = prefix + "\\"; path = pystring::slice(path,1); } } else { // We have a drive letter - collapse initial backslashes if(pystring::startswith(path, "\\")) { prefix = prefix + "\\"; path = pystring::lstrip(path, "\\"); } } std::vector comps; pystring::split(path, comps, "\\"); int i = 0; while(i<(int)comps.size()) { if(comps[i].empty() || comps[i] == ".") { comps.erase(comps.begin()+i); } else if(comps[i] == "..") { if(i>0 && comps[i-1] != "..") { comps.erase(comps.begin()+i-1, comps.begin()+i+1); i -= 1; } else if(i == 0 && pystring::endswith(prefix, "\\")) { comps.erase(comps.begin()+i); } else { i += 1; } } else { i += 1; } } // If the path is now empty, substitute '.' if(prefix.empty() && comps.empty()) { comps.push_back("."); } return prefix + pystring::join("\\", comps); } // Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B. // It should be understood that this may change the meaning of the path // if it contains symbolic links! // Normalize path, eliminating double slashes, etc. std::string normpath_posix(const std::string & p) { if(p.empty()) return "."; std::string path = p; int initial_slashes = pystring::startswith(path,"/") ? 1 : 0; // POSIX allows one or two initial slashes, but treats three or more // as single slash. if (initial_slashes && pystring::startswith(path,"//") && !pystring::startswith(path,"///")) initial_slashes = 2; std::vector comps, new_comps; pystring::split(path, comps, "/"); for(unsigned int i=0; i 0) path = pystring::mul("/",initial_slashes) + path; if(path.empty()) return "."; return path; } std::string normpath(const std::string & path) { #ifdef WINDOWS return normpath_nt(path); #else return normpath_posix(path); #endif } ////////////////////////////////////////////////////////////////////////////////////////////// /// /// // Split the extension from a pathname. // Extension is everything from the last dot to the end, ignoring // leading dots. Returns "(root, ext)"; ext may be empty. // It is always true that root + ext == p void splitext_generic(std::string & root, std::string & ext, const std::string & p, const std::string & sep, const std::string & altsep, const std::string & extsep) { int sepIndex = pystring::rfind(p, sep); if(!altsep.empty()) { int altsepIndex = pystring::rfind(p, altsep); sepIndex = std::max(sepIndex, altsepIndex); } int dotIndex = pystring::rfind(p, extsep); if(dotIndex > sepIndex) { // Skip all leading dots int filenameIndex = sepIndex + 1; while(filenameIndex < dotIndex) { if(pystring::slice(p,filenameIndex) != extsep) { root = pystring::slice(p, 0, dotIndex); ext = pystring::slice(p, dotIndex); return; } filenameIndex += 1; } } root = p; ext = ""; } void splitext_nt(std::string & root, std::string & ext, const std::string & path) { return splitext_generic(root, ext, path, "\\", "/", "."); } void splitext_posix(std::string & root, std::string & ext, const std::string & path) { return splitext_generic(root, ext, path, "/", "", "."); } void splitext(std::string & root, std::string & ext, const std::string & path) { #ifdef WINDOWS return splitext_nt(root, ext, path); #else return splitext_posix(root, ext, path); #endif } } // namespace path } // namespace os }//namespace pystring } OCIO_NAMESPACE_EXIT opencolorio-1.1.0~dfsg0.orig/src/core_tests/0000755000175000017500000000000013223553423017227 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/src/core_tests/CMakeLists.txt0000644000175000017500000000666513223553423022004 0ustar mfvmfv############################################################################### ### CORE UNIT TESTS ### add_definitions("-DOCIO_UNIT_TEST") add_definitions("-DOCIO_SOURCE_DIR=${CMAKE_SOURCE_DIR}") include_directories( ${CMAKE_SOURCE_DIR}/export/ ${CMAKE_BINARY_DIR}/export/ ${CMAKE_SOURCE_DIR}/ext/oiio/src/include ${EXTERNAL_INCLUDE_DIRS} ) if(WIN32) # Hack to get around the "Debug" and "Release" sub directories # cmake tries to add with Windows VC+++ IDE # Set output path set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) # For multi-config builds (e.g. msvc) foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} ) string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR} ) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR} ) set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_CURRENT_BINARY_DIR} ) endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES ) endif() ## do not link with OpenColorIO since we reuse the sources files to build this app (avoid double link definition) file( GLOB_RECURSE core_test_src_files "${CMAKE_SOURCE_DIR}/src/core/*.cpp" ) add_executable(ocio_core_tests ${EXTERNAL_OBJECTS} ${core_test_src_files}) set_target_properties(ocio_core_tests PROPERTIES COMPILE_FLAGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}) if(USE_EXTERNAL_TINYXML) target_link_libraries(ocio_core_tests ${TINYXML_LIBRARIES}) else(USE_EXTERNAL_TINYXML) add_dependencies(ocio_core_tests TINYXML_LIB) endif(USE_EXTERNAL_TINYXML) if(USE_EXTERNAL_YAML) target_link_libraries(ocio_core_tests ${YAML_CPP_LIBRARIES}) else(USE_EXTERNAL_YAML) add_dependencies(ocio_core_tests YAML_CPP_LIB) endif(USE_EXTERNAL_YAML) if(EXTERNAL_LIBRARIES) target_link_libraries(ocio_core_tests ${EXTERNAL_LIBRARIES}) endif() set_target_properties(ocio_core_tests PROPERTIES COMPILE_FLAGS "${EXTERNAL_COMPILE_FLAGS}" LINK_FLAGS "${EXTERNAL_LINK_FLAGS}" ## to avoid import/export link dll incoherences (since we build an app with OpenColorIO sources) COMPILE_DEFINITIONS OpenColorIO_STATIC ) ############################################################################### ### CTEST ### set(OCIO_TEST_AREA ${CMAKE_CURRENT_BINARY_DIR}) if(UNIX) message(STATUS "Create ocio_core_tests.sh.in from ocio_core_tests.sh") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ocio_core_tests.sh.in ${CMAKE_CURRENT_BINARY_DIR}/ocio_core_tests.sh @ONLY) add_custom_target(MainTests COMMAND /bin/sh ${CMAKE_CURRENT_BINARY_DIR}/ocio_core_tests.sh DEPENDS ocio_core_tests COMMENT "Setting Up and Running OCIO UNIT tests") else() message(STATUS "Create ocio_core_tests.bat.in from ocio_core_tests.bat") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ocio_core_tests.bat.in ${CMAKE_CURRENT_BINARY_DIR}/ocio_core_tests.bat @ONLY) add_custom_target(MainTests COMMAND ${CMAKE_CURRENT_BINARY_DIR}/ocio_core_tests.bat DEPENDS ocio_core_tests COMMENT "Setting Up and Running OCIO UNIT tests") endif() add_test(ocio_core_tests "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target MainTests) opencolorio-1.1.0~dfsg0.orig/src/core_tests/ocio_core_tests.sh.in0000644000175000017500000000036113223553423023353 0ustar mfvmfv#!/bin/sh OCIO_TEST_AREA=@OCIO_TEST_AREA@ \ OCIO_DATA_ROOT=@OCIO_TEST_AREA@/test_search \ OCIO_TEST1=foobar \ OCIO_JOB=meatballs \ OCIO_SEQ=cheesecake \ OCIO_SHOT=mb-cc-001 \ @CMAKE_CURRENT_BINARY_DIR@/ocio_core_tests --log_level=test_suite;opencolorio-1.1.0~dfsg0.orig/src/core_tests/ocio_core_tests.bat.in0000644000175000017500000000041313223553423023505 0ustar mfvmfv@echo off set OCIO_TEST_AREA=@OCIO_TEST_AREA@ set OCIO_DATA_ROOT=@OCIO_TEST_AREA@/test_search set OCIO_TEST1=foobar set OCIO_JOB=meatballs set OCIO_SEQ=cheesecake set OCIO_SHOT=mb-cc-001 @CMAKE_CURRENT_BINARY_DIR@/ocio_core_tests.exe --log_level=test_suiteopencolorio-1.1.0~dfsg0.orig/CMakeLists.txt0000644000175000017500000007352313223553423017040 0ustar mfvmfvproject(OpenColorIO) set(OCIO_VERSION_MAJOR 1) set(OCIO_VERSION_MINOR 1) set(OCIO_VERSION_PATCH 0) cmake_minimum_required(VERSION 2.8) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/share/cmake) if(NOT DEFINED CMAKE_FIRST_RUN) SET(CMAKE_FIRST_RUN 1 CACHE INTERNAL "") endif() ############################################################################### ### GLOBAL ### set_property(GLOBAL PROPERTY USE_FOLDERS ON) option(OCIO_BUILD_SHARED "Set to OFF to disable building the shared core library" ON) option(OCIO_BUILD_STATIC "Set to OFF to disable building the static core library" ON) option(OCIO_BUILD_TRUELIGHT "Set to OFF to disable truelight" ON) option(OCIO_BUILD_APPS "Set to OFF to disable command-line apps" ON) option(OCIO_BUILD_NUKE "Set to OFF to disable building nuke plugins" ON) option(OCIO_BUILD_DOCS "Specify whether to build documentation" UNIX) option(OCIO_BUILD_TESTS "Specify whether to build unittests" ON) option(OCIO_BUILD_PYGLUE "Specify whether to build python bindings" ON) option(OCIO_BUILD_JNIGLUE "Specify whether to build java bindings" OFF) option(OCIO_STATIC_JNIGLUE "Specify whether to statically link ocio to the java bindings" ON) option(OCIO_USE_SSE "Specify whether to enable SSE CPU performance optimizations" ON) option(OCIO_INLINES_HIDDEN "Specify whether to build with -fvisibility-inlines-hidden" UNIX) # Use boost's shared_ptr by default on Windows (as etc." FORCE) endif(NOT OCIO_NAMESPACE) messageonce("Setting Namespace to: ${OCIO_NAMESPACE}") # If CMAKE_INSTALL_EXEC_PREFIX is not specified, install binaries # directly into the regular install prefix if(NOT CMAKE_INSTALL_EXEC_PREFIX) messageonce("Exec prefix not specified, defaulting to ${CMAKE_INSTALL_PREFIX}") set(CMAKE_INSTALL_EXEC_PREFIX ${CMAKE_INSTALL_PREFIX}) endif() messageonce("Use Boost Ptr: ${OCIO_USE_BOOST_PTR}") if(OCIO_USE_BOOST_PTR) set(Boost_ADDITIONAL_VERSIONS "1.49" "1.45" "1.44" "1.43" "1.43.0" "1.42" "1.42.0" "1.41" "1.41.0" "1.40" "1.40.0" "1.39" "1.39.0" "1.38" "1.38.0" "1.37" "1.37.0" "1.34.1" "1_34_1") set(Boost_USE_MULTITHREADED ON) find_package(Boost 1.34) if(NOT Boost_FOUND) message(FATAL_ERROR "OCIO_USE_BOOST_PTR is specified, but a boost installation could not be found.") else() set(OCIO_USE_BOOST_PTR 1) endif() set(EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} ${Boost_INCLUDE_DIR}) # set(EXTERNAL_LIBRARIES ${EXTERNAL_LIBRARIES} ${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) else() set(OCIO_USE_BOOST_PTR 0) endif() if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if(OCIO_INLINES_HIDDEN) execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (GCC_VERSION VERSION_LESS 4.2) message(STATUS "WARNING: GCC Version < 4.2 - disabling hidden inlines") set(OCIO_INLINES_HIDDEN OFF) endif() endif() endif() if(CMAKE_COMPILER_IS_GNUCXX) # Enable a bunch of compiler warnings... # http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wshadow -Wconversion -Wcast-qual -Wformat=2") # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") endif(CMAKE_COMPILER_IS_GNUCXX) ############################################################################### ### Python ### OCIOFindPython() # Find Python, used for (possibly) building pyglue, and now to # construct the external project path set(EXTDIST_ROOT ${CMAKE_BINARY_DIR}/ext/dist) set(EXTDIST_BINPATH ${EXTDIST_ROOT}/bin) if(PYTHON_OK) set(EXTDIST_PYTHONPATH ${EXTDIST_ROOT}/${PYTHON_VARIANT_PATH}) if(UNIX) set(PYTHONPATH ${EXTDIST_PYTHONPATH}:$ENV{PYTHONPATH}) else() # The line below should work but ';' is always replaced by a space # which breaks the build. Anyway in the worst scenario, no expected # modules are present in the local python so install them. #set(PYTHONPATH ${EXTDIST_PYTHONPATH}\\;$ENV{PYTHONPATH}) set(PYTHONPATH ${EXTDIST_PYTHONPATH}) endif() endif() messageonce("Setting EXTDIST_BINPATH: ${EXTDIST_BINPATH}") messageonce("Setting EXTDIST_PYTHONPATH: ${EXTDIST_PYTHONPATH}") ############################################################################### ### tinyxml ### ##TODO: yaml and tinyxml : when there are not USE_EXTERNAL_TINYXML, use the same cmake schema/instructions => maybe refactorize in a cmake functions/macros ? if(USE_EXTERNAL_TINYXML) set(TINYXML_VERSION_MIN "2.6.1") find_package(TinyXML) if(TINYXML_FOUND) if(TINYXML_VERSION VERSION_EQUAL ${TINYXML_VERSION_MIN} OR TINYXML_VERSION VERSION_GREATER ${TINYXML_VERSION_MIN}) message(STATUS "External TinyXML will be used.") else() message(FATAL_ERROR "ERROR: ${TINYXML_VERSION} found, but ${TINYXML_VERSION_MIN} or newer is required.") endif() else(TINYXML_FOUND) message(STATUS "TinyXML was not found. Perhaps you forgot to install the development package?") endif(TINYXML_FOUND) else(USE_EXTERNAL_TINYXML) set(TINYXML_VERSION 2_6_1) set(TINYXML_CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/ext/dist -DOCIO_INLINES_HIDDEN:BOOL=${OCIO_INLINES_HIDDEN}) if(CMAKE_TOOLCHAIN_FILE) set(TINYXML_CMAKE_ARGS ${TINYXML_CMAKE_ARGS} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) endif() set(TINYXML_CMAKE_ARGS ${TINYXML_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}) set(TINYXML_ZIPFILE "${CMAKE_SOURCE_DIR}/ext/tinyxml_${TINYXML_VERSION}.tar.gz") set(TINYXML_PATCHFILE "${CMAKE_SOURCE_DIR}/ext/tinyxml_${TINYXML_VERSION}.patch") set(TINYXML_SOURCE_DIR "${CMAKE_BINARY_DIR}/ext") ## Create our TINYXML_LIB target if(CMAKE_VERSION VERSION_GREATER "2.8.7") option(TINYXML_OBJECT_LIB_EMBEDDED ${OCIO_BUILD_STATIC} "directly embedded tinyxml 3rdParty object lib into our resulting static lib, no link needed anymore") else() set(TINYXML_OBJECT_LIB_EMBEDDED OFF CACHE BOOL "directly embedded tinyxml 3rdParty object lib into our resulting static lib, no link needed anymore" FORCE) message("Force disable TINYXML_OBJECT_LIB_EMBEDDED feature due to CMake Version less than 2.8.8") endif() mark_as_advanced(TINYXML_OBJECT_LIB_EMBEDDED) ## two way to build with tinyxml (objects embedded or static transitive link) if(TINYXML_OBJECT_LIB_EMBEDDED) set(tinyxml_sources ${TINYXML_SOURCE_DIR}/tinyxml/tinystr.cpp ${TINYXML_SOURCE_DIR}/tinyxml/tinyxml.cpp ${TINYXML_SOURCE_DIR}/tinyxml/tinyxmlerror.cpp ${TINYXML_SOURCE_DIR}/tinyxml/tinyxmlparser.cpp ) set(tinyxml_headers ${TINYXML_SOURCE_DIR}/tinyxml/tinystr.h ${TINYXML_SOURCE_DIR}/tinyxml/tinyxml.h ) add_custom_command( ## will be done at build time OUTPUT ${tinyxml_sources} ${tinyxml_headers} ## expected output files COMMAND ${CMAKE_COMMAND} -E tar xzf ${TINYXML_ZIPFILE} DEPENDS ${TINYXML_ZIPFILE} WORKING_DIRECTORY ${TINYXML_SOURCE_DIR} COMMENT "Unpacking ${TINYXML_ZIPFILE} to ${TINYXML_SOURCE_DIR}" VERBATIM ) include_directories(BEFORE ${TINYXML_SOURCE_DIR}/tinyxml) ## needed to build correctly add_library(TINYXML_LIB OBJECT ${tinyxml_sources}) ## embedded tinyxml objects files (no static link needed anymore) ## => great news when build staticaly since we do not want another client project have to link also with tinyxml when he want to use this project ## => could be problematic if the client project use another version of tinyxml... In this case build tinyxml as shared lib with all projects could be a solution ## => TODO: so maybe provide a simple cmake way to build 3rdParty as shared and auto install with this project ? set_target_properties(TINYXML_LIB PROPERTIES COMPILE_FLAGS "-DTIXML_USE_STL -fPIC -fvisibility-inlines-hidden -fvisibility=hidden") add_definitions(-DTIXML_USE_STL) ## needed to build correctly, and also need to be propagated in child projects (client projects) list(APPEND EXTERNAL_OBJECTS $) else() find_package(Git REQUIRED) ## in order to apply patch (for crossplateform compatibility) ExternalProject_Add(tinyxml URL ${TINYXML_ZIPFILE} SOURCE_DIR ${TINYXML_SOURCE_DIR}/tinyxml PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-whitespace ${TINYXML_PATCHFILE} BINARY_DIR ext/build/tinyxml INSTALL_DIR ext/dist CMAKE_ARGS ${TINYXML_CMAKE_ARGS} ) if(WIN32) set(TINYXML_STATIC_LIBRARIES ${PROJECT_BINARY_DIR}/ext/dist/lib/tinyxml.lib) else() set(TINYXML_STATIC_LIBRARIES ${PROJECT_BINARY_DIR}/ext/dist/lib/libtinyxml.a) endif() add_library(TINYXML_LIB STATIC IMPORTED) ## static is the .lib location, shared is the .dll/.so location (see IMPORTED_IMPLIB for the associated .lib archive location on windows) set_property(TARGET TINYXML_LIB PROPERTY IMPORTED_LOCATION ${TINYXML_STATIC_LIBRARIES}) add_dependencies(TINYXML_LIB tinyxml) list(APPEND EXTERNAL_LIBRARIES TINYXML_LIB) endif() set_target_properties(TINYXML_LIB PROPERTIES FOLDER External) endif(USE_EXTERNAL_TINYXML) ############################################################################### ### YAML ### if(USE_EXTERNAL_YAML) # Set minimum yaml version for non-patched sources. set(YAML_VERSION_MIN "0.3.0") include(FindPkgConfig) pkg_check_modules(PC_YAML_CPP REQUIRED QUIET yaml-cpp) find_path(YAML_CPP_INCLUDE_DIR yaml-cpp/yaml.h HINTS ${PC_YAML_CPP_INCLUDEDIR} ${PC_YAML_CPP_INCLUDE_DIRS} ) find_library(YAML_CPP_LIBRARY LIBRARY_NAMES yaml-cpp libyaml-cpp HINTS ${PC_YAML_CPP_LIBRARY_DIRS} ) set(YAML_CPP_LIBRARIES ${YAML_CPP_LIBRARY}) set(YAML_CPP_INCLUDE_DIRS ${YAML_CPP_INCLUDE_DIR}) set(YAML_CPP_VERSION ${PC_YAML_CPP_VERSION}) if(YAML_CPP_VERSION VERSION_LESS ${YAML_VERSION_MIN}) message(FATAL_ERROR "ERROR: yaml-cpp ${YAML_VERSION_MIN} or greater is required.") endif() find_package_handle_standard_args(yaml-cpp REQUIRED_VARS YAML_CPP_LIBRARIES YAML_CPP_INCLUDE_DIRS ) set(YAML_CPP_FOUND ${YAML-CPP_FOUND}) mark_as_advanced(YAML_CPP_INCLUDE_DIR YAML_CPP_LIBRARY YAML-CPP_FOUND) if(YAML_CPP_FOUND) if(YAML_CPP_VERSION VERSION_GREATER "0.5.0") # Need to also get the boost headers here, as yaml-cpp 0.5.0+ requires them. # Don't bother doing this step if we are already including the boost headers for shared_ptr if(NOT OCIO_USE_BOOST_PTR) set(Boost_ADDITIONAL_VERSIONS "1.49" "1.45" "1.44" "1.43" "1.43.0" "1.42" "1.42.0" "1.41" "1.41.0" "1.40" "1.40.0" "1.39" "1.39.0" "1.38" "1.38.0" "1.37" "1.37.0" "1.34.1" "1_34_1") set(Boost_USE_MULTITHREADED ON) find_package(Boost 1.34) if(NOT Boost_FOUND) message(FATAL_ERROR "Error: Detected system yaml-cpp version ${YAML_CPP_VERSION} is greater than 0.5.0, and therefore requires boost, but a boost installation could not be found.") endif() set(EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} ${Boost_INCLUDE_DIR}) endif() endif() set(EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} ${YAML_CPP_INCLUDE_DIRS}) else(YAML_CPP_FOUND) message(FATAL_ERROR "ERROR: System yaml-cpp library was not found. Make sure the library is installed and the pkg-config file exists.") endif(YAML_CPP_FOUND) else(USE_EXTERNAL_YAML) ## provide 2 ways to build this dependency set(YAML_CPP_VERSION 0.3.0) set(YAML_CPP_CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/ext/dist -DYAML_CPP_BUILD_TOOLS:BOOL=FALSE -DOCIO_INLINES_HIDDEN:BOOL=${OCIO_INLINES_HIDDEN}) if(CMAKE_TOOLCHAIN_FILE) set(YAML_CPP_CMAKE_ARGS ${YAML_CPP_CMAKE_ARGS} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}) endif() set(YAML_CPP_CMAKE_ARGS ${YAML_CPP_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}) set(YAML_CPP_ZIPFILE "${CMAKE_SOURCE_DIR}/ext/yaml-cpp-${YAML_CPP_VERSION}.tar.gz") set(YAML_CPP_SOURCE_DIR "${CMAKE_BINARY_DIR}/ext") set(YAML_CPP_PATCHFILE "${CMAKE_SOURCE_DIR}/ext/yaml-cpp-${YAML_CPP_VERSION}.patch") set(YAML_CPP_SRCLISTFILE "${CMAKE_SOURCE_DIR}/ext/yaml-cpp-${YAML_CPP_VERSION}-sourcesList.txt") ## see cmd line for this generated file bellow ## Create our YAML_CPP_LIB target if(CMAKE_VERSION VERSION_GREATER "2.8.7") option(YAML_CPP_OBJECT_LIB_EMBEDDED ${OCIO_BUILD_STATIC} "directly embedded yaml-cpp 3rdParty lib into our resulting static lib, no link needed anymore") else() set(YAML_CPP_OBJECT_LIB_EMBEDDED OFF CACHE BOOL "directly embedded yaml-cpp 3rdParty object lib into our resulting static lib, no link needed anymore" FORCE) message("Force disable YAML_CPP_OBJECT_LIB_EMBEDDED feature due to CMake Version less than 2.8.8") endif() mark_as_advanced(YAML_CPP_OBJECT_LIB_EMBEDDED) if(YAML_CPP_OBJECT_LIB_EMBEDDED) ## generated at extraction level dir, with (use git bash or cygwin under windows): ## find yaml-cpp -type f \( -name "*.h" -o -name "*.cpp" \) -not \( -path "*/test/*" -o -path "*/util/*" \) > yaml-cpp-sourcesList.txt ## this will exclude test and util paths since we want YAML_CPP_BUILD_TOOLS:BOOL=OFF (see externalProject cmake args) file(STRINGS ${YAML_CPP_SRCLISTFILE} YAML_CPP_SRCLISTFILE_CONTENT) foreach(yamlsrc ${YAML_CPP_SRCLISTFILE_CONTENT}) list(APPEND yamlcpp_sources ${YAML_CPP_SOURCE_DIR}/${yamlsrc}) ## get absolute filepath endforeach() include_directories(BEFORE ${YAML_CPP_SOURCE_DIR}/yaml-cpp/include) ## needed to build correctly add_custom_command( ## will be done at build time OUTPUT ${yamlcpp_sources} ## expected output files COMMAND ${CMAKE_COMMAND} -E tar xzf ${YAML_CPP_ZIPFILE} DEPENDS ${YAML_CPP_ZIPFILE} WORKING_DIRECTORY ${YAML_CPP_SOURCE_DIR} COMMENT "Unpacking ${YAML_CPP_ZIPFILE} to ${YAML_CPP_SOURCE_DIR}" VERBATIM ) add_library(YAML_CPP_LIB OBJECT ${yamlcpp_sources}) ## embedded yaml-cpp objects files (no static link needed anymore) ## => great news when build statically since we do not want another client project have to link also with yaml-cpp when he want to use this project ## => could be problematic if the client project use another version of yaml-cpp... In this case build yaml-cpp as shared lib with all projects could be a solution ## => TODO: so maybe provide a simple cmake way to build 3rdParty as shared and auto install with this project ? list(APPEND EXTERNAL_OBJECTS $) else() find_package(Git REQUIRED) ## in order to apply patch (for crossplateform compatibility) ExternalProject_Add(YAML_CPP_LOCAL URL ${YAML_CPP_ZIPFILE} SOURCE_DIR ${YAML_CPP_SOURCE_DIR}/yaml-cpp PATCH_COMMAND ${GIT_EXECUTABLE} apply --ignore-whitespace ${YAML_CPP_PATCHFILE} BINARY_DIR ext/build/yaml-cpp INSTALL_DIR ext/dist CMAKE_ARGS ${YAML_CPP_CMAKE_ARGS} ) set(YAML_CPP_INCLUDE_DIRS ${PROJECT_BINARY_DIR}/ext/dist/include) set(YAML_CPP_LIBRARY_DIRS ${PROJECT_BINARY_DIR}/ext/dist/lib) add_library(YAML_CPP_LIB STATIC IMPORTED) if(WIN32) set(YAML_CPP_STATIC_DEBUG_LIBRARIES ${PROJECT_BINARY_DIR}/ext/dist/lib/libyaml-cppmdd.lib) set(YAML_CPP_STATIC_OPTIMIZED_LIBRARIES ${PROJECT_BINARY_DIR}/ext/dist/lib/libyaml-cppmd.lib) set_property(TARGET YAML_CPP_LIB PROPERTY IMPORTED_LOCATION_DEBUG ${YAML_CPP_STATIC_DEBUG_LIBRARIES}) set_property(TARGET YAML_CPP_LIB PROPERTY IMPORTED_LOCATION_RELEASE ${YAML_CPP_STATIC_OPTIMIZED_LIBRARIES}) else() set(YAML_CPP_STATIC_GENERAL_LIBRARIES ${PROJECT_BINARY_DIR}/ext/dist/lib/libyaml-cpp.a) set_property(TARGET YAML_CPP_LIB PROPERTY IMPORTED_LOCATION ${YAML_CPP_STATIC_GENERAL_LIBRARIES}) endif() add_dependencies(YAML_CPP_LIB YAML_CPP_LOCAL) list(APPEND EXTERNAL_LIBRARIES YAML_CPP_LIB) endif() set_target_properties(YAML_CPP_LIB PROPERTIES FOLDER External) endif(USE_EXTERNAL_YAML) if(YAML_CPP_VERSION VERSION_LESS "0.5.0") set(YAML_CPP_COMPILE_FLAGS "-DOLDYAML") endif() ############################################################################### ### Externals ### set(EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} ${PROJECT_BINARY_DIR}/ext/dist/include) ## maybe better to separate too general COMPILE_FLAGS (which are compiler specific) and split with specific COMPILE_DEFINITIONS ## so we can easily export it from cmake for the installation and be used easily in child projects ? if(UNIX) set(GCC_COMPILE_FLAGS "${GCC_COMPILE_FLAGS} -fPIC -fvisibility=hidden") if(OCIO_INLINES_HIDDEN) set(GCC_COMPILE_FLAGS "${GCC_COMPILE_FLAGS} -fvisibility-inlines-hidden") endif() else() set(OCIO_INLINES_HIDDEN OFF) endif() set(EXTERNAL_COMPILE_FLAGS "-DTIXML_USE_STL ${YAML_CPP_COMPILE_FLAGS} ${GCC_COMPILE_FLAGS}") set(EXTERNAL_LINK_FLAGS "") set(EXTERNAL_LIBRARY_DIRS ${PROJECT_BINARY_DIR}/ext/dist/lib) ## EXTERNAL_OBJECTS (used with add_library) or EXTERNAL_LIBRARIES (used with target_link_libraries) are available ## One will be empty (no effect) whereas the other will contain external dep to use (as object to incorporate or static lib to link) if(EXTERNAL_OBJECTS) list(REMOVE_DUPLICATES EXTERNAL_OBJECTS) elseif(EXTERNAL_LIBRARIES) list(REMOVE_DUPLICATES EXTERNAL_LIBRARIES) endif() ############################################################################### ### Documentation ### messageonce("Generate Documentation: ${OCIO_BUILD_DOCS}") if(OCIO_BUILD_DOCS) if(PYTHON_OK) add_subdirectory(docs) else() message(STATUS "Building the documentation requires Python, but locating Python failed: ${PYTHON_ERR}") endif() endif() ############################################################################### ### SSE ### messageonce("SSE Optimizations: ${OCIO_USE_SSE}") if(OCIO_USE_SSE) if(WIN32) # SSE instructions are automatically compiled into 64-bit applications so enabling the option is redundant and # actually produces an unknown option warning in Visual Studio. if(NOT CMAKE_CL_64) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2") endif() else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2") endif() add_definitions("-DUSE_SSE") endif() ############################################################################### ### TRUELIGHT ### if(OCIO_BUILD_TRUELIGHT) find_package(Truelight) if(TRUELIGHT_FOUND) messageonce("Will build the truelight transform support against ${Truelight_LIBRARY_DIR}") add_definitions(-DOCIO_TRUELIGHT_SUPPORT) set(EXTERNAL_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIRS} ${Truelight_INCLUDE_DIR}) set(EXTERNAL_COMPILE_FLAGS "${EXTERNAL_COMPILE_FLAGS} ${Truelight_COMPILE_FLAGS}") set(EXTERNAL_LINK_FLAGS "${EXTERNAL_LINK_FLAGS} ${Truelight_LINK_FLAGS}") set(EXTERNAL_LIBRARIES ${EXTERNAL_LIBRARIES} ${Truelight_LIBRARIES}) else() messageonce("Not building truelight transform support. Add the flag -D TRUELIGHT_INSTALL_PATH=... or set the TRUELIGHT_ROOT environment variable") endif() endif() ############################################################################### ### CORE ### add_subdirectory(src/core) messageonce("Build Unit Tests: ${OCIO_BUILD_TESTS}") if(OCIO_BUILD_TESTS) add_subdirectory(src/core_tests) endif() ############################################################################### ### APPS ### if(OCIO_BUILD_APPS AND (OCIO_BUILD_STATIC OR OCIO_BUILD_SHARED) ) # Try to find OpenImageIO (OIIO) and OpenGL stuff OCIOFindOpenImageIO() if(OIIO_FOUND) add_subdirectory(src/apps/ocioconvert) add_subdirectory(src/apps/ociolutimage) else() messageonce("Not building ocioconvert/ociolutimage. Requirement(s) found: OIIO:${OIIO_FOUND}") endif() # ociodisplay, displays color-transformed images (uses OpenImageIO, # and OpenGL) OCIOFindOpenGL() if(OPENGL_FOUND AND GLUT_FOUND AND GLEW_FOUND AND OIIO_FOUND) add_subdirectory(src/apps/ociodisplay) else() ## GLEW : http://glew.sourceforge.net/install.html ## on windows, if you use STATIC version, do not forget to use : GEW_BUILD=GLEW_STATIC preprocessor definition messageonce("Not building ociodisplay. Requirement(s) found, OpenGL:${OPENGL_FOUND}, GLUT:${GLUT_FOUND}, GLEW:${GLEW_FOUND}, OIIO:${OIIO_FOUND}") endif() # ociocheck: verifies an OCIO config add_subdirectory(src/apps/ociocheck) # ociobakelut writes out luts add_subdirectory(src/apps/ociobakelut) else() message(STATUS "Disable build of apps. See cmake options : OCIO_BUILD_APPS and OCIO_BUILD_SHARED/OCIO_BUILD_STATIC (requiered)") endif() ############################################################################### ### NUKE ### if(OCIO_BUILD_NUKE) find_package(Nuke) if(NUKE_FOUND) messageonce("Will build the Nuke plugins against ${Nuke_LIBRARY_DIR}") add_subdirectory(src/nuke) else() messageonce("Not building Nuke plugins. Add the flag -D NUKE_INSTALL_PATH=... or set the NDK_PATH environment variable") endif() endif() ############################################################################### ### PYGLUE ### if(OCIO_BUILD_PYGLUE AND NOT ${CMAKE_BUILD_TYPE} MATCHES "Debug") if(PYTHON_OK) add_subdirectory(src/pyglue) else() messageonce("Python bindings will not be built: ${PYTHON_ERR}") endif() endif() ############################################################################### ### JNIGLUE ### if(OCIO_BUILD_JNIGLUE) OCIOFindJava() if(Java_FOUND) add_subdirectory(src/jniglue) else() messageonce("Java bindings will not be built as we can't find Java") endif() endif() ############################################################################### ### Configure env script ### configure_file(${CMAKE_SOURCE_DIR}/share/ocio/setup_ocio.sh.in ${CMAKE_CURRENT_BINARY_DIR}/share/ocio/setup_ocio.sh @ONLY) INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/share/ocio/setup_ocio.sh DESTINATION share/ocio/) ############################################################################### ### CPACK ### set(CPACK_PACKAGE_VERSION_MAJOR ${SOVERSION}) set(CPACK_PACKAGE_VERSION_MINOR ${OCIO_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${OCIO_VERSION_PATCH}) set(CPACK_GENERATOR None) set(CPACK_SOURCE_GENERATOR TGZ) set(CPACK_SOURCE_PACKAGE_FILE_NAME "ocio.${OCIO_VERSION}") include(CPack) ############################################################################### ### CTEST ### add_custom_target(test_verbose COMMAND ctest -VV DEPENDS ocio_core_tests COMMENT "Running ctest with verbose output") # Log CMake first run done SET(CMAKE_FIRST_RUN 0 CACHE INTERNAL "") ## Export install ## Example of usage by another project : ## set(OpenColorIO_DIR "" CACHE PATH "the installation dir of OpenColorIO (Where to find OpenColorIOConfig.cmake)") ## option(OpenColorIO_USE_STATIC OFF "use static target version of OpenColorIO") ## find_package(OpenColorIO) ## if(OPENCOLORIO_FOUND) ## include_directories(${OpenColorIO_INCLUDE_DIR}) ## foreach(OCIO_DEF ${OCIO_COMPILE_DEFINITIONS}) ## add_definitions(-D${OCIO_DEF}) ## endforeach() ## endif() ## ## Target_link_library( ${OpenColorIO_LIBRARIES}) get_property(OCIO_DIR_COMPILE_DEFINITIONS DIRECTORY PROPERTY COMPILE_DEFINITIONS) if(NOT OCIO_DIR_COMPILE_DEFINITIONS) set(OCIO_DIR_COMPILE_DEFINITIONS ) endif() if(TARGET OpenColorIO) get_target_property(OCIO_SHARED_COMPILE_DEFINITIONS OpenColorIO COMPILE_DEFINITIONS) if(OCIO_SHARED_COMPILE_DEFINITIONS) set(OCIO_SHARED_COMPILE_DEFINITIONS ${OCIO_SHARED_COMPILE_DEFINITIONS} ${OCIO_DIR_COMPILE_DEFINITIONS}) list(REMOVE_DUPLICATES OCIO_SHARED_COMPILE_DEFINITIONS) elseif(OCIO_DIR_COMPILE_DEFINITIONS) set(OCIO_SHARED_COMPILE_DEFINITIONS ${OCIO_DIR_COMPILE_DEFINITIONS}) else() set(OCIO_SHARED_COMPILE_DEFINITIONS ) endif() endif() if(TARGET OpenColorIO_STATIC) get_target_property(OCIO_STATIC_COMPILE_DEFINITIONS OpenColorIO_STATIC COMPILE_DEFINITIONS) if(OCIO_STATIC_COMPILE_DEFINITIONS) set(OCIO_STATIC_COMPILE_DEFINITIONS ${OCIO_STATIC_COMPILE_DEFINITIONS} ${OCIO_DIR_COMPILE_DEFINITIONS}) list(REMOVE_DUPLICATES OCIO_STATIC_COMPILE_DEFINITIONS) elseif(OCIO_DIR_COMPILE_DEFINITIONS) set(OCIO_STATIC_COMPILE_DEFINITIONS ${OCIO_DIR_COMPILE_DEFINITIONS}) else() set(OCIO_STATIC_COMPILE_DEFINITIONS ) endif() endif() install(EXPORT OpenColorIO DESTINATION cmake) file(WRITE "${CMAKE_BINARY_DIR}/OpenColorIOConfig.cmake" " get_filename_component(OpenColorIO_DIR \"\${CMAKE_CURRENT_LIST_FILE}\" PATH) ## include set(OpenColorIO_INCLUDE_DIR \"\${OpenColorIO_DIR}/include\") set(OpenColorIO_INCLUDE_DIRS \"\${OpenColorIO_INCLUDE_DIR}\") message(STATUS OpenColorIO_INCLUDE_DIRS=\${OpenColorIO_INCLUDE_DIRS}) ## targets libraries + associated definitions if(NOT TARGET OpenColorIO) include(\"\${OpenColorIO_DIR}/cmake/OpenColorIO.cmake\") ## thanks to imported target if(TARGET OpenColorIO AND NOT OpenColorIO_USE_STATIC) message(STATUS \"shared target OpenColorIO : see OpenColorIO_LIBRARY\") set(OpenColorIO_LIBRARY OpenColorIO) set(OCIO_COMPILE_DEFINITIONS ${OCIO_SHARED_COMPILE_DEFINITIONS}) endif() if(NOT TARGET OpenColorIO AND TARGET OpenColorIO_STATIC) message(STATUS \"static target OpenColorIO_STATIC : see OpenColorIO_LIBRARY\") set(OpenColorIO_LIBRARY OpenColorIO_STATIC) set(OCIO_COMPILE_DEFINITIONS ${OCIO_STATIC_COMPILE_DEFINITIONS}) elseif(TARGET OpenColorIO_STATIC AND OpenColorIO_USE_STATIC) message(STATUS \"static target OpenColorIO_STATIC : see OpenColorIO_LIBRARY\") set(OpenColorIO_LIBRARY OpenColorIO_STATIC) set(OCIO_COMPILE_DEFINITIONS ${OCIO_STATIC_COMPILE_DEFINITIONS}) endif() endif() set(OpenColorIO_LIBRARIES \${OpenColorIO_LIBRARY}) message(STATUS OpenColorIO_LIBRARIES=\${OpenColorIO_LIBRARIES}) ## display available preprocessor definition to use if(OCIO_COMPILE_DEFINITIONS) message(STATUS \"OCIO_COMPILE_DEFINITIONS=\") foreach(OCIO_DEF \${OCIO_COMPILE_DEFINITIONS}) message(STATUS \" \${OCIO_DEF}\") endforeach() endif() ## found if(OpenColorIO_INCLUDE_DIRS AND OpenColorIO_LIBRARIES) set(OpenColorIO_FOUND ON) set(OPENCOLORIO_FOUND ON) else() set(OpenColorIO_FOUND OFF) set(OPENCOLORIO_FOUND OFF) endif() message(STATUS OPENCOLORIO_FOUND=\${OPENCOLORIO_FOUND}) " ) install(FILES "${CMAKE_BINARY_DIR}/OpenColorIOConfig.cmake" DESTINATION .) opencolorio-1.1.0~dfsg0.orig/README.md0000644000175000017500000000476413223553423015560 0ustar mfvmfvOpenColorIO =========== [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![Build Status](https://travis-ci.org/imageworks/OpenColorIO.svg?branch=master)](https://travis-ci.org/imageworks/OpenColorIO) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/fidyv9jkxeigyd2a/branch/master?svg=true)]() Introduction ------------ [linear]: /docs/ociotheme/static/clo_res19_lnf.0101.jpg [log]: /docs/ociotheme/static/clo_res19_lm10.0101.jpg [vd]: /docs/ociotheme/static/clo_res19_vd16.0101.jpg ![lnh][linear] ![lm10][log] ![vd8][vd] OpenColorIO (OCIO) is a complete color management solution geared towards motion picture production with an emphasis on visual effects and computer animation. OCIO provides a straightforward and consistent user experience across all supporting applications while allowing for sophisticated back-end configuration options suitable for high-end production usage. OCIO is compatible with the Academy Color Encoding Specification (ACES) and is LUT-format agnostic, supporting many popular formats. OpenColorIO is released as version 1.0 and has been in development since 2003. OCIO represents the culmination of years of production experience earned on such films as SpiderMan 2 (2004), Surf's Up (2007), Cloudy with a Chance of Meatballs (2009), Alice in Wonderland (2010), and many more. OpenColorIO is natively supported in commercial applications like Katana, Mari, Nuke, Silhouette FX, and others. OpenColorIO is free (http://opencolorio.org/License.html) and is one of several open source projects actively sponsored by Sony Imageworks (http://opensource.imageworks.com) Web Resources ------------- * Web page: http://opencolorio.org * Mail lists: * Developer: ocio-dev@googlegroups.com * User: ocio-users@googlegroups.com * Slack channel: https://opencolorio.slack.com * Please request access on the ocio-dev email with the email address you would like to be invited on Reference Configs ----------------- Reference OCIO configuration files and associated LUTs can be found at the Imageworks [OpenColorIO-Configs](https://github.com/imageworks/OpenColorIO-Configs) repository The following reference implementations are provided: * SPI: Sony Pictures Imageworks * spi-anim * spi-vfx * ACES: Academy Color Encoding System * aces_0.1.1 * aces_0.7.1 * aces_1.0.1 * aces_1.0.2 * aces_1.0.3 --- Images from "Cloudy With A Chance of Meatballs" Copyright 2011 Sony Pictures Inc. All Rights Reserved. opencolorio-1.1.0~dfsg0.orig/LICENSE0000644000175000017500000002602613223553423015301 0ustar mfvmfvAll code by Sony Pictures Imageworks except: Pystring http://code.google.com/p/pystring/ TinyXML http://sourceforge.net/projects/tinyxml/ yaml-cpp http://code.google.com/p/yaml-cpp/ PTex (Mutex), courtesy of Brent Burley and Disney http://ptex.us/ Little CMS http://www.littlecms.com/ MD5, courtesy L. Peter Deutsch, Aladdin Enterprises. http://sourceforge.net/projects/libmd5-rfc/files/ argparse, courtesy OpenImageIO and Larry Gritz http://openimageio.org --------------------------------------------------------------------- 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. --------------------------------------------------------------------- Pystring Copyright (c) 2008-2010, Sony Pictures Imageworks Inc 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 the organization 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. --------------------------------------------------------------------- TinyXML is released under the zlib license: This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. --------------------------------------------------------------------- yaml-cpp Copyright (c) 2008 Jesse Beder. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------- PTEX SOFTWARE Copyright 2009 Disney Enterprises, Inc. 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. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER 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 BASED 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 DAMAGES. --------------------------------------------------------------------- Little CMS Copyright (c) 1998-2010 Marti Maria Saguer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------- MD5 Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com --------------------------------------------------------------------- argparse Copyright 2008 Larry Gritz and the other authors and contributors. All Rights Reserved. Based on BSD-licensed software Copyright 2004 NVIDIA Corp. 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 the software's owners 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. (This is the Modified BSD License)opencolorio-1.1.0~dfsg0.orig/export/0000755000175000017500000000000013223553423015607 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/export/pkgconfig/0000755000175000017500000000000013223553423017556 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/export/pkgconfig/OpenColorIO.pc.in0000644000175000017500000000046713223553423022646 0ustar mfvmfvprefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=@CMAKE_INSTALL_EXEC_PREFIX@ includedir=${prefix}/include libdir=${exec_prefix}/lib@LIB_SUFFIX@ Name: OpenColorIO Description: A color management framework for visual effects and animation Version: @OCIO_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -lOpenColorIO opencolorio-1.1.0~dfsg0.orig/export/OpenColorIO/0000755000175000017500000000000013223553423017737 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/export/OpenColorIO/OpenColorIO.h0000644000175000017500000013327213223553423022250 0ustar mfvmfv/* 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_OCIO_OPENCOLORIO_H #define INCLUDED_OCIO_OPENCOLORIO_H #include #include #include #include #include "OpenColorABI.h" #include "OpenColorTypes.h" #include "OpenColorTransforms.h" /*!rst:: C++ API ======= **Usage Example:** *Compositing plugin that converts from "log" to "lin"* .. code-block:: cpp #include namespace OCIO = OCIO_NAMESPACE; try { // Get the global OpenColorIO config // This will auto-initialize (using $OCIO) on first use OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); // Get the processor corresponding to this transform. OCIO::ConstProcessorRcPtr processor = config->getProcessor(OCIO::ROLE_COMPOSITING_LOG, OCIO::ROLE_SCENE_LINEAR); // Wrap the image in a light-weight ImageDescription OCIO::PackedImageDesc img(imageData, w, h, 4); // Apply the color transformation (in place) processor->apply(img); } catch(OCIO::Exception & exception) { std::cerr << "OpenColorIO Error: " << exception.what() << std::endl; } */ OCIO_NAMESPACE_ENTER { /////////////////////////////////////////////////////////////////////////// //!rst:: // Exceptions // ********** //!cpp:class:: An exception class to throw for errors detected at // runtime. // // .. warning:: // All functions in the Config class can potentially throw this exception. class OCIOEXPORT Exception : public std::exception { public: //!cpp:function:: Constructor that takes a string as the exception message. Exception(const char *) throw(); //!cpp:function:: Constructor that takes an exception pointer. Exception(const Exception&) throw(); //!cpp:function:: Constructor that takes an exception pointer and returns an exception pointer (???). Exception& operator=(const Exception&) throw(); //!cpp:function:: virtual ~Exception() throw(); //!cpp:function:: virtual const char* what() const throw(); private: //Add pragma warnings, STL member is private and not consumed by client of DLL #ifdef _WIN32 #pragma warning(push) #pragma warning(disable:4251) #endif // _WIN32 std::string msg_; #ifdef _WIN32 #pragma warning(pop) #endif // _WIN32 }; //!cpp:class:: 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. class OCIOEXPORT ExceptionMissingFile : public Exception { public: //!cpp:function:: Constructor that takes a string as the exception message. ExceptionMissingFile(const char *) throw(); //!cpp:function:: Constructor that takes an existing exception. ExceptionMissingFile(const ExceptionMissingFile&) throw(); }; /////////////////////////////////////////////////////////////////////////// //!rst:: // Global // ****** //!cpp:function:: // OpenColorIO, during normal usage, tends to cache certain information // (such as the contents of LUTs on disk, intermediate results, etc.). // Calling this function will flush all such information. // Under normal usage, this is not necessary, but it can be helpful in particular instances, // such as designing OCIO profiles, and wanting to re-read luts without // restarting. extern OCIOEXPORT void ClearAllCaches(); //!cpp:function:: Get the version number for the library, as a // dot-delimited string (e.g., "1.0.0"). This is also available // at compile time as OCIO_VERSION. extern OCIOEXPORT const char * GetVersion(); //!cpp:function:: Get the version number for the library, as a // single 4-byte hex number (e.g., 0x01050200 for "1.5.2"), to be used // for numeric comparisons. This is also available // at compile time as OCIO_VERSION_HEX. extern OCIOEXPORT int GetVersionHex(); //!cpp:function:: Get the global logging level. // You can override this at runtime using the :envvar:`OCIO_LOGGING_LEVEL` // environment variable. The client application that sets this should use // :cpp:func:`SetLoggingLevel`, and not the environment variable. The default value is INFO. extern OCIOEXPORT LoggingLevel GetLoggingLevel(); //!cpp:function:: Set the global logging level. extern OCIOEXPORT void SetLoggingLevel(LoggingLevel level); /////////////////////////////////////////////////////////////////////////// //!rst:: // Config // ****** // // A config defines all the color spaces to be available at runtime. // // The color configuration (:cpp:class:`Config`) is the main object for // interacting with this library. It encapsulates all of the information // necessary to use customized :cpp:class:`ColorSpaceTransform` and // :cpp:class:`DisplayTransform` operations. // // See the :ref:`user-guide` for more information on // selecting, creating, and working with custom color configurations. // // For applications interested in using only one color config at // a time (this is the vast majority of apps), their API would // traditionally get the global configuration and use that, as opposed to // creating a new one. This simplifies the use case for // plugins and bindings, as it alleviates the need to pass around configuration // handles. // // An example of an application where this would not be sufficient would be // a multi-threaded image proxy server (daemon), which wished to handle // multiple show configurations in a single process concurrently. This // app would need to keep multiple configurations alive, and to manage them // appropriately. // // Roughly speaking, a novice user should select a // default configuration that most closely approximates the use case // (animation, visual effects, etc.), and set the :envvar:`OCIO` environment // variable to point at the root of that configuration. // // .. note:: // Initialization using environment variables is typically preferable in // a multi-app ecosystem, as it allows all applications to be // consistently configured. // // See :ref:`developers-usageexamples` //!cpp:function:: Get the current configuration. extern OCIOEXPORT ConstConfigRcPtr GetCurrentConfig(); //!cpp:function:: Set the current configuration. This will then store a copy of the specified config. extern OCIOEXPORT void SetCurrentConfig(const ConstConfigRcPtr & config); //!cpp:class:: class OCIOEXPORT Config { public: /////////////////////////////////////////////////////////////////////////// //!rst:: .. _cfginit_section: // // Initialization // ^^^^^^^^^^^^^^ //!cpp:function:: Constructor a default empty configuration. static ConfigRcPtr Create(); //!cpp:function:: Constructor a configuration using the OCIO environmnet variable. static ConstConfigRcPtr CreateFromEnv(); //!cpp:function:: Constructor a configuration using a specific config file. static ConstConfigRcPtr CreateFromFile(const char * filename); //!cpp:function:: static ConstConfigRcPtr CreateFromStream(std::istream & istream); //!cpp:function:: ConfigRcPtr createEditableCopy() const; //!cpp:function:: // This will throw an exception if the config is malformed. The most // common error occurs when references are made to colorspaces that do not // exist. void sanityCheck() const; //!cpp:function:: const char * getDescription() const; //!cpp:function:: void setDescription(const char * description); //!cpp:function:: // Returns the string representation of the Config in YAML text form. // This is typically stored on disk in a file with the extension .ocio. void serialize(std::ostream & os) const; //!cpp:function:: // 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 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 Config::serialize). const char * getCacheID() const; //!cpp:function:: const char * getCacheID(const ConstContextRcPtr & context) const; /////////////////////////////////////////////////////////////////////////// //!rst:: .. _cfgresource_section: // // Resources // ^^^^^^^^^ // Given a lut src name, where should we find it? //!cpp:function:: ConstContextRcPtr getCurrentContext() const; //!cpp:function:: void addEnvironmentVar(const char * name, const char * defaultValue); //!cpp:function:: int getNumEnvironmentVars() const; //!cpp:function:: const char * getEnvironmentVarNameByIndex(int index) const; //!cpp:function:: const char * getEnvironmentVarDefault(const char * name) const; //!cpp:function:: void clearEnvironmentVars(); //!cpp:function:: void setEnvironmentMode(EnvironmentMode mode); //!cpp:function:: EnvironmentMode getEnvironmentMode() const; //!cpp:function:: void loadEnvironment(); //!cpp:function:: const char * getSearchPath() const; //!cpp:function:: void setSearchPath(const char * path); //!cpp:function:: const char * getWorkingDir() const; //!cpp:function:: void setWorkingDir(const char * dirname); /////////////////////////////////////////////////////////////////////////// //!rst:: .. _cfgcolorspaces_section: // // ColorSpaces // ^^^^^^^^^^^ //!cpp:function:: int getNumColorSpaces() const; //!cpp:function:: This will null if an invalid index is specified const char * getColorSpaceNameByIndex(int index) const; //!rst:: // .. note:: // These fcns all accept either a color space OR role name. // (Colorspace names take precedence over roles.) //!cpp:function:: This will return null if the specified name is not // found. ConstColorSpaceRcPtr getColorSpace(const char * name) const; //!cpp:function:: int getIndexForColorSpace(const char * name) const; //!cpp:function:: // .. note:: // If another color space is already registered with the same name, // this will overwrite it. This stores a copy of the specified // color space. void addColorSpace(const ConstColorSpaceRcPtr & cs); //!cpp:function:: void clearColorSpaces(); //!cpp:function:: Given the specified string, get the longest, // right-most, colorspace substring that appears. // // * If strict parsing is enabled, and no color space is found, return // an empty string. // * If strict parsing is disabled, return ROLE_DEFAULT (if defined). // * If the default role is not defined, return an empty string. const char * parseColorSpaceFromString(const char * str) const; //!cpp:function:: bool isStrictParsingEnabled() const; //!cpp:function:: void setStrictParsingEnabled(bool enabled); /////////////////////////////////////////////////////////////////////////// //!rst:: .. _cfgroles_section: // // Roles // ^^^^^ // A role is like an alias for a colorspace. You can query the colorspace // corresponding to a role using the normal getColorSpace fcn. //!cpp:function:: // .. note:: // Setting the ``colorSpaceName`` name to a null string unsets it. void setRole(const char * role, const char * colorSpaceName); //!cpp:function:: int getNumRoles() const; //!cpp:function:: Return true if the role has been defined. bool hasRole(const char * role) const; //!cpp:function:: Get the role name at index, this will return values // like 'scene_linear', 'compositing_log'. // Return empty string if index is out of range. const char * getRoleName(int index) const; /////////////////////////////////////////////////////////////////////////// //!rst:: .. _cfgdisplayview_section: // // Display/View Registration // ^^^^^^^^^^^^^^^^^^^^^^^^^ // // Looks is a potentially comma (or colon) delimited list of lookNames, // Where +/- prefixes are optionally allowed to denote forward/inverse // look specification. (And forward is assumed in the absence of either) //!cpp:function:: const char * getDefaultDisplay() const; //!cpp:function:: int getNumDisplays() const; //!cpp:function:: const char * getDisplay(int index) const; //!cpp:function:: const char * getDefaultView(const char * display) const; //!cpp:function:: int getNumViews(const char * display) const; //!cpp:function:: const char * getView(const char * display, int index) const; //!cpp:function:: const char * getDisplayColorSpaceName(const char * display, const char * view) const; //!cpp:function:: const char * getDisplayLooks(const char * display, const char * view) const; //!cpp:function:: For the (display,view) combination, // specify which colorSpace and look to use. // If a look is not desired, then just pass an empty string void addDisplay(const char * display, const char * view, const char * colorSpaceName, const char * looks); //!cpp:function:: void clearDisplays(); // $OCIO_ACTIVE_DISPLAYS envvar can, at runtime, optionally override the allowed displays. // It is a comma or colon delimited list. // Active displays that are not in the specified profile will be ignored, and the // left-most defined display will be the default. //!cpp:function:: Comma-delimited list of display names. void setActiveDisplays(const char * displays); //!cpp:function:: const char * getActiveDisplays() const; // $OCIO_ACTIVE_VIEWS envvar can, at runtime, optionally override the allowed views. // It is a comma or colon delimited list. // Active views that are not in the specified profile will be ignored, and the // left-most defined view will be the default. //!cpp:function:: Comma-delimited list of view names. void setActiveViews(const char * views); //!cpp:function:: const char * getActiveViews() const; /////////////////////////////////////////////////////////////////////////// //!rst:: .. _cfgluma_section: // // Luma // ^^^^ // // Get the default coefficients for computing luma. // // .. note:: // There is no "1 size fits all" set of luma coefficients. (The // values are typically different for each colorspace, and the // application of them may be nonsensical depending on the // intensity coding anyways). Thus, the 'right' answer is to make // these functions on the :cpp:class:`Config` class. However, it's // often useful to have a config-wide default so here it is. We will // add the colorspace specific luma call if/when another client is // interesting in using it. //!cpp:function:: void getDefaultLumaCoefs(float * rgb) const; //!cpp:function:: These should be normalized (sum to 1.0 exactly). void setDefaultLumaCoefs(const float * rgb); /////////////////////////////////////////////////////////////////////////// //!rst:: .. _cflooka_section: // // Look // ^^^^ // // Manager per-shot look settings. // //!cpp:function:: ConstLookRcPtr getLook(const char * name) const; //!cpp:function:: int getNumLooks() const; //!cpp:function:: const char * getLookNameByIndex(int index) const; //!cpp:function:: void addLook(const ConstLookRcPtr & look); //!cpp:function:: void clearLooks(); /////////////////////////////////////////////////////////////////////////// //!rst:: .. _cfgprocessors_section: // // Processors // ^^^^^^^^^^ // // Convert from inputColorSpace to outputColorSpace // // .. note:: // This may provide higher fidelity than anticipated due to internal // optimizations. For example, if the inputcolorspace and the // 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 supported (ignored) // using the pixelStrideBytes arg). //!cpp:function:: ConstProcessorRcPtr getProcessor(const ConstContextRcPtr & context, const ConstColorSpaceRcPtr & srcColorSpace, const ConstColorSpaceRcPtr & dstColorSpace) const; //!cpp:function:: ConstProcessorRcPtr getProcessor(const ConstColorSpaceRcPtr & srcColorSpace, const ConstColorSpaceRcPtr & dstColorSpace) const; //!cpp:function:: // .. note:: // Names can be colorspace name, role name, or a combination of both. ConstProcessorRcPtr getProcessor(const char * srcName, const char * dstName) const; //!cpp:function:: ConstProcessorRcPtr getProcessor(const ConstContextRcPtr & context, const char * srcName, const char * dstName) const; //!rst:: Get the processor for the specified transform. // // Not often needed, but will allow for the re-use of atomic OCIO // functionality (such as to apply an individual LUT file). //!cpp:function:: ConstProcessorRcPtr getProcessor(const ConstTransformRcPtr& transform) const; //!cpp:function:: ConstProcessorRcPtr getProcessor(const ConstTransformRcPtr& transform, TransformDirection direction) const; //!cpp:function:: ConstProcessorRcPtr getProcessor(const ConstContextRcPtr & context, const ConstTransformRcPtr& transform, TransformDirection direction) const; private: Config(); ~Config(); Config(const Config &); Config& operator= (const Config &); static void deleter(Config* c); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const Config&); /////////////////////////////////////////////////////////////////////////// //!rst:: .. _colorspace_section: // // ColorSpace // ********** // The *ColorSpace* is the state of an image with respect to colorimetry // and color encoding. Transforming images between different // *ColorSpaces* is the primary motivation for this library. // // While a complete discussion of color spaces is beyond the scope of // header documentation, traditional uses would be to have *ColorSpaces* // corresponding to: physical capture devices (known cameras, scanners), // and internal 'convenience' spaces (such as scene linear, logarithmic). // // *ColorSpaces* are specific to a particular image precision (float32, // uint8, etc.), and the set of ColorSpaces that provide equivalent mappings // (at different precisions) are referred to as a 'family'. //!cpp:class:: class OCIOEXPORT ColorSpace { public: //!cpp:function:: static ColorSpaceRcPtr Create(); //!cpp:function:: ColorSpaceRcPtr createEditableCopy() const; //!cpp:function:: const char * getName() const; //!cpp:function:: void setName(const char * name); //!cpp:function::Get the family, for use in user interfaces (optional) const char * getFamily() const; //!cpp:function::Set the family, for use in user interfaces (optional) void setFamily(const char * family); //!cpp:function::Get the ColorSpace group name (used for equality comparisons) // This allows no-op transforms between different colorspaces. // If an equalityGroup is not defined (an empty string), it will be considered // unique (i.e., it will not compare as equal to other ColorSpaces with an // empty equality group). This is often, though not always, set to the // same value as 'family'. const char * getEqualityGroup() const; //!cpp:function:: void setEqualityGroup(const char * equalityGroup); //!cpp:function:: const char * getDescription() const; //!cpp:function:: void setDescription(const char * description); //!cpp:function:: BitDepth getBitDepth() const; //!cpp:function:: void setBitDepth(BitDepth bitDepth); /////////////////////////////////////////////////////////////////////////// //!rst:: // Data // ^^^^ // 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 // :cpp:class:`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. //!cpp:function:: bool isData() const; //!cpp:function:: void setIsData(bool isData); /////////////////////////////////////////////////////////////////////////// //!rst:: // Allocation // ^^^^^^^^^^ // 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. //!cpp:function:: Allocation getAllocation() const; //!cpp:function:: void setAllocation(Allocation allocation); //!rst:: // Specify the optional variable values to configure the allocation. // If no variables are specified, the defaults are used. // // ALLOCATION_UNIFORM:: // // 2 vars: [min, max] // // ALLOCATION_LG2:: // // 2 vars: [lg2min, lg2max] // 3 vars: [lg2min, lg2max, linear_offset] //!cpp:function:: int getAllocationNumVars() const; //!cpp:function:: void getAllocationVars(float * vars) const; //!cpp:function:: void setAllocationVars(int numvars, const float * vars); /////////////////////////////////////////////////////////////////////////// //!rst:: // Transform // ^^^^^^^^^ //!cpp:function:: // If a transform in the specified direction has been specified, // return it. Otherwise return a null ConstTransformRcPtr ConstTransformRcPtr getTransform(ColorSpaceDirection dir) const; //!cpp:function:: // Specify the transform for the appropriate direction. // Setting the transform to null will clear it. void setTransform(const ConstTransformRcPtr & transform, ColorSpaceDirection dir); private: ColorSpace(); ~ColorSpace(); ColorSpace(const ColorSpace &); ColorSpace& operator= (const ColorSpace &); static void deleter(ColorSpace* c); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const ColorSpace&); /////////////////////////////////////////////////////////////////////////// //!rst:: .. _look_section: // // 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. //!cpp:class:: class OCIOEXPORT Look { public: //!cpp:function:: static LookRcPtr Create(); //!cpp:function:: LookRcPtr createEditableCopy() const; //!cpp:function:: const char * getName() const; //!cpp:function:: void setName(const char * name); //!cpp:function:: const char * getProcessSpace() const; //!cpp:function:: void setProcessSpace(const char * processSpace); //!cpp:function:: ConstTransformRcPtr getTransform() const; //!cpp:function:: Setting a transform to a non-null call makes it allowed. void setTransform(const ConstTransformRcPtr & transform); //!cpp:function:: ConstTransformRcPtr getInverseTransform() const; //!cpp:function:: Setting a transform to a non-null call makes it allowed. void setInverseTransform(const ConstTransformRcPtr & transform); //!cpp:function:: const char * getDescription() const; //!cpp:function:: void setDescription(const char * description); private: Look(); ~Look(); Look(const Look &); Look& operator= (const Look &); static void deleter(Look* c); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const Look&); /////////////////////////////////////////////////////////////////////////// //!rst:: // Processor // ********* //!cpp:class:: class OCIOEXPORT Processor { public: //!cpp:function:: static ProcessorRcPtr Create(); //!cpp:function:: bool isNoOp() const; //!cpp:function:: does the processor represent an image transformation that // introduces crosstalk between the image channels bool hasChannelCrosstalk() const; //!cpp:function:: ConstProcessorMetadataRcPtr getMetadata() const; /////////////////////////////////////////////////////////////////////////// //!rst:: // CPU Path // ^^^^^^^^ //!cpp:function:: Apply to an image. void apply(ImageDesc& img) const; //!rst:: // Apply to a single pixel. // // .. note:: // This is not as efficient as applying to an entire image at once. // If you are processing multiple pixels, and have the flexibility, // use the above function instead. //!cpp:function:: void applyRGB(float * pixel) const; //!cpp:function:: void applyRGBA(float * pixel) const; //!cpp:function:: const char * getCpuCacheID() const; /////////////////////////////////////////////////////////////////////////// //!rst:: // GPU Path // ^^^^^^^^ // Get the 3d lut + cg shader for the specified // :cpp:class:`DisplayTransform`. // // cg signature will be:: // // shaderFcnName(in half4 inPixel, const uniform sampler3D lut3d) // // lut3d should be size: 3 * edgeLen * edgeLen * edgeLen // return 0 if unknown //!cpp:function:: const char * getGpuShaderText(const GpuShaderDesc & shaderDesc) const; //!cpp:function:: const char * getGpuShaderTextCacheID(const GpuShaderDesc & shaderDesc) const; //!cpp:function:: void getGpuLut3D(float* lut3d, const GpuShaderDesc & shaderDesc) const; //!cpp:function:: const char * getGpuLut3DCacheID(const GpuShaderDesc & shaderDesc) const; private: Processor(); ~Processor(); Processor(const Processor &); Processor& operator= (const Processor &); static void deleter(Processor* c); friend class Config; class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:class:: // This class contains meta information about the process that generated // this processor. The results of these functions do not // impact the pixel processing. class OCIOEXPORT ProcessorMetadata { public: //!cpp:function:: static ProcessorMetadataRcPtr Create(); //!cpp:function:: int getNumFiles() const; //!cpp:function:: const char * getFile(int index) const; //!cpp:function:: int getNumLooks() const; //!cpp:function:: const char * getLook(int index) const; //!cpp:function:: void addFile(const char * fname); //!cpp:function:: void addLook(const char * look); private: ProcessorMetadata(); ~ProcessorMetadata(); ProcessorMetadata(const ProcessorMetadata &); ProcessorMetadata& operator= (const ProcessorMetadata &); static void deleter(ProcessorMetadata* c); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; /////////////////////////////////////////////////////////////////////////// //!rst:: // Baker // ***** // // In certain situations it is necessary to serialize transforms into a variety // of application specific lut formats. The Baker can be used to create lut // formats that ocio supports for writing. // // **Usage Example:** *Bake a houdini sRGB viewer lut* // // .. code-block:: cpp // // OCIO::ConstConfigRcPtr config = OCIO::Config::CreateFromEnv(); // OCIO::BakerRcPtr baker = OCIO::Baker::Create(); // baker->setConfig(config); // baker->setFormat("houdini"); // set the houdini type // baker->setType("3D"); // we want a 3D lut // baker->setInputSpace("lnf"); // baker->setShaperSpace("log"); // baker->setTargetSpace("sRGB"); // std::ostringstream out; // baker->bake(out); // fresh bread anyone! // std::cout << out.str(); class OCIOEXPORT Baker { public: //!cpp:function:: create a new Baker static BakerRcPtr Create(); //!cpp:function:: create a copy of this Baker BakerRcPtr createEditableCopy() const; //!cpp:function:: set the config to use void setConfig(const ConstConfigRcPtr & config); //!cpp:function:: get the config to use ConstConfigRcPtr getConfig() const; //!cpp:function:: set the lut output format void setFormat(const char * formatName); //!cpp:function:: get the lut output format const char * getFormat() const; // TODO: Change this to an enum //!cpp:function:: set the lut output type (1D or 3D) void setType(const char * type); //!cpp:function:: get the lut output type const char * getType() const; //!cpp:function:: set *optional* meta data for luts that support it void setMetadata(const char * metadata); //!cpp:function:: get the meta data that has been set const char * getMetadata() const; //!cpp:function:: set the input ColorSpace that the lut will be // applied to void setInputSpace(const char * inputSpace); //!cpp:function:: get the input ColorSpace that has been set const char * getInputSpace() const; //!cpp:function:: set an *optional* ColorSpace to be used to shape / // transfer the input colorspace. This is mostly used to allocate // an HDR luminance range into an LDR one. If a shaper space // is not explicitly specified, and the file format supports one, // the ColorSpace Allocation will be used void setShaperSpace(const char * shaperSpace); //!cpp:function:: get the shaper colorspace that has been set const char * getShaperSpace() const; //!cpp:function:: set the looks to be applied during baking // Looks is a potentially comma (or colon) delimited list of lookNames, // Where +/- prefixes are optionally allowed to denote forward/inverse // look specification. (And forward is assumed in the absence of either) void setLooks(const char * looks); //!cpp:function:: get the looks to be applied during baking const char * getLooks() const; //!cpp:function:: set the target device colorspace for the lut void setTargetSpace(const char * targetSpace); //!cpp:function:: get the target colorspace that has been set const char * getTargetSpace() const; //!cpp:function:: override the default the shaper sample size, // default: void setShaperSize(int shapersize); //!cpp:function:: get the shaper sample size int getShaperSize() const; //!cpp:function:: override the default cube sample size // default: void setCubeSize(int cubesize); //!cpp:function:: get the cube sample size int getCubeSize() const; //!cpp:function:: bake the lut into the output stream void bake(std::ostream & os) const; //!cpp:function:: get the number of lut writers static int getNumFormats(); //!cpp:function:: get the lut writer at index, return empty string if // an invalid index is specified static const char * getFormatNameByIndex(int index); static const char * getFormatExtensionByIndex(int index); private: Baker(); ~Baker(); Baker(const Baker &); Baker& operator= (const Baker &); static void deleter(Baker* o); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; /////////////////////////////////////////////////////////////////////////// //!rst:: // ImageDesc // ********* //!rst:: // .. c:var:: const ptrdiff_t AutoStride // // AutoStride const ptrdiff_t AutoStride = std::numeric_limits::min(); //!cpp:class:: // This is a light-weight wrapper around an image, that provides a context // for pixel access. This does NOT claim ownership of the pixels or copy // image data class OCIOEXPORT ImageDesc { public: //!cpp:function:: virtual ~ImageDesc(); private: ImageDesc& operator= (const ImageDesc &); }; extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const ImageDesc&); /////////////////////////////////////////////////////////////////////////// //!rst:: // PackedImageDesc // ^^^^^^^^^^^^^^^ //!cpp:class:: class OCIOEXPORT PackedImageDesc : public ImageDesc { public: //!cpp:function:: // Pass the pointer to packed image data: rgbrgbrgb, etc. // The number of channels must be greater than or equal to 3 // If a 4th channel is specified, it is assumed to be alpha // information. Channels > 4 will be ignored. PackedImageDesc(float * data, long width, long height, long numChannels, ptrdiff_t chanStrideBytes = AutoStride, ptrdiff_t xStrideBytes = AutoStride, ptrdiff_t yStrideBytes = AutoStride); //!cpp:function:: virtual ~PackedImageDesc(); //!cpp:function:: float * getData() const; //!cpp:function:: long getWidth() const; //!cpp:function:: long getHeight() const; //!cpp:function:: long getNumChannels() const; //!cpp:function:: ptrdiff_t getChanStrideBytes() const; //!cpp:function:: ptrdiff_t getXStrideBytes() const; //!cpp:function:: ptrdiff_t getYStrideBytes() const; private: class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } PackedImageDesc(const PackedImageDesc &); PackedImageDesc& operator= (const PackedImageDesc &); }; /////////////////////////////////////////////////////////////////////////// //!rst:: // PlanarImageDesc // ^^^^^^^^^^^^^^^ //!cpp:class:: class OCIOEXPORT PlanarImageDesc : public ImageDesc { public: //!cpp:function:: // Pass the pointer to the specified image planes: rrrr gggg bbbb, etc. // aData is optional, pass NULL if no alpha exists. // {r,g,b} Data must be specified PlanarImageDesc(float * rData, float * gData, float * bData, float * aData, long width, long height, ptrdiff_t yStrideBytes = AutoStride); //!cpp:function:: virtual ~PlanarImageDesc(); //!cpp:function:: float* getRData() const; //!cpp:function:: float* getGData() const; //!cpp:function:: float* getBData() const; //!cpp:function:: float* getAData() const; //!cpp:function:: long getWidth() const; //!cpp:function:: long getHeight() const; //!cpp:function:: ptrdiff_t getYStrideBytes() const; private: class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } PlanarImageDesc(const PlanarImageDesc &); PlanarImageDesc& operator= (const PlanarImageDesc &); }; /////////////////////////////////////////////////////////////////////////// //!rst:: // GpuShaderDesc // ************* //!cpp:class:: class OCIOEXPORT GpuShaderDesc { public: //!cpp:function:: GpuShaderDesc(); //!cpp:function:: ~GpuShaderDesc(); //!cpp:function:: Set the shader program language void setLanguage(GpuLanguage lang); //!cpp:function:: GpuLanguage getLanguage() const; //!cpp:function:: Set the function name of the shader program void setFunctionName(const char * name); //!cpp:function:: const char * getFunctionName() const; //!cpp:function:: void setLut3DEdgeLen(int len); //!cpp:function:: int getLut3DEdgeLen() const; //!cpp:function:: const char * getCacheID() const; private: GpuShaderDesc(const GpuShaderDesc &); GpuShaderDesc& operator= (const GpuShaderDesc &); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; /////////////////////////////////////////////////////////////////////////// //!rst:: // Context // ******* //!cpp:class:: class OCIOEXPORT Context { public: //!cpp:function:: static ContextRcPtr Create(); //!cpp:function:: ContextRcPtr createEditableCopy() const; //!cpp:function:: const char * getCacheID() const; //!cpp:function:: void setSearchPath(const char * path); //!cpp:function:: const char * getSearchPath() const; //!cpp:function:: void setWorkingDir(const char * dirname); //!cpp:function:: const char * getWorkingDir() const; //!cpp:function:: void setStringVar(const char * name, const char * value); //!cpp:function:: const char * getStringVar(const char * name) const; //!cpp:function:: int getNumStringVars() const; //!cpp:function:: const char * getStringVarNameByIndex(int index) const; //!cpp:function:: void clearStringVars(); //!cpp:function:: void setEnvironmentMode(EnvironmentMode mode); //!cpp:function:: EnvironmentMode getEnvironmentMode() const; //!cpp:function:: Seed all string vars with the current environment. void loadEnvironment(); //! Do a string lookup. //!cpp:function:: Do a file lookup. // // Evaluate the specified variable (as needed). Will not throw exceptions. const char * resolveStringVar(const char * val) const; //! Do a file lookup. //!cpp:function:: Do a file lookup. // // Evaluate all variables (as needed). // Also, walk the full search path until the file is found. // If the filename cannot be found, an exception will be thrown. const char * resolveFileLocation(const char * filename) const; private: Context(); ~Context(); Context(const Context &); Context& operator= (const Context &); static void deleter(Context* c); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const Context&); } OCIO_NAMESPACE_EXIT #endif // INCLUDED_OCIO_OPENCOLORIO_H opencolorio-1.1.0~dfsg0.orig/export/OpenColorIO/OpenColorTransforms.h0000644000175000017500000006376413223553423024107 0ustar mfvmfv/* 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_OCIO_OPENCOLORTRANSFORMS_H #define INCLUDED_OCIO_OPENCOLORTRANSFORMS_H #include "OpenColorTypes.h" #ifndef OCIO_NAMESPACE_ENTER #error This header cannot be used directly. Use instead. #endif /*!rst:: C++ Transforms ============== Typically only needed when creating and/or manipulating configurations */ OCIO_NAMESPACE_ENTER { //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: class OCIOEXPORT Transform { public: virtual ~Transform(); virtual TransformRcPtr createEditableCopy() const = 0; virtual TransformDirection getDirection() const = 0; virtual void setDirection(TransformDirection dir) = 0; private: Transform& operator= (const Transform &); }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const Transform&); //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: Forward direction wraps the 'expanded' range into the // specified, often compressed, range. class OCIOEXPORT AllocationTransform : public Transform { public: //!cpp:function:: static AllocationTransformRcPtr Create(); //!cpp:function:: virtual TransformRcPtr createEditableCopy() const; //!cpp:function:: virtual TransformDirection getDirection() const; //!cpp:function:: virtual void setDirection(TransformDirection dir); //!cpp:function:: Allocation getAllocation() const; //!cpp:function:: void setAllocation(Allocation allocation); //!cpp:function:: int getNumVars() const; //!cpp:function:: void getVars(float * vars) const; //!cpp:function:: void setVars(int numvars, const float * vars); private: AllocationTransform(); AllocationTransform(const AllocationTransform &); virtual ~AllocationTransform(); AllocationTransform& operator= (const AllocationTransform &); static void deleter(AllocationTransform* t); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const AllocationTransform&); //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: An implementation of the ASC CDL Transfer Functions and // Interchange - Syntax (Based on the version 1.2 document) // // .. note:: // the clamping portion of the CDL is only applied if a non-identity // power is specified. class OCIOEXPORT CDLTransform : public Transform { public: //!cpp:function:: static CDLTransformRcPtr Create(); //!cpp:function:: // Load the CDL from the src .cc or .ccc file. // If a .ccc is used, the cccid must also be specified // src must be an absolute path reference, no relative directory // or envvar resolution is performed. static CDLTransformRcPtr CreateFromFile(const char * src, const char * cccid); //!cpp:function:: virtual TransformRcPtr createEditableCopy() const; //!cpp:function:: virtual TransformDirection getDirection() const; //!cpp:function:: virtual void setDirection(TransformDirection dir); //!cpp:function:: bool equals(const ConstCDLTransformRcPtr & other) const; //!cpp:function:: const char * getXML() const; //!cpp:function:: void setXML(const char * xml); //!rst:: **ASC_SOP** // // Slope, offset, power:: // // out = clamp( (in * slope) + offset ) ^ power //!cpp:function:: void setSlope(const float * rgb); //!cpp:function:: void getSlope(float * rgb) const; //!cpp:function:: void setOffset(const float * rgb); //!cpp:function:: void getOffset(float * rgb) const; //!cpp:function:: void setPower(const float * rgb); //!cpp:function:: void getPower(float * rgb) const; //!cpp:function:: void setSOP(const float * vec9); //!cpp:function:: void getSOP(float * vec9) const; //!rst:: **ASC_SAT** //!cpp:function:: void setSat(float sat); //!cpp:function:: float getSat() const; //!cpp:function:: These are hard-coded, by spec, to r709 void getSatLumaCoefs(float * rgb) const; //!rst:: **Metadata** // // These do not affect the image processing, but // are often useful for pipeline purposes and are // included in the serialization. //!cpp:function:: Unique Identifier for this correction void setID(const char * id); //!cpp:function:: const char * getID() const; //!cpp:function:: Textual description of color correction // (stored on the SOP) void setDescription(const char * desc); //!cpp:function:: const char * getDescription() const; private: CDLTransform(); CDLTransform(const CDLTransform &); virtual ~CDLTransform(); CDLTransform& operator= (const CDLTransform &); static void deleter(CDLTransform* t); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const CDLTransform&); //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: class OCIOEXPORT ColorSpaceTransform : public Transform { public: //!cpp:function:: static ColorSpaceTransformRcPtr Create(); //!cpp:function:: virtual TransformRcPtr createEditableCopy() const; //!cpp:function:: virtual TransformDirection getDirection() const; //!cpp:function:: virtual void setDirection(TransformDirection dir); //!cpp:function:: const char * getSrc() const; //!cpp:function:: void setSrc(const char * src); //!cpp:function:: const char * getDst() const; //!cpp:function:: void setDst(const char * dst); private: ColorSpaceTransform(); ColorSpaceTransform(const ColorSpaceTransform &); virtual ~ColorSpaceTransform(); ColorSpaceTransform& operator= (const ColorSpaceTransform &); static void deleter(ColorSpaceTransform* t); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const ColorSpaceTransform&); //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: class OCIOEXPORT DisplayTransform : public Transform { public: //!cpp:function:: static DisplayTransformRcPtr Create(); //!cpp:function:: virtual TransformRcPtr createEditableCopy() const; //!cpp:function:: virtual TransformDirection getDirection() const; //!cpp:function:: virtual void setDirection(TransformDirection dir); //!cpp:function:: Step 0. Specify the incoming color space void setInputColorSpaceName(const char * name); //!cpp:function:: const char * getInputColorSpaceName() const; //!cpp:function:: Step 1: Apply a Color Correction, in ROLE_SCENE_LINEAR void setLinearCC(const ConstTransformRcPtr & cc); //!cpp:function:: ConstTransformRcPtr getLinearCC() const; //!cpp:function:: Step 2: Apply a color correction, in ROLE_COLOR_TIMING void setColorTimingCC(const ConstTransformRcPtr & cc); //!cpp:function:: ConstTransformRcPtr getColorTimingCC() const; //!cpp:function:: Step 3: Apply the Channel Viewing Swizzle (mtx) void setChannelView(const ConstTransformRcPtr & transform); //!cpp:function:: ConstTransformRcPtr getChannelView() const; //!cpp:function:: Step 4: Apply the output display transform // This is controlled by the specification of (display, view) void setDisplay(const char * display); //!cpp:function:: const char * getDisplay() const; //!cpp:function::Specify which view transform to use void setView(const char * view); //!cpp:function:: const char * getView() const; //!cpp:function:: Step 5: Apply a post display transform color correction void setDisplayCC(const ConstTransformRcPtr & cc); //!cpp:function:: ConstTransformRcPtr getDisplayCC() const; //!cpp:function:: A user can optionally override the looks that are, // by default, used with the expected display / view combination. // A common use case for this functionality is in an image viewing // app, where per-shot looks are supported. If for some reason // a per-shot look is not defined for the current Context, the // Config::getProcessor fcn will not succeed by default. Thus, // with this mechanism the viewing app could override to looks = "", // and this will allow image display to continue (though hopefully) // the interface would reflect this fallback option.) // // Looks is a potentially comma (or colon) delimited list of lookNames, // Where +/- prefixes are optionally allowed to denote forward/inverse // look specification. (And forward is assumed in the absense of either) void setLooksOverride(const char * looks); //!cpp:function:: const char * getLooksOverride() const; //!cpp:function:: Specifiy whether the lookOverride should be used, // or not. This is a speparate flag, as it's often useful to override // "looks" to an empty string void setLooksOverrideEnabled(bool enabled); //!cpp:function:: bool getLooksOverrideEnabled() const; private: DisplayTransform(); DisplayTransform(const DisplayTransform &); virtual ~DisplayTransform(); DisplayTransform& operator= (const DisplayTransform &); static void deleter(DisplayTransform* t); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const DisplayTransform&); //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: Represents exponent transform: pow( clamp(color), value) // // If the exponent is 1.0, this will not clamp. Otherwise, the input color // will be clamped between [0.0, inf] class OCIOEXPORT ExponentTransform : public Transform { public: //!cpp:function:: static ExponentTransformRcPtr Create(); //!cpp:function:: virtual TransformRcPtr createEditableCopy() const; //!cpp:function:: virtual TransformDirection getDirection() const; //!cpp:function:: virtual void setDirection(TransformDirection dir); //!cpp:function:: void setValue(const float * vec4); //!cpp:function:: void getValue(float * vec4) const; private: ExponentTransform(); ExponentTransform(const ExponentTransform &); virtual ~ExponentTransform(); ExponentTransform& operator= (const ExponentTransform &); static void deleter(ExponentTransform* t); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const ExponentTransform&); //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: class OCIOEXPORT FileTransform : public Transform { public: //!cpp:function:: static FileTransformRcPtr Create(); //!cpp:function:: virtual TransformRcPtr createEditableCopy() const; //!cpp:function:: virtual TransformDirection getDirection() const; //!cpp:function:: virtual void setDirection(TransformDirection dir); //!cpp:function:: const char * getSrc() const; //!cpp:function:: void setSrc(const char * src); //!cpp:function:: const char * getCCCId() const; //!cpp:function:: void setCCCId(const char * id); //!cpp:function:: Interpolation getInterpolation() const; //!cpp:function:: void setInterpolation(Interpolation interp); //!cpp:function:: get the number of lut readers static int getNumFormats(); //!cpp:function:: get the lut readers at index, return empty string if // an invalid index is specified static const char * getFormatNameByIndex(int index); //!cpp:function:: get the lut reader extension at index, return empty string if // an invalid index is specified static const char * getFormatExtensionByIndex(int index); private: FileTransform(); FileTransform(const FileTransform &); virtual ~FileTransform(); FileTransform& operator= (const FileTransform &); static void deleter(FileTransform* t); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const FileTransform&); //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: class OCIOEXPORT GroupTransform : public Transform { public: //!cpp:function:: static GroupTransformRcPtr Create(); //!cpp:function:: virtual TransformRcPtr createEditableCopy() const; //!cpp:function:: virtual TransformDirection getDirection() const; //!cpp:function:: virtual void setDirection(TransformDirection dir); //!cpp:function:: ConstTransformRcPtr getTransform(int index) const; //!cpp:function:: int size() const; //!cpp:function:: void push_back(const ConstTransformRcPtr& transform); //!cpp:function:: void clear(); //!cpp:function:: bool empty() const; private: GroupTransform(); GroupTransform(const GroupTransform &); virtual ~GroupTransform(); GroupTransform& operator= (const GroupTransform &); static void deleter(GroupTransform* t); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const GroupTransform&); //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: Represents log transform: log(color, base) // // * The input will be clamped for negative numbers. // * Default base is 2.0 // * Only the rgb channels are affected class OCIOEXPORT LogTransform : public Transform { public: //!cpp:function:: static LogTransformRcPtr Create(); //!cpp:function:: virtual TransformRcPtr createEditableCopy() const; //!cpp:function:: virtual TransformDirection getDirection() const; //!cpp:function:: virtual void setDirection(TransformDirection dir); //!cpp:function:: void setBase(float val); //!cpp:function:: float getBase() const; private: LogTransform(); LogTransform(const LogTransform &); virtual ~LogTransform(); LogTransform& operator= (const LogTransform &); static void deleter(LogTransform* t); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const LogTransform&); //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: class OCIOEXPORT LookTransform : public Transform { public: //!cpp:function:: static LookTransformRcPtr Create(); //!cpp:function:: virtual TransformRcPtr createEditableCopy() const; //!cpp:function:: virtual TransformDirection getDirection() const; //!cpp:function:: virtual void setDirection(TransformDirection dir); //!cpp:function:: const char * getSrc() const; //!cpp:function:: void setSrc(const char * src); //!cpp:function:: const char * getDst() const; //!cpp:function:: void setDst(const char * dst); //!cpp:function:: Specify looks to apply. // Looks is a potentially comma (or colon) delimited list of look names, // Where +/- prefixes are optionally allowed to denote forward/inverse // look specification. (And forward is assumed in the absense of either) void setLooks(const char * looks); //!cpp:function:: const char * getLooks() const; private: LookTransform(); LookTransform(const LookTransform &); virtual ~LookTransform(); LookTransform& operator= (const LookTransform &); static void deleter(LookTransform* t); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const LookTransform&); //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: Represents an MX+B Matrix transform class OCIOEXPORT MatrixTransform : public Transform { public: //!cpp:function:: static MatrixTransformRcPtr Create(); //!cpp:function:: virtual TransformRcPtr createEditableCopy() const; //!cpp:function:: virtual TransformDirection getDirection() const; //!cpp:function:: virtual void setDirection(TransformDirection dir); //!cpp:function:: bool equals(const MatrixTransform & other) const; //!cpp:function:: void setValue(const float * m44, const float * offset4); //!cpp:function:: void getValue(float * m44, float * offset4) const; //!cpp:function:: void setMatrix(const float * m44); //!cpp:function:: void getMatrix(float * m44) const; //!cpp:function:: void setOffset(const float * offset4); //!cpp:function:: void getOffset(float * offset4) const; //!rst:: **Convenience functions** // // to get the mtx and offset corresponding to higher-level concepts // // .. note:: // These can throw an exception if for any component // ``oldmin == oldmax. (divide by 0)`` //!cpp:function:: static void Fit(float * m44, float * offset4, const float * oldmin4, const float * oldmax4, const float * newmin4, const float * newmax4); //!cpp:function:: static void Identity(float * m44, float * offset4); //!cpp:function:: static void Sat(float * m44, float * offset4, float sat, const float * lumaCoef3); //!cpp:function:: static void Scale(float * m44, float * offset4, const float * scale4); //!cpp:function:: static void View(float * m44, float * offset4, int * channelHot4, const float * lumaCoef3); private: MatrixTransform(); MatrixTransform(const MatrixTransform &); virtual ~MatrixTransform(); MatrixTransform& operator= (const MatrixTransform &); static void deleter(MatrixTransform* t); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const MatrixTransform&); //!rst:: ////////////////////////////////////////////////////////////////// //!cpp:class:: Truelight transform using its API class OCIOEXPORT TruelightTransform : public Transform { public: //!cpp:function:: static TruelightTransformRcPtr Create(); //!cpp:function:: virtual TransformRcPtr createEditableCopy() const; //!cpp:function:: virtual TransformDirection getDirection() const; //!cpp:function:: virtual void setDirection(TransformDirection dir); //!cpp:function:: void setConfigRoot(const char * configroot); //!cpp:function:: const char * getConfigRoot() const; //!cpp:function:: void setProfile(const char * profile); //!cpp:function:: const char * getProfile() const; //!cpp:function:: void setCamera(const char * camera); //!cpp:function:: const char * getCamera() const; //!cpp:function:: void setInputDisplay(const char * display); //!cpp:function:: const char * getInputDisplay() const; //!cpp:function:: void setRecorder(const char * recorder); //!cpp:function:: const char * getRecorder() const; //!cpp:function:: void setPrint(const char * print); //!cpp:function:: const char * getPrint() const; //!cpp:function:: void setLamp(const char * lamp); //!cpp:function:: const char * getLamp() const; //!cpp:function:: void setOutputCamera(const char * camera); //!cpp:function:: const char * getOutputCamera() const; //!cpp:function:: void setDisplay(const char * display); //!cpp:function:: const char * getDisplay() const; //!cpp:function:: void setCubeInput(const char * type); //!cpp:function:: const char * getCubeInput() const; private: TruelightTransform(); TruelightTransform(const TruelightTransform &); virtual ~TruelightTransform(); TruelightTransform& operator= (const TruelightTransform &); static void deleter(TruelightTransform* t); class Impl; friend class Impl; Impl * m_impl; Impl * getImpl() { return m_impl; } const Impl * getImpl() const { return m_impl; } }; //!cpp:function:: extern OCIOEXPORT std::ostream& operator<< (std::ostream&, const TruelightTransform &); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/export/OpenColorIO/OpenColorABI.h.in0000644000175000017500000001003113223553423022724 0ustar mfvmfv/* 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_OCIO_OPENCOLORABI_H #define INCLUDED_OCIO_OPENCOLORABI_H // Makefile configuration options #define OCIO_NAMESPACE @OCIO_NAMESPACE@ #define OCIO_USE_BOOST_PTR @OCIO_USE_BOOST_PTR@ #define OCIO_VERSION "@OCIO_VERSION@" #define OCIO_VERSION_NS v@SOVERSION@ /* Version as a single 4-byte hex number, e.g. 0x01050200 == 1.5.2 Use this for numeric comparisons, e.g. #if OCIO_VERSION_HEX >= ... Note: in the case where SOVERSION is overridden at compile-time, this will reflect the original API version number. */ #define OCIO_VERSION_HEX ((@OCIO_VERSION_MAJOR@ << 24) | \ (@OCIO_VERSION_MINOR@ << 16) | \ (@OCIO_VERSION_PATCH@ << 8)) // Namespace / version mojo #define OCIO_NAMESPACE_ENTER namespace OCIO_NAMESPACE { namespace OCIO_VERSION_NS #define OCIO_NAMESPACE_EXIT using namespace OCIO_VERSION_NS; } #define OCIO_NAMESPACE_USING using namespace OCIO_NAMESPACE; // shared_ptr / dynamic_pointer_cast #if OCIO_USE_BOOST_PTR #include #define OCIO_SHARED_PTR boost::shared_ptr #define OCIO_DYNAMIC_POINTER_CAST boost::dynamic_pointer_cast #elif defined(_LIBCPP_VERSION) #include #define OCIO_SHARED_PTR std::shared_ptr #define OCIO_DYNAMIC_POINTER_CAST std::dynamic_pointer_cast #elif __GNUC__ >= 4 #include #define OCIO_SHARED_PTR std::tr1::shared_ptr #define OCIO_DYNAMIC_POINTER_CAST std::tr1::dynamic_pointer_cast #elif (_MSC_VER > 1600) #include #define OCIO_SHARED_PTR std::shared_ptr #define OCIO_DYNAMIC_POINTER_CAST std::dynamic_pointer_cast #else #error OCIO needs gcc 4 or later to get access to (or specify USE_BOOST_PTR instead) #endif // If supported, define OCIOEXPORT, OCIOHIDDEN // (used to choose which symbols to export from OpenColorIO) #if defined __GNUC__ #if __GNUC__ >= 4 #define OCIOEXPORT __attribute__ ((visibility("default"))) #define OCIOHIDDEN __attribute__ ((visibility("hidden"))) #else #define OCIOEXPORT #define OCIOHIDDEN #endif #elif defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) || defined(_MSC_VER) // Windows requires you to export from the main library and then import in any others #ifndef OpenColorIO_STATIC #if defined OpenColorIO_EXPORTS #define OCIOEXPORT __declspec(dllexport) #else #define OCIOEXPORT __declspec(dllimport) #endif #else #define OCIOEXPORT #endif #define OCIOHIDDEN #else // Others platforms not supported atm #define OCIOEXPORT #define OCIOHIDDEN #endif #endif // INCLUDED_OCIO_OPENCOLORABI_H opencolorio-1.1.0~dfsg0.orig/export/OpenColorIO/OpenColorTypes.h0000644000175000017500000003216613223553423023045 0ustar mfvmfv/* 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_OCIO_OPENCOLORTYPES_H #define INCLUDED_OCIO_OPENCOLORTYPES_H #include "OpenColorABI.h" #ifndef OCIO_NAMESPACE_ENTER #error This header cannot be used directly. Use instead. #endif #include #include /*!rst:: C++ Types ========= */ OCIO_NAMESPACE_ENTER { // Predeclare all class ptr definitions //!rst:: // Core // **** class OCIOEXPORT Config; //!cpp:type:: typedef OCIO_SHARED_PTR ConstConfigRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR ConfigRcPtr; class OCIOEXPORT ColorSpace; //!cpp:type:: typedef OCIO_SHARED_PTR ConstColorSpaceRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR ColorSpaceRcPtr; class OCIOEXPORT Look; //!cpp:type:: typedef OCIO_SHARED_PTR ConstLookRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR LookRcPtr; class OCIOEXPORT Context; //!cpp:type:: typedef OCIO_SHARED_PTR ConstContextRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR ContextRcPtr; class OCIOEXPORT Processor; //!cpp:type:: typedef OCIO_SHARED_PTR ConstProcessorRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR ProcessorRcPtr; class OCIOEXPORT ProcessorMetadata; //!cpp:type:: typedef OCIO_SHARED_PTR ConstProcessorMetadataRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR ProcessorMetadataRcPtr; class OCIOEXPORT Baker; //!cpp:type:: typedef OCIO_SHARED_PTR ConstBakerRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR BakerRcPtr; class OCIOEXPORT ImageDesc; class OCIOEXPORT GpuShaderDesc; class OCIOEXPORT Exception; //!rst:: // Transforms // ********** class OCIOEXPORT Transform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR TransformRcPtr; class OCIOEXPORT AllocationTransform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstAllocationTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR AllocationTransformRcPtr; class OCIOEXPORT CDLTransform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstCDLTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR CDLTransformRcPtr; class OCIOEXPORT ColorSpaceTransform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstColorSpaceTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR ColorSpaceTransformRcPtr; class OCIOEXPORT DisplayTransform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstDisplayTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR DisplayTransformRcPtr; class OCIOEXPORT ExponentTransform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstExponentTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR ExponentTransformRcPtr; class OCIOEXPORT FileTransform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstFileTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR FileTransformRcPtr; class OCIOEXPORT GroupTransform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstGroupTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR GroupTransformRcPtr; class OCIOEXPORT LogTransform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstLogTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR LogTransformRcPtr; class OCIOEXPORT LookTransform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstLookTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR LookTransformRcPtr; class OCIOEXPORT MatrixTransform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstMatrixTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR MatrixTransformRcPtr; class OCIOEXPORT TruelightTransform; //!cpp:type:: typedef OCIO_SHARED_PTR ConstTruelightTransformRcPtr; //!cpp:type:: typedef OCIO_SHARED_PTR TruelightTransformRcPtr; template inline OCIO_SHARED_PTR DynamicPtrCast(OCIO_SHARED_PTR const & ptr) { return OCIO_DYNAMIC_POINTER_CAST(ptr); } //!rst:: // Enums // ***** enum LoggingLevel { LOGGING_LEVEL_NONE = 0, LOGGING_LEVEL_WARNING = 1, LOGGING_LEVEL_INFO = 2, LOGGING_LEVEL_DEBUG = 3, LOGGING_LEVEL_UNKNOWN = 255 }; //!cpp:type:: enum ColorSpaceDirection { COLORSPACE_DIR_UNKNOWN = 0, COLORSPACE_DIR_TO_REFERENCE, COLORSPACE_DIR_FROM_REFERENCE }; //!cpp:type:: enum TransformDirection { TRANSFORM_DIR_UNKNOWN = 0, TRANSFORM_DIR_FORWARD, TRANSFORM_DIR_INVERSE }; //!cpp:type:: // // Specify the interpolation type to use // If the specified interpolation type is not supported in the requested // context (for example, using tetrahedral interpolationon 1D luts) // an exception will be throw. // // INTERP_BEST will choose the best interpolation type for the requested // context: // // Lut1D INTERP_BEST: LINEAR // Lut3D INTERP_BEST: LINEAR // // Note: INTERP_BEST is subject to change in minor releases, so if you // care about locking off on a specific interpolation type, we'd recommend // directly specifying it. enum Interpolation { INTERP_UNKNOWN = 0, INTERP_NEAREST = 1, //! nearest neighbor in all dimensions INTERP_LINEAR = 2, //! linear interpolation in all dimensions INTERP_TETRAHEDRAL = 3, //! tetrahedral interpolation in all directions INTERP_BEST = 255 //! the 'best' suitable interpolation type }; //!cpp:type:: enum BitDepth { BIT_DEPTH_UNKNOWN = 0, BIT_DEPTH_UINT8, BIT_DEPTH_UINT10, BIT_DEPTH_UINT12, BIT_DEPTH_UINT14, BIT_DEPTH_UINT16, BIT_DEPTH_UINT32, BIT_DEPTH_F16, BIT_DEPTH_F32 }; //!cpp:type:: enum Allocation { ALLOCATION_UNKNOWN = 0, ALLOCATION_UNIFORM, ALLOCATION_LG2 }; //!cpp:type:: Used when there is a choice of hardware shader language. enum GpuLanguage { GPU_LANGUAGE_UNKNOWN = 0, GPU_LANGUAGE_CG, ///< Nvidia Cg shader GPU_LANGUAGE_GLSL_1_0, ///< OpenGL Shading Language GPU_LANGUAGE_GLSL_1_3 ///< OpenGL Shading Language }; //!cpp:type:: enum EnvironmentMode { ENV_ENVIRONMENT_UNKNOWN = 0, ENV_ENVIRONMENT_LOAD_PREDEFINED, ENV_ENVIRONMENT_LOAD_ALL }; //!rst:: // Conversion // ********** //!cpp:function:: extern OCIOEXPORT const char * BoolToString(bool val); //!cpp:function:: extern OCIOEXPORT bool BoolFromString(const char * s); //!cpp:function:: extern OCIOEXPORT const char * LoggingLevelToString(LoggingLevel level); //!cpp:function:: extern OCIOEXPORT LoggingLevel LoggingLevelFromString(const char * s); //!cpp:function:: extern OCIOEXPORT const char * TransformDirectionToString(TransformDirection dir); //!cpp:function:: extern OCIOEXPORT TransformDirection TransformDirectionFromString(const char * s); //!cpp:function:: extern OCIOEXPORT TransformDirection GetInverseTransformDirection(TransformDirection dir); //!cpp:function:: extern OCIOEXPORT TransformDirection CombineTransformDirections(TransformDirection d1, TransformDirection d2); //!cpp:function:: extern OCIOEXPORT const char * ColorSpaceDirectionToString(ColorSpaceDirection dir); //!cpp:function:: extern OCIOEXPORT ColorSpaceDirection ColorSpaceDirectionFromString(const char * s); //!cpp:function:: extern OCIOEXPORT const char * BitDepthToString(BitDepth bitDepth); //!cpp:function:: extern OCIOEXPORT BitDepth BitDepthFromString(const char * s); //!cpp:function:: extern OCIOEXPORT bool BitDepthIsFloat(BitDepth bitDepth); //!cpp:function:: extern OCIOEXPORT int BitDepthToInt(BitDepth bitDepth); //!cpp:function:: extern OCIOEXPORT const char * AllocationToString(Allocation allocation); //!cpp:function:: extern OCIOEXPORT Allocation AllocationFromString(const char * s); //!cpp:function:: extern OCIOEXPORT const char * InterpolationToString(Interpolation interp); //!cpp:function:: extern OCIOEXPORT Interpolation InterpolationFromString(const char * s); //!cpp:function:: extern OCIOEXPORT const char * GpuLanguageToString(GpuLanguage language); //!cpp:function:: extern OCIOEXPORT GpuLanguage GpuLanguageFromString(const char * s); //!cpp:function:: extern OCIOEXPORT const char * EnvironmentModeToString(EnvironmentMode mode); //!cpp:function:: extern OCIOEXPORT EnvironmentMode EnvironmentModeFromString(const char * s); /*!rst:: Roles ***** ColorSpace Roles are used so that plugins, in addition to this API can have abstract ways of asking for common colorspaces, without referring to them by hardcoded names. Internal:: GetGPUDisplayTransform - (ROLE_SCENE_LINEAR (fstop exposure)) (ROLE_COLOR_TIMING (ASCColorCorrection)) External Plugins (currently known):: Colorpicker UIs - (ROLE_COLOR_PICKING) Compositor LogConvert - (ROLE_SCENE_LINEAR, ROLE_COMPOSITING_LOG) */ //!rst:: // .. c:var:: const char* ROLE_DEFAULT // // "default" extern OCIOEXPORT const char * ROLE_DEFAULT; //!rst:: // .. c:var:: const char* ROLE_REFERENCE // // "reference" extern OCIOEXPORT const char * ROLE_REFERENCE; //!rst:: // .. c:var:: const char* ROLE_DATA // // "data" extern OCIOEXPORT const char * ROLE_DATA; //!rst:: // .. c:var:: const char* ROLE_COLOR_PICKING // // "color_picking" extern OCIOEXPORT const char * ROLE_COLOR_PICKING; //!rst:: // .. c:var:: const char* ROLE_SCENE_LINEAR // // "scene_linear" extern OCIOEXPORT const char * ROLE_SCENE_LINEAR; //!rst:: // .. c:var:: const char* ROLE_COMPOSITING_LOG // // "compositing_log" extern OCIOEXPORT const char * ROLE_COMPOSITING_LOG; //!rst:: // .. c:var:: const char* ROLE_COLOR_TIMING // // "color_timing" extern OCIOEXPORT const char * ROLE_COLOR_TIMING; //!rst:: // .. c:var:: const char* ROLE_TEXTURE_PAINT // // This role defines the transform for painting textures. In some // workflows this is just a inverse display gamma with some limits extern OCIOEXPORT const char * ROLE_TEXTURE_PAINT; //!rst:: // .. c:var:: const char* ROLE_MATTE_PAINT // // This role defines the transform for matte painting. In some workflows // this is a 1D HDR to LDR allocation. It is normally combined with // another display transform in the host app for preview. extern OCIOEXPORT const char * ROLE_MATTE_PAINT; } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/export/PyOpenColorIO/0000755000175000017500000000000013223553423020250 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/export/PyOpenColorIO/PyOpenColorIO.h0000644000175000017500000001027713223553423023071 0ustar mfvmfv/* 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_PYOCIO_H #define INCLUDED_PYOCIO_PYOCIO_H #include #include OCIO_NAMESPACE_ENTER { // ColorSpace PyObject * BuildConstPyColorSpace(ConstColorSpaceRcPtr colorSpace); PyObject * BuildEditablePyColorSpace(ColorSpaceRcPtr colorSpace); bool IsPyColorSpace(PyObject * pyobject); bool IsPyColorSpaceEditable(PyObject * pyobject); ConstColorSpaceRcPtr GetConstColorSpace(PyObject * pyobject, bool allowCast); ColorSpaceRcPtr GetEditableColorSpace(PyObject * pyobject); // Config PyObject * BuildConstPyConfig(ConstConfigRcPtr config); PyObject * BuildEditablePyConfig(ConfigRcPtr config); bool IsPyConfig(PyObject * config); bool IsPyConfigEditable(PyObject * config); ConstConfigRcPtr GetConstConfig(PyObject * config, bool allowCast); ConfigRcPtr GetEditableConfig(PyObject * config); // Context PyObject * BuildConstPyContext(ConstContextRcPtr context); PyObject * BuildEditablePyContext(ContextRcPtr context); bool IsPyContext(PyObject * config); bool IsPyContextEditable(PyObject * config); ConstContextRcPtr GetConstContext(PyObject * context, bool allowCast); ContextRcPtr GetEditableContext(PyObject * context); // Exception // Warning: these cannot return valid PyObject pointers before // the python module has been initialized. Beware of calling these // at static construction time. PyObject * GetExceptionPyType(); PyObject * GetExceptionMissingFilePyType(); // Processor PyObject * BuildConstPyProcessor(ConstProcessorRcPtr processor); bool IsPyProcessor(PyObject * pyobject); ConstProcessorRcPtr GetConstProcessor(PyObject * pyobject); // ProcessorMetadata PyObject * BuildConstPyProcessorMetadata(ConstProcessorMetadataRcPtr metadata); bool IsPyProcessorMetadata(PyObject * pyobject); ConstProcessorMetadataRcPtr GetConstProcessorMetadata(PyObject * pyobject); // Transform PyObject * BuildConstPyTransform(ConstTransformRcPtr transform); PyObject * BuildEditablePyTransform(TransformRcPtr transform); bool IsPyTransform(PyObject * pyobject); bool IsPyTransformEditable(PyObject * pyobject); ConstTransformRcPtr GetConstTransform(PyObject * pyobject, bool allowCast); TransformRcPtr GetEditableTransform(PyObject * pyobject); // Look PyObject * BuildConstPyLook(ConstLookRcPtr look); PyObject * BuildEditablePyLook(LookRcPtr look); bool IsPyLook(PyObject * pyobject); bool IsPyLookEditable(PyObject * pyobject); ConstLookRcPtr GetConstLook(PyObject * pyobject, bool allowCast); LookRcPtr GetEditableLook(PyObject * pyobject); } OCIO_NAMESPACE_EXIT #endif opencolorio-1.1.0~dfsg0.orig/INSTALL0000644000175000017500000000006413223553423015317 0ustar mfvmfvFor install instructions, see docs/installation.rst opencolorio-1.1.0~dfsg0.orig/.travis.yml0000644000175000017500000000206313223553423016400 0ustar mfvmfv# travis-ci.org build file # https://docs.travis-ci.com/user/languages/cpp matrix: include: - os: linux language: cpp compiler: clang - os: linux language: cpp compiler: gcc - os: osx language: cpp compiler: clang - os: osx language: cpp compiler: gcc - os: osx language: cpp compiler: clang osx_image: xcode9.1 env: - OPTIONS="-DCMAKE_BUILD_TYPE=Release -DOCIO_BUILD_TESTS=yes -DOCIO_BUILD_DOCS=yes" # Install missing packages install: - if [[ $TRAVIS_OS_NAME = linux ]]; then sudo apt-get update -qq; fi - if [[ $TRAVIS_OS_NAME = linux ]]; then sudo apt-get install -qq texlive-full; fi # Run the Build script script: - mkdir _build - cd _build - cmake .. -DCMAKE_INSTALL_PREFIX=../_install $OPTIONS - cmake --build . --target install - ctest --output-on-failure . - if [[ $TRAVIS_OS_NAME = linux ]]; then cmake --build . --target pdf; fi deploy: provider: pages skip_cleanup: true github_token: $GITHUB_TOKEN on: tags: true local_dir: ./docs/build-html opencolorio-1.1.0~dfsg0.orig/.gitignore0000644000175000017500000000010013223553423016245 0ustar mfvmfv.DS_Store attic build* _build* _install* dist* mastercopy *.pyc opencolorio-1.1.0~dfsg0.orig/ChangeLog0000644000175000017500000003077413223553423016053 0ustar mfvmfv**Version 1.1.0 (Jan 5 2018):** * libc++ build fixes * Added support for YAML > 5.0.1 * YAML and TinyXML patch fixes * Clang visibility fix * Added write support for Truelight LUTs * Improved OCIOYaml * Python string corruption fix * Added support for CDL * Updated documentation * Added args/kwargs support to Python MatrixTransform * Added description field to Look objects * Improved Python 3 compatibility * CSP file read fix * Added Linux, MacOS, and Windows continuos integration * Improved 1D LUT extrapolation * Improved 1D LUT negative handling * Improved Windows build system * Improved cross-platform build system * Undefined role crash fix * After Effects plugin updated * Added reference Photoshop plugin * Added reference Docker image **Version 1.0.9 (Sep 2 2013):** * CDL cccid supports both named id and index lookups * ociobakelut / ocioconvert updates * FreeBSD compile dixes * FileTransform disk cache allows concurrent disk lookups * CSP windows fix * Python 3 support * Fix envvar abs/relative path testing * Can explicitly declare config envvars * gcc44 compile warning fixes **Version 1.0.8 (Dec 11 2012):** * After Effects plugin * Core increased precision for matrix inversion * Core md5 symbols no longer leaked * CMake compatibility with OIIO 1.0 namespacing * Cmake option to control python soname * Nuke register_viewers defaults OCIODisplay to "all" * Nuke ColorLookup <-> spi1d lut examples * Windows uses boost shared_ptr by default * Windows fixed csp writing * Windows build fixes * ociobakelut supports looks **Version 1.0.7 (April 17 2012):** * IRIDAS .look support * ociolutimage utility added (handles image <-> 3dlut) * CMake build allows optional reliance on system libraries * CMake layout changes for python and nuke installs * Bumped internals to yaml 0.3.0, pystring 1.1.2 * Optimized internal handling of Matrix / Exponent Ops * Added INTERP_BEST interpolation option * Python config.clearLooks() added * Python docs revamp * Nuke config-dependent knob values now baked into .nk scripts * Nuke OCIOLookTransform gets reload button * Nuke nodes get updated help text **Version 1.0.6 (March 12 2012):** * JNI (Java) updates * ocioconvert arbitrary attr support **Version 1.0.5 (Feb 22 2012):** * Internal optimization framework added * SetLoggingLevel(..) bugfix * Python API Documentation / website updates * Clang compilation fix **Version 1.0.4 (Jan 25 2012):** * ocio2icc deprecated (functionality merged into ociobakelut) * rv integration (beta) * nuke: updated channel handling * Documentation / website updates **Version 1.0.3 (Dec 21 2011):** * Tetrahedral 3dlut interpolation (CPU only) * ociocheck and Config.sanityCheck() have improved validation * Mari: updated examples * Makefile: misc updates to match distro library conventions **Version 1.0.2 (Nov 30 2011):** * 3D lut processing (cpu) is resiliant to nans * Nuke OCIOFileTransform gains Reload buttons * Installation on multi-lib *nix systems improved * Installation handling of soversion for C++/python improved * ociobakelut improvements * Initial version of Java bindings (alpha) **Version 1.0.1 (Oct 31 2011):** * Luts with incorrect extension are properly loaded * ocio2icc / ociobakelut get --lut option (no longer requires ocio config) * DisplayTransform looks do not apply to 'data' passes. **Version 1.0.0 (Oct 3 2011):** * ABI Lockoff for 1.0 branch * General API Cleanup (removed deprecated / unnecessary functions) * New features can be added, but the ABI will only be extended in a binary compatible manner. Profiles written from 1.0 will always be readable in future versions. * Fixed Truelight Reading Bug * ocio2icc no longer requires ocio config (can provide raw lut(s) ------------------------------------------------------------------------------- **Version 0.8.7 (Oct 3 2011):** * Fixed Truelight Reading Bug **Version 0.8.6 (Sept 7 2011):** * Updated .ocio config reading / writing to be forwards compatibile with 1.0 (Profiles written in 0.8.6+ will be 1.0 compatible. Compatibility from prior versions is likely, though not guaranteed.) * Better logging * Added ColorSpace.equalitygroup (makes ColorSpace equality explicit) * Substantial Nuke node updates * Added support for Iridas .itx read/write * Windows Build Support **Version 0.8.5 (Aug 2 2011):** * Nuke OCIODisplay fixed (bug from 0.8.4) * Updated Houdini HDL Reader / Writer **Version 0.8.4 (July 25 2011):** * Native Look Support * Core / Nuke OCIODisplay supports alpha viewing * Added Houdini (.lut) writing * Added Pandora (.mga,.m3d) reading * Additional internal bug fixes **Version 0.8.3 (June 27 2011):** * OCIO::Config symlink resolution fixed (bugfix) * Nuke OCIODisplay knobs use string storage (bugfix) * Makefile cleanup * Documentation cleanup **Version 0.8.2 (June 7 2011):** * Numerous Windows compatibility fixes * Python binding improvements * OCIO::Baker / ociobakelut improvements * Lut1D/3D do not crash on nans (bugfix) * Nuke UI doesnt crash in known corner case (bugfix) **Version 0.8.1 (May 9 2011):** * New roles: TEXTURE_PAINT + MATTE_PAINT * Mari API Example (src/mari) * FileFormat registry updated to allow Windows + Debug support * boost_ptr build compatibility option **Version 0.8.0 (Apr 19 2011):** * ABI Lockoff for stable 0.8 branch New features can be added, but the ABI will only be extended in a binary compatible manner * Otherwise identical to 0.7.9 ------------------------------------------------------------------------------- **Version 0.7.9 (Apr 18 2011):** * Added support for .vf luts * Misc. Nuke enhancements * Adds optional boost ptr support (backwards compatibility) * Makefile enhancements (Nuke / CMAKE_INSTALL_EXEC_PREFIX) * cdlTransform.setXML crash fix **Version 0.7.8 (March 31 2011):** * Iridas lut (.cube) bugfix, DOMAIN_MIN / DOMAIN_MAX now obeyed * Exposed GPU functions in python (needed for Mari) * Nuke OCIODisplay cleanup: Fixed knob names and added envvar support * ociobaker cleanup * tinyxml ABI visibility cleaned up * Removed Boost dependency, tr1::shared_ptr now used instead **Version 0.7.7 (March 1 2011):** * Lut baking API + standalone app * Truelight runtime support (optional) * Cinespace (3d) lut writing * CSP prelut support * Boost argparse dependency removed * SanityCheck is more exhaustive * FileTransform supports relative path dirs * Python enhancements (transform kwarg support) * Makefile enhancements (OIIO Path) * Processor API update (code compatible, binary incompatible) **Version 0.7.6 (Feb 1 2011):** * Updated Config Display API (.ocio config format updated) * Added ocio2icc app (ICC Profile Generation) * Revamp of ASC CDL, added .cc and .ccc support * Documentation Improvements * Makefile enhancements (Boost_INCLUDE_DIR, etc) **Version 0.7.5 (Jan 13 2011):** * ociodisplay enhancements * gpu display bugfix (glsl profile 1.0 only) * Makefile enhancements * Nuke installation cleanup * Doc generation using sphinx (html + pdf) **Version 0.7.4 (Jan 4 2011):** * Added 'Context', allowing for 'per-shot' Transforms * Misc API Cleanup: removed old functions + fixed const-ness * Added config.sanityCheck() for validation * Additional Makefile configuration options, SONAME, etc. **Version 0.7.3 (Dec 16 2010):** * Added example applications: ociodisplay, ocioconvert * Makefile: Add boost header dependency * Makefile: Nuke plugins are now version specific * Fixed bug in GLSL MatrixOp **Version 0.7.2 (Dec 9 2010):** * GPUAllocation refactor (API tweak) * Added AllocationTransform * Added LogTransform * Removed CineonLogToLinTransform * A few bug fixes **Version 0.7.1 (Nov 15 2010):** * Additional 3d lut formats: Truelight .cub + Iridas .cube * FileTransform supports envvars and search paths * Added Nuke plugins: LogConvert + FileTransform * Improved OCIO profile formatting * GCC visibility used (when available) to hide private symbols * A few bug fixes **Version 0.7.0 (Oct 21 2010):** * Switched file format from XML to Yaml ------------------------------------------------------------------------------- **Version 0.6.1 (Oct 5 2010):** * Exposed ExponentTransform * Added CineonLogToLinTransform - a simple 'straight-line' negative linearization. Not strictly needed (could be done previously with LUTs) but often convenient to have. * Added DisplayTransform.displayCC for post display lut CC. * Many python improvements * A few bug fixes * A few Makefile enhancements **Version 0.6.0 (Sept 21 2010):** * Start of 0.6, "stable" branch All 0.6.x builds will be ABI compatible (forward only). New features (even experimental ones) will be added to the 0.6 branch, as long as binary and source compatibility is maintained. Once this no longer is possible, a 0.7 "dev" branch will be forked. * Split public header into 3 parts for improved readability (you still only import though) * Added MatrixTransform * Refactored internal unit testing * Fixed many compile warnings ------------------------------------------------------------------------------- **Version 0.5.16 (Sept 16 2010):** * PyTransforms now use native python class inheritance * OCIO namespace can now be configured at build time (for distribution in commercial apps) * Updated make install behavior * DisplayTransform accepts generic cc operators (instead of CDL only) * A few bug fixes / compile warning fixes **Version 0.5.15 (Sept 8 2010):** * OCIO is well behaved when $OCIO is unset, allowing un-color-managed use. * Color Transforms can be applied in python config->getProcessor * Simplification of API (getColorSpace allows cs name, role names, and cs objects) * Makefile enhancements (courtesy Malcolm Humphreys) * A bunch of bug fixes **Version 0.5.14 (Sept 1 2010):** * Python binding enhancements * Simplified class implmentations (reduced internal header count) **Version 0.5.13 (Aug 24 2010):** * GPU Processing now supports High Dynamic Range color spaces * Added log processing operator * Numerous bug fixes * Numerous enhancements to python glue * Exposed PyOpenColorIO header, for use in apps that require custom python glue * Matrix op is optimized for diagonal-only subcases * Numerous changes to Nuke Plugin (now with an addition node, OCIODisplay) **Version 0.5.12 (Aug 18 2010):** * Additional DisplayTransform improvements * Additional GPU Improvements * Added op hashing (processor->getGPULut3DCacheID) **Version 0.5.11 (Aug 11 2010):** * Initial DisplayTransform implementation * ASC CDL Support * Config Luma coefficients **Version 0.5.10 (July 22 2010):** * Updated Nuke Plugin, now works in OSX * Fixed misc. build warnings. * Continued GPU progress (still under development) **Version 0.5.9 (June 28 2010):** * Renamed project, classes, namespaces to OpenColorIO (OCIO) * Added single-pixel processor path * Improved python path makefile detection * Continued GPU progress (still under development) **Version 0.5.8 (June 22 2010):** * Support for .3dl * Support for matrix ops * Code refactor (added Processors) to support gpu/cpu model * Much better error checking * Compilation support for python 2.5 * Compilation support for OSX **Version 0.5.7 (June 14 2010):** * Python API is much more fleshed out * Improved public C++ header **Version 0.5.6 (June 8 2010):** * PyConfig stub implementation * Dropped ImageDesc.init; added PlanarImageDesc / PackedImageDesc * Dropped tr1::shared_ptr; added boost::shared_ptr **Version 0.5.5 (June 4 2010):** * .ocio supports path references * Switch config envvar to $OCIO * Added 3D lut processing ops **Version 0.5.4 (June 1 2010):** * Initial Release * CMake linux support * XML OCIO format parsing / saving * Example colorspace configuration with a few 'trivial' colorspaces * Mutable colorspace configuration API * Support for 1D lut processing * Support for SPI 1D fileformats. * Nuke plugin opencolorio-1.1.0~dfsg0.orig/share/0000755000175000017500000000000013223553423015370 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/share/nuke/0000755000175000017500000000000013223553423016332 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/share/nuke/init.py0000644000175000017500000000114513223553423017650 0ustar mfvmfvimport nuke EBANNER = "OCIO Error: " OCIO = None def load_ocio_plugins(): """Loads the PyOpenColorIO module and the OCIO-prefixed nodes """ global OCIO try: import PyOpenColorIO as OCIO except Exception, e: print '%s%s\n%s' % (EBANNER, 'Loading OCIO python module', e) allplugs = nuke.plugins(nuke.ALL | nuke.NODIR, "OCIO*.so", "OCIO*.dylib", "OCIO*.dll") for p in allplugs: try: nuke.load(p) except Exception, e: print '%sLoading OCIO node %s\n%s' % (EBANNER, p, e) if __name__ == "__main__": load_ocio_plugins() opencolorio-1.1.0~dfsg0.orig/share/nuke/ocio_icon.png0000644000175000017500000000471313223553423021006 0ustar mfvmfvPNG  IHDRw=iCCPICC ProfilexTkA6n"Zkx"IYhE6bk Ed3In6&*Ezd/JZE(ޫ(b-nL~7}ov r4 Ril|Bj A4%UN$As{z[V{wwҶ@G*q Y<ߡ)t9Nyx+=Y"|@5-MS%@H8qR>׋infObN~N>! ?F?aĆ=5`5_M'Tq. VJp8dasZHOLn}&wVQygE0  HPEaP@<14r?#{2u$jtbDA{6=Q<("qCA*Oy\V;噹sM^|vWGyz?W15s-_̗)UKuZ17ߟl;=..s7VgjHUO^gc)1&v!.K `m)m$``/]?[xF QT*d4o(/lșmSqens}nk~8X<R5 vz)Ӗ9R,bRPCRR%eKUbvؙn9BħJeRR~NցoEx pHYs  IDATH } lUϱW^t{ .)UZ(Bh"FFI#Q DmMEt9.rtvcfwf|o`O^?QU< l61jB kLZ[n7oެ9k'H }v;ZZZI%00 g{M!L]]vﮐ |H !AA%z//;gP`3kDBۍMM/$b! '=ޙSOĐ̤Am۲??];jMeeLI F:(b\UeY,IR-BQ,FWOo-Qplʹ)pKeRmqGUmxw&2&^=lH >w8\Fh2_D rE__vV S*&j[,N06D=CH4[xyb,]2AEy qJ6`$ <\{=QM;?gT9 r,mɨiW): X, b_V>߱.^Au%B*9U-<>;+Z49o~KUW=9WO,9B/TQ|& Z ߴf͢q@:z{fɰX&Pfo[7yWIObY EE"'(EFOxӹ׏cKL${jU|]vW9vd(rQ^O'17Yq)FLa?#ACE,zKJb6M{Z@M$64 ڧcZʹʐ(G~ӹ?OU_ E +eԁK},{#;wo0_FW#"j_l4g5V gi%~'Wlq{ȵ©3ruƶ0!m[)ME1r MJ4 Wvh 蓀[)(>(˦ gc 4>u켅'Ɣtc_$.*˲*aZ8ǧggժ.q~;yi@CPAԔTՖs~TQQvq HQk?Qݫ6872PO 0EYtL@ؖ5ܜyٹtkj0 TYyzkv5X믢IHuVgozoG러;"#!LmXV6Gr[$DPX +WHիҬNϴXKͻ81҇CO > 3^W5 G 'aRRlRsg/ eBPpt:GG‘ Ԕ> G"G[h xh=9 MkRVkxW037֦u̠_A崌b4G[u(IENDB`opencolorio-1.1.0~dfsg0.orig/share/nuke/menu.py0000644000175000017500000000211013223553423017642 0ustar mfvmfvimport os import nuke import ocionuke.cdl def ocio_populate_menu(): """Adds OCIO nodes to a menu in Color """ m_nodes = nuke.toolbar('Nodes') m_color = m_nodes.findItem("Color") m_ocio = m_color.addMenu("OCIO", icon = "ocio_icon.png") allplugs = nuke.plugins(nuke.ALL | nuke.NODIR, "OCIO*.so", "OCIO*.dylib", "OCIO*.dll") for fname in allplugs: nodeMenu = nodeClass = os.path.splitext(fname)[0] # strip .so extension # Put a space after "OCIO" to match The Foundry's convention (huh?) if nodeMenu.startswith("OCIO"): nodeMenu = nodeMenu.replace("OCIO", "OCIO ", 1) # Only add the item if it doesn't exist if not m_ocio.findItem(nodeMenu): m_ocio.addCommand(nodeMenu, lambda nodeClass=nodeClass: nuke.createNode(nodeClass)) m_utils = m_ocio.addMenu("Utils") m_utils.addCommand("Import .ccc to CDL nodes", ocionuke.cdl.import_multiple_from_ccc) m_utils.addCommand("Export selected CDL's to .ccc", ocionuke.cdl.export_multiple_to_ccc) if __name__ == "__main__": ocio_populate_menu() opencolorio-1.1.0~dfsg0.orig/share/nuke/ocionuke/0000755000175000017500000000000013223553423020146 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/share/nuke/ocionuke/__init__.py0000644000175000017500000000000013223553423022245 0ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/share/nuke/ocionuke/viewer.py0000644000175000017500000000352713223553423022030 0ustar mfvmfvimport nuke def register_viewers(also_remove = "default"): """Registers the a viewer process for each display device/view, and sets the default viewer process. ``also_remove`` can be set to either: - "default" to remove the default sRGB/rec709 viewer processes - "all" to remove all processes - "none" to leave existing viewer processes untouched """ if also_remove not in ("default", "none", "all"): raise ValueError("also_remove should be set to 'default', 'none' or 'all'") if also_remove == "default": nuke.ViewerProcess.unregister('rec709') nuke.ViewerProcess.unregister('sRGB') nuke.ViewerProcess.unregister('None') elif also_remove == "all": # Unregister all processes, including None, which should be defined in config.ocio for curname in nuke.ViewerProcess.registeredNames(): nuke.ViewerProcess.unregister(curname) # Formats the display and transform, e.g "Film1D (sRGB)" DISPLAY_UI_FORMAT = "%(view)s (%(display)s)" import PyOpenColorIO as OCIO config = OCIO.GetCurrentConfig() # For every display, loop over every view for display in config.getDisplays(): for view in config.getViews(display): # Register the node nuke.ViewerProcess.register( name = DISPLAY_UI_FORMAT % {'view': view, "display": display}, call = nuke.nodes.OCIODisplay, args = (), kwargs = {"display": display, "view": view, "layer": "all"}) # Get the default display and view, set it as the default used on Nuke startup defaultDisplay = config.getDefaultDisplay() defaultView = config.getDefaultView(defaultDisplay) nuke.knobDefault( "Viewer.viewerProcess", DISPLAY_UI_FORMAT % {'view': defaultView, "display": defaultDisplay}) opencolorio-1.1.0~dfsg0.orig/share/nuke/ocionuke/cdl.py0000644000175000017500000002151313223553423021264 0ustar mfvmfv"""Various utilities relating to the OCIOCDLTransform node """ import nuke import PyOpenColorIO as OCIO import xml.etree.ElementTree as ET def _node_to_cdltransform(node): """From an OCIOCDLTransform node, returns a PyOpenColorIO CDLTransform object, which could be used to write XML """ # Color_Knob.value returns single float if control is not # expanded, so use value(index=...) to always get three values slope = [node['slope'].value(x) for x in range(3)] offset = [node['offset'].value(x) for x in range(3)] power = [node['power'].value(x) for x in range(3)] sat = node['saturation'].value() cccid = node['cccid'].value() cdl = OCIO.CDLTransform() cdl.setSlope(slope) cdl.setOffset(offset) cdl.setPower(power) cdl.setSat(sat) cdl.setID(cccid) return cdl def _cdltransform_to_node(cdl, node): """From an XML string, populates the parameters on an OCIOCDLTransform node """ # Treat "node" as a dictionary of knobs, as the "node" argument could be # a the return value of PythonPanel.knob(), as in SelectCCCIDPanel node['slope'].setValue(cdl.getSlope()) node['offset'].setValue(cdl.getOffset()) node['power'].setValue(cdl.getPower()) node['saturation'].setValue(cdl.getSat()) node['cccid'].setValue(cdl.getID()) def _xml_colorcorrection_to_cdltransform(xml, cccposition): """From an XML string, return a CDLTransform object, if the cccid is absent from the XML the given cccposition will be used instead """ ccxml = ET.tostring(xml) cdl = OCIO.CDLTransform() cdl.setXML(ccxml) if "cccid" not in xml.getchildren(): cdl.setID(str(cccposition)) return cdl def _xml_to_cdltransforms(xml): """Given some XML as a string, returns a list of CDLTransform objects for each ColorCorrection (returns a one-item list for a .cc file) """ tree = ET.fromstring(xml) # Strip away xmlns for elem in tree.getiterator(): if elem.tag.startswith("{"): elem.tag = elem.tag.partition("}")[2] filetype = tree.tag cccposition = 0 if filetype == "ColorCorrection": return [_xml_colorcorrection_to_cdltransform(tree, cccposition)] elif filetype in ["ColorCorrectionCollection", "ColorDecisionList"]: allcdl = [] for cc in tree.getchildren(): if cc.tag == "ColorDecision": cc = cc.getchildren()[0] # TODO: something better here if cc.tag != "ColorCorrection": continue allcdl.append(_xml_colorcorrection_to_cdltransform(cc, cccposition)) cccposition += 1 return allcdl else: raise RuntimeError( "The supplied file did not have the correct root element, expected" " 'ColorCorrection' or 'ColorCorrectionCollection' or 'ColorDecisionList', got %r" % (filetype)) def _cdltransforms_to_xml(allcc): """Given a list of CDLTransform objects, returns an XML string """ root = ET.Element("ColorCorrectionCollection") root.attrib['xmlns'] = 'urn:ASC:CDL:v1.2' for cc in allcc: cur = ET.fromstring(cc.getXML()) # Strip away xmlns for elem in cur.getiterator(): if elem.tag.startswith("{"): elem.tag = elem.tag.partition("}")[2] root.append(cur) return ET.tostring(root) def SelectCCCIDPanel(*args, **kwargs): # Wrap class definition in a function, so nukescripts.PythonPanel # is only accessed when ``SelectCCCIDPanel()`` is called, # https://github.com/imageworks/OpenColorIO/issues/277 import nukescripts class _SelectCCCIDPanel(nukescripts.PythonPanel): """Allows the user to select from a list of CDLTransform objects """ def __init__(self, allcdl): super(_SelectCCCIDPanel, self).__init__() self.available = {} for cur in allcdl: self.available[cur.getID()] = cur self.addKnob(nuke.Enumeration_Knob("cccid", "cccid", self.available.keys())) self.addKnob(nuke.Text_Knob("divider")) self.addKnob(nuke.Color_Knob("slope")) self.addKnob(nuke.Color_Knob("offset")) self.addKnob(nuke.Color_Knob("power")) self.addKnob(nuke.Double_Knob("saturation")) def selected(self): return self.available[self.knobs()['cccid'].value()] def knobChanged(self, knob): """When the user selects a cccid, a grade-preview knobs are set. This method is triggered when any knob is changed, which has the useful side-effect of preventing changing the preview values, while keeping them selectable for copy-and-paste. """ _cdltransform_to_node(self.selected(), self.knobs()) return _SelectCCCIDPanel(*args, **kwargs) def export_as_cc(node = None, filename = None): """Export a OCIOCDLTransform node as a ColorCorrection XML file (.cc) If node is None, "nuke.thisNode()" will be used. If filename is not specified, the user will be prompted. """ if node is None: node = nuke.thisNode() cdl = _node_to_cdltransform(node) if filename is None: ccfilename = nuke.getFilename("Color Correction filename", pattern = "*.cc") if ccfilename is None: # User clicked cancel return xml = cdl.getXML() print "Writing to %s - contents:\n%s" % (ccfilename, xml) open(ccfilename, "w").write(xml) def import_cc_from_xml(node = None, filename = None): """Import a ColorCorrection XML (.cc) into a OCIOCDLTransform node. If node is None, "nuke.thisNode()" will be used. If filename is not specified, the user will be prompted. """ if node is None: node = nuke.thisNode() if filename is None: ccfilename = nuke.getFilename("Color Correction filename", pattern = "*.cc *.ccc *.cdl") if ccfilename is None: # User clicked cancel return xml = open(ccfilename).read() allcc = _xml_to_cdltransforms(xml) if len(allcc) == 1: _cdltransform_to_node(allcc[0], node) elif len(allcc) > 1: do_selectcccid = nuke.ask( "Selected a ColorCorrectionCollection, do you wish to select a ColorCorrection from this file?") if do_selectcccid: sel = SelectCCCIDPanel(allcc) okayed = sel.showModalDialog() if okayed: cc = sel.selected() _cdltransform_to_node(cc, node) else: return else: nuke.message("The supplied file (%r) contained no ColorCorrection's" % ccfilename) return def export_multiple_to_ccc(filename = None): """Exported all selected OCIOCDLTransform nodes to a ColorCorrectionCollection XML file (.ccc) """ if filename is None: filename = nuke.getFilename("Color Correction XML file", pattern = "*.cc *.ccc") if filename is None: # User clicked cancel return allcc = [] for node in nuke.selectedNodes("OCIOCDLTransform"): allcc.append(_node_to_cdltransform(node)) xml = _cdltransforms_to_xml(allcc) print "Writing %r, contents:\n%s" % (filename, xml) open(filename, "w").write(xml) def import_multiple_from_ccc(filename = None): """Import a ColorCorrectionCollection file (.ccc) into multiple OCIOCDLTransform nodes. Also creates a single node for a .cc file """ if filename is None: filename = nuke.getFilename("Color Correction XML file", pattern = "*.cc *.ccc *.cdl") if filename is None: # User clicked cancel return xml = open(filename).read() allcc = _xml_to_cdltransforms(xml) def _make_node(cdl): newnode = nuke.nodes.OCIOCDLTransform(inputs = nuke.selectedNodes()[:1]) _cdltransform_to_node(cdl, newnode) newnode['label'].setValue("id: [value cccid]") if len(allcc) > 0: for cc in allcc: _make_node(cc) else: nuke.message("The supplied file (%r) contained no ColorCorrection's" % filename) def select_cccid_for_filetransform(node = None, fileknob = 'file', cccidknob = 'cccid'): """Select cccid button for the OCIOFileTransform node, also used in OCIOCDLTransform. Presents user with list of cccid's within the specified .ccc file, and sets the cccid knob to the selected ID. """ if node is None: node = nuke.thisNode() filename = node[fileknob].value() try: xml = open(filename).read() except IOError, e: nuke.message("Error opening src file: %s" % e) raise allcc = _xml_to_cdltransforms(xml) if len(allcc) == 0: nuke.message("The file (%r) contains no ColorCorrection's") return sel = SelectCCCIDPanel(allcc) okayed = sel.showModalDialog() if okayed: node[cccidknob].setValue(sel.selected().getID()) opencolorio-1.1.0~dfsg0.orig/share/nuke/examples/0000755000175000017500000000000013223553423020150 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/share/nuke/examples/ocio_to_colorlookup_rgb.py0000644000175000017500000000123513223553423025440 0ustar mfvmfvimport SpImport OCIO = SpImport.SpComp2("PyOpenColorIO",2) #import PyOpenColorIO as OCIO c = OCIO.GetCurrentConfig() processor = c.getProcessor(OCIO.FileTransform('woz_qt_to_mxfva.spi1d', interpolation=OCIO.Constants.INTERP_LINEAR)) node = nuke.createNode("ColorLookup") node.setName("woz_post_film") knob = node['lut'] knob.removeKeyAt(0.0, 1) knob.removeKeyAt(1.0, 1) knob.removeKeyAt(0.0, 2) knob.removeKeyAt(1.0, 2) knob.removeKeyAt(0.0, 3) knob.removeKeyAt(1.0, 3) SIZE = 11 for i in xrange(SIZE): x = i/(SIZE-1.0) y = processor.applyRGB((x,x,x)) knob.setValueAt(y[0],x, 1) knob.setValueAt(y[1],x, 2) knob.setValueAt(y[2],x, 3) opencolorio-1.1.0~dfsg0.orig/share/nuke/examples/colorlookup_to_spi1d.py0000644000175000017500000000102513223553423024672 0ustar mfvmfv def WriteSPI1D(filename, fromMin, fromMax, data): f = file(filename,'w') f.write("Version 1\n") f.write("From %s %s\n" % (fromMin, fromMax)) f.write("Length %d\n" % len(data)) f.write("Components 1\n") f.write("{\n") for value in data: f.write(" %s\n" % value) f.write("}\n") f.close() knob = nuke.selectedNode()['lut'] SIZE = 2**10 data = [] for i in xrange(SIZE): x = i/(SIZE-1.0) data.append(knob.getValueAt(x)) WriteSPI1D('/tmp/colorlookup.spi1d', 0.0, 1.0, data) opencolorio-1.1.0~dfsg0.orig/share/nuke/examples/ocio_to_colorlookup_all.py0000644000175000017500000000153713223553423025443 0ustar mfvmfv#import SpImport #OCIO = SpImport.SpComp2("PyOpenColorIO", 2) c = OCIO.GetCurrentConfig() cs_to_lin = c.getProcessor(OCIO.Constants.ROLE_COMPOSITING_LOG, OCIO.Constants.ROLE_SCENE_LINEAR) node = nuke.createNode("ColorLookup") node.setName("sm2_slg_to_ln") knob = node['lut'] knob.removeKeyAt(0.0) knob.removeKeyAt(1.0) node2 = nuke.createNode("ColorLookup") node2.setName("sm2_ln_to_slg") knob2 = node2['lut'] knob2.removeKeyAt(0.0) knob2.removeKeyAt(1.0) def Fit(value, fromMin, fromMax, toMin, toMax): if fromMin == fromMax: raise ValueError("fromMin == fromMax") return (value - fromMin) / (fromMax - fromMin) * (toMax - toMin) + toMin SIZE = 2**10 for i in xrange(SIZE): x = i/(SIZE-1.0) x = Fit(x, 0.0, 1.0, -0.125, 1.5) y = cs_to_lin.applyRGB((x,x,x))[1] knob.setValueAt(y,x) knob2.setValueAt(x,y) opencolorio-1.1.0~dfsg0.orig/share/sphinx/0000755000175000017500000000000013223553423016701 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/share/sphinx/ExtractRstFromSourceCPP.py0000755000175000017500000002160413223553423023734 0ustar mfvmfv#!/usr/bin/python """ Small Script to extract reStructuredText from OCIO headers - http://sphinx.pocoo.org/rest.html - http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html """ # TODO: extract void foo() { blah = 0 }; signatures correctly # TODO: handle typedef and enums better # TODO: handle OCIOEXPORT macro better # TODO: handle thow() funcs better RUNTEST = False import re, sys single_rst_comment = r"//(?P(!cpp:|!rst::).*\n)" block_rst_comment = r"/\*(?P(!cpp:|!rst::)([^*]*\*+)+?/)" rst_comment_regex = re.compile(r"(%s)|(%s)" % (single_rst_comment, block_rst_comment), re.MULTILINE) func_signature_regex = re.compile(r"(?P[^ ]*\(.*\))") rst_types = ["!rst::", "!cpp:class::", "!cpp:function::", "!cpp:member::", "!cpp:type::"] def getRstType(string): for rtype in rst_types: if string[0 : len(rtype)] == rtype: return rtype[1:] return None def getNextCodeLine(string, rst_type, from_pos): end = from_pos signature = "" if rst_type == "rst::": return signature, end if rst_type == "cpp:class::": class_open = False # first non-blank line that starts with 'class' found_signature = False # loop till the end of the class '};' ## skip other open/close '{' '}' skip_close = False x = end while x < len(string): if string[x] != '\n' and not found_signature: signature += string[x] if string[x] == '\n' and not found_signature: signature = signature.strip() if signature != '': found_signature = True signature = signature.replace("class", "") # TODO: this seem a bit dirty signature = signature.replace("OCIOEXPORT ", "") signature = signature.strip() signature = signature.split(' ', 1)[0] if string[x] == '{' and not class_open: class_open = True elif string[x] == '{' and class_open: skip_close = True elif string[x] == '}' and skip_close: skip_close = False elif string[x] == '}': end = x break x += 1 return signature, end # else skip = False while string[end] != ";": if string[end] != ' ' and skip: skip = False signature += ' ' if string[end] == '\n': skip = True if not skip: signature += string[end] end += 1 signature += string[end] # TODO: this seem a bit dirty signature = signature.replace("OCIOEXPORT ", "") signature = signature.replace(" throw()", "") signature = signature.strip() if signature[len(signature)-1] == ';': signature = signature[:len(signature)-1] # hack hack hack if rst_type == "cpp:type::": if signature[:7] == "typedef": bits = signature.split() signature = bits[len(bits)-1] if signature[:4] == "enum": bits = signature.split() signature = bits[1] return signature, end def getNextCommentLine(string, from_pos, buffer = ""): end = from_pos tmp = "" while string[end] != "\n": tmp += string[end] end += 1 tmp += string[end] if tmp.lstrip()[:2] == "//": if tmp.lstrip()[2:][0] == " ": buffer += tmp.lstrip()[3:] else: buffer += tmp.lstrip()[2:] buffer, end = getNextCommentLine(string, end+1, buffer) else: end = from_pos return buffer, end class Comment: def __init__(self, comment, start, end): self.comment = comment self.start = start self.end = end def getRstType(self): return getRstType(self.comment) def __str__(self): buffer = self.comment for rtype in rst_types: if buffer[0 : len(rtype)] == rtype: buffer = buffer[len(rtype):] buffer_lines = buffer.splitlines() buffer_lines[0] = buffer_lines[0].strip() if self.getRstType() == "rst::": buffer_lines.append('') buffer = '\n'.join(buffer_lines) return buffer if buffer_lines[0] != '': buffer_lines.insert(0, '') for x in range(0, len(buffer_lines)): buffer_lines[x] = " %s" % buffer_lines[x] buffer_lines.append('') buffer = '\n'.join(buffer_lines) return buffer def ExtractRst(string, fileh): items = [] for item in rst_comment_regex.finditer(string): start, end = item.span() itemdict = item.groupdict() if itemdict["single_comment"] != None: ## buf = itemdict["single_comment"] comment, end = getNextCommentLine(string, end) buf += comment ## items.append(Comment(buf, start, end)) elif itemdict["block_comment"] != None: ## itemdict["block_comment"] = \ itemdict["block_comment"][:len(itemdict["block_comment"])-2] buf_lines = itemdict["block_comment"].splitlines() indent = 0 if len(buf_lines) > 1: for char in buf_lines[1]: if char != ' ': break indent += 1 # remove indent bufa = [buf_lines[0]] for x in range(1, len(buf_lines)): bufa.append(buf_lines[x][indent:]) buf = '\n'.join(bufa) + '\n' ## items.append(Comment(buf, start, end)) ## fileh.write('\n') namespaces = [] for thing in items: rst_type = thing.getRstType() # .. cpp:function:: SomeClass::func2(const char * filename, std::istream& foo) # this is some of the documentation # for this function signature, end = getNextCodeLine(string, rst_type, thing.end) # if we are a class work out the begining and end so we can # give function signatures the correct namespace if rst_type == "cpp:class::": tmp = { 'name': signature, 'start': thing.end, 'end': end } namespaces.append(tmp) fileh.write(".. %s %s\n" % (rst_type, signature) ) elif rst_type != "rst::": for namespace in namespaces: if end > namespace['start'] and end < namespace['end']: func = func_signature_regex.search(signature) funcpart = str(func.groupdict()["sig_name"]) signature = signature.replace(funcpart, "%s::%s" % (namespace['name'], funcpart)) break fileh.write(".. %s %s\n" % (rst_type, signature) ) fileh.write(str(thing)) fileh.write('\n') fileh.flush() if __name__ == "__main__": if not RUNTEST: if len(sys.argv) <= 2: sys.stderr.write("\nYou need to specify an input and output file\n\n") sys.exit(1) src = open(sys.argv[1]).read() output = open(sys.argv[2], 'w+') ExtractRst(src, output) output.close() elif RUNTEST: testdata = """ //!rst:: ------------- // this comment should be ignored //!rst:: foobar // this is apart of the same // comment // this is also ignored /* this is a block comment which is ignored */ //!cpp:class:: // this is a comment about the class class FooBar : public std::exception { ... }; /*!cpp:class:: this is also a comment about this class */ class FooBar2 : public std::exception { ... }; /*!cpp:class:: this is also a comment about this class with no new line */ class FooBar3 : public std::exception { ... }; //!cpp:class:: class SomeClass { public: //!cpp:function:: // this is some cool function for // some purpose // this line is indented static fooPtr func1(); /*!cpp:function:: this is a much better func for some other purpose this is also indented */ static barPtr func2(); /*!cpp:function:: this func wraps over two lines which needs to be caught */ static weePtr func2(const char * filename, std::istream& foo); }; //!cpp:function:: the class namespace should still get set correctly void foobar1(); //!cpp:class:: this is some super informative // docs class SomeClass { public: //!cpp:function:: the class namespace should still get set correctly void foobar2(); }; //!cpp:function:: the class namespace should still get set correctly void foobar3(); /*!rst:: this is a rst block **comment which needs** to be supported */ """ ExtractRst(testdata) opencolorio-1.1.0~dfsg0.orig/share/sphinx/ExtractRstFromSourceSimple.py0000755000175000017500000000577713223553423024560 0ustar mfvmfv#!/usr/bin/python """ Small Script to extract reStructuredText from OCIO headers - http://sphinx.pocoo.org/rest.html - http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html This looks for the tokens: /*+doc and puts everything inside of them */ //+doc in the RST file. """ RUNTEST = False import sys, os, string # Remove the specified number of whitespace from the start of the string # If non-whitespace text is encountered in the 'indent' area, it is preserved def _RemoveIndent(s, indent): firstcharindex = s.find(s.strip()) startindex = min(firstcharindex, indent) return s[startindex:] def ExtractRst(inputstr, ofile): inMultiline = False onelineDocTag = '//+doc' multilineDocTag = '/*+doc' multilineEndTag = '*/' multilineStartIndent = 0 newOutputFile = False for line in inputstr.splitlines(): if inMultiline: if multilineEndTag in line: data = line[:line.index(multilineEndTag)] ofile.write(_RemoveIndent(data, multilineStartIndent) + '\n\n') inMultiline = False multilineStartIndent = 0 else: ofile.write(_RemoveIndent(line, multilineStartIndent) + '\n') elif onelineDocTag in line: docstring = line.split('//+doc', 1)[1] # TODO: Add this part to the CPP extracting script if "*New File*" in docstring: filename = line.split('*New File*', 1)[1].strip() # Make sure that the file name is valid here if newOutputFile: ofile.close() ofile = open(filename, 'w') newOutputFile = True ofile.write(docstring.strip() + '\n') else: if multilineDocTag in line: multilineStartIndent = line.index(multilineDocTag) inMultiline = True # TODO: Handle code after the multiline start tag? if __name__ == "__main__": if not RUNTEST: if len(sys.argv) <= 2: sys.stderr.write("\nYou need to specify an input and output file\n\n") sys.exit(1) src = open(sys.argv[1]).read() output = open(sys.argv[2], 'w') ExtractRst(src, output) output.close() elif RUNTEST: #print _RemoveIndent('',4) #print _RemoveIndent('sfdfsd',4) #print _RemoveIndent(' sfdfsd',4) #print _RemoveIndent(' sfdfsd',4) testdata = """ #include <...> void Random C++ Code //+doc Some one-line doc. Everything on the line after the onelineDocTag gets added. /*+doc What should this do? !rst::This is a multi-line rst text there is a blank line above this this is before the final endtag */ class TestClass /*+doc What should this do? !rst::additional rst indented code more indented code This is left indented This is original indent This is indented 4 spaces */ """ ExtractRst(testdata, sys.stdout) opencolorio-1.1.0~dfsg0.orig/share/ocio/0000755000175000017500000000000013223553423016321 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/share/ocio/setup_ocio.sh.in0000644000175000017500000000076213223553423021440 0ustar mfvmfv#!/bin/sh OCIO_ROOT="@CMAKE_INSTALL_PREFIX@" OCIO_EXECROOT="@CMAKE_INSTALL_EXEC_PREFIX@" # For OS X export DYLD_LIBRARY_PATH="${OCIO_EXECROOT}/lib:${DYLD_LIBRARY_PATH}" # For Linux export LD_LIBRARY_PATH="${OCIO_EXECROOT}/lib:${LD_LIBRARY_PATH}" export PATH="${OCIO_EXECROOT}/bin:${PATH}" export PYTHONPATH="${OCIO_EXECROOT}/@PYTHON_VARIANT_PATH@:${PYTHONPATH}" export NUKE_PATH="${OCIO_EXECROOT}/lib/nuke@Nuke_API_VERSION@:${NUKE_PATH}" export NUKE_PATH="${OCIO_ROOT}/share/nuke:${NUKE_PATH}"; opencolorio-1.1.0~dfsg0.orig/share/cmake/0000755000175000017500000000000013223553423016450 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/share/cmake/andriod-toolchain.cmake0000644000175000017500000000436213223553423023055 0ustar mfvmfv set(NDK /Applications/android-ndk-r5b) set(NDK_LEVEL 9) set(NDK_ARCH arm) set(NDK_CPU_ABI armeabi-v7a) # armeabi, armeabi-v7a, x86 set(NDK_SYSROOT ${NDK}/platforms/android-${NDK_LEVEL}/arch-${NDK_ARCH}) set(NDK_TOOLCHAIN_PREFIX arm-linux-androideabi) set(NDK_TOOLCHAIN_NAME ${NDK_TOOLCHAIN_PREFIX}-4.4.3) set(NDK_TOOLCHAIN_SYSTEM darwin-x86) set(NDK_TOOLCHAIN ${NDK}/toolchains/${NDK_TOOLCHAIN_NAME}/prebuilt/${NDK_TOOLCHAIN_SYSTEM}) set(CMAKE_FIND_ROOT_PATH "${NDK_TOOLCHAIN}" "${NDK_SYSROOT}" "${NDK}") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_SYSTEM_NAME GNU) set(CMAKE_SYSTEM_VERSION 1) set(CMAKE_SYSTEM_PROCESSOR armv7-a) set(CMAKE_OSX_ARCHITECTURES armv7-a) set(CMAKE_C_COMPILER ${NDK_TOOLCHAIN_PREFIX}-gcc) set(CMAKE_CXX_COMPILER ${NDK_TOOLCHAIN_PREFIX}-g++) include_directories("${NDK}/sources/cxx-stl/gnu-libstdc++/libs/${NDK_CPU_ABI}/include") include_directories("${NDK}/sources/cxx-stl/gnu-libstdc++/include") include_directories("${NDK_SYSROOT}/usr/include") # TODO: work out if we need any of these compile flags # -DNDEBUG -MMD -MP -MF -fpic -ffunction-sections -funwind-tables # -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ # -D__ARM_ARCH_5TE__ -mtune=xscale -msoft-float -mthumb # -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -Wno-psabi # -Wa,--noexecstack -Os -O2 -g set(NDK_COMPILE_FLAGS "-DANDROID -march=${CMAKE_SYSTEM_PROCESSOR} -mfloat-abi=softfp") # TODO: work out if we need any of these link flags # -Wl,--gc-sections -Wl,-z,nocopyreloc -Wl,--no-undefined -Wl,-z,noexecstack # -Wl,-rpath-link=${NDK_PLATFORM_ROOT}/usr/lib") set(NDK_LINK_FLAGS "-Wl,--fix-cortex-a8 --sysroot=${NDK_SYSROOT} -L${NDK_SYSROOT}/usr/lib -lsupc++ -lstdc++ -lm -lc -ldl") add_definitions(${NDK_COMPILE_FLAGS}) set(CMAKE_C_LINK_FLAGS ${NDK_LINK_FLAGS}) set(CMAKE_CXX_LINK_FLAGS ${NDK_LINK_FLAGS}) set(CMAKE_CROSSCOMPILING TRUE) set(ANDROID TRUE) set(OCIO_BUILD_SHARED TRUE) set(OCIO_BUILD_STATIC FALSE) set(OCIO_BUILD_UNITTESTS FALSE) set(OCIO_BUILD_TRUELIGHT FALSE) set(OCIO_BUILD_TESTBED FALSE) set(OCIO_BUILD_APPS FALSE) set(OCIO_BUILD_NUKE FALSE) set(OCIO_BUILD_PYGLUE FALSE) set(OCIO_BUILD_JNIGLUE TRUE) set(OCIO_BUILD_SSE FALSE) opencolorio-1.1.0~dfsg0.orig/share/cmake/iPhone-toolchain.cmake0000644000175000017500000000300213223553423022645 0ustar mfvmfv set(IPHONE_SDK "4.3") set(IPHONE_ROOT "/Developer/Platforms/iPhoneOS.platform/Developer") set(IPHONE_SDK_ROOT "${IPHONE_ROOT}/SDKs/iPhoneOS${IPHONE_SDK}.sdk") set(CMAKE_FIND_ROOT_PATH "${IPHONE_SDK_ROOT}" "${IPHONE_ROOT}") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_SYSTEM_NAME "GNU") set(CMAKE_SYSTEM_PROCESSOR armv7) set(CMAKE_OSX_ARCHITECTURES armv7) set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) set(CMAKE_C_COMPILER gcc-4.2) set(CMAKE_CXX_COMPILER g++-4.2) add_definitions("-D__IPHONE__") add_definitions("-arch armv7 -pipe -no-cpp-precomp --sysroot=${IPHONE_SDK_ROOT} -miphoneos-version-min=${IPHONE_SDK}") set(CMAKE_C_LINK_FLAGS "-arch armv7 --isysroot=${IPHONE_SDK_ROOT} -miphoneos-version-min=${IPHONE_SDK} -L${IPHONE_SDK_ROOT}/usr/lib -L${IPHONE_SDK_ROOT}/usr/lib/system") set(CMAKE_CXX_LINK_FLAGS ${CMAKE_C_LINK_FLAGS}) include_directories("${IPHONE_SDK_ROOT}/usr/include") include_directories("${IPHONE_SDK_ROOT}/usr/include/c++/4.2.1") include_directories("${IPHONE_SDK_ROOT}/usr/include/c++/4.2.1/armv7-apple-darwin10") link_directories("${IPHONE_SDK_ROOT}/usr/lib") link_directories("${IPHONE_SDK_ROOT}/usr/lib/system") set(CMAKE_CROSSCOMPILING TRUE) set(IPHONE TRUE) set(OCIO_BUILD_SHARED FALSE) set(OCIO_BUILD_STATIC TRUE) set(OCIO_BUILD_TRUELIGHT FALSE) set(OCIO_BUILD_APPS FALSE) set(OCIO_BUILD_NUKE FALSE) set(OCIO_BUILD_PYGLUE FALSE) set(OCIO_BUILD_JNIGLUE FALSE) set(OCIO_BUILD_SSE FALSE) opencolorio-1.1.0~dfsg0.orig/share/cmake/iPhoneSimulator-toolchain.cmake0000644000175000017500000000307213223553423024554 0ustar mfvmfv set(IPHONE_SDK "4.3") set(IPHONE_ROOT "/Developer/Platforms/iPhoneSimulator.platform/Developer") set(IPHONE_SDK_ROOT "${IPHONE_ROOT}/SDKs/iPhoneSimulator${IPHONE_SDK}.sdk") set(CMAKE_FIND_ROOT_PATH "${IPHONE_SDK_ROOT}" "${IPHONE_ROOT}") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_VERSION 1) set(CMAKE_OSX_ARCHITECTURES i686) set(CMAKE_OSX_SYSROOT "${IPHONE_SDK_ROOT}") set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) set(CMAKE_C_COMPILER gcc-4.2) set(CMAKE_CXX_COMPILER g++-4.2) add_definitions("-D__IPHONE__") add_definitions("-arch i686 -pipe -no-cpp-precomp --sysroot=${IPHONE_SDK_ROOT} -miphoneos-version-min=${IPHONE_SDK}") set(CMAKE_C_LINK_FLAGS "-arch i686 --isysroot=${IPHONE_SDK_ROOT} -miphoneos-version-min=${IPHONE_SDK} -L${IPHONE_SDK_ROOT}/usr/lib -L${IPHONE_SDK_ROOT}/usr/lib/system") set(CMAKE_CXX_LINK_FLAGS ${CMAKE_C_LINK_FLAGS}) include_directories("${IPHONE_SDK_ROOT}/usr/include") include_directories("${IPHONE_SDK_ROOT}/usr/include/c++/4.2.1") include_directories("${IPHONE_SDK_ROOT}/usr/include/c++/4.2.1/i686-apple-darwin10") link_directories("${IPHONE_SDK_ROOT}/usr/lib") link_directories("${IPHONE_SDK_ROOT}/usr/lib/system") set(IPHONE_BUILD TRUE) set(CMAKE_CROSSCOMPILING TRUE) set(OCIO_BUILD_SHARED FALSE) set(OCIO_BUILD_STATIC TRUE) set(OCIO_BUILD_TRUELIGHT FALSE) set(OCIO_BUILD_APPS FALSE) set(OCIO_BUILD_NUKE FALSE) set(OCIO_BUILD_PYGLUE FALSE) set(OCIO_BUILD_JNIGLUE FALSE) set(OCIO_BUILD_SSE FALSE) opencolorio-1.1.0~dfsg0.orig/share/cmake/TestForDDImageVersion.cxx0000644000175000017500000000100013223553423023272 0ustar mfvmfv#include #include "DDImage/ddImageVersionNumbers.h" int main(int, char*[]) { // Print a Nuke API identifier number, used to make the // lib/nuke${API_NUMBER} directory // Nuke aims to maintain API compatibilty between "v" releases, so // compiling for 6.1v1 will work with 6.1v2 etc (but not // 6.2v1). Only exception has been 5.1v5 and 5.1v6 (because it was // supposed to be 5.2v1) std::cout << kDDImageVersionMajorNum << "." << kDDImageVersionMinorNum; return 0; } opencolorio-1.1.0~dfsg0.orig/share/cmake/FindTruelight.cmake0000644000175000017500000000573213223553423022231 0ustar mfvmfv#========== # # Copyright (c) 2011, Malcolm Humphreys. # 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 Dan Bethell nor the names of any # other contributors to this software 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. # #========== # # Variables defined by this module: # Truelight_FOUND # Truelight_INCLUDE_DIR # Truelight_COMPILE_FLAGS # Truelight_LINK_FLAGS # Truelight_LIBRARIES # Truelight_LIBRARY_DIR # # Usage: # FIND_PACKAGE( Truelight ) # FIND_PACKAGE( Truelight REQUIRED ) # # Note: # You can tell the module where Truelight is installed by setting # the TRUELIGHT_INSTALL_PATH (or setting the TRUELIGHT_ROOT environment # variable before calling FIND_PACKAGE. # # E.g. # SET( TRUELIGHT_INSTALL_PATH "/usr/fl/truelight" ) # FIND_PACKAGE( Truelight REQUIRED ) # #========== # our includes FIND_PATH( Truelight_INCLUDE_DIR truelight.h $ENV{TRUELIGHT_ROOT}/include ${TRUELIGHT_INSTALL_PATH}/include ) # our library FIND_LIBRARY( Truelight_LIBRARIES libtruelight.a $ENV{TRUELIGHT_ROOT}/lib ${TRUELIGHT_INSTALL_PATH}/lib ) SET( Truelight_COMPILE_FLAGS "" ) SET( Truelight_LINK_FLAGS "" ) IF( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) SET( Truelight_COMPILE_FLAGS "" ) SET( Truelight_LINK_FLAGS "-framework CoreServices -framework IOKit" ) ENDIF( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) # our library path GET_FILENAME_COMPONENT( Truelight_LIBRARY_DIR ${Truelight_LIBRARIES} PATH ) # did we find everything? INCLUDE( FindPackageHandleStandardArgs ) FIND_PACKAGE_HANDLE_STANDARD_ARGS( "Truelight" DEFAULT_MSG Truelight_INCLUDE_DIR Truelight_LIBRARIES Truelight_LIBRARY_DIR ) opencolorio-1.1.0~dfsg0.orig/share/cmake/FindTinyXML.cmake0000644000175000017500000000456713223553423021573 0ustar mfvmfv# Find the tinyxml XML parsing library. # # Sets the usual variables expected for find_package scripts: # # TINYXML_INCLUDE_DIRS - header location # TINYXML_LIBRARIES - library to link against # TINYXML_FOUND - true if tinyxml was found. # TINYXML_MAJOR_VERSION # TINYXML_MINOR_VERSION # TINYXML_PATCH_VERSION # TINYXML_VERSION find_path(TINYXML_INCLUDE_DIR tinyxml.h) find_library(TINYXML_LIBRARY NAMES tinyxml) # Try to get the tinyxml version from the header file. if(TINYXML_INCLUDE_DIR) set(_tixml_header ${TINYXML_INCLUDE_DIR}/tinyxml.h) file(READ ${_tixml_header} _contents) if(_contents) string(REGEX MATCH "const int TIXML_MAJOR_VERSION = ([0-9]+);" _TMP_major "${_contents}") string(REGEX REPLACE ".*([0-9]+).*" "\\1" _OUT_major "${_TMP_major}") string(REGEX MATCH "const int TIXML_MINOR_VERSION = ([0-9]+);" _TMP_minor "${_contents}") string(REGEX REPLACE ".*([0-9]+).*" "\\1" _OUT_minor "${_TMP_minor}") string(REGEX MATCH "const int TIXML_PATCH_VERSION = ([0-9]+);" _TMP_patch "${_contents}") string(REGEX REPLACE ".*([0-9]+).*" "\\1" _OUT_patch "${_TMP_patch}") if(NOT ${_OUT_major} MATCHES "[0-9]+") message(FATAL_ERROR "Version parsing failed for TIXML_MAJOR_VERSION!") endif() if(NOT ${_OUT_minor} MATCHES "[0-9]+") message(FATAL_ERROR "Version parsing failed for TIXML_MINOR_VERSION!") endif() if(NOT ${_OUT_patch} MATCHES "[0-9]+") message(FATAL_ERROR "Version parsing failed for TIXML_MICRO_VERSION!") endif() set(TINYXML_MAJOR_VERSION ${_OUT_major}) set(TINYXML_MINOR_VERSION ${_OUT_minor}) set(TINYXML_PATCH_VERSION ${_OUT_patch}) set(TINYXML_VERSION ${TINYXML_MAJOR_VERSION}.${TINYXML_MINOR_VERSION}.${TINYXML_PATCH_VERSION}) else() message(FATAL_ERROR "Include file ${_tixml_header} does not exist") endif() endif() # Support the REQUIRED and QUIET arguments, and set TINYXML_FOUND if found. include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS (TinyXML DEFAULT_MSG TINYXML_LIBRARY TINYXML_INCLUDE_DIR) message(STATUS "TinyXML version: ${TINYXML_VERSION}") if(TINYXML_FOUND) set(TINYXML_LIBRARIES ${TINYXML_LIBRARY}) set(TINYXML_INCLUDE_DIRS ${TINYXML_INCLUDE_DIR}) endif() mark_as_advanced(TINYXML_LIBRARY TINYXML_INCLUDE_DIR) opencolorio-1.1.0~dfsg0.orig/share/cmake/iPhone-armv6-toolchain.cmake0000644000175000017500000000300213223553423023676 0ustar mfvmfv set(IPHONE_SDK "4.3") set(IPHONE_ROOT "/Developer/Platforms/iPhoneOS.platform/Developer") set(IPHONE_SDK_ROOT "${IPHONE_ROOT}/SDKs/iPhoneOS${IPHONE_SDK}.sdk") set(CMAKE_FIND_ROOT_PATH "${IPHONE_SDK_ROOT}" "${IPHONE_ROOT}") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_SYSTEM_NAME "GNU") set(CMAKE_SYSTEM_PROCESSOR armv6) set(CMAKE_OSX_ARCHITECTURES armv6) set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE) set(CMAKE_C_COMPILER gcc-4.2) set(CMAKE_CXX_COMPILER g++-4.2) add_definitions("-D__IPHONE__") add_definitions("-arch armv6 -pipe -no-cpp-precomp --sysroot=${IPHONE_SDK_ROOT} -miphoneos-version-min=${IPHONE_SDK}") set(CMAKE_C_LINK_FLAGS "-arch armv6 --isysroot=${IPHONE_SDK_ROOT} -miphoneos-version-min=${IPHONE_SDK} -L${IPHONE_SDK_ROOT}/usr/lib -L${IPHONE_SDK_ROOT}/usr/lib/system") set(CMAKE_CXX_LINK_FLAGS ${CMAKE_C_LINK_FLAGS}) include_directories("${IPHONE_SDK_ROOT}/usr/include") include_directories("${IPHONE_SDK_ROOT}/usr/include/c++/4.2.1") include_directories("${IPHONE_SDK_ROOT}/usr/include/c++/4.2.1/armv6-apple-darwin10") link_directories("${IPHONE_SDK_ROOT}/usr/lib") link_directories("${IPHONE_SDK_ROOT}/usr/lib/system") set(CMAKE_CROSSCOMPILING TRUE) set(IPHONE TRUE) set(OCIO_BUILD_SHARED FALSE) set(OCIO_BUILD_STATIC TRUE) set(OCIO_BUILD_TRUELIGHT FALSE) set(OCIO_BUILD_TESTBED FALSE) set(OCIO_BUILD_APPS FALSE) set(OCIO_BUILD_NUKE FALSE) set(OCIO_BUILD_PYGLUE FALSE) set(OCIO_BUILD_SSE FALSE) opencolorio-1.1.0~dfsg0.orig/share/cmake/OCIOMacros.cmake0000644000175000017500000003307713223553423021362 0ustar mfvmfvMACRO(messageonce MSG) if(CMAKE_FIRST_RUN) message(STATUS ${MSG}) endif() ENDMACRO() MACRO(OCIOFindOpenGL) if(APPLE) INCLUDE_DIRECTORIES(/System/Library/Frameworks) endif() # Find OpenGL find_package(OpenGL) if(OPENGL_FOUND) message(STATUS "Found OpenGL library ${OPENGL_LIBRARY}") message(STATUS "Found OpenGL includes ${OPENGL_INCLUDE_DIR}") else() message(STATUS "OpenGL not found") endif() # Find GLUT find_package(GLUT) if(GLUT_FOUND) message(STATUS "Found GLUT library ${GLUT_LIBRARY}") else() message(STATUS "GLUT not found") endif() # Find GLEW if(GLEW_PATH) message(STATUS "GLEW path explicitly specified: ${GLEW_PATH}") endif() set(GLEW_VERSION 1.5.1) FIND_PATH(GLEW_INCLUDES GL/glew.h ${GLEW_PATH}/include /usr/include /usr/local/include /sw/include /opt/local/include DOC "The directory where GL/glew.h resides") FIND_LIBRARY(GLEW_LIBRARIES NAMES GLEW glew glew32 ${GLEW_PATH}/lib /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /sw/lib /opt/local/lib PATHS DOC "The GLEW library") if(GLEW_INCLUDES AND GLEW_LIBRARIES) set(GLEW_FOUND TRUE) message(STATUS "Found GLEW library ${GLEW_LIBRARIES}") message(STATUS "Found GLEW includes ${GLEW_INCLUDES}") else() message(STATUS "GLEW ${GLEW_VERSION} not found. Specify GLEW_PATH to locate it") set(GLEW_FOUND FALSE) endif() ENDMACRO() MACRO(OCIOFindOpenImageIO) if(OIIO_PATH) message(STATUS "OIIO path explicitly specified: ${OIIO_PATH}") endif() if(OIIO_INCLUDE_PATH) message(STATUS "OIIO INCLUDE_PATH explicitly specified: ${OIIO_INCLUDE_PATH}") endif() if(OIIO_LIBRARY_PATH) message(STATUS "OIIO LIBRARY_PATH explicitly specified: ${OIIO_LIBRARY_PATH}") endif() FIND_PATH( OIIO_INCLUDES OpenImageIO/version.h ${OIIO_INCLUDE_PATH} ${OIIO_PATH}/include/ /usr/include /usr/local/include /sw/include /opt/local/include DOC "The directory where OpenImageIO/version.h resides") FIND_LIBRARY(OIIO_LIBRARIES NAMES OIIO OpenImageIO PATHS ${OIIO_LIBRARY_PATH} ${OIIO_PATH}/lib/ /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /sw/lib /opt/local/lib DOC "The OIIO library") if(OIIO_INCLUDES AND OIIO_LIBRARIES) set(OIIO_FOUND TRUE) message(STATUS "Found OIIO library ${OIIO_LIBRARIES}") message(STATUS "Found OIIO includes ${OIIO_INCLUDES}") # Unfortunately, OIIO hides a dependency to Ilmbase includes if(ILMBASE_PATH) message(STATUS "Ilmbase path explicitly specified: ${ILMBASE_PATH}") endif() FIND_PATH( ILMBASE_INCLUDES OpenEXR/half.h ${ILMBASE_PATH}/include/ /usr/include /usr/local/include /sw/include /opt/local/include DOC "The directory where OpenEXR/half.h resides") if(ILMBASE_INCLUDES) message(STATUS "Found Ilmbase includes ${ILMBASE_INCLUDES}") else() set(OIIO_FOUND FALSE) message(STATUS "Ilmbase not found. Specify ILMBASE_PATH to locate it") endif() else() set(OIIO_FOUND FALSE) message(STATUS "OIIO not found. Specify OIIO_PATH to locate it") endif() ENDMACRO() MACRO(OCIOFindPython) # Set the default python runtime if(NOT PYTHON) set(PYHELP "path to Python executable (also used to find headers against which to compile Python bindings)") set(PYTHON_HEADER Python.h) set(PYTHON python CACHE FILEPATH ${PYHELP} FORCE) endif(NOT PYTHON) if(CMAKE_FIRST_RUN) message(STATUS "Setting python bin to: ${PYTHON}") endif() set(PYTHON_OK YES) # OK until something goes wrong if(MSVC) # Python default installation on Windows is Python 32bit execute_process(COMMAND ${PYTHON} -c "import sys,platform; print platform.architecture()[0]" OUTPUT_VARIABLE PYTHON_X64 RESULT_VARIABLE PYTHON_RETURNVALUE OUTPUT_STRIP_TRAILING_WHITESPACE ) if( NOT ${PYTHON_RETURNVALUE} EQUAL 0 OR NOT ${PYTHON_X64} MATCHES "64bit") set(PYTHON_OK NO) endif() endif() # Get Python version if(WIN32) # Windows install path use the version without the dot set(version_cmd "from distutils import sysconfig; print(sysconfig.get_config_var('VERSION'))") else() set(version_cmd "from distutils import sysconfig; print(sysconfig.get_python_version())") endif() execute_process(COMMAND ${PYTHON} -c "${version_cmd}" OUTPUT_VARIABLE PYTHON_VERSION RESULT_VARIABLE PYTHON_RETURNVALUE OUTPUT_STRIP_TRAILING_WHITESPACE ) if(${PYTHON_RETURNVALUE} EQUAL 0) # Everything is fine else() # TODO: These error strings clobber previous values set(PYTHON_ERR "${PYTHON} returned ${PYTHON_RETURNVALUE} trying to determine version number.") set(PYTHON_OK NO) endif() # Determine Python UCS version execute_process(COMMAND ${PYTHON} -c "import sys; print(sys.maxunicode > 65536 and 'ucs4' or 'ucs2')" OUTPUT_VARIABLE PYTHON_UCS RESULT_VARIABLE PYTHON_RETURNVALUE OUTPUT_STRIP_TRAILING_WHITESPACE ) if(${PYTHON_RETURNVALUE} EQUAL 0) # Hurray else() set(PYTHON_OK NO) set(PYTHON_ERR "${PYTHON} returned ${PYTHON_RETURNVALUE} trying to determine UCS version.") endif() # Locate headers execute_process(COMMAND ${PYTHON} -c "from distutils import sysconfig; print(':'.join(set(sysconfig.get_config_var('INCLUDEPY').split())))" OUTPUT_VARIABLE PYTHON_INCLUDE_RAW RESULT_VARIABLE PYTHON_RETURNVALUE OUTPUT_STRIP_TRAILING_WHITESPACE ) # Handle errors, and process include path if(${PYTHON_RETURNVALUE} EQUAL 0) file(TO_CMAKE_PATH "${PYTHON_INCLUDE_RAW}" PYTHON_INCLUDE) else() set(PYTHON_ERR "${PYTHON} returned ${PYTHON_RETURNVALUE} trying to determine header location.") set(PYTHON_OK NO) endif() if(WIN32) # LIBPL does not exist on Windows, and no variable exist set(library_cmd "from distutils import sysconfig; print '%s/libs' % sysconfig.get_config_var('prefix')") else() set(library_cmd "from distutils import sysconfig; print(':'.join(set(sysconfig.get_config_var('LIBPL').split())))") endif() # Locate Python library execute_process(COMMAND ${PYTHON} -c "${library_cmd}" OUTPUT_VARIABLE PYTHON_LIBRARY_DIRS_RAW RESULT_VARIABLE PYTHON_RETURNVALUE OUTPUT_STRIP_TRAILING_WHITESPACE ) # Handle errors, and process include path if(${PYTHON_RETURNVALUE} EQUAL 0) file(TO_CMAKE_PATH "${PYTHON_LIBRARY_DIRS_RAW}" PYTHON_LIBRARY_DIRS) FIND_LIBRARY(PYTHON_LIBRARY NAMES "python${PYTHON_VERSION}" PATHS ${PYTHON_LIBRARY_DIRS} NO_DEFAULT_PATH # Don't be "helpful" and randomly grab library from /usr/lib etc ) message("Python library: ${PYTHON_LIBRARY}") else() set(PYTHON_ERR "${PYTHON} returned ${PYTHON_RETURNVALUE} trying to determine library path.") set(PYTHON_OK NO) endif() # Construct variant path - a path that sufficiently identifies the # ABI-compatbility of the built library. See Github issue #236 if(OCIO_PYGLUE_RESPECT_ABI) # Respect Python major/minor version, and UCS version (unicode # content system). E.g install into "lib/python2.6/ucs4/site-packages" # Windows & *nix does not use the same path, refer to https://docs.python.org/2/install/ if(WIN32) set(PYTHON_VARIANT_PATH "lib${LIB_SUFFIX}/${PYTHON_UCS}/site-packages") else() set(PYTHON_VARIANT_PATH "lib${LIB_SUFFIX}/python${PYTHON_VERSION}/${PYTHON_UCS}/site-packages") endif() else() # Ignore UCS value and install into lib/python2.6/site-packages dir if(WIN32) set(PYTHON_VARIANT_PATH "lib${LIB_SUFFIX}/site-packages") else() set(PYTHON_VARIANT_PATH "lib${LIB_SUFFIX}/python${PYTHON_VERSION}/site-packages") endif() endif() ENDMACRO() MACRO(OCIOFindJava) if(APPLE) SET(_JAVA_HINTS $ENV{JAVA_HOME}/bin) SET(_JAVA_PATHS /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands) FIND_PROGRAM(Java_JAVA_EXECUTABLE NAMES java HINTS ${_JAVA_HINTS} PATHS ${_JAVA_PATHS} ) IF(Java_JAVA_EXECUTABLE) EXECUTE_PROCESS(COMMAND ${Java_JAVA_EXECUTABLE} -version RESULT_VARIABLE res OUTPUT_VARIABLE var ERROR_VARIABLE var # sun-java output to stderr OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE) IF( res ) IF(${Java_FIND_REQUIRED}) MESSAGE( FATAL_ERROR "Error executing java -version" ) ELSE() MESSAGE( STATUS "Warning, could not run java --version") ENDIF() ELSE() # extract major/minor version and patch level from "java -version" output # Tested on linux using # 1. Sun / Sun OEM # 2. OpenJDK 1.6 # 3. GCJ 1.5 # 4. Kaffe 1.4.2 IF(var MATCHES "java version \"[0-9]+\\.[0-9]+\\.[0-9_.]+[oem-]*\".*") # This is most likely Sun / OpenJDK, or maybe GCJ-java compat layer STRING( REGEX REPLACE ".* version \"([0-9]+\\.[0-9]+\\.[0-9_.]+)[oem-]*\".*" "\\1" Java_VERSION_STRING "${var}" ) ELSEIF(var MATCHES "java full version \"kaffe-[0-9]+\\.[0-9]+\\.[0-9_]+\".*") # Kaffe style STRING( REGEX REPLACE "java full version \"kaffe-([0-9]+\\.[0-9]+\\.[0-9_]+).*" "\\1" Java_VERSION_STRING "${var}" ) ELSE() IF(NOT Java_FIND_QUIETLY) message(WARNING "regex not supported: ${var}. Please report") ENDIF(NOT Java_FIND_QUIETLY) ENDIF() STRING( REGEX REPLACE "([0-9]+).*" "\\1" Java_VERSION_MAJOR "${Java_VERSION_STRING}" ) STRING( REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" Java_VERSION_MINOR "${Java_VERSION_STRING}" ) STRING( REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" Java_VERSION_PATCH "${Java_VERSION_STRING}" ) # warning tweak version can be empty: STRING( REGEX REPLACE "[0-9]+\\.[0-9]+\\.[0-9]+\\_?\\.?([0-9]*)$" "\\1" Java_VERSION_TWEAK "${Java_VERSION_STRING}" ) if( Java_VERSION_TWEAK STREQUAL "" ) # check case where tweak is not defined set(Java_VERSION ${Java_VERSION_MAJOR}.${Java_VERSION_MINOR}.${Java_VERSION_PATCH}) else( ) set(Java_VERSION ${Java_VERSION_MAJOR}.${Java_VERSION_MINOR}.${Java_VERSION_PATCH}.${Java_VERSION_TWEAK}) endif( ) ENDIF() ENDIF(Java_JAVA_EXECUTABLE) FIND_PROGRAM(Java_JAR_EXECUTABLE NAMES jar HINTS ${_JAVA_HINTS} PATHS ${_JAVA_PATHS} ) FIND_PROGRAM(Java_JAVAC_EXECUTABLE NAMES javac HINTS ${_JAVA_HINTS} PATHS ${_JAVA_PATHS} ) FIND_PROGRAM(Java_JAVAH_EXECUTABLE NAMES javah HINTS ${_JAVA_HINTS} PATHS ${_JAVA_PATHS} ) FIND_PROGRAM(Java_JAVADOC_EXECUTABLE NAMES javadoc HINTS ${_JAVA_HINTS} PATHS ${_JAVA_PATHS} ) # Check for everything include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Java REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE Java_VERSION) set(Java_FOUND TRUE) find_package(JNI) else() find_package(Java) find_package(JNI) endif() ENDMACRO() MACRO(ExtractRstCPP INFILE OUTFILE) add_custom_command( WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT ${OUTFILE} COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/share/sphinx/ExtractRstFromSourceCPP.py ${INFILE} ${OUTFILE} DEPENDS ${INFILE} COMMENT "Extracting reStructuredText from ${INFILE} (using old process)" ) ENDMACRO() MACRO(ExtractRstSimple INFILE OUTFILE) add_custom_command( WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT ${OUTFILE} COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/share/sphinx/ExtractRstFromSourceSimple.py ${INFILE} ${OUTFILE} DEPENDS ${INFILE} COMMENT "Extracting reStructuredText from ${INFILE}" ) ENDMACRO() MACRO(CopyFiles TARGET) # parse the macro arguments PARSE_ARGUMENTS(COPYFILES "OUTDIR;" "NOTUSED" ${ARGN}) # get the list of sources from the args set(FILES ${COPYFILES_DEFAULT_ARGS}) # find the shader compiler if(NOT COPYFILES_OUTDIR) set(COPYFILES_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}) endif() set(${TARGET}_OUTPUT) foreach(FILE ${FILES}) get_filename_component(_FILE_NAME ${FILE} NAME) set(OUTFILENAME "${COPYFILES_OUTDIR}/${_FILE_NAME}") list(APPEND ${TARGET}_OUTPUT ${OUTFILENAME}) add_custom_command( OUTPUT ${OUTFILENAME} COMMAND ${CMAKE_COMMAND} -E copy ${FILE} ${OUTFILENAME} DEPENDS ${FILE} COMMENT "Copying file ${FILE}\n to ${OUTFILENAME}" ) endforeach() ENDMACRO() opencolorio-1.1.0~dfsg0.orig/share/cmake/ParseArguments.cmake0000644000175000017500000000514013223553423022412 0ustar mfvmfv#------------------------------------------------------------------------------- # The PARSE_ARGUMENTS macro will take the arguments of another macro and define # several variables. The first argument to PARSE_ARGUMENTS is a prefix to put # on all variables it creates. The second argument is a list of names, and the # third argument is a list of options. Both of these lists should be quoted. # The rest of the PARSE_ARGUMENTS args are arguments from another macro to be # parsed. # # PARSE_ARGUMENTS(prefix arg_names options arg1 arg2...) # # For each item in options, PARSE_ARGUMENTS will create a variable with that # name, prefixed with prefix_. So, for example, if prefix is MY_MACRO and # options is OPTION1;OPTION2, then PARSE_ARGUMENTS will create the variables # MY_MACRO_OPTION1 and MY_MACRO_OPTION2. These variables will be set to true if # the option exists in the command line or false otherwise. # # For each item in arg_names, PARSE_ARGUMENTS will create a variable with that # name, prefixed with prefix_. Each variable will be filled with the arguments # that occur after the given arg_name is encountered up to the next arg_name or # the end of the arguments. All options are removed from these lists. # PARSE_ARGUMENTS also creates a prefix_DEFAULT_ARGS variable containing the # list of all arguments up to the first arg_name encountered. # # Downloaded from: http://www.itk.org/Wiki/CMakeMacroParseArguments # cmake_minimum_required(VERSION 2.4.7) MACRO(PARSE_ARGUMENTS prefix arg_names option_names) SET(DEFAULT_ARGS) FOREACH(arg_name ${arg_names}) SET(${prefix}_${arg_name}) ENDFOREACH(arg_name) FOREACH(option ${option_names}) SET(${prefix}_${option} FALSE) ENDFOREACH(option) SET(current_arg_name DEFAULT_ARGS) SET(current_arg_list) FOREACH(arg ${ARGN}) SET(larg_names ${arg_names}) LIST(FIND larg_names "${arg}" is_arg_name) IF (is_arg_name GREATER -1) SET(${prefix}_${current_arg_name} ${current_arg_list}) SET(current_arg_name ${arg}) SET(current_arg_list) ELSE (is_arg_name GREATER -1) SET(loption_names ${option_names}) LIST(FIND loption_names "${arg}" is_option) IF (is_option GREATER -1) SET(${prefix}_${arg} TRUE) ELSE (is_option GREATER -1) SET(current_arg_list ${current_arg_list} ${arg}) ENDIF (is_option GREATER -1) ENDIF (is_arg_name GREATER -1) ENDFOREACH(arg) SET(${prefix}_${current_arg_name} ${current_arg_list}) ENDMACRO(PARSE_ARGUMENTS) opencolorio-1.1.0~dfsg0.orig/share/cmake/FindNuke.cmake0000644000175000017500000000615313223553423021162 0ustar mfvmfv#========== # # Copyright (c) 2010, Dan Bethell. # 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 Dan Bethell nor the names of any # other contributors to this software 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. # #========== # # Variables defined by this module: # Nuke_FOUND # Nuke_INCLUDE_DIR # Nuke_COMPILE_FLAGS # Nuke_LINK_FLAGS # Nuke_LIBRARIES # Nuke_LIBRARY_DIR # # Usage: # FIND_PACKAGE( Nuke ) # FIND_PACKAGE( Nuke REQUIRED ) # # Note: # You can tell the module where Nuke is installed by setting # the NUKE_INSTALL_PATH (or setting the NDK_PATH environment # variable before calling FIND_PACKAGE. # # E.g. # SET( NUKE_INSTALL_PATH "/usr/local/Nuke5.2v3" ) # FIND_PACKAGE( Nuke REQUIRED ) # #========== # our includes FIND_PATH( Nuke_INCLUDE_DIR DDImage/Op.h $ENV{NDK_PATH}/include ${NUKE_INSTALL_PATH}/include ) # our library FIND_LIBRARY( Nuke_LIBRARIES DDImage $ENV{NDK_PATH} ${NUKE_INSTALL_PATH} ) SET( Nuke_COMPILE_FLAGS "" ) SET( Nuke_LINK_FLAGS "" ) IF( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) SET( Nuke_COMPILE_FLAGS "-arch i386" ) SET( Nuke_LINK_FLAGS "-arch i386" ) ENDIF( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) # our library path GET_FILENAME_COMPONENT( Nuke_LIBRARY_DIR ${Nuke_LIBRARIES} PATH ) # did we find everything? INCLUDE( FindPackageHandleStandardArgs ) FIND_PACKAGE_HANDLE_STANDARD_ARGS( "Nuke" DEFAULT_MSG Nuke_INCLUDE_DIR Nuke_LIBRARIES Nuke_LIBRARY_DIR ) SET( Nuke_API_VERSION "" ) IF( NUKE_FOUND ) TRY_RUN(NUKE_VERSION_EXITCODE NUKE_VERSION_COMPILED ${CMAKE_BINARY_DIR} ${CMAKE_MODULE_PATH}/TestForDDImageVersion.cxx COMPILE_DEFINITIONS "-I${Nuke_INCLUDE_DIR}" RUN_OUTPUT_VARIABLE Nuke_API_VERSION) message(STATUS "Nuke_API_VERSION: --${Nuke_API_VERSION}--") ENDIF() opencolorio-1.1.0~dfsg0.orig/share/docker/0000755000175000017500000000000013223553423016637 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/share/docker/dockerfile_centos7_gcc480000644000175000017500000000373113223553423023327 0ustar mfvmfv# # Centos 7 Dockerfile for OCIO # # Pull base image FROM centos:7 LABEL maintainer="sean@seancooper.xyz" # Install yum hosted dependencies RUN yum -y install epel-release && \ yum -y install gcc-c++ \ make \ cmake3 \ git \ wget \ bzip2 \ file \ which \ patch \ python-devel.x86_64 \ python-sphinx \ glew-devel \ java \ libtiff-devel \ zlib \ libpng-devel \ libjpeg-turbo-devel \ bzip2-devel \ freeglut-devel \ libXmu-devel \ libXi-devel && \ yum -y clean all # Install Truelight library RUN mkdir /home/download && \ cd /home/download && \ wget -O truelight-4.0.7863_64.run --post-data 'access=public&download=truelight/4_0/truelight-4.0.7863_64.run&last_page=/support/customer-login/truelight_sp/truelight_40.php' https://www.filmlight.ltd.uk/resources/download.php && \ sh truelight-4.0.7863_64.run # Install Boost RUN cd /home/download && \ wget https://sourceforge.net/projects/boost/files/boost/1.61.0/boost_1_61_0.tar.gz && \ tar -xzf boost_1_61_0.tar.gz && \ cd boost_1_61_0 && \ sh bootstrap.sh && \ ./b2 install --prefix=/usr/local # Install OpenEXR RUN mkdir /home/git && \ cd /home/git && \ git clone https://github.com/openexr/openexr.git -b v2.2.1 && \ cd /home/git/openexr/IlmBase && \ mkdir /home/git/openexr/IlmBase/build && \ cd /home/git/openexr/IlmBase/build && \ cmake3 .. && \ make install -j2 && \ cd /home/git/openexr/OpenEXR && \ mkdir /home/git/openexr/OpenEXR/build && \ cd /home/git/openexr/OpenEXR/build && \ cmake3 -DILMBASE_PACKAGE_PREFIX=/usr/local .. && \ make install -j2 # Install OIIO RUN cd /home/git && \ git clone https://github.com/OpenImageIO/oiio.git -b RB-1.7 && \ cd /home/git/oiio && \ mkdir build && \ cd /home/git/oiio/build && \ cmake3 .. && \ make install -j2 # Remove cache RUN rm -rf /var/cache/yum && \ rm -R /home/git && \ rm -R /home/download opencolorio-1.1.0~dfsg0.orig/.appveyor.yml0000644000175000017500000000156713223553423016745 0ustar mfvmfvversion: '{branch}-{build}' image: Visual Studio 2013 clone_folder: C:\source\ocio test: auto configuration: - Release platform: - x64 environment: global: CMAKE_PREFIX_PATH: C:/Libraries/boost BOOST_ROOT: 'C:\Libraries\boost' matrix: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 CMAKE_PLATFORM: "Visual Studio 12 2013 Win64" - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 CMAKE_PLATFORM: "Visual Studio 14 2015 Win64" install: - cinstall: python build_script: - echo Running cmake... - mkdir _build - cd _build - cmake -G "%CMAKE_PLATFORM%" -DCMAKE_INSTALL_PREFIX=..\_install -DOCIO_USE_BOOST_PTR=ON -DCMAKE_BUILD_TYPE=%CONFIGURATION% .. - cmake --build . --target install --config %CONFIGURATION% - cmake --build . --target MainTests --config %CONFIGURATION% matrix: fast_finish: true opencolorio-1.1.0~dfsg0.orig/testdata/0000755000175000017500000000000013223553423016077 5ustar mfvmfvopencolorio-1.1.0~dfsg0.orig/testdata/mga.zip0000644000175000017500000067627413223553423017415 0ustar mfvmfvPK /b>mga/UT Iz N NUxPKJ>&mga/mgaformatnotesUT ] N,z NUxmUn6+ȡ1Z46N,"ئ=&,HqoHڱH,q83o޼޵]@)ng2mp6`%)fGO]izq}/IZ* bC:OHhgҸMn%H7ޥ;Ŝ:glc.PqE0+;rp|RL[o dBJ=8dzX`$g~J@^ք3Ly;kqxuW^_tE5N7kbހU7 djpo^v=0O bvBtgx]+NN έjziX,T#Lzw Kh<73C~QJ"_5ՈKK' 6Jb47GD5Dn\lvTSP{هMk5:[A)0TY?Рg_ՙ/$>YuL>"ɘ{S1ggMACvuI HaBTzZl}2њu3Qg-@',qk~1k0T2BWʢƬ݁ä5/z1Z;Y|DI.B(720ψ|[Lr1=T[Z]J";NgEIՑHFr^^^Wt~)7#&$70ڮx՘k74P2,4a`$uro`{38B2Msq`ߒyw:gQ*zL!ZbˌH&QF,WmdVV8Y1S)CQV꿨,Ttnlot7ʑE0ߘ#n\1sI t'،9C?s8M0 'bQx<}6 ~V}r]}_^b6c|+u9PKjW>;-g\vmga/3dbypass.m3dUT g Ny NUxmˮ-ud P@ vvP%VYY333xOAq?o׿~?_/?/Rן??o_R׿oǿo/W_ϟܗ;=~O/=r7;e=.viw{]wP9~O{ŝ޳lOnw=;=wvy/w{]^nk'{xyN{gwzxN]S]s.vyow7`r&w;a>=s{bj遞SO/;>sr|N}F9m#xOw#KZ@ & [s+]GWN +& @9;pl<~e~xTwI?wKP-M@u4k\h#8PGpz_$86h%?Wzfcns|/W@s4twKqwK-M^(+8PVpz_+86+?W Ƃcs|/ &`[ni%rDn=fyOYS0;fM _s&`nw|/ X&`[ni X&]38Pgpjg~4+ @ @9|I+`K^%[^%[^%[^%[^|# Ok~kpl?!@9?#@9?%@ xϗw?-& [ni (&g^h68Plpzh{lk~+& 9^S!+Kni &[_h68Plpz_5865?S+xϗw &[ni @9+GW N+& @9kpU6w|/Wp4 wK0-Mt4(7_^h68Plpz_5865?Wz^c^s|/y%Mr4,wK-M5txJ OSi ^BçЩq>wHjr7;kzӿwԧn~T޻n?sHMޟ٧Bp~Kk{ÝMHNrifcF 77?%ͿJi**ݟ_EesSTf|`UTS}`j UTÝMQj)榨n+YNVBp-ZLCbڈ5fLBbڎɕVN ~W8u6R1F 95&h1F9#&و7gCFD`fd`fd`fd`fd`wlOCs||z|OS=N>NǧuV竹]݌~f{7c߻ [?^n)Hxꥅ|}K ?pss09(L7? 7Y#G(hϯG<}` Uw|`JUTMQJ)*榨nnJ)*ߛQS8jTKLS1j =&T1 +&WV7[MZD?TF ЬpzbrsKL^crs{Looκ p 020g#20gFu6z1B`ƌu6VH1fu6sH,1f9u6#s6#s6#s6#AڳFk9kۻFjo9kܻFooζ pQj޳Fy9k䤞޻FNjz9k䤮޻Fo$g3Ȇu6sdp\g3G٤]#'g5rR{I]#'5wT5rR{I]#'w%ޜA:+9+9+9+99"]#'gT5rR|I]#'uw5rR|I]#'uw-ޜ5A:k9k9k9k9k9k|̶uSC`zukHYo1.193&Y7g]FD`Fd`Fd`Fd`Fd`Ψ~I-Y#'g5rR|I]#'uw5rR|I]#猷7gSfD`fd`fd`Vd`Vd`Ψ~I-Y#'g5rR|I]#'uw5rR|I]#玷7g[vD`vd`vd`vd`vd`Ψ~E-Y#g\5rQ|E]#uw\5rQ|E]#WV>%G/92"]#g\T5rQ|E]#uw\5rQ|E]#uw\%ޜA:+9+9>'20g520gTkJF.k:F.kۛ&\g-"0g-20g-20g-2,E%bF.j>k:F.k:F.F9u6"s6"s6"s6"s6"s)??п>OӫS<}zs|%}JO{O{Oc)z2gK;^]d,wK3-Mr4,>VW!& X+&!1%;Z9&W.!17fh WҎӎ LՎ ֎ "l'b`opzTCpBpcb07Bb2fL'ͥisi>q.O΂'>.GΑ9ˑ9`VRLcbJWj\i" "ʈ+SD^L_Q,*`*h*h*h*h4~&]G<ɕXWLLb"[IlYDWb+"[>JlIlŕ     ؉wܽ+\$!+ľDt%-+qđEt%$JIIIII:=7g\ ss+|w>7wssK|M?7wSp0KOd4L4L4L4L" J>3*젛;nLS6n;nPsނI܊ŕ  \O<1IgräM\0M0M\1ݧ&.#HL90U}"i>4qtM r) ,A) .X͂χ' .?\adf4M\@&nMWP ;%}i>4UAVbVUp*j\` .Z7ɬj12-V[Ym%fڪjk"3 VYm6EŬ6V]p.j\`;*}j~j~j>|5qEuaM\Rg&nYT{h4XY VCp)*DsʕiG-Fʝjg#fʭkgKdf{;mg.EŬ.VKp%\`[w}Y #X3X.2EugSdfu "{ ,x .x .x .x .x w͙3ezs.9s}ޜ˾oe7g3ww͙;bVYp,j\`.ʅ;ms29s}˾peI8g(3wwΙ; ]sVEŬVVUp*j\` w*Ι3es.9s}'㜹˾qe8gp3ww:Ι;X튊Y vV]p.)=M)tl&OcX<ݕt{;}tc#|][4uaht +F&g\ wl^f#$3gL\!cdVZ9DJ׊l fmE" [HWhM.!1wI=DGL12{ѕx>Z WyGWyE&+"xѕx^xfk<ϯ󜇏󤇏Ly#dygx+W{]=ff<2ә̊  JEp"ja.?{t>sZFj1ղDfVˎ$2Zj-1ZEfV UQ1U`*j\` .Xm;P?7Ȭ#Xm]dfj"3m̬3XIdf "X vV]pU:d g΅;Z]sֹp }w\u.F:ntD`u(*fu ,:X NV\Xv.\W ;ψ w΅;c…ݱsٹpe}\Sv.\Z-;%RTX`u .X݂ nVҞ]{vم۳ Xgnn.\aݞ]ú=ru{vZr$՚ZbVk\jMY\hiϮf=r}]ٕ۳+wYgWnϮeݞ]˺=ru{v͂EŬVEp"j\`o-2Y-+FfjM"35 VkYUdfj"3Uժ*j\` .Xm r=r}eݳ+wYgWnϮeݞ]˺=ru{v.]ٵ "X vV]pU.gWn]̾{v.]ٕ۳+wYgWnϮeݞ]˺=NAVbVSp)\`u .ʅmݳ+wϮeݞ]˺=ru{v.]ٕ۳+wYg%RTX`u .X݂ nVҞ];{v2ٕ۳+wYgWnneݞݸ˺=qu{v.ڒr$ՖڒbV[\j˂Ym\hinf=q}]ٍ۳wYg7nneݞݸ˺=qu{v+EŬVEp"j\` -ٍg7.ݸ˺=qu{v.]ٍ۳wYg7nnUժ&j\` .Xm ~ X>6ǰϹV>Og}ܧ>fU>=97[[ok. uw_03}aeȠ~;6/Ԍ#F&hX12McL"Ț9FkFP6 6# Hf3ҀI4{v[)ĕCbW $#Z q5bd $#"H܂I$Hw;Ҁi@&goi+FqNȮ Ly'dy 'dWy gf󼇣n~~/z 5z^)=:=̤rBv7rZ=/kosZKj1DfVk!2Zj]1պEfV MQ1M`&j\` .XI{vٝkgwnn>ݞݹ=s u{v&mٝ۳{D`+*f ,:X V\Xi\W=s]}uٝ۳;Vgwnn\Yݞݹ=siu{vNEŬNVSp)\`,ٝgwݹ=su{vٝ;۳;Xgwnn[խ-\`u .X݂ r=s}eݳwYgneݞ=˺={pu{.]# "fu$EZY`1# .fudŬ,Ց:V#3筥]絥]%RȮ撺kk3z^ Y͂ fV3qA5%sZrj)1REfVK.2Zj1ղDfV UQ1U`*j\` .ZXӕ>3UhV}>d9f-UUnVdf "Xm vV]pU.g/{}ً ۳7Vg/n^Yݞ={ AVbVCp!\`u. ݳw^_ݞ={qu{ ًK۳Xg%RTX`u .X] .VҞ;{2ً۳wYg/n^eݞ˺={qu{.X݊YYIp1; .fu'Ŭ$՝ܷ֖vZiZiȬDvcfVwN"Vw"Vw.13;W]; "fugEZY`,j\`5 .ZXBK{6ٛgoneݞ˺={su{.]ٛ۳wD`**f ,ZX VV\hif={s}]ٛ۳7wYgoneݞ˺={su{n6EŬvV]p.j\` -ٛgo.˺={su{.]ٛ۳7wYgonCա!\`u.:X r={s}eݳ7wYgoneݞ˺={su{.]{ "X] .VKpU.gon̾{.]ٛ۳7wYgoneݞ˺={oAZ-))*jII`VKJ˵ZR\Ւrk$.=$nϞ]g.g]ݳK.%q}쒸˾{vIe=$]RD`5+*f5 ,X- VgJf4Y:3ұ79fU>7k9fx׭fPu 3V/4Ϟ]CTؼSjH`CGm4#3V 9@Y,Z0 Gp#  H;ٳywľCbG $#8J qbdG$#8"HI$Hg3Ҁi@$=wi#FqA\"3s *W\Yd&s"3Kϥ%\t .pH݂ ngΔ?7Ȭ#X]dfu"3{̬3z^ ٵz^R7OLQV+S!V+S>3畩])TȮԳJ])~g|tW|dV+S!V+S>3畩]畩])j"3Yլ"j\`.ZX- rD=͈fk'"r*7Pd-'3D2mr#jD`**f ,ZX 6V\Xsunz`l V>d[df;+~U.?YvEŬvV]p.j\`w.gٳKٿ*2 ݳK %s}쒹ľ{vb=!TTX`u .:X NV~쒹>{v\f=d]2ww.g]ݳK.%s}쒹˾{vKե%\`u .X݂ n0nܬ#G`uOսb{Z-)Z-)̬TDv$Ւk$Ŭ$ՒZbVK\jBݳK6٥p}R˾{v)e=] ww.g]ݳK.٥AVbVEp"j\`.ʅgmٳK2٥p}R˾{v)e=] ww.g]ݳKVEŬVVMp&j\` w}Y2٥p}R˾{v)e=] ww.g]ݳKvEŬvV]p.\` w.geٳK.٥p}R˾{v)e=] ww.g2XY NVSp)*] g.g]ݳK.٥p}R˾{v)e=w6be=%RTX`u .X݂ nVҞ];{v2م۳ wYgWnϮeݞ]˺=ru{v.Zr$՚ZbVk\j͂Y=/Z=/Yٵyk_f]Oost}sn>]aSsUJ[TuaNq +F gܱy9$N12Aji#FfAV]12_5r&Xa@\4E" l$6ݳϻS$vH ĞC$#[ 9@b,Lb0 G8" H$HѠ=3M12c"+fP9L"33 6g霂|NEńNFSp)@\`u1}ޙfuUc̬3X]CdfuMյbk̬nAVbV[p-\`u . )nVѵz^Y=LZ=L̬WBvWBvW|fV+S!V+S\- ,f23z^ ٵڲbV[\jI{vٍkg7nnn>ݞݸ=q u{v&mٍ۳[D`(*f,ZX- V\X}kJ<7\WU`OfV"Un?YU`KOfV MQ1M`&j\` .X}|s;'1U.>Yr}ɺ*O6EfV ]Q1C`!\`u.:XBK{v6ٍg7nneݞݸ˺=qu{v.]ٍ۳D`u**fu ,:X .V}+lmj12VY]3f"3; VwY݂nEŬnV[p-\` -ٝgw.ݹ˺=su{v.]ٝ۳;wYgwnI1=+*jYYp1= .fgŬ,΅mݳ;weݞݹ˺=su{v.]ٝ۳;wYg"jQTjX`.ZX VVҞݹ;{v2ٝ۳;wYgwneݞݹ˺=su{v.XmYm 6VMp&*Zڳ;w\f=su{v.]ٝ۳;wYgwneݞ݇ CQ1C`!\`u.:XBK{v6ٝgwneݞݹ˺=su{v.]ٝ۳D`u**fu ,X] .V\hif=s}]ٝ۳;wYgwneݞݹ˺=su{v߂nEŬnV[p-Ցz^>=/Yٵyk_f]_*>7{ͪ;U=yy9UVm6s~ w7kI簒}a$}{yBbjJ #Tj਴cdd#U"(+YHj}5Ҁi@b%=;Mb!1u뎑Il)DrLb+12[Il$6$[-Ҁi@b4  ڳ;S4#{ >c}\-29R`sd!PTLX`t.P:8 Vs)nVgY%F:l1EfVY3f:D`u)*fu ,X] .VО}ޙfuյc;̬3XEdfuWb̬nAVbV[p1畩]3 .fu&ŬNgO=v{ٓ۳'PgOnnϞFݞ=={fAĬά\3 ,fufVYp,*Vڳ'wϞ\W={r]u{Ʌٓ۳'WVgOnϞ\Zݞ= UQ1U`*j\` .ZX6_YȬrE\`2 r*w؟̬rEb2XmYm vV]p.*Zz*Yn֟hV>d;f]_OEfV>dUdfu"::X VSp4gfub̬3XSdfu.չc+̬.AVbVKp%\`u .ʅmݳ'wϞeݞ=˺={ru{.]ٓ۳'wYg-VTՕbVW\JY]Ip1 -ًg/.˺={qu{.]ً۳wYg/n^Y1++*f5 ,X͂ V\hi^f={q}]ً۳wYg/n^eݞ˺={qu{VEŬVVUp*j\` -ًg/.˺={qu{.]ً۳wYg/n^Mծ.j\` .X r={q}eݳwYg/n^eݞ˺={qu{.]k"::X NVSpU.g/n̾{.]ً۳wYg/n^eݞ˺={-AVbVKp%\`u .)?јO3)|l&?a]s3|{O_}ڧ9}zs~m7Z:oS=yy9fΛT|nV΃T5r^郞;^3T.j#T.1; *]A *Ly~G+GP # +ܕHJ%ҀB4{yw2Bb $#Xv Ěcdk $#X#HI$Hk5Ҁi@b#gwil5F汵Ad"3m *lKd&fO"3]Ϯ.h\ .pH vݳ;Sܬ#:r`uQc̬.2:F`uL!PTX`u .:X NV'q=312sVY])f*"3 VWY].EŬ.VKp-\`+'ٛ;goy={st{-ٛgmݳkF5%AZ))*jMI`VkJ˵ZS\՚r֔k&.=&Ϟ]gϮg}ݳk5qc}울{vMY=&.]SD`(*f,ZX- V`{vM_=&Ϟ]wϮ g ݳk 5q}울ľ{vMb=*jUTjX` .Xm 6VgiܬrEdV"U?Y. VdfOfV"U?YvEŬvV]p.j\`uoY9QbdVG&2:z`u 1EfVNJ-2:XY NVSp)*]gϮg]ݳk.5q}울˾{vMe=&]wwϮi "X݂ nV[pU.=&nϞ;12e=&]wwϮg]ݳk.5s}욓 bVsRT՜bVs\jNYYp1 wϮgeٳk.5s}욹˾{ve=f]3wwϮg\X-Y- VEp"*]3gϮg]ݳk.5s}욹˾{ve=f]3wwϮ "ZXm 6VMpU.=fnϞ]3gϮg]ݳk.5s}욹˾{ve=f]sD`+*f ,X V\h{vf=f.Ϟ]3wwϮg]ݳk.5s}욹˾{ve=)TTX`u .:X NVOE5ҙ<%t 7sY;]aT>7[k[}5K]/lw_}ad}?Gg86/{sޠtr9:/Pj:P:Od|t}קąoCS>S.2w)]})x%wx^rɕxޜr $#W 1ĒbdK$#X"H,I,$HK%Ҁi@b%=wi%FAdm"3 *Sd&f"3MϦ&h\ .pHm 6g`<7mȬ#XYdfj"3̬3XCdf "X VCpA\{v=Ls:F1ձDfVǎ$2:,1YEfV SQ1S`)\`u .Xݳkٵp|Zy{v->=w6bB=wDfV=p#u{vقnEŬnV[p-\` +مgW]=r_u{vʍٕ+۳+wVgW.nϮI15)*jYYp15 .ffŬ, ݳ+wϮ_ݞ]=ru{v ٕK۳+Xg"jQTjX`.ZX VVҞ];{v2ٕ۳+wYgWnϮeݞ]˺=ru{v.XmYm 6VMp&js [[=ssj/1^EfV{.2ڇj1վDfV CQ1C`!\`u.:XB__3Y2_*wٟmV>*w٧|*2]_OEfV SQ1S`)\`u .XBK{v6ٕgWnϮeݞ]˺=ru{v.]ٕ۳D`u+*fu ,X݂ nVbVZڳwn\f=qu{v.]ٍ۳wYg7nneݞݲ bV[VTՖڲbV[\j˂YmYpU.g7nݸ̾{v.]ٍ۳wYg7nneݞݸ˺=AVbVUp*j\` .ʅmݳwneݞݸ˺=qu{v.]ٍ۳wYg&jSTjX` .Xm vVҞݸ;{v2ٍ۳wYg7nneݞݸ˺=qu{v.6XY VCp!)hIf4Y:3ұ79fU>7k9fkxumrׅ ;f/,w_Yt}re͐B;k"89Fi]CY|ʶ`avq;Ҁiy|GWy|ϻSJ{S>sS.2)])qo# WyjGWyiE&<4## H̑$fA{ygʟƒcdKD*23YZ̠t2Df2ˌl%2Y  VJUp*je.=3j]12uV[Ym9fڊj"3 V[Ym6EŬ6V]p.j\`ڳ;Sܬ#G`Oվb}̬$2:r`u!PTX`u.:X VrҞݹs{vٝ۳;OgwnnBݞݹ=su{vFX]Y] .VKp%*Vڳ;w\W=s]u{v΅ٝ۳;WVgwn\Zݞݷ [Q1[`1# .fu$Ŭ$Ց:Ҟ={ك۳Xgnn\aݞ=ú={pu{:r,j\`5 .X- r={p}eݳwYgneݞ=˺={pu{.]٣ "ZZX VVUp4fՖc̬3XmMdfu6bm̬6AVbV]p.j\` .ʅ?;͈f,"]r*wٟ]ڬr*wٟ̬ru{.1XY VSp)*Zz*YjVWX.UO[dKdf~ge|,2X]Y] .VKp%*Zڳw\f={pu{.]ك۳wYgneݞ= bVgRTՙ:bVg\LYIp1 -ٓgO.=˺={ru{.]ٓ۳'wYgOnϞYլ,j\`.ZX- r={r}eݳ'wYgOnϞeݞ=˺={ru{.]ٳ "ZZX VVUpU.gOn=̾{.]ٓ۳'wYgOnϞeݞ=˺={vAVbV]p.j\` .)??5&gfSbL~+⧻>f[>97sOWslouY04}agt #ݳCTؼS3gH`gCG+4#3J k9@,ڊ0 nEp" [ H7)wlw I-${L!=cdI;D&6+<6%.>`q%|t%\dCS>[S.2)]筩练k3ϯ̔ʔLye*dyeg22+23Sd3 "Z- NEp\{ygʟ2cdVˊ-2ZS`fZDfVk&2ZXY VVMp&j#.gwYm-Ffj"3m VYm[dfj"3]ծ.j\` .X r={q|ŵݳ7Og/nn^@ݞ={qu{6ōk"::X NVSpU.g/{}ً ۳7Vg/n^Yݞ={-AVbVKp-\`u . ݳw^_ݞ={qu{ ٛK۳7Xg$՝ku'Ŭ$՝bVw\BK{6ٛgoneݞ˺={su{.]ٛ۳wD`(*f,ZX- V}+lmij125VkY%fZjm"3 VYVEŬVVMp&j\` -ٛgo.˺={su{.]ٛ۳7wYgon]ծ.j\` .X r={s}eݳ7wYgoneݞ˺={su{.]{ "::X NVSpU.5;U.լrů]'3ezY.4OEfV>M%RTX`u .X݂ nVҞ;{2ٛ۳7wwng]ݳ[.-q}언˾{vKIV[JʱRXՖrk,\-eZm wngeٳ[.-q}언˾{vKe=%wwngTX-Y- VEp"*gng]ݳ[.-q}언˾{vKe=%wwn "Xm 6VMpShf4Y:3ұ79fU>7k9fxumRwׅ ;f/ w_tߟ=ܱy=$fΘ12AcƎi)FfjA,12_3r)Xa@܌4nF7# $.g;6$H\-F&qA12k$"H\;F&qG # Hܑ$Hw;ҀM4{v;LsӸwʔLye*dyeg22+23y^ y^R7?E =L=L̔WBv|fRSS!V[Swygʟ_)-*w٧q|2AVbV[p-\jMY\hiϮf=r}]ٕ۳+wYgWnϮeݞ]˺=ru{v͂YYQVkXj͂YYp15 .XBK{v6ٕgWnϮeݞ]˺=ru{v.]ٕ۳kD`(*f ,ZX VVBfdl~J,OcXt ~z+ާ>fWs|c5K]/4w_}a}{yBbjz #gਯcdF d#5"(YčHF}#Ҁi@ =;M!1gI-D8{L12s犑I$.$W+Ҁi@4 q ڳ;S4#v r'ɝc\*2[`sw-VTLX`t .243z ٵzޚzzޙyfGyeGf2k23ٵz^ ٵz^Y=LZ=L~/YQV+S!V+S>,j\`5 .Z )nVKY-5FZj12DfVY-+fZjD`**f ,ZX VV\9in9=q|ٍۧ۳7Pg7nnnDݞݸ=q#u{vk6EŬ6V]p.j\` +ٍg7ݸ=q_u{vƍٍ+۳wVg7.nnCա!\`u.:X r=q}ݳWg7.nn`ݞݸº=qu{v-m "X] .VKpU.g7nݸ̾{v.]ٍ۳wYg7nneݞݸ˺=mAVr$՞ړbV{\jOY}+lmϯ՞f՞VjO[dj)ff,k"k3sٵڳ bV{VTjX`5 .X- VҞݹ;{v2ٝ۳;wYgwneݞݹ˺=su{v.^XY VVUp**Zڳ;w\f=su{v.]ٝ۳;wYgwneݞݛ ]Q1]`.j\` .XBK{v6ٝgwneݞݹ˺=su{v.]ٝ۳D`u(*fu,:X NV\hif=s}]ٝ۳;wYgwneݞݹ˺=su{v_.EŬ.VKp%\` -~5fɟȬrů]'3e+r*wٟ̬r}d[dHYIQVGXHYIp1# .fu$Ŭ.gn=̾{.]ك۳wYgneݞ=˺={dAVbVEp"j\`.z -ldlKfW:] Jw:+WܬJ0vz*5K]/Tw_}a}{yVCbjZ #Fbdd##(낅YHz}=Ҁi@b'=;MH!1#GI5D8ZL12cnjI$$g3Ҁi@4 q ڳ;S4#8W rnɕb+\"2j`s5%RTLX`t .P8݂ nV7s)nVwY=F1սDfVٵz^Y=LZ=LO\畩])TȮҔyj*dykygʟ_)])TȮʔye*dye*df5Ϙj^"3Yբ"j\`.ZX- r={r|ɵݳ'7OgOnnϞ@ݞ=={ru{6ɍٳ "ZZX 6VMpU.gO={}ٓ ۳'7VgOnϞYݞ=={vAVbV]p.j\` . ݳ'wϞ_ݞ=={ru{ ٓK۳'Xg)TTX`u .:X NVҞ=;{2ٓ۳'wYgOnϞeݞ=˺={ru{.X]Y] nV[p-v -12{VY;ffu$ku,ku3Rٵ bVWRTՕbVW\JY]Yp1 -ًg/.˺={qu{.]ً۳wYg/n^Eբ"j\`.ZX- r={q}eݳwYg/n^eݞ˺={qu{.]٫ "ZXm 6VMpU.g/n̾{.]ً۳wYg/n^eݞ˺={uAVbV]p.\`u.ʅmݳw^eݞ˺={qu{.]ً۳wYg)TTX`u .:X NVҞ;{2ً۳wYg/n^eݞ˺={qu{.X݊Y nV[p-*Zz*YjVWd._.]Ovn?\Ov$՝ku'Ŭ$՝bVw\PKf_>I-5)K mga/S-curve_for_CineStyle.mgaUT M;y NUxtͮK]7|z,ݼgH@#  ZKbPW~n>@3#ug?+/?O_?O_/_?߿Cww׿?R~?ÿo~?_/׿}kξ~㏿}Wk__k_F9?׼g1~1}eh_'O0sO0W Z~'X|^~?߿ag>_=g_sy#3nggW'unq>MĭLx5nk4<}F?{ƛ>m70?u tɟ)ʟĉiʟȉʟ̉霘ʟЉ)ʟԅi]ʟ~s7'wa*z{+ ^; ^7'xȟ]}w[b[ #n'xO<}z?{>1?Oa" #lɟ`P'0? 6LOa*'`*'`*'|2߼ >ʟZRq{kiW繖=6n纖ٮe}kٸ}Z=~w|&&7cw>7f79 oR7Pۛ]M6&uj{I݉ޤnEmoR7q{IݏY_)ſ7"Uw*ro"?+ro"po"P^]^EF犌7a(2ތt琮xS"7g(2ߠ|"M7i(2ߤ|"M7i(2ߤ|"MJOw*ޤgW)׌{*rU^9W"qo"K[(r/ +r/!+r/"+r/#Ȟ";sE0oPd琮)C{c"Ķ EM؛47i(boPޤIC& EΛ49oPIC3)wyp9oP~ܫνq*uS Ͻ}iso_EڽWv/WvWd Cf EF銌7e(2ޘxs" 7i(2ߤ|"M7i(2ߤ4oPdIC& EV˪ypYoPd+}ܫνqם{*r;W{ṷ]{ṷ]B{ṷ]{ṷ]{wEx9+߄~3";tE27f(boPޠIC{"& EM؛47i(boPIC& EΛ/Atz ]F\EΛ49"sϑ{[Wν}_(%< {pM{pU'{p]G)W^6ϖ^hҫK/9kNJ^czy]^s`wלإ5Gvkz͙]^sfל5gvsz˙]rfw-gv{z˙]rfצbV˙9/kWOD߭Vou__ka;䯉w_2v!q;4 РIݡC# 79p84rphșá3C3gf͜99s84sph̙á3Ck:9Z;䯳5ޭ됿vok+:t/_~C~TCнOqv{4;sphЦqݡC;,',G,g,g,g,g,g,g,g,gN9:{N'ס3Cpo9tl~:tm~:tmޭpƽuh܋kOˢ{_/4_rxB|q5vF͉ݡQsdwhԜ5gvF͙ݡQsfwhԜ-gvF˙ݡrfwh-gvF{-:-gvF#'C^¿gu?~;/w_w!CxphRwhiáAC# F89r84rph̙á3C3gf͜99s84sph4~v\V-rݔ~u_C~7?pܡ{qw^p^⧸CϽm9k8sZ!HC; v89999999999:9s8t*?߽NəáCNCv+۽uk۽}ku/n/=vwh\_uh\_\fs?fIC,9;4 {5uf́ 9c9s\sxfs͙3[5gw[o<-gvf˙ݡ?^N>f˙ݡȉмWo潲ϡ-C^?zq݋Cн;t/n~݋[wPIݡC# 79p84rphșá3 93>3C3gf͜99s84sph{\f-rWнннů_{]7;oyw.Sܡ]^6M59m8i\wh΁áC;G,g,g,g,g,g,gƧ_rprprprp~v{J'ס3Cp s~}k[!3޾{aס{qw^?V'ܡu/n~pZסu/nSC CФסUrVwhZƽCЪ9;j3CЪ9;j3CЪ9;Zj9s|4UgkLU˙cUOVݫۥ>\ul~~^U/C^:ܡ{qw^7?p-~;7PIݡC# 79p84rphșá3C#gF͜99s84sph̙á3Cs{:4sf|4O罏~+ߺk߾k[u^7?pܡ{qw^).sC&uv64;sphΉá#C;g,g,g,g,g,g,g,g,g,g:9:;tns^u^s_ܡ{qw^?Y㓟{q,~hIS%gڅƽCЮ9;k3CЮ9;k3CЮ9;k3Cn{N'CnuhA; ۟C? ~?1gC{qpн;t/nSܡ^:M59m84h\whȁáC#GF99s84rph̙á3C3gf͜9{E'ס3CpN97ܡ{mס{m_݋Cн;t/n~݋C?%>~GiRwhiáMC; v89r8sph?^NC'g9ݫ۝s^u^u^ׯCн;bw;diF)!+~:d%gu^_m(9o|wj_s9s|ӡe3j_y9;d5gv՜3CrfwZgWkt9d-gv!::[2۟C6!=Yr/n:d~q_;7)PsC&uz64;4rphȉ=99s84rphșá3C#gf͜99s84sph~v&\fMrWs?o]:;tmס{qw^7?p!=p[SܡesC&uv64;sphΉá#C;gvΌ/]UYYYYYYg:d9s8t wȿVDow:C0)C{;_ нK)סS*ϡSh)9;tJNB^NyݡSr`w蔜:%GvN͙ݡSsfwԜ:5gvN͙|5gƗr_͙|5go՜9 ?߽Z379_W:>?νů{q]\Nvνu܋C?~uӤPYáӆCuz89q84rphșá3C#gF99s84sph̙נ̙áINC3?zegڻuݾ~ZCwhwܡ5߁;%kY~uhѤYáӆCuv89q8sphΙá3C;g,g,g,g,g,g,gl{:d93aLNė_Ls(ݺŗסP|;p߁;yܡww/nSƥ,fo KɉRr`)9w|o<9XJ,%oKRsa9}|Ԝ>IXjN%,5o K=;BG;H^a޼9nwӿW{_c_;~'Uvݓ2_I|({_iw.YCSCsCNd='d=Gd#gd#d#d#d#d#d#d#d#d#d3d3dwt͜M2&$nw%=p%[/xOB264; xOB2< ֢-9$[95$[97$4xHsrHstHsvHsxHszHszHszHszHszHf9=$YN,dC2dC2#cB2;ҹTBSo@v?ufΊ!q;:G)7_8 &D`F82RS"Q0&Rs"Q0(R"Q0iUC!5ߓ0iHUC!5_0iUCe*_5=~&_5;xϺ+UCI5Cpj5CppE!w\UbsSBf*=fS1/+{67.NCSCs  "*2:BJRZbj͜r͜zFG.$cB2O3;ndslZlwNBUIH; V'!B5ǻdfVN V  erxHszHszHszHszHszHszHf9=$YN,d6;N:r,dFƄdQ/SW/N*-.q-U!Ũj\GUHIERc,\4?,\D #`&Xn€8`&Xn 8`&XqB#Xh~]>s 8`Oaa\j J]5:c]E:{]5>Lɮ"ծ"""M)ӇGķAX #CX AEX aGX qGX qGX+qGX+qGX+q.q38^i}Bl9"V{\_ FXqXq$Xq*Xq0Xq6X-WV{/<ŵw-懅`ag, ;QN, qAp, qAp, '}g3p,SXW(W=ѯ7V{\39V{\:V̗L`a\=V{\3?V{\@V{\)BV<[xpp,\.b `& X n 8`&Xn 8`&XqB#XhMv>s 8`Oaa\3=.3~IG鬚Վ?Lgجvq:fә7YuFjsVY2 y#uu5/ɿ]PĮWQcWg,3Evu"Y:Wa\%bh. M@8t14] M7ADt34LM7ADGa"hn&ݪDĶ46 yubx:d'N,ʫ@":d3N,ͫu-,Յ3Wޤ_]0t1 4]Mibh.f"hn&f"hn&f"hrnE]Sc"hjb[h7#X޽) օ3(XW,+ Eu"@}b`]00 4=MiayB](4݅B](4݅B](4݅B](4݅B](4ݕB](4ݵ.~.W](4UlsMwlH[@ = u@ºclaݱPX(^YDgw"@ úcam06ሿ 1 >,;3Mh;@<д34LM;ADд34LMADt04LMA1UCt04b[hjuAĺc&bݱPXXw,G;#%E*u"ĺa⯫t1 4]Mibh.b"hn&f"hn&f"hMu9tMmil.[@6= u@źcbݱPX(Xw,Ta; 1>MqMpIa7 LhzƁy7ߺZja"7&Z(4D& M0QhjBSLZ˽{mrx5DU55|/9uc5|/);VEbcX(X-j=VEsڔaք5$5f M Leiw_ ܙ M;ADд34LM;ADt04LMADt >5LM&0#Y-ʑbxyrMc̊dXf$"0%Y-9jL*JV&øS8B$t1 4].qbh.&eDf"hn&f"hn&{.~wCt345-4MejdZ٧{%*"@jP>͟jD*3YOSک2kz#4=LM@#0ahz恦BS(4=BS(4=BS(4=_Dk b/L0JZT{ZjD٫E;>K|ʔ`x zd,¬@0"9zd,Ŭu1iC&iL,i㚞4< M;ADд34LM;ADд34LMADtt>5LM&f=dbYOڬ'jm6E"@znփSzet Gh:.fK`B4t14]MADt14]LMADt34LM7ADt34Kuo9tM7A-}$<_ų|"@izbg=00 4=Miahz\V &rM[)L䚶R5m0kJa"״Di+\V ܻ"T&rM[bմP m% {@B[=rߓNgWVbhh+P7X(J,Tm%Һ iJi+I\W jJc״8i+y\V:t&ig"hڙv&ig"hڙ&h߽ˡk:-4*r/` x-Vi+H E `4i+XN  woe.5N&Yt1 4]M@@t14]LMADt14LM7ADt34LMT]K]Dtm+x봕AAyV^uO[y>m%x^yV^5P["@ԆPztBmq M9Ԇ@Q*uDmHqWYԆhQuFmq`yԆRJvHmq$hǙԆRvJmq,pǹԆSJwLmq4xljC.é ͻL6T(|jC ;J6(jCC -s ,SXnm=/z\3z\3z\3z\3z\3K5,k1[[p 'ONN"I p,\D aEp,\ qEp,\ qMp,Mv>s 7q>qpkq~­5:íE:í[ny0.nm=.nm=.nm=.nmOO `a,< QC,< qCGX8 qGX8 qGX8 qLqZq>qaGBpk5FgHgHgHgHgHgHSzxkh<[8FahF ahFahFahNaN, ;qN,&N}8``¸JGBpkq~PHgHgHgHgHgY'nIIp2BX8N(`" X. 8`"X. 8`"Xn [n),4­m%:ím/(6 ?Ng y:ímnmpk#5[۰)ø&a1 4f&0!aXyZ恗 a"yj& a"y(Y(Y(e.~)WY(,ElsMö[|FZj:Zv[ nmigM6v[Knm/nSj2tVpMgct6f Mgt6 Mgct6 Mgct6& Mgct6& Mggtv& Mgg"hڙv&ig"hڷw79tM;A!^nmpkqpks͸S͸S͸S͸S͸sYet Gh:NfS`B4t24M'ADt14]LMADt14]LMADt14EuwU]Dtmi,[@[ی= ím@6cpkPX(ڦ[%4 [۴!ø&1 45f&01 4=M@@04=LMAD04=LM0Qh 0QhJW]C0Qh暮nm+ {@[ nm /g-ֶ{[+nm /g-Nֶa k*1Kh1Mhㄦ1Oh1Qh1Qh3Qh:34LM;ADд/5LMe5/ɿpk[PX(V,nm+ [ۊE­m"ֶfa\)dh:N M'@8t24 M'ADt14]LMADt14]LMADt}9tM7A- nm { = ímapk[X2 E ímapk[X(ږu55MI1 45 Mi14=MAD04=LMAD04=LM0Qh 4j mMֶc pk۱d(v,nmGjB[ێE­m"@ֶcpku0W]5ݕIB]%4M`\ݘ&4ݍqBݘ'4ݍBݘ(4ݍBݘ(4ݍBݘ(4ݝBݙ(4ݝig"hڙݗiBnm; =Zinmogm=ֶ}[[nmgmIOֶǑa\)dh:N M'@8t24 M'ADt14]LMADt14]LMADtw?rn&[l M~[ƻ/6޼ֶ}[ێE­m"@ֶcpk۱PX(ڶU555MI1 45 Mi145恦a"hz&a"hz&a VJë& Mm&pk2, 6=­bpkX(ڬGdCSE­bpkX8ڬNjjU8\SLZeԪ֘&485 M1PhjBSkLZc֘(4Du& M3Qhjig"hڇwrv&]l Mc@Ylnm{@[ʿ5E­bpk^qY,nm["fdtGh:NfS`B4t24M'ADt24LMADt14]LMADt14][uBM뿚fdYnm["@fPY,nm["fVeԄ#45&,&458ԘAD04=LMAD04=LMAD0QhzJQ]Rjz mG">­c~/>v) [ۉE­TKhzbpk;p:di|A­T& MOeTqMOe4 MOc4 MOc4& MOc4j~nm1QhzJDLDдw>5LM&0#Nl[[­VtWi,3í"03N,3í"03N,­-øC8B$t2 4Nqdh:N&d"h:.&b"h.&Z}ˡk.-4Mv6}I/4= í@vbpk;P|?ínmpk;T?[۱"ø&1 45f&01 45Ɓ<AD04=LMAD04=LMAD{)E?M{)LRĶi/[{­`x^d,n@[{"^d,n[{]4 մ$i/Y\^\M{LR51kKc ״Di/\^4&rM{iLҘ51kKc"״Di/\^zS]]]Dдmil"G^bpk/PX(ˠFCX(K,n_pk/<[{KqMpI`h:&4LM'@ín߼pk/}[{w3K,n% 㚚p$Ԙ4@Sc hjLMa"hz&a"hz&1~jZ miM^c pkvS(k,n5 [{E­"@^cpk0WZ5IBZ%4U`\Z&4qBZ'4Bژ(4Bژ(4Bژ(4<[{mLFEF­6& Mkgдܻ&ig"hŶд_+n{ = íbpkX2+ E íbpkɋ~SqMpI`h:&4LM'@##7= #Gxk׬gWܮg37WbǾ^reExMz,\zy}E?1,p O"A p,D 'aIp, 'qIp, 'qEp,\Mv>s q> FD~C\eqrqqqɽqսqq{0.0r3 'M`BJcXi-y14&DPӘnANc"yz& a"z&gɡKz-4E<}}2}:>p%ςlgB\˳!.9Ud2]Հ k:*2Kh:2Mh:*ㄦ2Oh:*2Qh:*1Qh:1Qh:1Qh:1Qh:w?rx5B6t:y>p}30.YLk}6f>#}j>plSgdtGh:fC`B4t04M'ADt24LM'ADt24LM'ADt14]Uuw_M]Dtm)-h }`mXAE +}` mXC nM7@,t LhjLMq145DԘASc"hjLMa"hz&}ʡkz-4&>Bm^O٨@Fj">dO,٩@j"@>0WY5IBY%4U`\Y&4qBY'4BY(4BY(4B٘(4B٘(4B٘(4Bٶw79Dbk: D# >m2b:Ul">dǶO,@l"@)>Ga\!`h: M@8t04 M'ADt24LM'ADt24LM'ADt}U9tMA%k@6n|m%^me^m,^mjn% e0-Tv+VX ښ[2ksMؠ 5a&lׄ _6| aG?LGzaG] Eo 'V^ n_^n_-,n_mln_eLU=^EU*<^UU+<^UU,<^UU-<^UU-<^UՄ-<^MՄ-<^MՄ-<^MՄ-<^mx5a W;zz=^c9xܾ;/ uB}aRn_X((6 jb}aZn_LPx<BbC0x< AC6x< OaS6x< OaS6x<#6x*}aȌn_5v eJ}a٠n_X6 ej}an_LVx .n>2n3>4Ant&+Qx< C!\x<B!lx<)lx <)lx v"q?$}3`٠(q?X6J< eģ`0(Lǣ%R={Dxi(oxQޮQ޲Q޲Q޲Q޲Q߲Q߲AQKәǵ({\0ǵUx\bǵWx\ǵYx\ǵ [x\ǵ [x\ǵ [x\ǵ [x\ǵ [x\ǵ&GhMOǵ [x\Wlh"!EGŮUtgGŲA]QlPyT,TFG}il#GO=Jwa]qWx<!hx<!lx<)lx <a?Sx ho٠@xI.4םDxIn4נHx!J4WLxIJ4ץPxqJ.5WTxJn5WXxJ5W\xJ5W`xJ.6WdxKn6Whx5K6WlxUK6WDyek[fy% \Ry%՛\Ry%Nj]Ry%k^ry%7ǫ_ry&WNj`ry&wKary& bry&&ǫbry.&ל+cry6&ǫcry>&+dryF&7ǫdryN&W+eryV&wǫery^&23<^-32)<^.2)<^03)<^2 539lRydi#[}Yۤ&Wuxnrᶻ;uv |] 8OA8)Zs͕ 'כ>7\o^xpp~#ýfw 73\ofxfof8fofeofeofxeof8e]w҉p F^⛙< ;qSdY~_ Mfy|wFGyV^S\f[_3Gs f__3ܰQ!*}~ߓCgc*\Mey.?ٙEO.0ighv恦`"h:&`"h:&`"h:΢ܻ*d"h:Ŷ@>˚1<&,?E cbX<&,?Ec!øK8B$t1 4].qfhn&f"hn&f"hjLM14݇DĶ@cbx1dyL,Y~@"1dyL,Y~<[qMpIBU%4]E`\U&4]qBU'4]BU(4]BU(4]BU(4]BU(4]BU(4]BUwrx5]BU6taX^y,<,?E caXX?L`EOc6xlbxmqidyY~AqlPy,T~Aqlpyu&(Qx| G#\{ٙY';< *?ςeϳ`٠,X6< .?% 0#T(Vx| GZ-PX.x| !GV-#d<>"lq/"lq/"lq/"lq/"lq/Ijq.Ɗox߮ϳ]#ϳe#ϳe#ϳe#ϳe#ϳe#ϳS*޺t=Mބ)ȣ0fS(M?12),íCîC0Bve(! vm8·/q_3ܹ/gn׿3ne{_2ܾY85>Bk׽DK^¯wN_2ϵpFaO}G+۽Gn|Gnᗸ|Gn̟~}KZ%.-9[E.-"yF alFal~w~uk+y5: Mq-g).,4 Mm0 GhjLM@#0ahz恦a"hz&BU(4]BU(4]BU(4]BUwrx5]BU6t:QJWӅsY~Y~ߛY~ T~ۦ&L؄ bG0x| AG6x| aG؊V-<"la &#L=[؊{ ;QذLPy *?O>AiX(< a4\~VMg[U"ؚ0ք*ES-<>ES^Ou=>-(?޿xy<v *?σe`٠Uӄ*<>Mӄ+<>Mӄ,<>Mc|^4a O)?Ӆ-<>]Ӆ wa]q6x]qWcl(?6W~<5<[6<[6<[6<[6<[6<[6<,:{<(<PX.x< O!S6x /aK6x /aK6x ä{ ou1<ƶ<4<v,?σ]`٠B#l<>#l<>ǫasW)a?BUǫuz WUkdyT~^}T"ϫKdy,?>2Ug&WKg<^*x*L*UUb]Wi=^ {J4x&l*MUǫ4asWi҅=^ {J6x܅ wa}0a{܅ wu1<~*0+?>KUlPy,T~^WAUlPy,\~^e=JOaSTx <)hx <%lx <^%lx <^0{ ou1<ƶ*4 v,?]ϫ`٠*X6 *?eϫ`٠*X65=6% M <6 M <6!G6x| aG6x| aGa k?LZ- lPy],?-B֙D&x< O p)`x <)lx <%lx <^%lx&#l=u.$Q~^m5^ykdyldyldyldyldyldylPy5+:{lJ0c*xlpc0xlBM <>#l<>#l<>a="lq/{ܱm:6,?]#ϫcנX6: *?eϫc٠/-__ϫ׮3]{U"Wa {Wr{W {7A {7a {7a {7a {]ޅ-<0{܅ wu1<~e(?RK_"ϫ2EWi,?Y~^WDzҙD&x< O p)`x <)lx <%lx <^%lx&#,=u.6P~^FWǮձkPyu,T~^WDzAձlPyu,T~^WGgrMc&xlBMc.xlM <6a&l<>#l<>#l^Gxu=6Vx+?vW~^Y~^-Y~^-Y~^-Y~^-Y~^-Y~^:VWtJ*LBX*`B&hh&lh&lh&lh&lh.lIzS &+dryF&׫dryN&+eryV&׫ery^&2^-32^.2^03^253IL*?gRyeC+3T~^YҤʘ&W42IUM*?jRyeY+ۚT~^Yפʾ&W6I畕M*?lRyei+[T~^Yۤ&׌ -?/u6㶻"Cy}8g(??jRQ~^3>)s͑ 'Ǜ>7\o^x8pp|#ýfw 73\ofx6plz3ífW Vg5]Zofx҉p(NQ~^_v7i=Үy6GyFs; ^SY61Bfnj `<3€iFp͈q7#wu8!w}g~gn!8x'^"Y%/k׻|'/vZͬ{~w~w*[%.ߑ["?-4ŵK\[5.s4\[E.-\/r\nD~sY~^^ em,?/{oPy:{(<PX.xlM <6a&l؄ c6xlM6x| aǧ0a{| u1<~Dy{w^y,T~^>AuPPylT~^+Nu֙ǧ({|0ǧ Ux|bǧ Wx|ǧ Yx+ש*l*li&li&li&l1'uiR~^`:5v *?e`٠:X6 *?e 1)?3% 0!Tx(Vx< C4x< OaS6x< OaS6x< Oa0>*z/aK] m6,?]#7'{"뼷({"w){"):{(<PX.x c4xlM <6a&l؄ c6x| aǧ0{| u1<~oaDy+?޾xukPy,T~wA]lPy,T~w)Kg<ޥ(x"L.E]b]wR=ޥ {K4x*l.U]ǻTasw҄=ޥ {K6x&l.M]a?]ǻ4uz wy+?vW~Y~-Y~-Y~-Y~-Y~-Y~-T~ޥ=JaCPx<!hx<)lx <)lx <0{ /u1<ƶ.4 v,?]ϻ`٠.X6 *?eϻ`٠.X6n:{(<PX.x o!&h؄ c6xlM <6a&l؄ aǧ0>izaG] m 6,?]#ϻ`נ.Y~}\"ϻLdy,?>3]߇&k:%rk kQ,V kV! kVa kVa kVa k6a k6a k$ڄ-ٙݰlPy7,T~ wòAݰlpy]t&x+Qx o[-\x cۘQ~ |ݰk^wX6fwò1ݱl,?ecfyw,ϻ3]{Q"a {r{ {WA {Wa {Wa {Wa {Wa {7a {k?LGzz=Mަ^; wǦݱkdy]8.?eϻc٠["Y~}S$ϻdym*?ޗw% 0.Tx(Vx< C4x< aC6x< OaS6x< Oas0a{< Ou1<~%ox߮ϻ]#ϻe#ϻe#ϻe#ϻe#;\~-T~}=Joa[Vx <-hx <M <6a&l؄ c6xl~p=>c@ywlY~FwǮAݱlPyw,T~wDzA=^Z"{(MgD("T("\(# =ǣ [x<ǣ [x<ǣ [x<ǣ [x<ǣ [x<ǣ&GhMOǣ [x<WK{.+?Y~)+SdyM=lPyR~ޣO=Jwa]qWx<!hx<!lx<)lx <a?Sx Z4?ZD6#a&Xm€i8&ضmq83wF0ψq>wh} Ե0{o[FGaa'cW< ΣİZ%.-9[E.-"yB aL.\[ a_򝅅GX%.- ?[.-y~y~a{"{:{Bq޸gyo\7Y~,?=>&øG8\S+LZaԊV&48 M0PhjBS+LZa*V(4DU& M2QhjBSLZݪjjBSkbkjX[= ]WS"p\S"p\S"p\S"p\S"p\S"?5^euM;@,д LhڙvƁyig h:&`"h:&`"h:&.ʡk:N-4&p=?|?bpM-;3: M?~ax|gBS,)2k#4]LM>Mifhnf"hn&f"hASc"hjLM 9tMmWSl {+?omX @aT~ކE ۰Py2kz#4=L,)㚞4)<) D)LD)LDLDLD)\~ާ.jz*m&>X{=y/ dy@y/ dy@iW{i3]cOW"Wta] mW oA.h0 wA!lwA!l0xa}Y-^~'_1@y9=~gyfx^>-,?>m,?>LRx <^BbK0x oA[6x oa[6x oa&l؄ [a?BS؄ {y>X& *?}`>(V *?3G#L{l(J.J0J2J4J6J6J6J6J6J6J6J6J6J6J?LGXzyl {lc+X6P~M#Vkd v *?[Ag+X6l _,T~eVљ>t%[[Bb]q0x܅ wA]q6x< aC6x< aC6x"`q+B"hq+"lq+"lq+"lq+*lq*lqICOǭ [xܪ(?[{xgkl}"ְlP *?[òAgkX6l a򳵶uqkJ&LqBXq.d <.l <!lx<~䏰=c@6,?[îgk5l a٠5,T~eְlP .?[[EgrK*x+<^%dx <^-lx <-lx <}~t&lְidv,?[îAgkX6l a٠5,T~eφ_u&(Qx| G#\Xx܋ǽZx܋ǽ[x܋ǽ[x܋ǽ[x܋ǽ[xܫǽ [xka?Bq.ֱid:v,?[ǮAgX6lc٠u,T~eֱlpz[:7%r{/IzW,w {0x܅ wA]q6x܅ wa]6x< aC6x<CP(?[|gl}3';lc٠u,T~eֱlp<:{(<^PX.x /!K6x oa[6x oa[6x oa?S؄ cۘQ~McuM}1gX6fc٘Y~ecf:gX6&3G#L<>GxA Gxa Gxa Gxa N"l1(gUQ#ԦQ-<U]t m` Y~]6lP *?xM,?xm*?hSgDh&Th.\.d <.l <!lx<1~0=D4^5^5l-Y~,?xFme#6޲go٠i:{<(<^PX.x /!K6x /a[6x oa[6x $Sx <6u1<ƶ lY~]#6kP *?AgX6lmDmm3G#L<>G2x|-Bzz=UYEx2Em.+?|]W~Y~Y~Y~Y~Y~e6lpf:x6%rgx6 gS,x6 gxv! !)?.l <.lx<0=c@&6,?Įg5lmb٠M,T~eφ?q& .?ۜ[grS*x+<^%dx <^%lx <-lx <~䏰=cXQ~6W~vW~v,?|Fme#6߲goͷld&urLQ<>BbG0x| AGU-<^EU-<^EU-<^EU-<^EU-<^0>B-zz=^UUExe϶l`l+Xl+#Xl++Xl+3Xl+;Xl+CXl-T~כ$'lAg{!J.?۫Qr^\~B%U*lTg{J.?+Vr^ʕ\~W򳽂%U,ldg{5K.?+Zr^Ւʖ(?+[f^2T~%e.ltIg{K*?]r^ʗ\~W&E0lg{)L.?۫ar^\~W.&1lg{uL.?cr^!\~WN&2lg{L.?elg{,?۫eR^.zT~̤b&%3lgj&-ۙT~gRٲIgˌ&-KT~iRٲIgˤ&-T~jRٲIg˶&-T~kRٲIg&-+T~lRٲIg&-kT~mRپV>fܺ~͸}я@پf~i8pWf_T3ѯ~~=s_P'(ĉ[. w{ÿ/wKhIx73|of𬿙X3ïf[ ƛNJhy.73<D8(?|ݣٞ0iwi< fɣi< fˣpj< 栟^SY&&a"8-g0`"-o8`"8mw8`&!N}'8fh|u-nfg {*?ٖa\SԘfG`B404=MAD04=LM0Qhz 0Qhz 0Qhz ,jz m"g;^W~= vdPm,Y~E vd*?iE&iL,i㚞4)>g;yB(4չl3Qhz:34LM;ADд34LM;A~T{Q5LMb/}{%-hrMܳ= Mܳ= Mܳtv5N&Yt2 4M@@t14]LMADt14]LMADt34LMwS]]]Dtm)6pbpMrM;tbx|gBS,ڒa\SԘ@#0ahz恦a"hz&a"D)\S &rMO)L䚞R5=,94=0kzJۮ`@Y~>ϧ|{Q ϧ|JeS Y~>2SKT~>3DWS04riOiu= k{J0&d.)MS4aswO҅= A.l0 0[< u1< |Jb)c{,},?^)-,?)m,?)LTx #d<>#l<>ǵ[x\ǵ[x\.O-SOǵ[x\W,(?M#ϧb5|* *?eϧb٠X6|* *?eϧVәǵ*{\0ǵ Ux\bǵ Wx\ǵ YxOJ&l1[Mڅ-<]څ wa]q6x܅ $S <bxmWݢ5|{s"ϧb٠-,?ޤ],?ަ} *?:O% 0)Tx*Vx< OS4x /aK6x /aK6x /aǻ0>®zoa[] [Q~>ϧ/^TT~>+SlPT,T~>OŲSmL)QxlM)Vxl#d<>#l<>#lq+"lq+0z܊ǭqöioxޮϧ]#ϧe#ϧe#ϧe#ϧe#ϧe#ϧeϧխ3][U"Ua [5r[5 [5A [5a [5a [ua [6x܅ wa]q_?LGzwa]] m|6,?]#ϧaנiX6| *?eϧa٠iX6| .?6O% 0)Tx*Vx< OS4x< /aK6x /aK6x /a0>.zoa[] m|6,?]#ϧaנiY~>}\"ϧLd,?>3އ&|u=6% M <6 M <>B#l<>#l<>ǽ[x܋ǽ&#t="lq/{*|4+?>LϧRdt,T~>ODzAӱlPt,T~>OKgDq*Tqo&\qo&dqo&lWg$Ir+uLvueAM|HψEl7{^vs]~>{vs7e7e7e>I`;v\6she]~>;v\6;}9V&9Vb+Qen2J`c%̱ZX-sĖ96be2Flc#̱[؈-slĖ9x=˱[97ǹmsӨgQ]]~>;v\6she]~>;v\6c;}9&9bQen2A` !!!!!!!!!!cvs,c>I{_eͱ cm#/?M.? vHy藟.?e]~>F|$vH.Nd/2X&Qd/DzX"cYvs,neͱ,b9El7DzX&cvs,2Ǜ2[$}OP~9Ė9ޜśc|^~>v|uY.?e]~>-~H.\6#N_n2JTcec%̱XX,s9Vb+e2Flc#̱[؈-slĖ96be͟$}O~96b;g8 䦡|$w /ǹlh]~>ˆ#lh]~>=~H.Z䲡N_n2AT` qX8,s9>Ė9>Ė9>Ė9>Ė9>Ė9>Ė9>Ė9>Ė9>Ė9>vscF|4v(~K.?o]|-.?˱N&rnuͱNrnuͱ."9Eh7ǺX"c]vsnuͱ.b9Ml7Ǻ8?G~=Axx[xso$Ql|.?ŮQb٨GlX6Q,u1v8ӗcac!̱UXX+s9V"+e2Jlc%̱[؈-slĖ96be2Flc'I_2Y9m#/?M.?].?]]~>F|4vh.\68-QD|4ӗ` qU88+s9"e2LJ2LJ2LJ2LJ2LJ2LJ2LJ2LJ2LJ2uNScMQ.?e_~>67/6˱Mb9IT76˱M9I`7Ƕ"c[vslnmͱ-b9OEl7Ƕ6&cI/Ǜ2ǛxsF^~>F]~>F]~>F|,v=~X.\6clr藟;}9&9b Qen2J`c%̱ZX-sĖ9Vb+e2Flc#̱[؈-slĖ96}=x؈-slś6^~>Mac51,u| F]~>e.?òQ;VW~/D7AL q0qW8,sD9Be2LJ2LJ2LJ2LJ2LJ2LJ2LJ2LJ2'$}O8<,~9]~>^7񺁕 ,\~>^Gpx]u ,\~>^p8vd|pw_~>>/?ܠ엟Q(烓]~8e|p_~>R/?\엟U+烫~ze|p_~>b/?\엟Y-烫e˼|pٲ.?ܶ-ve|p]~>8v.?ܻ엟n^/~f|p_~>8/?\엟b71烫]~2f|p_~>/?엟.d72+~Rf|p+_~>/?2̺|p-]~>8.?lf3烓~vvv vv%v1v=vIvUv]vevmvuv}vԅvԍvԕvԝvԥvԭvԵvԽv]ܼ+Bwl3_.mȟwd3'_pNlKmgw^3'_^#oO wZ/5mM+}їΘſh]ezʿ};ǿ9YĿ})]-MŪɋUocf.V _g>s[bn\ }"ǡ}QC5q/ׁw.f7rylND/֍w+soDe qI'Ig Jjj j(j'0j'8j'@j'Hj'Pj'Xj'`Z'hZ'pZ'x|rQDRݘ恱bj_LSo}1f7wݘ~So_2n{cN/ԉ;I4:K44:M4:N4:O4:P4:Q4:Q4:Q4:QtDӉ2eLO'ʘN1=qN/eL̛9q>K90}7NLY92}>g~_bd/gDuC{&c}=nl$3LB=nt"ݳ,b=n|"߳ݝ>gۍYv3!I'_&97Xs'9Xp ul u us0s1s2;wr,Lts,Ĕ9 c qe2Jdc%̱[X-sĖ9Vb+e2Jlc%̱[؈-slI/Flc,c"`sLԉsNԍsOԑsPԕsQԙsRԝsSC;}9v&9vb;Qen2A` qZ8-sĖ9be2LJ2LJ2LJ2LJ2LJ2G$}O0~9>Ė9>śc,NX g%ooEo忩/S_֧8MOy/ïlHߘP1~11~1Q~E_DoL_DoL_D%|ף1Q~㿔ob7r7N{o` :6:7>͠c'sӧtl%uo:2nЅ2Bt. A"DЅt!F] AWDЕ(t%J]AWDЕ(t%J]AWDЍ(tOȾ %n :~9bYnбϿa߼Afбt,-i[oAfб|AwWAwfˠ;!N|3`=ABDЃ H=ADЃ( J=ADQ"(C!J !JpR3Xh?Ab>'?Y?Cy>(X~ch|?)o~㡼93s2i~~Nfɰoɸ97?'fdތ\̛yS7 yS7yS7-ySż)O ;7[4&MkB}TS 9߽&`-j'ƇivofBkB}腣S{MivKS;o74N454&8PgV iaB0.L 0!&„`^ yaB0/L8 „g~M8 Γ4[SD9ͮ 3,Lص4i5aTƛׄ]KSH+5a{3as {0izMؓYӄ=6Mؓiӄ=7Mؓyӄ=7Mؓyӄ=7Mؓyӄ7M؋yӄ7M؋yӄ7MK3L؋yӄ_ߞ8oΪM'M?6vvZoi&`ij#EX;,M? Xک ;7&2M ¤0A4A&aZ ya0/L ʼ0A&(e^ ya2/LPw q)ͮ ؙT^4#cq,M1~no>7&C&8sgRj aa3-Lpƅ 0!&„`^ yaB0/L 0!&{Ιp&'iǟ5A&4[Ikv&7M7k&Scf#LҤu.o4N4i~4(gNL AMYa3,Lp θ0&„`^ yaB0/L 0!&„8o̯ yayr&`k#35;Skvlo4NVV'Ɠnkgy5s 64M^l0k`aL&d4& 67MɼiMMl2o`y̛&d4 7Mg`y[O Vv͜f V;NM' VKSo 4 ۞7&2M 6yPaV ia0.L ¼0A&a^ ya2/LP ʼ0A}=k2/L'i3MiY &`4' >7MɼiOM|2oy̛&d4' >7Mżi{Z3 _[S ͌f 34ҁc,Mvo9N5٭+]jgBet߽&TM4.+ӄZo&i{(gNL AMYa3,Lp θ0&8g^ yaB0/L 0!&„79̯ 0<9NڅƯohvMho*w H#F4jD8h&c(@#jijgB`5sL sB?ׄ: &ԡ^7g46Z9 uW#͙7MCνoμiBt sMsI3oPg{U|>τ:O u9+fJτ:\ SPW[uPנ[}xPW[x [7&2M 6„ Ya0,L ¸0A&a^ ya0/L ʼ0A&(os_ya>9Njk 5v&/T I4_o 4UXi&j54&8PgV ia3.Lp μ0&8„`^ yaB0/L 0!}?kB0/L'iBf0YZ/ww:M~wW( Lq2'0ʔSějŗdWTW&p;^)>(29=829Mduw;X߹ݔMTuzyfqd2gsvS;R]kٗ߁$Scw:/ r;LɗYj̾,jvz<,[nY_r=wÛ˓fsQsw&sw*$tVftw.tw0T:* YΆJgC^!ِYlHt6V:+ ΆjgC~uq6Mo!JYkٯomrsf7z߻9цcm9Նcm96i̱ign2֙cTȱV;r 9N{GC!ِclȱw6;r 9ΆGgC!ِPN}8:rq!o0T7ti{CCMO3o}"Ƈ_9}c n zA7s BcM oDy= 9&Qt1{I7sLcM(oDy3>$9&Qޔ11c},#9o9;o7AGMOρ#Oρ$ {ݠofˠoC7!3M&F]ADЅ(t!J]ADЅ(t!J]ADЕ(tOȾ % :[-7>AǾra߼ARs,/7}AR ݧt-coj7lt#:݈A7̠;"N#;Q"N%D;Q"Nz%DQ"Az z% :잘LuÓ}'>Ӻ'BӺ'BӺ'BӺ'BӺ'BӺ'Bӻ'8v~}ˠA|9}"̠K=1 A(3se}̠I92>'Qf$ DA(3se}NBv<>'QfޠOl4=1'ꞘLuỎ}uỎuOL|޻'BӺ'&~ѻ'BӺ'Bӻ'ܓ_ ̖ADoC7f7"M&H]ADЅ(t!J]ADЅ(t!J]ADuDx|D'5$֙ov^?oMG4߽aƙ1oqƙAoƙQ&̟2C3SfxPo`  _i3k0nf 57fd`MMdT`MMdޔ`MM ִ79?da'ׄ~?ߟ?Z4LXygª~^V}%l_%~kyτk 6„ YafX&lƅ ya0/L ¼0A&a^ ya0/L :5A&4>Ꞙ>rQ\7&C&scR`j` aa3-Lpƅ μ0&8g^ yawJ yaB0/L>g?kB0/L'i&tO̅uO̅uO̅wO̅wO̅wOLp444Q\Ǟ7&2M8  {<ׄ=5M؃aӄ=6M؃qӄ=7M؃yӄ=7M؃yӄ=7Mؓyӄ=7Mؓyӄ=7Mؓyӄ=}=τ=7M5ackBؘZؙZW래>jsG_{buO]~=1w}ջ'^yτk̙&ͤ0a?ifV&l qaf^&a^ ya0/L ¼0A&H9 qPeXuO]UؙzXzXzXzXzXzX{bn[^L9a1)L5M0f ư0&8g^ ya3/Lp μ0&8g^ b_yaB<9N5{bژ{bڙ{bڙZܵ4kijsԺ'殥uO]KS래=1 Ls„ä0<̚&`4AӦ 27Mi Md0o y̛&`4A& 27MɼiLMdʛ} 27M ؚ=1S래uOLԻ'`iS4)Xz,M{b =1KuOLYg 9L&~Pӄͬ0a3,LL 6„ͼ0a3/L ya0/L ¼0A&a^ >'5A&4['`cjS3)ؙzĔ*Q래R_'jS E{bJ}uOL)=1{(cN`L AMYa1,L0 Ƹ0&8g^ ya3/Lp μ0&8„o|ׄ`^OӄQvOLoUĔQuOL)Xz,M{b =1KSwOLDSg?̛&|r|MwvOLpWĴ wuOLopi =1 KSwOLԻ'aiӰ4QĴe~&&wOL[̙&b4zMͬim iaf\&l yaf^&a^ ya0/L}wc qI{b6&iؙp7]w XuOLҤ{b&mӰ4i래I[4,Mڻ'y`e` Ia=i1+L0 ƴ0&c^ ya3/Lp μ0&8g^>7MiM|0oy̛&`4 >7M9}ϙ&d4keژ{bzL=1v=1=1=1=1=1=1=1} k/L|1iA&f47æ &lƅ yaf^&l yaf^ ya0/L "os_ya<9N5{b:6=1;S래wOLԻ'ciӱ4Xz:MԺ'}=1]yk>i1'L0& Ƭ0&c\` ya1/Lp μ0&8g^ yaxg^OӄlQuOLF=1uبuOLF{bz6jQ래wOLD|p40'L8L ΃&f aaaZp7MiB Mb0oyӄ̛&`4! 17MiB Mb7s| 17Mؚ=1S래uOԻ'f`i34Xz ,M{b=1KuOXgB9ӄXL&zP 5MͰiBlMb3.L 6„ͼ0a3/L 6„ͼ0A&a^ }ǟ5&4]3-HtOh =1݂duOh {bF;Y3=ꞘBVČZzĬ=14uO̺&MnJSĬ=14uO:1MLSĬc=14uO̺:M.OSĬ=15uO̺BM.QSĬk=1"5uO̺JM.SSĬ=1B5uO̺RM.U{b֥=Qw!ojw?`uuwO:[ݻ'f]WY{b kꞘuɚ'f]Y{bQkꞘuך'fY׭{bցkꞘu㚺'f]Yw{b֥kꞘu뚺'f]Y{bkꞘu'f]Yw{bkꞘu'f]Y=1u래uuO̺~ݻ'f_Y{Ĭ ؽ{b =16uOvwOv wOvwOvwOvwOvwOvwOvwOv"wOv%wOv'wOv)wOv+wOv-wOv/wOv1wOv3wOv5wOv7wOv9wOv;wOv=wOv?wO̓uO_bbrM~l2!eC1ʴaI(SQLx7ݧ}&#է2ͧSH) ${=qS~ǰs%v.ay_Z vξ })]cM]\t}\cMLi_uξ$߭k~)\CyG/w_5f,Zݶ}=~w12~W1R~71r~%sZwesnZKW~Wk%tg{bչnJXtnRuMUkLoZ؝ yݝ ݝ ݝ ݝ ݝ ݝ ݝ Ά$}OEӛalHP3y,_Xn%߻9ӆcm9نc]m9݆cO;+e3!کc%̱u.:rl 9[gC!ِclȱu6:r 9Ά{gC!.ͱw6)c﷪ cQ5-TXZXZZXZZX Z!zj7lCt!>0`!r}>ĈdDQ"ۇ(C92=Qf D 4ǩA9 }HD9z>dĚE{bM#=&=&6=&V=&v=&=oz}b-kɯ}.fA2s_}.Aک{bEt@=" DA(3s%ADoD7Q"(M&J]!2y|.D '5}%'IJRkb_55555555UnЕ2Jt AW"DЍt#FA7DЍ(t#J݈A7DЍ(t#J݉AwDН(tOC7NsR3Xh{bMl3=pįuO}uOuOuOuOuOuOwOίv̖AC!3C!F$~A?DDQf DA_(3ke} ̠A5 } DA_zdZf{b-3=====Qݻ'BӺ'Bӻ'Z_ Zve" Z xf" ZĘA_ 3ke}m̠MADoD7Q"(M&J}'dCd]ANjMvOm'>SkaikaikaikaikaikaikakWAWfˠ+!J|2`]AWBDЍt#H݈A7DЍ(t#J݈A7DЍ(t#J݉AwD}=!&Eσ?̊E"qüa^0/?̛i̛ ̛i>Ǟ̛"q>v>4Lyw?v}_v}_v}_v}_v}_v}5ag^5a/Lb4a {1lӦ {1n {1o7 {3o7„ͼ0a3/L 6„ͼ0aǛ̯ ¼0A gB}"󚀥(3M^&`1L7jTO~4A}(eNL AMYa2,LP Ƹ0&c^` ya1/L0 Ƽ0&8g^_ya?9N4{bmlL{bmL{bmL{bm,M{bm,M{bm,M{bm,M{b,M=vׄx(ӄ`NL AM„ð00-L8 „ü00/L8 „üi Md0o y̛&Ȑ79?d0oorlMXܲwO,Ժ'ԇ^{bI}պ'Lo4Aï=>jK=>Kf'5a3/L'iB}4KsX"iv=tXwO;,M{b =KuO,5A4A&(}PeV ia2.L0 Ƽ0&c^` ya1/L0 Ƽ0Ǜ9>5&4['TKjg%3%4%4%4%4%4%M҄ P 0!&ă&„ð00-L8 „ü00/L8 „ü00oy̛&`4A~w#3A :_['bcjK3ؙzR,M{b)=t&(=KSX'N3ACyMɜi.&Mt=]̚&b4AӦ 7Mżi.Mt1oy̛&f4mK7„ͼ0a3/L>ǟ5a3/LOlMXuO,Ժ'bgKD{b*XZ_(jK+E{bi}uO,/:7&C&(seRj aa2-LPƅ ʼ0&c^` ya1/L0 Ƽ0&y=3&8r&{bi}ۨ'֗{bi}רuO,Ի'biK4XzR,M{b)&XykB̙&d4zMŬi/M|1mq_̛&b4 7Mżi/M|3oy 6„-os_6„8M֤=VrLN,Mں'ci=KXuO,Ҥ{b9&%7&C&(seRj aa2-LPƅ ʼ0A&(c^` ya1/L0 Ƽ0&ωg~M0 8MքؘZrL{b9v=KSXwO,jk7Zݶ=~wO,5!4!&„xPӄ`V iaB0.L8 „ü00/L8 „ü00/L8  1ƛsbgyӄO Q+jc3UĊڙZĊZZĊZZĊZZĊZZĊZZĊZzĊ)~&|( 13MɤiBYӄX &b4! 7MżiB,Mb1oyӄX̛&b4!6 7Mͼ0a79̯ ya~r&`kB lL{bv=;SXwOԻ'V`i N+4QXQz P œ0A&胚&(eXL qa2/LP ʼ0A&c^` ya1/L0 fos_ya=9NQvOF=UĊkԺ'Va=.uڨuOF{b=KuO5!4!&„xPӄ`V iaB0.L yaa^p& yaa^p& ya9o~9c<τ37M85`kB:ؘZ:ؙZ:ؙz:Xz:Xz:Xz:Xz:Xz:X{b7L8&79{bɤi™5LfMd4,Mb4,Mb4,Mb4wO7M8y\'̛&ͼi}~ׄͼ0a?9N5YvOSSuOS;SuOS;SX=N-M{bZZ:4ujij{m;:b^L9a0)L5MPf ʰ0A&(e^ ya2/LP Ƽ0&c^` L3&{r&k{bv [X݂u1X]u9X݃uAX=~4uO#MISĪ=4uO.MNLSĪ;=4uO8MNSĪ=4uO@MPSĪK=5uOHMRSĪ=:5uOPMTSĮKuuOUݺ'v]V]7{Įս{b=xuu'vݰ]{b5kuњ'v]w{bikuݚ'v]7{bוku皺'v]]{b׵ku'v]]7{bku'v]]{bku_ڥow 4]{Įؽ{b=vu'vݻ'vݻ'vݻ'vݻ'v;ݻ'vݻ'v;ݻ'vݻ'v;ݻ'vݻ'vݻ'vݻ'vݻ'vݻ'vݻ'vݻ'vݻ'vݻ'vݻ'vݻ'vݻ'vݻ'vݻ'v_|`rM/21x=d(Qܽp7>Hu !ŀ$GA QHpŁFq QH)z)=Ł@:Oq 8=_mvx#wf_ ]z/7k%u;,=n[u o"g~WkxS9x?&u/7u{՛Ͽmz:'a݌]nӛ9;Xuޤ]nӛտ5ʹnӛ׿mzwҺ{3wѺMojZ-=l]׻'\-w˚=aO~!ś9r[oknwa8g7hq@E0s,3"N7BDcLȱt*X+s, 9k'C!ِclȱv6X;r 9ΆkgC!ِclȱmN}:rḻ='BuO쉅uO쉥uO>4cuh_uOuOwOίv#̖vC`u!r`1"Av%DpQ"A!J%~ ?DDQ"Ǟ݇8oQ"燓zdĿ/ HuO}uO셍uO셕uO셝uO셥uO셭uO셵wO55}MˠI|5}M"̠ItuO5 2&Qf" ZDA_(3ke}-̠E2Qf" Z =x}m̠I͠c_T^W{b/,,{b/,{b/,{b/,-{b/l-{b/-{b/-{b/j7lt!:]A̠ "B#+Q"J%D+Q"J%DQ"F'd!7FqR3Xh{b/l3= L M M MBfбдnН2Nt A"DЃ F=ADЃ( J=ADQ"(C!J%~ }%~8tl4=7LuO}uO썅uO썅uO썅uO썅uO썅uO썅wO==}OˠI|=}O"̠I=1'Af$ DAߋ(3{e}/̠E2Qf" ^DA+݇Aߛ(3{sRo76LuO}'>Ӻ'BӺ'BӺ'BӺ'BӺ'BӺ'Bӻ'ův.̖ACЅta !. 1"J%D+Q"J%D+Q"J%nD|B=oЍ(tfбѠ{bo3{bz#=wuO]?i{iZ=wuO]?{>ox3eޙw&EA"H~0-"H0/̋B`^p y!a^Xp}>a^p 8{btOl R'-RR+-RR.-RR0-#7Ls~MɜiL&Md>̚&d4A&Ӧ 27MɼiLMd2o yY̛&b4A 7Mżi,Mdx 7M ovMO[߽&`-io&`1i6o&`5iv&i P œ0A&ȃ&aX L qa2/LP ʼ0A&(e^ ya2/LP 6}ϱ̯ Ƽ0 X?bcLߟLg5Kg3M&`im7&i(gNL AM eB0,L 0!&„`^ yaB0/L yaa^p& G50/L8OlM؂uOl9kև^{bk}պ'G_{bk}պ'֧_{bk}պ'_{b ?t<̙&d4AzMɬiNMt2mq̛&d4A' :7Mżi.Mt1oy]̛&b4Agy]&h}4[sZUVL{b+=X؊wOlԻ'bi[4QV^L9a0)L5Mf °0A&a^ ya2/LP ʼ0A&(e^ c_ya=9N5{bkmL=vZ;SZKSZKSZKSZKSZKSZKSyk?i3'Lp& ά02!&„`^ yaB0/L 0!&„ü00/L8}~ׄü0<9N5{b+6=;S؊wOlԻ'ai۰4mXz6,M{b&6y5s 64M^l2k`aL&d4& 67MɼiMMl2o`y[̛&b4 7Mos&wOl[O ۰1mؙZ6L{b[}uOlm=RԺ'wZĶRQضy(aN L AMYa0,L ¸0A&e^ ya2/LP ʼ0A&(79_ya=9N G=mTF=kԺ'ai۰4mXz6,M{b= KuOl54&8PgV iaB0.L 0!&„`^ yaB0/L ya™o̯ yayr&`kB6lL{bv= ;S؆wOlԻ'ci۱4Xzv,M=} >kL|0iA&d4'æ >6MɸiOM|2oy̛&d4' 7Mżi/M|1oK3Lżi'քؘZvL{b;v=KS؎wOlԻ'6t؎wOlDw'5A&ؓ4['ccj۱3ؙzv,M{b;=KS؎wOlԻ'ci>7&C&8sgRj aa3-Lpƅ 0!&„`^ yaB0/L 0!&{Ιp&'iB};'w{b{}'7[w؎wOԻ'v`i;4X{bǐ ?b<̙ׄ&`4!ƃzMiBLMb2mqӄ̛&d4!& 17MɼiBLMb2oyӄX̛&b4!~w#3! _[flLZ;3;S6;L,Mں'v`i=KXuOҤ{b&;?oxMe&yPaV ia0.L ¼0A&e^ ya2/LP ʼ0A}?k2/L'i&tOԺ'v`gj;3Xz,M{bGV[Qֺ'vﶵm{b P Μ0&&8gXL qa3/L 0!&„`^ yaB0/L q}9_„8M}1UĎڙ{bGL{bG-M{bG-M{bG-M{bZZ>4}jig5 L`4p g0lp&Ӧ g2np& g2op& g2op& g2op& g2op g1opzwgY̛&֫}1}3M'Ի'Ի'Ի'Ի'D{bOԻ'5a?ifN&ȃ&aX L qa0/L ¼0A&e^ ya2/LP os_ya>9NQvOSw{bkT]=O6je=O6jm==&(gNL AMYa3,Lp θ0&8„`^ yaB0/L 0!&„79_„8Mք}1}3}3}4}4}4}4 Xz ,M=!c &gI 2ƃ c05A`kq 2&^dL&Ș{M1 c25Adk¿9^dL&Ș{M c7sz?d,&XO?d`kw3AFL=!v=!=!=!=!=!=!sH L6s„ͤ0a?i0+L ´0A&a^ ya0/L ʼ0A&(e^>G5A&4]2-HtOh =!݂ duOh {BF;Y2=ꞐBVZzhꞐ#MRפ{B4uOH =!ub'LSԱiꞐ8MRW{B4uOH] =!u'.QS5jꞐHMRW{B25uOH] =!u'.U{BRu랐Uݺ'U ս{Bfu:[ݻ'.W ս{B~5uOHݰ K=!u͚'.ZSQkꞐkMR{B5uOH =!u嚺'\SԥkꞐuMR׮{B5uOH] =!u'^SkꞐ}MRׯ{B5'_ow?uݻ'` ؽ{BvMҮ` i{{ؽ{BM=!,vvwO ´0A&a^ ya0/L ¼0A&(e^}x|cD'5e$'da YXG{B{{B6=! +I랐uORҺ'da+i Y}A߃n ėA߃o A߃3{d}̠A=2'Qf$ DAߓ(3{e}O̠I= }2'}c_ XV{B6ꞐuOҺ'dcgi =!kK랐wOދ_}3[}A ADoBD71"B%.D Q"B%.D Q"B%D|B=DoЕ(tfбdll3=!LuO>Ӻ'dciд XhZl,4{B6=! Mmʯvn̖A7CЍtc !;1"N%D;Q"N%DQ"Az%D\j"Rz Ls :4M^t0kaL&`4A :7MiMt2oy̛&d4A' :7Mios&d4AkgR=!ZHUh}"UXz(֢=!wOb1،z(V=!݈'Dx3ACyMXL &lf aafZ&l ¼0A&a^ ya0/L ¼0AΛ9:5A&4K=ؘ5;ko&`iio&`iio&`io&~`e` Ia=i1+L0 δ0&8g^ ya3/Lp μ0&„`^}~ׄ`^OlMߟl1]w>3}^C8 ? 4>&ԧ_?ӄgPׄP 9aa4ƃzMi Ml0m`q̛&`4 67MiMMl2o`y̛&d4& 6&d4kGc=!?kb=!wOaibXz=!wO~픺'İ4Q:~&~( 3Mͤ0a?ifV&l qaf^&a^ ya0/L ¼0A&H9 q b1UXL=!V;SuOԺ'jijb4 ZZX-M{B{(cN`L AMYa1,L0 θ0&8g^ ya3/Lp μ0&„ozׄ`^OlMԺ'İ3 1L{B KS&`ibXz=!'Ď>oxM8ep&& A&`4æ >6MiM|0oy̛&`4 >7MɼiOM|2oS3Lɼi'ք qlL{B;SԻ'D{BNԺ' E{BRԺ';E{BTԻ'Wǟ5A&ȓ4['$1 L{B;SԻ'$4 ,M{BKSԻ'$4Q P Ɯ0&؃&cX`L qa1/Lp μ0&8g^ ya3/Lp ~}ω̯ 0! 5자pWD}'$ܭ{Bݺ'$4 ,M{BKSԻ'$4Q^C& IayPӄì00lpӦ g0np g0op g0op g0op g0op& g2opzwg™̛&ۓ=![flLZr3oz~&,Mں'`i=!K 9XuOҤ{B&=!g=ׄ3M@{B~P g3kp6„ʹ0a3.L 6„ͼ0a3/L ya0/L ¼0A&ϱg~M 8Mք 9ؘZL{Bv=!KSwOȩjkr7Zݶ=!~wO54&{PcV` ia1.L0 Ƽ0&8g^ ya3/Lp μ0}yׄ`^Oӄݷ자SSuOȩ'Ժ'Ժ'Ժ'Ժ'Ժ'Ժ'Ի'5Ӻ'Tд ,4{B MPBӺ'Tд ,4{BE_]-D+!ʀt%BA7bDЍ t#J݈A7DЍ(t#J݈A7DН(t'J݉A>Dx|D;'5&'G[ P>Ӻ'Tд ,4{B MPBӺ'Tд ,4{B%_=-DCf"C!H%~A?D̠ ̠ ̠ ̠'d!/:2zh{BLuOb U3{B MPBӺ'Tд U,4{B MPBӻ'TWnu]]eu1 ."̠" .b̠" .̠& n̠uOnD7Q"(M&J}%!2x|.D '5XgZ?=Z?iC=Z?is=Z?i=Z?7ׇ2C̉+"fY|eX$ߘ7Ey~c^ߘ7Ey!1/ 0Ƽp8_os38Br& tOzP' PuOJ{B>ZjRPZj}Ի'TÞ7&C&s„`Rp40+L8 „ø00/L8 „ü00o`y̛&`4 67Mos&`4ƓkgR=VHUZ}"UjXz֢=wOa1j،zV=݈'y3CyMŜi-&Ml=[̚&b4Ӧ }P[̛&b46 7Mͼ0a3/L 6„ͼ0a3/L>oxM2M 0!40+L8 „ø00/L8 „ü00/L8̛&`4 >7Miyw3 >_>9~C~~&8vܽ~&8gci&8kci&8kciorM~&|( 3MŤiY_ &b4 7Mżi̛&f47„ͼ0a3/L 6„ͼ0a3&l 8Mք ژ{BvPuOԺ'kij4 ZZP`B-M{B]}(eNL AMYa2,LP ʸ0&c^` ya1/L0 Ƽ0&o|g^OlMPԺ'Ա3 uL{BKSPԻ'Ա4 u,M{BKSPD!^L9aB0)L5Mf aaaZp& yaa^p& yaa4! 17MiB>GgB Mb<9&&tOh`cjؙZv=Q_%ju=Q_(j=Q)j=1yτ5!&s 4M^b1kaӄXL&b4! 7MżiB>b3oyӄ 6„ͼ0a3/L>ǟ5a3/LOӄQvOhԷ{BlT]=VuOh`iXz=wOh`i ^L9a2)L5MPf ʰ0A&(e^` ya1/L0 Ƽ0&c^` _ya?9N5{BSԺ'43 ,M{BKSԻ'44 ,M{BKuOh~e IaBg?τ37M85`kBlL{Bv=;SЃwOԻ'`iz4 =Xz=g g>ׄ33M8IӄkY̚&ŰiYL&ŸiY̛&-wOY̛&żinsͼi̛&ͼ0a3/L ϱg~M 4['`cjz3 =ؙz,M{B=KSЃwOԻ'`i =r7&C&(seRj aa2-LPƅ ʼ0A&c^` ya1/L0 Ƽ0&X9 qP_ =S_ = =ݺ'`iz4 =Xz,M{B&ykBQ9yτ9kœ̙&ɤiœ5aNfMb4a.Mb4a.Mb4a.Mp'l.Mb4a.Mf4anMf^yׄͼ0a?9NQvOجF=aUͺkԺ'la=a䉺'li=an XzM,M=aSyk{v~_;}GYE[tK{L#RH4LkQ ZHŁjq ZHŁZq VHiŁTLMh-OBK=aט$hE4j̣6DZZctk̥{g2=n62љTHhVf4:R 9NFGCV!ِlHllHllHllHlqN}BftLu~9ݱߨw/ǿ՘}9{_19Koxs;Z17ǿO9ݫnw7ǿ7ǿ59IX7ǿ592ǿ59h5NVwͽ9^uMoeu̱Ζ92ǿ[59I'Ml,f7 &X{BuO`ah&XZ =aաuO`{h&X Z v=a"¯v#-̖Cja!r`+1"J%Dp+Q"J%D+Q"F%2nD~Bv"<17D΍A2&E{HuO`i&HZ V=auO`)i&JZ ֒=aίv̖AwCЃ` z!1"Az%DQ"A!J%~A?DDQ"Ǟ݇8oQ"臓zW{JuOb_ S,,{+K0Һ'L Sl-{kK0һ'LWnu]]'eu2 N"̠$ Nb̠$ N̠" .̠" .̠" .̠" .̠" {<(39t,4=am' ?jgZ)=auObiXhZ)=awOWAfˠ !B|0`]ABDЕt%H]AWDЕ(t%J]AWDЕ(t%J݈A7Dm=!`f^L9a3)L5Mf 0!&„`^ yaB0/L 00/L8 „ü0ț}ׄü0<9N30O{¼> s,E{kQ0^Ի'̱ slF{Q0nD#7LP^|2gI5' >6MɴiOM|2oy̛&b4 7Mżi/M|1oy_>'g/M|?9&8&tOccjؙZ9v=a8JXz9=awOciX{\y(aN L AMYa0,L ¸0A&(e^ ya2/LP ʼ0A&(o|c^`OlM0Ժ'̱3 ЫuO_{¼>jW0OZy}պ'=a54&8PgV iaB0.L 0!&„`^ yaa^p& gϑg~M8 Γ4>}m}.]c?; _K7&o|M,MX5!47& ?b<̙ׄ&d4!zMɬiBLMb2mqӄ̛&d4!& 17MżiB,Mb1oyӄX̛&b4!gyӄXO mmL>3!jgyMׄZ? 4Lji&3MgPK&i P œ0A&ȃ&aX L qa0/LP ʼ0A&(e^ ya2/LP ʼ03&[ ؘZv=awOX`iXz=awOX`iM^L9a3)L5Mpf ΰ0!&„`^ yaB0/L 0!&„ü00/L8}~ׄü0<9N5{S랰Ժ',3 ;U=aNԺ' /4WZNQ랰S_*v=opCyM89ӄ34M8A&ɬi™ &ɴi™&3 37M8yӄ37M8yӄ7M8yӄ7M8yӄ7M8K3L8yӄ_p'Է{N}٨'j,M{=aKSwOԻ'`i C {Ž4 X{ &gI >ƃc25dkɴq >&^|L&{M1c25dkży >^|,&X>GF&ք ؘZL{v=KSwOԻ'|`i>4 e2yk~(aN L AMYa0,L ¸0A&a^ ya2/LP ʼ0A&(79̯ ʼ0 5Q Qn>ܭ{=KSwOԻ'|`i >7&C&8sgRj aa3-Lpƅ 0!&„`^ yaB0/L 0!&{Ιp&'i& ؘ'|`g^4iI[O,Mں'|bi=K XwO8n|sP^`4a&MxP s0k0'æ s2m0' s2o0' s2o0' s2o0' s2o0 s1o0 s79?b4{'&tO8.m ؙZOL{'=KSYֺ'|o m{gv[yk~(ӄ͜0A&ȃ&aX L qa0/L ¼0A&(e^ ya2/LP jos_ya>9Nw߲{gmL=oJ 3 4 4 4 4 4 4 >7&C&8sgRj aa3-Lpƅ μ0!&„`^ yaB0/L 0!&y=g~M8 Γ4['|bcj>3 ؙzO,M{'=KSwOD{W'~3as k0iƃzMXYӄ56MXiӄ57MXyӄ57MXyӄ57MXyD'|MMd4a-Mb4a>g?τ7MX5aey'|] _uh{W5=UfuOԻ'[= KS'|m{4a3'LL AMYa0,L ¸0A&a^ ya2/LP ʼ0A&(79̯ ʼ0A ؚ= SuOԻ'7,M{= KSwODӺ'ܰд >z=ᆅuOainXhz^j72M|f &B}"ADЅ(t!J]ADЅ(t!J]ADЅ(t%J]!x|D+'5&'ܰTp>Ӻ'ܰд 7,4{ MpBӺ'ܰд 7,4{͔_ݘ-nD!ƀt'B AwbDН t'J݉AwDН(t'J݉ADЃ( J=AyBv\jRpz{(cN`L AMYa3,Lp θ0&8g^ ya3/Lp 0!&„os_yaB<9N3pO{½> w,EuOc-{{lXfpf4[;Vٺ'ܱ=~yky(ӄÜiB &Mb<ׄ̚&`4!Ӧ 17MiB Mb0oyӄ̛&d4!& 17MɼiBLMbڛ 17MX=၍uOx`gjؙz=ၥwOx`iXz=ၥ'jWOZG}պ'<=ayk=i1'L0& Ƭ0&8g\ ya3/Lp μ0&8g^ yaB79_yaB<9N꣱Ū{£> L{KSԻ'<4 ,M{ =ၥ'<=oxM8ep&&MxP g0kpæ g0mp g0op g0op g0op& g2op& g2op& wO?d4'ׄ?ژ~τS;So~&Z~k©7&Z~k©7&Z~k©{k. ?~( g3gp6„ YafX&lƅ yaf^ ya0/L ¼0A&a^ > 1&^b'ǟ 1 G=mT1F=kԺ'b`i14XzD ,M{"p`'b`i+7c= 16s^bl&&j&l ef\&l ya0/L ¼0A&a^ 3&}r&`kBD lL{"v=;SwOԻ'b`i14XzD ,M={(cN`L AMYa1,L0 Ƹ0&8g^ ya3/Lp μ0&8„o|ׄ`^OlM螈uOԺ'b`g14XzD ,M{"=KS'byp40'L8L ΃&fM`4aM`4aMp'bM`4aM`4aMd4aNMd4a>Ggœ̛&05{"&6=;S랈wOԻ'bbi14XzDL,M{"pw'b.31s s3i0zMYafX&lƅ yaf^&l ¼0A&a^ ya؛a^ OӄwvOĬpWD wuOĬop =KSwOԻ'bbi14QDL^L9a1)L5M0f ư0&c^ ya3/Lp μ0&8g^ _yaB<9N5ivOƤ=;nI[DL,Mں'bbi='bbi=Kg?oxM8ep&& AM„ðiL&i̛&i̛&i̛&i̛&iš̛&ɼiš}~ k2okք׻'bagj3XXzD,,M{"VV[랈Uֺ'bﶵXm{"ֲ ?z( k1g k?ׄ5MXaafZ&l yaf^&l ¼0A&a^ D3&yr&eDژ{"VL=v=======K{(cN`L AMYa1,L0 Ƹ0&g^ ya3/Lp μ0&879_yaB<9N5{"6= ;S랈wOԻ'bai4XXzD:MԺ'b}= wO:ep&& AM„ð00m {0o {0o {0o {0o {0o' {7sz {2ok®F=UDkTQ랈]ZDlԺ'bi=nXzDl,M={ {=ׄ3M؋I|'bofMf4ao qaf^&l yaf^&a^ yaț}a^ OlM螈uOԺ'bcg4XzDl,M{"6=KS'bkD9> 9> 9>9> 9> 9> 9> 9> 9>-s;Y]ӛ7w7ǿ{592ǿkՕ߱lߩꞤC/ǿC59ݩn/ǿ3_oDöPaXZD=uOauhaZD=wOůEL" -Tbk| _[ElѶMmDpoD7Q"ޛ(M&J$|%"De>!"7BȹpR3XF{" HuOa0#{" IJҺ'°0,%{" [IZһ'TnЕ2Jt A7"DЍt#FA7DЍ(t#J݈A7DЍ(t'J݉AwDН(t'd!t'J9t+=e'°TD=uOagiaXZZD=uOaoaj7lCt!>0`!~A?ĈDQ"(CtDAAtDAAtDAAtDAOC_}e''ݱdD8>SgZD8=uOciXhZD8:$Ir[~nHEcӕA8i #AY= Mر&Xv2豈/oca=!fcc=AfC2BDЅ(t!J]ADЅ(t!J]A{Nߠ+Q"I͠cf{b؁}uOBӺ'v`i;дXhZ,4{b=Ô_ݘ-nD!ƀt#B AwbDН t'J݉AwDН(t'J݉AwDЃ( J=AyBv0`!~A?ĈDQ"(C! DA߃(3{e}̠A=2?! A߃(3{pRo76tOuuO]?G4{b!Mػ~LӺ'Ӵ5{bIMػ~Tӻ'^y/{=7{1g~/&Ŭ6fb^̛¼-̛¼ȿ0/¼P@Ba^X z q~s'6S2|&`i{I{bPuO]+룥=w}Ժ'ZSyk=i1'L0& Ƭ0&8g\ ya3/Lp μ0&8g^ yaB79̯ 0! TvO]HUTuO썥wO썵wO썽wOŨwOͨwOըwO݈'5a?ifN&5M8 „ô00.L8 „ü00/L8̛&i̛&i̛&i>ǟg̛&p4{blL{bL{bL{b,M{b,M{bc}4}4}4Q>Wا>j_{bwOcyk=i1'L0& Ƭ0&g\ ya3/Lp μ0&8g^ yaB7sb=kB0/L'iB}4b=O},V`g`i`i`i`i`i`i}=oxMe&l& AM„ð00-L8 „ü00/L8 „üׄ3^{M8c05ׄ3ϱg3ׄ3Ɠτ35{ژ{ڙ{ڙZ43jijgԺ'ΨuOQKS8=qL8c> g,&pzP?XzM8c15Ŵׄ3^X{M8c15żׄ3y g^ ¼0A&a^ >g?k0/L'iؘ5;~o7U,M8M,M8M,M8Mt$M54&{PcV` ia1.Lp μ0&8g^ ya3/Lp μ0!ƛ915!&ē4[-6kvkvw UOkB}P_(&W~ ߟiB}{4aׄP 9afR4a3+L8 „ø00/L8 „ü00/L8  s0o0 s0o0 s3Lyӄ9_f}('άoUęY\f}רuOwOwOwOwOwO'Μgœ5aNLb4a0 s1l0Ӧ s1n =qb4g.M0o0yӄ) ya0/L os_yagJ gbcjOwOwOwOwOwOwOwO'δ54&{PcV` ia1.L0 μ0&8g^ ya3/Lp μ0ϛ915!&ē4['33333434SęXzęXzęX{-^C&l Ia~Pӄͬ0a3,L8L „ü00/L8 „ü00/L8  k0o k79?`4a'ׄ gacjgagjgaggaigaigaigaigaigai?o&s k2iփzMXYӄ6MXiӄ7MXyӄ7MXyӄ7MXyӄ%̛&,a4a a^ 3&yr&`kBY8]g7[Y =q=q=q=q=q&8K{(cN`L AMYa1,L0 Ƹ0&g^ ya3/Lp μ0&8os3&„xr&`k7]3ojw XuOZYXuOZYXuOzY{=oxMe&l& AM6„Ͱ0a3-L8 „ü00/L8 „ü00/L8  27M1#c=̛&xr|MlM8uOԺ'`gG4#Xzđ=q~uOmkGzđi~&|( 23Mɤi YY &b4A 7Mżi,Md1o y|GyMD&79̯ ¼0A o=q68R;SuOuOuOuOuOuOuOwO5A4&{PcV` ia1.L0 Ƽ0&8g^ ya3/Lp μ0}~g^OlM8uOԺ'`gG4#Xz,M{=qN#uwOyk~(ӄ͜0a3)Lj&l iaf\p& yaa^p& yaa^p&Mt73A :_.eѺkTGQuOF{h6j7q{h6jGQ8wODG>o&d4A' :kNfMt1li]&b4A 7Mżi.Mt1oyMT7MPa^ >G5A&ȓ4['bcjG3ؙzQ,M{(=qKS8wOiX{}(eN`L AMYa1,L0 Ƹ0&c^` ya3/Lp μ0&879̯ μ0 ؚ<'TGkg344444cێt L6s„ͤ0a?ifV&l qaf^p& yaa^p& yaa^p&&`4Ɠkk{Xc$'[=qcduOk {XYA8VKS8u?'NݑSפ{Mi8uX'N]S'{ԝi8ul'N]SW{i8u}'N]SW{%j8u'N]SW{^ϑg~M 8M)'N]nnUSת{ĩս{=qlu8uwO:^ݻ'JI5A4A&({PcV` ia1.L0 Ƽ0&c^ ya3/Lp μ0}?k3/L'iBmM=qu8uuO~ݻ'N_S{ĩ ؽ{ =q6uOvwOv wOvwOvwOvwOvwOvwOvwOv"wOv%wOv'wOv)wOv+wOv-wO3/L8 „ü00/L8}y zv8~v8 ng3g=q~7|̾zBʾvS8#wtS7x/ݿ9WYq4,L0vrb&w;g7wMvnb߼ݤ*L)~TWqd:}G&w:g7וWV4Jq )Ló{n\cr?/n]Q/ :0G[{8f.ll8FtD΄|jBB2ֹR`ȩu2$:j iΆZgCb!ِZlȭw6$; Άr7ِb,f=8֘hjqHf a8 3m9N7ADݙݩMXݹɐѐِِِِِِِِِِMӛ2ǿ;mwK8E'N`[XZ , {=qC8uOѺ'N`'W"nc]:&ec2uL"\$ vLbd$Ȍv,l" w,t"ʌw,|" x,̄"ʌx,̌" yxB=D&%r. :8m=qHuO>Һ'N`#i'IZ ,%{=qkI8ʯv̖AWCЕte !n1"F%nDQ"F%nDQ"N%D$x|~A?&'6SgcϴдддддW'ݠIt=/'ޠI= 1'1f$ DAߋ(3{e}/̠E2Qf" ^DAߋ(3{'dCd ̠ofбdf{l3=q6=q6=q6=q6=q6=q6=q6=q 2[]AWCЕ3J"nĈA"F%nDQ"F%nDQ"N% }݉AwNjMvOm'>SgcigcigcigcigcigcigcgݠeЃ >}3`}! AĈoD7Q"(M&J}%~A?DDQ"(cOC7(I͠cA9XgZ9sG4'Ω8~L3{9ͬs5'Ω8~T3[9TjJ{huOS.s=qN}Ի'5A4A&(}PeV ia1.L0 Ƽ0&c^` ya1/L0 μ0盿95&4>s8>sssssssQ9a^L9aB0)L5M 6„ʹ0a3.L 6„ͼ0a3/L 6„ü00/L8 „os_„8M҄s1U;SuOM'?Ƌ?B cτgi3o&?y?τɜ s&L??7gτ9~&3oμ sL3g¿bτ9~&͙3oμ sL3gªiyτ9~&˓ s٢5;SuOM5>8M{oi&_=o\|e Ia>i2+LP ʴ0A&c^` ya1/L0 Ƽ0&c^ qPP{ow XZߘ.,M{o&v k=76 XZ8h&`ijo&xe Ia>i2+LP ʴ0A&(c^` ya1/L0 Ƽ0&c^` |=k7?~l1}kv&ow U8MiB}7N+EqP)ӄR&iBׄx(ӄ`NL AMYaB0,LL 6„ͼ0a3/L 6„ͼ0a3/L 6„ü00/L8}ׄ55MXaӄ56MXqӄ57MXy\5aMMd4a-Mb4a-Mb4a-Mb4a- k1o֓k֔fؘ{o:id߽&`ijcquOi=7&i P ʜ03W&胚&(eXL qa2/LP Ƽ0&c^` ya1/L0 g~Mp 8MpώlL=7U^38MԺ'ƛi=ouO'IykBǞg,Md=9&H}vO> Bk'LԺ'J4KS;,M{o7&C&(seRj aa2-LPƅ ʼ0A&(c^` ya1/L0 Ƽ0&X` qnߌWR S{Md=7v X'ƛi&c,Mֺ'ykB4&hV[uO' :io>o㡼&`4A :kfMt2li&d4A' :7MɼiNMt2oy]̛&b4A }>]̛&zr|Mݷ=74Lڙ=oZ;SuO' ZKSuOiB-M=76 4y&iB P 0!&ă&„`XL qaB0/L 6„ͼ0a3/L 6„ͼ0a3/L y=g~M8 Γ4.Pw=7uׄ:lTM4NUV{oGg-Ml=9&> ;SuOMԺ'Ɠ|wOi=76~4Ayk!hzs;r)þ죛dl  ͛e, =7>4cuii DuOMM_v3e L xcf Ęރ 3{ef{OpI=2'Qf$ D ߓ(3{ef|O̐y}Y_"^evOo#:/IuOMwޠo$=o'Oo7֒=7~ta .ć fЅt!D]AWDЕ(t%J]AWDЕ(t%J]AWDЍ(t#J %n :=7>AǾ᡿y'O3XZ{o*}ARSwȠݠ;eНt'>=0D!"Az$DQ"Az%DoD7Q"(M&J} &J}sR3XhnĿtO gޠci MuOMO3Xh{o}ABӺ'Ƈ_ v~e  x~f ĘA? 3ge ̠I32~&Qf$ DA =7& DA?s?!9<~Qfޠl4{o$}`Ao~A[4`UӺ'MTt;ܠYj7lt!:]A̠ "B#+Q"J%D+Q"J%D+Q"F'dCl݈A7NjyݠcAp߼ABSXh{o:4'ҧt,4{olj7lt':݉Aw̠"Az#Q"Az%DQ"A&J}%ADo}BvbWq3ap'ƇƟ sL{o>70k1/L'iB}&u'fFkB}"i߽&`-jC4QO XZXM P Μ0&&8„`XL qaB0/L 0!&„`^ 6„ͼ0a3/L>G5a3/LO,MvO6ͮ ؙVuÓi94=1պ'ҴZXV래Kjs`iZ{b^C&L`4a0 s0l^9 s0o0 s0o0 s2o0' s2o0' s2o0' sx s2o0kք91939C=1g}պ'欏ZĜW래>js_{bwO)yτ)5a saR j aa0-Lƅ ¼0A&(e^ ya2/LP ʼ0A&y=3&{r&Gc=1g}.Vsb=1'v=1'=1'=1'=1'=1'=1'&Ꞙyk?i3'Lp& ά0&„`\ yaB0/L 0!&„`^&l {ϑg~M 4['欍'欝'欝uOLuOiB-M{bZZĜ49kisp40'L8L&^`4a M`4a M`4a M`4a M`4aMMd4aMMd4aMMִ79?d4a'ׄ sacj ;S KS KS KS KS KS KuO̵ KkL0)L5Mf °0A&a^ ya2/LP ʼ0A&(e^ t9` q sacjsagjsagsWZ\u=1W}uOU_)jswZ\=1 P Μ0&&8gXL qaB0/L 0!&„`^ yaB0/L |=gg~M 4p?ovM/5K7N4}4K7N4}4K7N47I=oxM8ep&& A&`4Aæ 26Mi Md0o y̛&`4A 27MɼiLMd2o S3Lɼi'9~C ؙL,Mw%L,M]>K5A4}^K5A47&~&e œi "j aa0-Lƅ ¼0A&e^ ya2/LP ʼ0A&( q S1)ؙZL{b =1KSb &`iS4)X{b P Μ0&&8gXL qaB0/L 0!&„`^ yaB0/L {3&l q S1)ؙZL{b =1KSwOO Xz,M=1ׄP 9aaRp40kaL&`4A :7MiMpk'M[h=1u2oy̛&79?t2o5A&h}'W{bj}uOLopEkbiS4XzT,M=1u k.LT4MPyP * aa0-Lƅ ¼0A&a^ ya2/LP ʼ0A&ωg~MP 8Md=1UTL k&kS4Y래ZT,Mֺ'bi=1K>7&C&8sgRj aa3-Lpƅ μ0!&„`^ yaB0/L 0!&y=gg~M 4['bcjS3ؙzT,M{b*=1~uOLlkSwZ=1ׄP 9aaRp40+L8 &`4 67Mi Ml0o`y̛&`4 67Mɼi>GgMMl>9&X[vOL'TjgjjijjijjijjijjijjiӖ?o`롼&b4 &5Y ´0A&a^ ya0/LP ʼ0A&(e^>ǟ5A&4['acjӰ3iؙz4,M{b=1_=1 KSVZĴOԻ'ye Ia?i3+Lp δ0&8g^ yaB0/L 0!&„`^}yׄͼ0a?9NQvOLF=1UĴkԺ'a=1.iuڨuOLF{b=1 KuOL;yky(ӄÜ00)L8jp& i&`4 >7MiM|0oy̛&`4' >盿9s=̛&|r|MplM螘uOLԺ'cgӱ4Xzt,M{b:=1KS'/{3CyM@{bb4׃zMpa4a ¸0A&a^ ya0/LP ʼ0A&(79̯ ʼ0A ؚ<'Tkg344444cێ{(gNL AMYa3,Lp θ0&8g^ yaB0/L 0!&„79_ya~r&k{bz$'[=1duOLo {bzYAꞘ^KSu?'fݑYפ{bMiꞘuX'f]Y'{b֝iꞘul'f]YW{biꞘu}'f]YW{b%jꞘu'f]YW{bejꞘu'f]YW{b֥jtO̺Tݺ'fݪnUY{Ĭս{b=1ruuwO̺_MnXSĬK=15uO̺hMZSĬ=15uO̺nM\SĬ=15uO̺sM.]SĬ[=15uO̺wM.^SĬ=15uO̺{M._SĬ=15uO̺Yׯ[Ĭ׭{b=1uuwO:ݻ'f]N`Y7{b+ؽ{b[ؽ{b{ؽ{bؽ{bؽ{bؽ{bؽ{bؽ{bٽ{b+ٽ{b;ٽ{bKٽ{b[ٽ{bkٽ{b{ٽ{bٽ{bٽ{bٽ{bٽ{bٽ{bٽ{bٽ{bٽ{b.h߽,5`/Ln߹ߊQ~Fe7Q|W̄dz}B| )>E@zOqdrsvS;%7w;g7{Gw;g7sd^r3f_svuٗߡ/ט|Iy'u/<.[cxk57\.Z׿Mu{/5WܫSeB"ѽ:Wt9]MuMoVt6U:* ΆJgCj!ِ\lȮv6W;򫋓t 4Ά+e1s_XwFfmaVfM0slچ.96w96"[gBS!NXc\ȱw0;r 9Ά{gC!ِclqt68:r 9ΆGgC8I NӛlqP3nX{bnl =17=17=17=17V=17=17=17v=1>j7҇2ӇC|Ha!B"}>hDQf LD>(3ge ̄A323~QfOCI397HvÕ]':RuMwÕuÕuÕuÕuÕuÕwO̳,ˠE|t|]'YDA?30uO#A?B#D Q"B%.D Q"B%D|B=DoЕ(tfбdx|D'5&'6S`yϴyдyдyдyдyдyyWA̖A?DCf"C!H%~A?Dy 5Qޠ1}A7k A_c (o>d5Qޠ19_Fk`5TgZXhZXhZXhZXhZXhZXhzkb/k,A_c /|ِ'Xx"5Aޠ!Dy B%.D Q"B%.D Q":}t%J]9tl4=XLuO}uOuOuOuOuOuOwOaʯvn̖A7CЍtc !;1"N%D;Q"N%D;Q"Az%DZjkևK{bxuOY05x3a0s s1i0׃zMYӄ6Miӄ7Myӄ)̛&La4a a^ ya0/L ¼0AΛ9:5A&4>5X>5555555QĚ&^L9a1)L5M0f ư0&8g^ ya3/Lp μ0&8„`^ bϑg~M 8M҄5153vXKSXKSXKSXKSXKSXKuOyk~(ӄ͜0a3)L8jp& iaa\p& yaa^p7MXyӄ57MXyӄ57MXyӄ5}?τ57MX5aakBZؘZZؙZZWX>jkG_{buOU~=<~&P^b4a-&MzP k1kæ k1m k1o K7MX¼i ¼0A&a^ d9 qPeZXuOUUZؙzZXzZXzZXzZXzZXzZX{b-[^L9a1)L5M0f ư0&8g^ ya3/Lp μ0&8g^ b_yaB<9N5{bژ{bڙ{bڙZZ4jijkԺ'֪uOUKSX=ֶ L6s„ͤ0a?iaVp& qaa^p& yaa^p7Mi Md0o y>Ǟg Md<9&&tO,Ժ'`gjK3%Xz,M{b =KSXwO,DK~3ACyMŜi,&Md=Y̚&b4AӦ 7Mżi,M=D7Ma4Aya0/L ¼0A&H q K1%ؙZL{bI}uO,%=RԺ'wZĒRQXbyk=i1'L0& Ƭ0&c\ ya3/Lp μ0&8g^ yaB7sb>kB0/L'iB}('Է{bI}٨'wZ,M{b =KSXwO,Ի'`i%[7&2M 6„ YaaXp&ƅ yaa^p& yaa^p7MiMt0oC3Li'mm}&uUo _K7&(o|MP,MX\t :kNLt1iA&b4Aæ 6MŸi.Mt1oy]̛&0o¼i a^ yaxa^ OlMߟؘ? ؙ? ؙ߽&`iL4]+ X?,Mߟi4K}4{(cN`L AMYa1,L0 Ƹ0&8g^ ya3/Lp μ0&8g^_yaBg~MքؘZRL{b)v=KSX'biK4XzҽM҄-^C&l Ia~Pӄͬ0a3,L8L tp& yaa^p& y̛&`4zw#3 6_Ɲ;=]ܭ{bY}uO,Ի'ai˰4eXz2,M=l 6kMLl2i`A&b4æ 6MŸi-Ml1o`y[̛&b4yM\X& ya؛a^ OlM˰1YuO,΄{Md{b&k _eXuO,d{b&_~-'Tkg3444444Ӟ7LP^|2gI5 6MŴi/M|1oy_̛&b4 7Mpa4y ¼0A}=k0/L'i&tO,Ժ'cgj 7g{b9=KSXwO,Ի'i=废7&C&scR`j` aa1-L0ƅ Ƽ0&g^ ya3/Lp μ0&x qP{by5uר']=u٨uO,F{by6j˱4X{b^C&l Ia~Pӄͬ0a3,LL 6„ü00/L8 „ü00/L8 „ü00oc='| 17Mؚ=SXuOԻ'V`i+4Xz ,M{b=KuOgḂ9ӄL&|P 15MŰiB,Mb1nyӄX̛&b4! 7MżiB,MB7Ma4!yaț}a^ OlM+jc3UĊڙZĊZZĊZZĊZZĊZZĊZZĊ~ϱmG5A4A&{PcV` ia1.L0 Ƽ0&g^ ya3/Lp μ0}N]Hn] H.x Ł@jOq 8SH)z<Łd@*;4]&w/C_71xSX4n[cxx[ݵfe=~71]AN_67kz;j]z{T{bZfΕ)].ڛUޤZfwLuMo^7kz;i].ZuVg2QXc5ݲI 7ِb,faXMnUyvO{7kDaXGf*7^c6_=sFtsD9΄kB2ֹc`ȱu2:rl 9Ά[gC!ِclȱw6;r 9Άr7ِc,fu(T:{b, {b, {b {b{bl{b,{b{bj7lMt&>z3`z!r ĈdoD7Q"ۛ(MH!J%}?DDQ"(OC6oQޜ/2d "=!HuO>Һ'd`#i2 IZ ,%{B=!kI1'/2&}A1]$t˘Dx.c I72&AޠXDy.c E72QޠXDy.c =!c E72Qޠː{L.CANjJvOR2TD}ֻ'd`ei2 XZZ l-{B֖=!{Kʯv̖AWCЕte !n1"F%nDQ"F%nDQ"N%D$x|~A?&'db g{B&=!iuOBӺ'dbi2д Xhz9վl7s]}Nˠɀ7sa}NB̠I9 2>'Qf" \DA(3se}.̠Et|g'd.̠;=!s'dCd ̠OfбdLl3=!LuO>Ӻ'dbi2д XhZL,4{B&=!A2UnЕ2Jt AW"DЕt#FA7DЍ(t#J݈A7DЍ(t#J݈AwDН(t_OC7NsR3h=!L랐Y? #=!~HӺ'd֏iZ9M랐Y?i2 =!3yÛx(3H}0)bfV3,ߌoE7"yͼf^pya^Hp{wzp"'iB!힐~ Yc3aI{BV}Ժ'dJ{BV}Ժ'dՇK{BV}Ժ'dL{B8~&P^d4aM&M|P k2k&æ k2m& k2o& k1o k1o k1o k1o k79&,a4aɓkªϤ{BV}"UꞐwOZԻ'da/ Y،z,F{Bv#Ꞑyk>i2'LP& ʬ0A&(c\` ya1/L0 Ƽ0&c^` ya7s|=k3/L'i&tOԺ'dagj3 YXz,,M{B=! KSwODž7&C&s„`Rj&l iaf\&l yaf^&l yaa^p& G3& qie,lL'D3ZH}պ'D꣯=!R~ uO_{B>"c?o 㡼&d4A& 2kLfMd2l i&d4A& 27Mżi,Md1o yY̛&b4A }~ 7Myr|Mh,'DsŪ{B;SԻ'D4 ,M{BKSԻ'D4Q P ʜ0A&胚&(eXL qa1/L0 Ƽ0&c^` ya1/L0 >}̯ μ0 ؚ=!RSuOT"3 ZZH-M{B=!RKSuOԻ'DB7&C&s„`Rj 6„ʹ0a3.L 6„ͼ0a3/L 6„ͼ00/L8 „#os_„8Mք lL{B;SԻ'D4 Q,M{BKSԻ'D4 Q,M=!5 ɤiY &d4A' :7MɼiNMt2oy]̛&b4A 7Mżi.w3A _['D1 QL{B;S :Q/ JQ RQ5A4A&(}PeV ia2.LP Ƽ0&c^` ya1/L0 Ƽ0Λ9>5&4pm/Uh}רuObiXz(=!wObiX{B4ykBG50/L8OlMԺ'D3 QL{B KSԻ'İ4 1,M{B KSDbß7LP^l0g`I5& 66MɴiMMl2o`y̛&d4& 7Mżi-Ml1o`y[>ǟg-Ml=9&bl1}΄"{M,M8M,M8M,MM9^L9a2)L5MPf ʰ0A&(e^ ya1/L0 Ƽ0&c^` l9 q5;5;,MߟiO,Mߟi4KgIykBkL|0iA&d4'æ >6MɸiOM|2oy̛&d4' 7Mżi/M|1oK3Lżir8& qlLVؙp7w?K q,Mֺ'ą&`i=!Z8&ⲟ7&C&(seRj aa2-LPƅ ʼ0A&(c^` ya1/L0 Ƽ0&X` q ؘZ8v=!wOci[m{B~uOﶵ =!ykBվ ٲ6XY:XG~9֑߈ ~9ֿ5r#-7M_=s,Jts,D9΄KB2ҹc`ȱv2X;r 9ΆkgC!ِclȱv6:rl 9Άp7ِc,f X{BЁuOк't`oh:: Z,{Bv=Ã_Fڙ-3DP! B:bD  Jd;D(M&J|%DoDȷ?! ߘoD7'5e$'t`Շ7GZl${BV=;IЁuOVҺ't`-:W>ݠAt9//PA91>1f DA(3se}N̠I92>'Qf$ DA(3s'dC2>'}b_ XV{B'ꞨzN,{B XZZNl-{B'֖={K)¯v.̖ACЅta !.+1"J%D+Q"J%D+Q"J%nDzBv"k1/L'i&tO`cj*ؙZ v=wO`i*Xz =wO`i  P Μ0&&8„`XL qaB0/L 0!&„`^ 6„ͼ0a3/L>G5a3/LOlMPԺ'T3 ЫuO_{B>j*WPOZJ}պ'T=ryky(ӄÜi&Mt<̚&`4AӦ :7MiMt0oy̛&d4A' :7MɼiNMtx :7MXvOb=ZU*v=wObiXz*=wObi U~&< ¤0A4A&aZ ya2/LP ʼ0A&(e^ ya2/L{g~M0 8Mք ژ{BvPuOԺ'Tkij4 ZZj-M{B=54&8PgV iaB0.L 0!&„`^ yaB0/L 6„3&l q ؘZ*v=wObiXz*=wObiX{BׄP 9aa4ƃzMi Ml0m`q̛&`4 67MiMMl2o`y̛&d4g`yO jؘZv=wOWZZ}uOZZ}uOwZZ}wOy`œi'AMYa0,L ¸0A&e^ ya2/LP ʼ0A&(os3&{r&{BmTjeP 5,M{B KSPԻ'԰4 5,M{B KuOze Ia?i3+Lp δ0!&„`^ yaB0/L 0!&„ͼ0a7szׄͼ0a?9N5{B SPԺ'԰3 5,M{B KSPԻ'԰4 5,M{B KuO{p40'L8L ΃zMiM|0mq̛&`4 >7MiM|2oy̛&d4ϱgyO ؘZ:v=wOciXz:=wOci_= k s .L&g?k2/L'i7l1}kv&\M5K7N4}4K7N4}4K7N47I|>oxM2Mp Τ04&8gZ yaB0/L 0!&„`^ yaB0/L=5a3/LOӄ?kB}5kB}gnj,Mk4KgIpyky(ӄÜ00)L8jp5MiB Mb0nyӄ̛&`4! 17MiB Mb2oyӄ̛&d4!>τ̛&|r|MlMؘ'4&{rML3!4Yd{BK ,Mֺ'44Yd{Bc kB?{¤iBȃzMaV ia0.L ¼0A&e^ ya2/LP ʼ0A}Nǟ5A&4.ekTQuO讻F{Bw6jQ]ZmԺ'tci4Qn;^L9a3)L5Mpf ΰ0&8g^ yaB0/L 0!&„`^ b9&'i&tOԺ'tcgj3 Xzn,M{B7=KSЍwODzp40'L8L ΃&f aaa4 M`4 M`4 M`4 M`4 M`4LMΜo?d4' 6S;SuO詝uO詥uO詥uO詥uO詥uO詥uOvt=oukY̙&ŤiY5 G6M8´0A&a^ ya0/L ʼ0A&(e^>Ǟ5A&4]z-HtOi =݂ =duOi {BO;Yz=BVZzhк#MZפ{B4uOh =ub'LSֱiк8MZW{B4uOh] =u'.QS5jкHMZW{B25uOh] =u'.U{BRuкUݺ'U ս{Bfu:[ݻ'.W ս{B~5uOhݰ K=u͚'.ZSQkкkMZ{B5uOh =au嚺'\SեkꞰuMV׮{5uOX] =au'^SkꞰ}MVׯ{5'_ ׭{u:ݻ'_ ؽ{v:ݻ'n`S+ؽ{-=avvwOX;ݻ']֎c k{ٽ{ڕ=aNvv)wOXݻ']e k{ٽ{=anvv9wOXݻ']g ]>],Ѝ~wnmbQ&L)F@p7>mH !ŀ${A ^HŁzq ^HŁFq QHhŁdFq =71ILN=aט$f7[߻iچmmކmܻ 3LN723!S!2s!!!!eZGkzi]ӛI7fwѺ7ĪwOuMor+7stLuMo~8 suMou~ kLϼgWr<+p57ǿVcxs;Y`uUwr;Y]ӛz՛c|EX7H79.ڛVxJgC!ِclȱt6X:r, 9ΆkgC!Ǻ8I BӛclȱR3 nM, =aBuOк'lbih67 XZMl{&=a;Diίv#m̖6Cjg!r턈`;1"N%Dp;Q"N%DQ"Ax%2D=!qߘQ"I͠cY{&v XG'lbY=aɪ XIVuON{&U6Ʞd ݠfˠC!3C!F$~A?DA_(3ke} ̠A52Qf DA_c?!9<&Qfޠ/+=a JuO¾R [XYZz-,-{=a kK랰wOZ_ Zve" Z xf" ZĘA_B%DA_B%.D Q"B%.D Q"J'dCt]AWNj MvO6ST-3{=a M랰uOBӺ'lai [fj7lt#:݈A7̠;"N#;Q"N%D;Q"Nz%DQ"Az z% :6잰m'la [gZ-,4{=a M랰uOBӺ'laWA̖A?DCf"C!H%~A?DAAtDAAtDAAtDAAt>d ̠ޠ 606S&g{L0BӺ'Lд ,4{ M0BӺ'L 5վbtYDAE|tY x.31.38G&Bt̠%.D Q"B%.D Q"B'dCt]AWNj 'Lδ LuOԏhZIuOԏiZIuOjZIuOԏjz7Pf9zcR̽1+ ;"θȾ3/̋;"μȿ3/pμP B`^X>G "ē4vO{$M yR0ZI}Ժ'L꣥=aR. xuOL{dׄP 9aaRp40+L8 „ø00/L8 „üiMt0oy̛&`4A :}N<̛&g&h}&TuO'R=awOb-؋z)=aͨwOb5؍{t ?t=]̙&b4A׃zMŬi.Mt1mq]̛&0o¼i a^ ya0/L ¼0AΛ9:5A&4K'L1{;S0Ի'L4 S,M{KS0Ի'L4Q{(cN`L AMYa1,Lp θ0&8g^ ya3/Lp μ0!&„Xos_yaB<9N5{S07d0Zi}պ'L룯=aZ~ uO_{´>۟7&2M 6„ YaaXp&ƅ yaa^p& y̛&`4 67Mi {w3 6_> \'c0Ի'̰4 3,M{ KS0Ի'̰4 3,M=a6 k-Ll1i`A&b4æ 6MŸi-Ml1o`¼i f¼0A&a^ d9 q f1UYL=aV;S0uOԺ'jijf4 ZZY-M{{(cN`L AMYa1,L0 θ0&8g^ ya3/Lp μ0&„ozׄ`^OlM0Ժ'̰3 3L{ KS0Ի'̰4 3,M{ KS0Df۞7&2M 6„ YaaXp&ƅ yaa^p& yaa4 >7MiM|蛿{ >7Mؚ=auOcgjؙzy}uO׉Zy}uOWZy}uOחz~&|( 3MŤiY_ &b4 7Mżi/M\7Mpa4ya0/L ¼0A&H qP_8 QuOח{¼kԺ'̱4 s,M{KS0Ի'̱4 s,M=anyk=i1'L0& Ƭ0&c\ ya3/Lp μ0&8g^ yaB7sb>kB0/L'i&tOccjؙZ9v=awOciXz9=awOci ^C&l Ia~Pӄͬ00,L8L „ü00/L8 „ü00/L8̛&`4! 17M!os&`4!ƓkB`kB6=auOX`gXz=awOX`iXz&ꞰgḂ9ӄXL&zP 5MŰiB,Mb1nyӄX̛&b4! !̛&0o¼0A&a^ >'5A&ȓ4[',1 L{;SԻ',4 ,M{KSԻ',4Q P Ɯ0&؃&cX`L qa1/Lp μ0&8g^ ya3/Lp ~}ω̯ 0! 5߭?ovMpͩ^ܿq Xq XqIyk~(ӄ͜0a3)Lj&l iaa\p& yaa^p& yaa4aM`4a>Gg̛&a3ackY3acgLؙLX? K5aci~&l,Mߟׄ󚰱47&~&P^d4aO&MzP {1kæ {1m {1o {1o {1oyӄ-̛&la^ ya0/La^ OlM螰uOԺ'lcg4 oQm[aBf[랰]ֺ'lo z7&C&scR`j` 8Ce1-L0ƅ Ƽ0&8g^ ya3/Lp μ0&~ws5!&ē4~-'lTkg ۵3 ۵4 ۵4 ۵4 ۵4 ۵4 ۵4 {=oxMe&l& AM6„Ͱ0a3-L8 „ü00/L8 „ü00/L8  g0op|{&iO ['`cjv3 ;ؙz,M{=aKSwOةD{N'2 ;&ɜi™L&^b4,Mb4,Mb4,M=ag1op =aG7M8¼i ¼0A}=k0/L'iB]6DwOةF=a ;uبuOةF{N6jvQ랰wODvt?oxMЇ2M0 Ƥ04&cZ` ya1/L0 μ0&8g^ ya3/Lxw5&ē4['`cjv3 ;ؙz,M{=aKSwOԻ'`i ;{>oxMe&l& AM6„Ͱ0a3-L، „ü00/L8 „ü00/L8 „üc{1y >Ɠؚ<'|T>jg 3 4 4 4 4 4 cmG>>o3|(?|L&LzM1Y >^|,&X{Mc15bkc?|,&X{MCCC&g~M 8Mh ov >-HtOh {G;Y>5AVv'|=ᣖ=u?'HS5i)M^{4uOx ;=ul'.NSi efM~+;}G Ǘx=;wI 𙗥{7>Hm !lŀ$[A VHkŁZq VHjŁzq ^HŁdzq n=ыIL'ߍkLncbnC0ߑjkaf2 3m+7{qwOuM33!S!2s!!!!!!!!!!!!!!gsM .YwȺMX羿NXcxpyvOxu/ǿ~Ûj oW o'19߽N_'kzsY]zsfVk7ǿE{s;Z]ӛVc9ݬduMoܛ2kuZ-sVgnUw'{,KgC9v'|aQ _{= KCuOк'|a{h@ _!z/5~ie̴BćT+fk#Dۈ6D(m#Jۈ6D(o#J܉ wDĝ(q'J }܉9wNjHvO.RT/#{6= +IuORҺ'|a+i _nЃ2M|f &B}"AoD7Q"(C!J%~A?DDQ"'݇lߠ̠ޠ pR.W{ KpҺ'\ ,-{[KpҺ'\ 9վdtDAI|t x.32 1.32 2.(3貈2.(3貈2.(3貈2.(3貈2.(3C.2}/"D '5&'\T p>Ӻ'\д ,4{ MpBӺ'\д ,4{E_]-D+!ʀt%BA7bDЍ t#J݈A7DЍ(t#J݈A7DН(t'J݉AwyBvӺ'\д ,4{ MpBӺ'\д ,4{%_=-DoC7f7"M&H}%ADoDQ"(C!J%~A?>$x|~A?tFf{LuObiXhZ+=ኅuO8> XhZ(Qj_u2 Nˠ$ NAItAItAIt]DAEt]DAEt]DAEt]DAEt]DAu}/*DAWfбѠ{=zk|'\G4{µ~HӺ'\4{µ~NӺ'\5{µ~RӺ'\G5{UyÛy}(3ʜH2)bj^WEi}c\dߘ7Eyc^ߘc^(` y!3/,>G"4vO{7M yRpZk}Ժ'\룥=Z. xuOL{5ykB 7,E{ kQp^Ի'ܰ 7lF{ QpnDnjnWpZ[}պ'=V P 0!&ă&lf aafZ&l yaf^&l yaa^p& ya79̯ yayr&Gc=VU{},VؙVpҴZ;պ'ܱ4=Ꭵi w,MuOciZ{} ?|<̙&d4zMɬiOM|2mq̛&d4' 7Mżi/M|1oy_̛&b4ek?_̛&<9&8&tOT3U{L{½=^KSpuOԺ'kij4 w^L9a2)L5MPf ʰ0A&(c^` ya1/L0 Ƽ0&c^` |_ya?9N5{SpԺ'ܱ3 w,M{KSpԻ'ܱ4 w,M{KuO>oxM2M 0!4!&l iaf\&l yaf^&l yaa^p& G3& q ؘZ;v=ၝwOxWZG}uOxZG}uOxwZG}wOxx3!CyMiBL&Mb>ׄ̚&d4!&Ӧ 17MɼiBLMb2oyӄX̛&b4! 7MżiB,Mbx 7MoUG}٨'ׄ=5Mؓaӄ=6Mؓqӄ=7Mؓyӄ=7Mؓyӄ=7M؋yӄ7M؋yӄ7M؋yӄ}?τ7M5ackBolL{7v=;SwOԻ'|ci4 Xzo,M=[}(eNL AMYa2,LP ʸ0A&(c^` ya1/L0 Ƽ0&os3&8r&׸{w}'|W{w}uOop Xzo,M{7=KS'|ze IaBǞgY̛&p5}bcL8ؙ??vw?4KgPyMl&L۾7Id?oxM2MP ʤ0A4A&(eZ ya2/LP Ƽ0&c^` ya1/L0 5&4~-'T~jg ?3 ?4 ?N>ZZZZZZZz^L9aB0)L5Mf 0!&„ͼ0a3/L 6„ͼ0a3/L 6„ͼ0a3/L8350/L8OlMuOԺ'`g~4 ?XzD ,M{"=NuwOτL1c05!xP?b f&Ę {M1c25!dkBɼׄy 1&^bL&Ę{M1c15!bkBżׄK3c15!=.eDkT1QuOĨF{"F6j1Q랈QZDmԺ'b`i14QD*IYrXs있w=+?^GDeMTݴ&tOatO3=KMdK?R-EDKC4k1 ZHjq ZHŁjq ZHjŁtZq VHi6i@)Shq'wDmvF_mytiLkf&0S52ontD΄|FBB2ѹ`it2$5: iΆFgCbwgCfwgCjwgCnwgCrwgCvwgCzwgC~wp6MowgCe1s|ͿwQ#mvs{{70s|'j6݆swo;}9fuͱN9huMoethuMoeth5NVwͽ9ͱΖ9ͱΖ9VuMo{'I/ǿC59ݩn/ǿ3_oDP!XZD=5ZDV=uO`h!!zD(ڍ0[fZC3Bȵ"Ĉd+A"Jȶ%­Dt+Q"Jȷ%DQ"Fȸ%Bn>Dy|cnD'5e$'BTD֑>Һ'B${";IRҺ'B%{ SD3[݉ACЃ3Az"ĈA"Az%DQ"(M&J}%ADoBvSa#=V?iac=V?ia=V?ia=&yÛyy(3œH0)b/j^Ei}e\d_WEye^_(e^( y!1/,{g~=08Mh?Ĺa'85>OjƇiB}Ժ'꣥=V.xuOL{"yk?i3'Lp& 0!&„`\ yaB0/L 0!&l yaf^&l}wc&'iB}&aTuO'R=wO/ ؋zD=ͨwOa5a؍{" 硼&`4 >kfM|0li&`4 >7MɼiOM|2oy̛&d4' >}~ >7MX=uOcgjؙzD8=wO~)'±4p,M{"KuO|3L9a0)L5Mf °0A&e^ ya2/LP ʼ0A&(e^ lc_ya=9N5{"SԺ'C=^|uOׇ_{">jWϿzD(gNL AMYaB0,L 0!&„`^ yaB0/L yaf^&lyw&'iB}4XuOb=wOciXzD8=wOciX{"ׄP 9ӄL&xP 15MiB Mb0nyӄ̛&`4! 17MɼiBLMb2oyӄ̛&79?b2o5!5{"6ꞈ'"jgj4ZZDD-M{"=QKS랈wODx3!䡼&0'L& ¬0A&a\ ya2/LP ʼ0A&(e^ ya7slG5a3/LOlM螈Ժ'"3L{"JԺ'"D{"PԺ'"+E{"SԺ'"KE{"ׄP 9aa4a {0lӦ {0n {0o {0o {2o' {2o' {2og' {>9&QvOĮoUDQuOĮXzDl,M{"6=KSwODy3aCyMœi& ¬0A&a\ ya2/LP ʼ0A&(e^ ya79_ya=9N5{"66=;S랈wOԻ'bci4XzDl,M{"6&ꞈyk?i3'Lp& ά0&8„`\ yaB0/L 0!&„`^ 6„=}_6„8MքؘZDlL{"6v=KSwOԻ'bci4- }yky(ӄÜ00)L85 fM`4 M`4 M`4 M`4 M`4LMd4LMd4L}wc3LM|r|M8ؚ=S랈uOԻ'`iq48XzD,M{"=KuOYy\8œi&Mg?k2/L'iB};'w{"N}'7[Dw랈wOԻ'`iq48X{" P Μ0&&8gXL qaB0/L 0!&„`^ yaB0/L {3&l qɲ{"6&8ؙp7 ,Mֺ'`i=K8XuOd{"&q>oxM8ep&& AM^ {Mc05aׄ=^{Mc05aׄ=^{Mc05aɼׄ=&^{Mcʛ}?{Mc>9L[w?gff?Δ;???j?l?m?n3aLc= {,&!LzMCτ=Ya0,L ¸0A&a^ ya2/LP ʼ0A&(79̯ ʼ0A o?lkcyM5v^ji&3MPK4ߟiB-Mߛ >7&C&8sgRj aa3-Lpƅ μ0!&„`^ yaB0/L 0!&„=5a%IJw#`늼Sf˹}ό7LFμ0 ؚ=L{v=KSwOԻ'|`i>4QQz P 0!&ă&„`4aM`4aM`4"Lyӄ97Myӄ97Myӄ97Myӄ9}>τ97M5aeYw{g5 uרuOF{g]6j>QYZO7&L,M=y>塼&RwO&M>ׄ̚&LeXL qa2/LP ʼ0A&(„ż0a1/LX „ż0a̯ٛ yazr&`kBOlL{'v=;SwO44QO L6s„ͤ0a?ifV&l qaf^& yaa^p& yaa^p&w qigژ{§ӆ&Ժ'|Ժ'|Ժ'|Ժ'|Ժ'|Ժ'|{m;!^L9aB0)L5Mf 0!6Mi Md0o y̛&`4A 27Mi Md2o s3&d4Akk{¥݂DKL=nAVK;Y.duOs=AVK;Y.M u?'HS5i)M^{4uOx ;=ul'.NSiӺ'ܰд 7,4{ MpBӺ'ܰд 7,4{{͘-nD!ƀM&D}# ADoD7Q"(M&J%~A?DDzBvby}̠IAh=L] +=~IӺ'|ׯiZ=M]i75{wwO- oaҌ~ f0l& f0nf+f2o+"ʼȿ2/PʼP@(Be^Xƛ9k>b^ 8{w '|MkB}Ժ'|ׇJ{w}Ժ'|GK{w}Ժ'|K{w}Ի'|z`e` Ia=i1+L 6„͸0a3/L 6„ͼ0a3/L 6„ü00/L8 Yp&'iB}&]HUo,E{7֢={QŨwOfԻ'|c5Qo?^L9aB0)L5Mf 0!&„`^ yaB0op g0op g0op g0op~wsg̛&p4{6=;SwOԻ'`i~4 ?Xz,M{&#yτ#5s G4M8^0kpaӄ#L&a4 G7M8ʼiQ ʼ0A&(e^ yaƛ9kka^p XvOŪ{O},V~3 ?Xz,M{=KSwOD~|?oxM2Mp Τ0!4!&„`Z yaB0/L 0!7MiM|0oy̛&79&`4ǓkckB{mL=^;SuOԺ'kij4 ZZ{-M{½=^KSpgCyMpa4I¬i æ .L&0n¼i ̛&2oʼ0A&(e^ yaxׄż0a=9N5{Sp|ݻ'ܱ3 w,M{KSpԻ'ܱ4 w,M{KuOoxM2M0 Ƥ04&cZ` 6„ͼ0a3/L 6„ͼ0a3/L 6„ͼ07s|ׄü0<9N5{SԺ'<3 ,M{KSԻ'<4 ,M{KuOxze Ia?i3+L 0!&„`^ yaB0/L ׄy 1^͙c蛿L1c<9L 11ؙZD L{"=KSwOԻ'b`i14QDy73!|(?bL&&&Đ3!05!05!05!05!05!05!05!05!25!25!2/LP ʼ0A&~ws5A&4Ɲ1;=]1ܭ{"F}uOԻ'b`i14XzD ,M={(cN`L AMYa1,L0 Ƹ0&l yaf^&l yaf^&l ;}9_„8Md=UD L7,Mֺ'b`i=KXuOd{"&1\7&C&8sgRj aaB0-Lƅ 0!&„`^ yaB0/LM`4aM79?`4a'ׄ 11ؙZDLL{"&=KSYuOĬֺ'bmk1os?o0CyM9ӄ94M^0k0aӄ)L&La4a V1yӄ)̛&La4a* S7Mʼ0A&(79_ya>9N]϶65v{τڙ&7Nji 4ӄZiB-M4M҄^L9a1)L5M0f ư0&c^` 6„ͼ0a3/L 6„ͼ0a3/L ωg~M8 Γ4[ؘ? ؙ ؙ^4} X?,M X?ӄ:MgP7I\7&C&8sgRj aa3-Lƅ 0!&„`^ yaB0/L i Md0o Cg Md<9&H]6AowMkT!uרuOa=RZDH6j!uۨuO`i!X{"d 2k~!I5AYMD6Ma4AyM3D7Ma4AyQMD7Me^ tϱg~MP 8MքlL{";SԻ'B4,M{"KSԻ'B4,M=ykz(cN`L AMYa1,L0 Ƹ0&c^&l yaf^&l ya>os_6„8Mִ{"6'Bjgj!4ZZDH-M{"=RKS#54&8PgV ia3.L 0!&„`^ yaB0/L i9:3Li'm oDhv duOc=ڮAVDh;YduO=ZKSMQw{"4uODݔ=u]'NLSDԝiꞈ:6MQ{"4uOD]=u'PSD%jꞈFMQ{"*5uOD]=u'TSDԥjtOD]nQ[DԵ=uwODݬQg{D=uwODݯ=uɚ'YSDEkꞈ:jMQw{"5uOD]=u㚺'\SDԝkꞈtMQ{"5uODݻ=u'^SDkꞈ|MQ{"5uODݿFD=uuOD]Q{D=uwOD]Q'{D lꞈvwODݻ'nbhg{Dؽ{"q=>vv"wODݻ'.eh{Dkٽ{"ڽ=bvv3wODݻ'.gh{Dٽ{"=Y7=wK/w-nqhw'ndM߅'ބ[|;53svfCi;uSw;g7Gsvw2svSw ;g7߼%őI]R%ő ]Rο9{ʥ3qf7ZHWBB2ֹR`ȩu2$:j iΆZgCb!ِِِِِِmMӛِMYd_D69>hf;z6݆s0sWzͱQ;r 9v{B!ɐchȱw6;r 9ΆGgC!ِlqt68:rIO~9;T]ӛ;mL=E'°-TD=uOaohaXZD=uOaaSվHdiDI|j xcm36 1m3&6!̶ QfM2mBo|e܄(3&D7!̸)QfM!*<1WDΕA2aE{" HuOaiaHZDV=uOa)iaJZD֒=QWT{"l1[}A_ A7"DЍt#FA7DЍ(t#J݈A7DЍ(M&J}%A }}%9t+=e'°TD=uOagiaXZZD=uOaoaneНt'>0D;!"N$D;Q"Nz%DQ"Az%DQ"q݇8oЃ(3{pRo7있m'bcgZDl,4{"6= M랈uOBӺ'bcW'ݠIt=/'ޠI= 1'1f$ ̠o! ̠o! ̠o! ̠o! ̠o! {NAJrR3h{"6ꞈ}'bciдXhZDl,4{"?YzDl,4{"6={-~lEt">}1`}!n1"F%nDQ"F%nDQ"(M&J}MfбdDll3=LuO>Ӻ'bciдXhZDl,4{"6= M} a !:݉Aw̠;"N#;Q"N%DQ"Az%DQ"Az'd!7AzpRo6tO:Ӻ'g{"NuOĩ_Ҵ8k=~OӺ'/jZDMM랈Sqx ̙?I3g>7g2kLɴ37&f0of0oG7 8¼M0oJpyӂ#{gypySOӄK=ouog R랈S+8R랈S.8R랈S08K7&2MX „ YabX`L qa1/L0 Ƽ0&c^` yaf^&lyw&'iB}&qꞈSHUD,E{"֢={QŨwOfԻ'`5qQD7&2M8 PgV ia3.Lp μ0&8g^ yaB0/L 0!}~ׄ`^O,MԺ'±3pL{"KSԻ'±4p,M{"KSD#7LP^|2gI5' >6MɴiOM|2oyM\7Mpa4yM\7Mpa4yw3y'քplL{";SZDx}պ'룯=^~uO_{">K7&2MX „ YabX&c^` ya1/L0 Ƽ0&c^&{Ζg~M 4>\'cԻ'±4p,M{"KSԻ'±4p,M=~yky(ӄÜ00)L8j aa3-Lpƅ μ0&8g^ yaB0/L 0!&zwc qI{"6ꞈ'"jgj4ZZDD-M{"=QKS랈wOD 3!CyMɜiBL&Mb>ׄ̚&d4!&Ӧ 17MɼiBLMb2o¼iB !̛&0o¼iB !̛&79?p'"5!5{"S랈Ժ'"3,M{"KSԻ'"4yvꞈDk>oxMXe&,& AM„Ű0a1-LX ya1/L0 Ƽ0&c^` ya1/L=5a3/LOlM螈Ժ'"3L{"JԺ'"D{"PԺ'"+E{"SԺ'"KE{" Ls„ä0Ǟg "O RvOfA LZ{7V 4Uol4Nji ^Ls„Ť0a=ibV&, qab^&, Ƽ0&c^` ya1/L>ǟ5&'iؘ5;S^3;ko&`iio&`iiB& u{4 Ls„ä0i2'LXL փ&,f aabZ&, yab^&c^` ya1/L0 g~M0 8Mִoo6ivM ^jih&T1ji8M҄37&2M8 „ YaaXp&ƅ ya3/Lp μ0&8g^ ya3/Lx='3&„xr&k_ohvMh {7ׄv 8Mh =oi =O_V-M{7 ?t͙3Mҽ{7P u]wO &ԝ=3nP{oμiB]9 uwƠ&%=3oP{oμiB]>τPݻ'~'ׄTVׄU]i~&=O_luiB-M=Iyk>i2'LP& AM„Ű0a1-LX „ż0a1/LX c^` ya1/L0 fos3&{r&t'jcBo:izM'~cqPKSuOF4ӄZZo^C& IayPӄì00,L8L „ü00/Lp μ0&8g^ ya3/Lpw qqߊ u'~ɏQ>Fp2ݤɾ O w ;g763svw;g76!w;nmE&(vnzNbY&vnja&vwj827svSj82ׯ?כο9{ʿו_+f_]&5f_ ]_-'~f_-{76ylM]k o&7{76\=ͦQS; Uʌ΅NΆΆΆĮΆ̮ΆԮΆZgCr!ِ^lȯ-N}f:Rḻ%MMnh=oi6Նmm9޻ 3yFg;o"΄N΅NΆΆΆ{gC!ِclȱw6;r 9IOp{gC9uOFG7=.ɛe, =>4cu4'tl{7j_`=.Ce`=0s!f Lޓ(3{e{OtI=2'Qf$LDߓ(3{e|xB=D&o!N 2r'~#/'~C?}c#4}c't VR;duݠ+eЕt%>]0D/BD1" E"J}%A_D/DQ"F%nD>!Y͠coiWA̖ADCf"C!H%~A?DDН(t'J݉AwDН(t'Jt'J9t,4{7}t}Oޠc4'~ӧt,4= _ v~e  x~f ĘA? 3geL̠I32~&Qf$ DA?(3geL̠OȾ#DA?IA?hno >pO~A?Xh{7>A?Xh{ MuOOo=+ 2[]AWCЕ3J"A_/DQ"(E"J}%A_DQ"F %n :6=>A>0'oбTo:4'~S :M!7 f &:}~0~A?bDA"(C!J%~AwDН(t'J݉AwDݞ݇lߠ;Q"I͠c33=Nެׯh{7Vg4=33=_}<7>3SI3>ԛ{̚|L}̛~̛ɼ̛d4'>7ɼ)OM |x.̛"<9&x%=)>+OuO?RuOƇ{7_>^x\\yk>i2'LP& ʬ0A&(„Ÿ0a1/LX „ż0a1/LX „ż0a1/L0 6}1yc^`OӄLvOffׄD ^cE{74NXi&`7=oxMe&l& AM„ð00-L8 „ü00/L8 „ü0&8g^ |ϱg~Mp 8MҔY욀'~?{MԺ'~cquOF4KSI5!kB Lb0iA&`4!æ 16MiB Mb0oyӄ̛&d4!& 17Mɼi6͙7My3LɼiBȓkB`kLhؙ{7] Q|Uoi|M'~c5!7ϿZo>7L}(eNL AMYa2,LP ʸ0a1/LX „ż0a1/LX „ż0a1/LX lc_ya=9N꣱=ͮ '~?{MԺ'~quOƓi=+IׄP 9afR4a3+L8 „ø00/L8 „ü00/L8 g^ ya뛿̯ μ0 ؚ{7s]jgBĿiL=O 4Uo4Njih&Ժ'~5!4!0`kALc05aׄ9^{Mc05aׄ9^{Mc25aɼׄ9&^{Mc25aɼׄ9~ws sL&1&́)'~I?T0=?&?3a,M{7~τ9ti2+LP ʴ0A&(„ż0a1/LX „ż0a1/LX „ż0aś965&ؓ4[SvOffL=nkB}'~cqP_(JQuOƓiB}uO5a?ifN&5M 6„ô00.L8 „ü00/L8 „ü00/Lp μ0}>k3/L'iB}vOffׄQuOQ5js`is`is`is`is`is`i9b?oxM2M i5afM`4aMp9'̛&i̛&i̛&ɼiœ̛&ɼiœ̛&ɼiœ>g?τ97M5abkBĜؘZĜؙZĜؙzĜXzĜXzĜXzUꞘKS<=1 SkTL2)L5MPf ʰ0A&(e^ „ż0a1/LX „ż0a1/LX ωg~M0 8Mք919393949494949494QĿg=̛&|r|Mo=16ꞘZ;SuOLuOLuOLuOLuOLuOLuOLwOLgCyMPa4AIʬ0A&(e\ ya2/LP yab^&, yab^̯ yazr&`kBTlL{b*v=1;SwOLԻ'biS4uuOLD{b^C&l Ia~Pӄͬ0a3,LL 6„ͼ00/L8 „ü00/L8 „ü00/L8{g~Mp 8MFFkB5iLF^8MF4Nӄm7N4}4K}4!ykB(3ge ̀A32#~Qf {2(3>2(3>2(3>2(3> }H O̠ޠ;6잘m'cgZt,4{b:=1 M래uOLBӺ'cEվ0 e]/€7.DAw! 1f] 2JtWDЕ(t%J]AWD t%J]A_D{ߠ/D'5&'cg{b:=1 M래uOLBӺ'ciӱдXhzt3~tc nćf7"M&H}%ADoD7Q"(C!J%~A? }%~8tl4螘uuOLTM래^i4{bzuOL_Դ=1~Uӻ'?ox3e>&EA"H~0-"H0o?fc0o yӀ̛ `t 17-q3<)B'ׄhĹ3op=1c*M?>OjYR래Q-R래Q/S!yτœiB !5'-ׄMB6Ma4!yӄPMB&(e^ yaoLP ʼ0a7s|ׄż0a=9N3잘QHUČD'f`)3؋z ,F{b6=1Q݈'fz`e` Ia=i1+L 6„͸0a3/L 6„ͼ0a3/L 6„ü00/L8 Yp&'i&tOԺ'f`gj33Xz ,M{b=1KSwOD3ꞐQiuOȨϿuOȐ 2L!yM!LzM!g akomr ak ak ak ek ek e^ ya2/LP de^{&'iB}42sꞐQU L{B=!KSwOԻ'd`i24Q P Ɯ0&؃&cX&lƅ yaf^&l yaf^&l yaa^p}>ka^p ؚ=!6ꞐQ;SuOȨuOȨuOȨuOȨuOȨuOȨuOȨwO54&8„xPӄ`V iaB0.L 0!&„`4aM`4aM`4aM79&iO ['dbcj23 ؙzL,M{B&=!KSwOԻ'dbi 37LP^0g0Iӄ)5a S6M´iM]\)̛&Le4a* S&(e^ ya2A}NoxM2Mp Τ04&8„`Z yaB0/L 0!&„`^̛&i̛&!os&iO [vOȪ'dTjgjjijjijBkªuOȪuOȪwOȚyτ5kš̙&ɤi’Yӄ% &,a4a K7MX¼iM0oyӄ̛&,e4a)e^ g~Me>9N5{B6=! ;S랐wOԻ'daiQJ4 YuuOȪD{B֊ P Ɯ0&؃&cX`L qa1/L0 yaf^&l yaf^&l 3& qP{BV5 Yuר'd]=! Yu٨uOuOȪF{B=! KuOrye Ia?i3+Lp δ0!&„`^ yaB0/L 0!& 67M1=dž<̛&xr|M0lMߝ74L0LyyM34}kai _ K7&&g͇`9L&|P &̚&0l`´i &̛&0o`¼i &̛&0o`ʼi) ]e^}=k2/L'iϿlkcP;S7ׄZLji3M[ 4&M4sڎlׄP Ɯ0&؃&cX`L qa1/L0 Ƽ0a3/L 6„ͼ0a3/L 6„ͼ0a3&l qЮA v b$'-k {B„v'=k!{B=!u?'HS5iꞐ)MR{B4uOH ;=!ul'.NSiꞐvMd{?RED{C4{1 ^H셁zq QHmŁFq QHiŁtFq QHeD߿x/߹;In]Kwn9<@uOw:g_/'uOw:7'V ZiÛ57Az/MkLo:L57gwӛ5hoN֘ޤ~W1YZ4iMw̞#-s{ertwӛ57Gt4Ά+e1smwrܛ2mvs50s}quaxif0szxmzEDՙթc#̱u.:rl 9[gC!ِclȱu6xw6xw6xw6xw6xw6xw6xoΆobxð=!BuOPr0 9XZ {BV=!C랐uOѻ'WvfL;!N|H3`ډvBDl'HDۉvD( J;D( JD<Dß݇ ̹N c q"=!u'ı ql${B+INҺ'ı ql%{BkI¯'ݠ$ OˠdtDAItĘAw! Qf]2Bt̠e7 Qf]2BtW̠'dCTx|D+'5}%'ıTx5{B KҺ'ı q,-{B[KҺ'm=!_}1[}A_ A7"DЍt#FA7DЍ(t#J݈A7DЍ(M&J}%A }}%9t,4=!m'ıT8=!uOciXhZ8=!uOcneНt'>0D;!"N$D;Q"Nz%DQ"Az%DQ"q݇8oЃ(3187聍&'$TꞐ>Ӻ'$д ,4{B M랐BӺ'$д ,4{BbN~/1=&ec_{Bba=&!fcc=&AfC2B̠e=(3!DAΩ{BB2Bt}&Ꞑ{NA%J]9tl4=!m'$T=!uO ,4{B M랐BӺ'$ ne!ŀE"nĈA"F%nDQ"F%nDoD7Q"(OCo7Q"蛓AF 3{B~?S+=!Qik=!Qi=!Qi=!q7DI{P3ά3,L;"μ3/̋;" B`^8 yaA79_y!B<9L~s't{B>Oj:C=>Wj:꣥=>\j:=>`:xL1c25A|P?tLf& {M1c25Adkakakakakakakakakak7st TuOO{B=Q_- ؋z,F{B6=QЁ݈'t,}4a1'LXL փ&,f aa1-L0ƅ Ƽ0&c^` ya1/L0 yaf^}>kf^ X=SЁuOԻ't`i:4 Xz,M{B=KuO8yky(ӄÜ00)L5Mpf ΰ0&8g^ ya3/Lp 0!&„`^ g~M 8Mք ؘZNL{Bg}պ't_{Bg}պ'tև_{Bg}պ't_{Bg}ջ'tx3a·0's s2i0zMYӄ96Miӄ97Myӄ97M¼iM0o0yӄ)̛&La40a S}N<τ̛&L}r|MXvOŪ{Bg},V:3 XzN,M{B'=KSЉwOD;=s=ibN&5MX „Ŵ0&c^` ya1/L0 Ƽ0&„ͼ0a7sNҤ{BK ,Mں'T4iPҤ{BK ~&x( 23Mɤi Y &d4A& $*y̛&0o ¼i "̛&0o ¼i߄ "}?MD_['T1 .*ؙzJ}uO׉ZJ}uOWZJ}uOԗzʚ^C&, IazPӄŬ0a1,LXL c^` ya1/L0 Ƽ0&c^` x=gg~M 4p*mP/UJ}רuO`i*Xz =wO`i*X{B Ls„ä0oxM8ep&& AM„ð00-L8 ya3/Lp μ0&8g^ ya3/L{Ng~M 8Mք 5lL{B ;SPԻ'԰4 5,M{B7=KSЍwODz3as {0iǃzM؃Yӄ=6Mؓiӄ=7Mؓyӄ=7Mؓyӄ=7Mؓyӄ=7Mؓyӄ-̛&la4a [}z [7M'kc}&ڙ vg?v-Mk®o&7Nji 4ӄ~ϱmG[}(eN&5MX „Ŵ0a1.LX „ż0a1/L0 Ƽ0&c^` yag~M0 8Mh gnA&[9S埽&c?ӄv gAL=ߟiB;3M{4 Ls„ä0}SHiS H)| =Ł@j8X/ՋI@J8P/Ӌ@*{&61ILa~C.'5&7}K,i݆8m odDTݴuo2ZwwӺ7>:SuMoBZfGʔ].ڛS,wպ7W1ʹMsof}vLAlܿs֕ݿk5;f]ӛ߿[=IDheuMoY;ֹM{&{~IoxswÛ㿳{MͿa8ϼ 3ygn2ڙcTȱVxu.xu0xu2xu4xu6xu6xu6xu6xu6xu6:rl 9Ά[gCmq7ِc,f u, =m'Ա0 u, {B{CPк'Ա= u,{B;DPίv#-3}>ćTX"D!"؇C!Jd%}vD(o'J܉ wDĝ(q'J%r :P.RXG{BW:6=uOc'iXJZ:=wOhɯ=ݠ z ˠ`DAAĘAADAIDAIDAljLИDAIDAI{LA! z'=dP|uOh`aiXYZͽ{BKKҺ'4 -{BC 2[]AWCЕ3J"D}#A_D/DQ"(E"J}%nDQ"Ft#J8t,4=m'4T=uOh`iXhZ=uOh`ݠofˠoC!3C!F$~A?DDQ"N%D;Q"N% } % :66Sg{BLР_t,4{B MBӺ'4д ,4{b1`/k A_c 1}A7k bA_c (oטDy$5&Qޠ1}I7kLA_c (oטDyƌ'dCd/kQޠ!/k`5Tg{b{b ,4{b ,4{b ,4{b ,4{b ,4{b ,4{b U~te ć+fЕt%D}#A_D/DQ"(E"J}%A7DЍ(t'd!t#J8tl4XLX~?SkԯhZK=FuOQik/jZ=FwO7oD7"AfE"iøa^0/?̋μ0 8g^H g~=p8MhĹk{b4&I{bPuO RX>\jkK{bwOg5aL`4a0 s0l0Ӧ s0n0 s0o0' s2o0' s2o0' s2o0' s2o0ωg0yӄ)O >5X>5$uOwO,|Ekb3kb5kb75U7&C&(seRj aa2-LX „ż0a1/LX „ż0a1/LX c^`g~M0 8M҄515353545454545454QĚ۞7&2M 6„ YaaXp&ƅ yaa^p& yaa^ ya3/Lp 3&8r&`kBĚؘZ=f}պ'֬ZĚWX ӯ=f}պ'֬ϿzĚ^⡼&`4A 2k fMd0l i&`4A 27MɼiLMd2o y̛&d4A& 2ϛ 27Myr|Mh,'b=>%ؙz,M{b =KSXwO,Ի'`i%:7L}(eNL AMYa2,LP ʸ0a1/LX „ż0a1/LX „ż0a1/LX lc_ya=9N5{bImL=vXR;SXRKSXRKSXRKSXRKSXRKSXRKSXׄP 9afR4a3+L8 „ø00/L8 „ü00/L8 g^ ya뛿̯ μ0 ؚ=SXuO,Ի'`i ={b =&LԻ'`i%q7&C&s :4M^t0kaL&`4A :7MiMt2oy̛&d4A' :7MйgyO K1ؙZRL{bi}uO,=RԺ'wZrR~&>U ʤ0A4A&(eZ yab^&, yab^&, yab^` qP_8mXZ_6]=KSXwO,Ի'biK4X{b L6s„ͤ0a?ifV& qaa^p& yaa^p& ya3/Lp .os_ya?9N5{b)6=;SXwO,Ի'biK4XzRk0KuO,5!4!& k<ׄ55MXaӄ56MXqӄ57MXyӄ57MXy|['̛֚&ɼiš̛&ɼiš̛&ios3LXyӄ5_&tOuOuOwOwOwOwOwOwO'֒x3aCyMXʜiR& ʬ0A&(e\ yab^&, yab^&, ya79̯ Ƽ0 ؚ=6=v=v======&XkׄP 9afR4a3+L 6„ø00/L8 „ü00/L8 „ü00/Lp >}qyg^OӄwvOU+=V}uO,M{b-,M{b-,M{b-,M{b-R&=oxM2M 0!k fMl0l`i&`4 67Mi Ml0o`y̛&d4& 6כ{ 67M`ؚ,'acX 34YXZ2,Mֺ'ai= KeXwO,3䡼&2g`ʤi~W˔Ya2,LP ʸ0A&(e^&, yab^&, ya:os_{r&`kB2lL{bv= ;SXGS2,M{bY=f[XVuO,ֻ'5a?ifN&5M 6„ʹ0a3.L8 „ü00/L8 „ü00/L8 o|g^Oӄo=6XV;SuO,uO,uO,uO,uO,uO,uO,wO,veB9&lM;'֩'֩'֩uOSKSX=N-M{bZZ:4u=Ƕ~&y( G3M8¤ipYӄ ia2.LP ʼ0A&(e^&, yab^&,{w5a1/LXOӄv w-?v 7&[Tg o&kqA\=8Mh!4M L6s„ͤ0a?ifV&l qaf^& yaa^p& yaa^p&w qP[ߟ5v4ojׄZLji3M4?ӄZLji$MyemeB0)L5Mf 0!6Mw~MߟiB]kBݹkB]____P7ׄzv9 uoμiB]??5'V]n_Uׯ{Ī׽{b=vXuwO:ݻ'Vծ`naanbb.cՎccNdծdd.eneծee.fnfծff.gngծgg]s`k Lnm`7(o L{~ʇFr;Ō]T"@wC4b@wA Ż(]H.$wR=Ł@ROq 8SH)$RyNz4@)Sq'w:'7mvM[f}a&G&0Sц{н{b}n62љހT ʌFBJ!ɐhuN3QkLo^֘~'olΖZczsݳ&7G#5kLozctw˺%{œ42];d]/rZ/}9y}9NW;\Ûluo99NV;Xwwӛc|FqH1Moՠ9Vczsѐclȱv6X;r 9ΆkgC!ǫ!ǫ!ǫ!K9I 7ǫ!Nj9^}E'V`[XZ , {b=CXuOѺ'V`+HeM|Hf&Bz"hoD7Q"ܛ(M!J%~ ?DDQ"g?!9<1?DNjHvO.R+T #{b6=+IXuORҺ'V`+i+1nЃ2Atz A"DЃ F=AA1 t(om A1 t(omЯ26Qޠ{< I76&' +=aJuOR6 XYZ ,{=a[K랰uOһ'l݆0tBt7/SP a/6om!ޠPbAynCAWDЕ(t%J]AWDЕ(t%J}%A_>Dy|A_ :잰m'l` gZ ,4{=a M랰uOBӺ'l`6lݠeЍt#>}3`}! AĈoD7Q"(M&J}%~A?DDQ"(cOC6oQ"臓AF6T 3=aL랰uOBӺ'l`i6д XhZ ,4{† z0[=ACЃ3T\ABDЃ H=A̠A92>Qf :dMl3=aLuO>Ӻ'lbi6д XhZM,4{&=a M)¯} ݠO! ˠ =aS0_aQM! T̠O% TDЕ(t%J]AWDЕ(t%J]A_D{ߠ/D'56δ ꞰYi64{fuOجӴ =a~SӺ'l֯jzM os"Ƥ=ͬfX$3-̋oE7"yͼ`3/ 8 ü0/,8}=a^p 8{f 'l5>Oj6C=a>Wj6룥=a>\j6=a>`6ݟ7&C&s„`Rj aaB0-Lƅ 0!& 27Mi Md0o y̛&`4A0A?̛&|r|ML*'L0O{KQ0ZԻ'L 0fԻ'L F=a"y œi "5AYMD6Ma4AyQMD&(e^ ya2/LP ʼ0a7s|ׄż0a=9N4{S0Ժ'L3 ,M{KS0Ի'L4 ,M{KuOz`e` Ia=i1+L 6„͸0a3/L 6„ͼ0a3/L 6„ü00/L8 Yp&'i&tO`cj&ؙZI}պ'Lꃯ=aR} uOԧ_{¤>j&W054&„xPӄ`V iaB0.L 0!& :7MiMt0oy̛&os3Li'Ʋ{´> X'L3 S,M{KS0Ի'L4 S,M{KuOx3A塼&0g¤iʃzMPa4AaMT7M@owO* ̛&2/LP ʼ0A&(e^ 4}Y_„8Mք ژ{´v0uOԺ'Lkij4 ZZi-M{´=aj54&{PcV` 6„͸0a3/L 6„ͼ0a3/L 6„ͼ00/L8 g~M8 Γ4['L1 SL{;S0Ի'L4 S,M{KS0Ի'L4Q P Μ0&ă&„`XL qaB0/L 0!& k0o k0o k0o330a'|ѭ'lacj3 [ؙz*Q랰U_'j E{V}uOت [=ak KkL0iA&,a4a æ K6MX¸iM0oyӄ̛&,e^ ya2/LP ʼ0A}N9N5{w{mL{6v=aKSwOخֺ'llkﶵ zm^L9a1)L5M0f ư0&c^&l yaf^&l yaf^&x=g~M8 Γ4[vOخ'lTkgjkijkijkijkijkijki]7&C&8sgRj aaB0-Lƅ 0!&„`^ yaB0/LM`4 Mΐ79?`4'ׄ v5`gjv3 ;Xz,M{=aKSSZOԻ'g™5LLd4ȃzM8¬iM0mpqӄ#̛&a4 G7M8¼iQM2opya2/LP jos3&(}r&e잰Sw{N5 ;uרuOةF{N]6jvQ랰SZ,M{&Ʞyk=i1'L0& Ƭ0&c\` yaf^&l yaf^&l ya79̯ yayr&`kBlL{v=a;SwOԻ'`iv4 ;Xz,M=ayk?i3'Lp& ά0&8„`\ yaB0/L 0!&„`^̛&`4|?|0o550'5kgj4 ZZy-M{¼=a^KS0vӞ7LP^|2gI5YM\6Mpa4yM\7Mpa4yM\7Mpe4ya2/L>Ǟ5A&4]$'-HtO[=aގAVyY4 v'A0wOXݏ ;=auM'nJSaiꞰ.MV'{4uOX =auu'.OSiꞰ@MVW{5uOX] =au'.SSujꞰPMVW{Rw?ژVτڙt^jiꞰYݻ'V ս{xu_MV7{5uOX] =auԚ'ZSikꞰnMV{5uOX] ;=au隺'n]SյkꞰwMV{5uOX] =au'n_SkꞰ9fFτ~nτ:yMߟׄ:yM ߟׄ:yMM }τv _=կ &7&.ckB;{pMh5ׄv%4ׄv)_ڭkBͯ ^7&nf^kB&(]  PK!b>QKYUr>bmga/GML_LUT.mgaUT .z Nʂ NUxmˮ.Kr7>)  gHH -dQ s3KNsG؟߲ן//_o??S?_/_ng/o9_/S O~~x?_?/?? 'C/'PVCɡ'cJ< /F᧴+gRyZ~Z,T96#/UJ?/Uۺ(j3S?srq]ϱp.Uf/;BeFKB\e+cbO=eݫ.~jIeWVԕ jB ^Y}+WkEY+F[hrY4BbmN6ϰOqofͮ R Ad=vUПg gk)=]y:-j駥v =*?=|&դo֥3j)/F6/0vZlhi+^ijk`T^,^̃͟RF:]<*PUU<(UU_cЫzU K#Sjի֫z)/1lZlW^RzeƟz5"9+W-^مQUZ"1GXyUZK^WsSǟ_W9.WuCaЫ3K˟~ O'ֶ??j/m4k'<(kR;KhR:Jͪq5]Z͊ԬYu5k]BjVwk:k3Sjcmh/?ЬTnBHRS 1[xlͲY㜧bZ<*uYjAf%9vVpۘ~fYji%;UOO/?VuCUF~i?rJެӘP/B5\7%,^*Y$w5k]ǝ%4kifZfγҬ颕֬T.YKs!5kfKYk-UoA ,-iV -yP:T֬ŧUjhzn<,~ O;Jj񰳄fwu5k}4v ZK/?Ѭp.XNS3F=@}>5fŘ@M6CxiykX5fjV<(ukV[mTv4+ϺJGV_~YQRv ZQ/U֓._5kfqJjV~9RWϵ1YcCxYAjJݚyYZZ8fUV_~ZֳwK|lLfM<*9YYe4vi5k=6uNZbʾ7&|j<6]\ZqGY '񸫴.~2;JÚyQ֬*%|<ˬfKY)˧fM\rjV[|J֬`.^RjӬ Ӭ2>5y,wŸ Up R5~ OJKmKs<,fuxUZZ/y=ˣYasy4k=z.6qt.6qy.·RSkhuլKYʫYm}«Yi}f-f-fAyfݬYiY띐o>iV6&x5Z '\Z8)]ƫz3וѬuOׅѬ_#f H>ͪKs:YaHYͰ^GZבDݬs_Z1ocV~9GQfY>Yܧ}ui=YKsYGaבDX#e:GhבDaƄ~iL,˩ۖњ+Ic1 * P{HăšKi^(+ iT•-^qh,`R LʮXT•_p W.ƧpOi=_ڥ]x^2*Fd -jU֐L҄. ZY]cZd 0]*N&Z}6 ,kQbx#m &cTL̲[]?/{煺!*I:[VV!)-j",b^3 f=NDԨ*Y&3:[*::*6 N-)sGXYOoThjU*KG]*232*x˧uG[ ħyp?x[>[ydzkoIΰV) gB(AЬYUp V;d_譽d ]ȔW^]i*!# j*0QST Az[2wGx,5 O~}ig1Y{yv"|Th2#[ jJ !a%E"22p[CsAWl#V薵=ܹˣTM@oSc @)uʄU4Uma34eDujS;,uA_Mk p:*]n5wU T8D/d cU4MJ,z]cU4wUm980kg? U 794"\;A*ur;>e:JAR]65bgU/Xu}jn;4wvJh+Vn@o:!CsYϪ@pR'xhUXa ;k#B͠|yӧxS6K >FUVsX1 !8rgT]7olTQuw:pɍ NDsdN:Y=2S'Ċn uh)'u"[A*uy dR((w4ty)'+YZX%VKY; zk<邘 sj{7yEPfl@@2uIzXQ۳fӜOqp} KU*}1gg^H7V?N+z5wg4wx~4YLeg{gLvsxܶ˳_yo^&{ ABt=m.Og+R/osm6NsNseOFw/ZHZAs8iew1Z:o&~o[L4{{ܱ˳߾ͭޟ4n)*kjn. e\PA[ͫ D޻@|o*!~>%t:AsA O\C;['&=Қ@Z筓MCg7iMCYu]ǕUYcUkubDԵ⚴ j *t0NX*u}Xqe#ծ"@b]P*{K)u"TvQڨ Ueq£QlT>#_b"=Ay{<-ƃ__lA`WkctպTDo%j`f+VUA>GAk`BK'?K'?O" *goFi,QTO}ԫA!sc##y*kk|QL(ul -$:Jn$ȄR{I1n`VJ(up#GڨVZ= ?$5]5sS`A|@(˼neT+ M"Pp)e1<*)e&:g {Jm*)5&gQ*`v-  gQP4w:~q6ۀ]6bv@/z5w6yJ<)ֲx vTUjXφdRd2Ψ**eTBLf(5{X7cB]3X5mDGZ=VEsjnKãrĶV;by;n0btv}dH6ct˦54^cQE~Ykx7 صqwG Z(Ur@ُ£ GUYiGFMyCL]ui[\SѠZ2q&<Ŗly/x ;@sn?.x;N8:#:|e=&%mƮ o6ہ]]!v/v]V?RWs ++<77_D`&l욁]˽=h@4wdd|;ҳA\;橆]4Z\Xxyi.\&2ʎD˳ǫ t5w*~9]#88!ص۳3g6vT+<հ+ڔ߿X͵6J䱏Ws 1_ͅg\"o։Lg.&:X2/X},m?? Ҝy\iۂLI76K?z{hErܺz݁l wx^3FlEdq[v-upkƲ5m~L;ru[~dpY7$KIU,q8%9JU=lvSr+~Sg]w߻P>=1o}J֓mq\տr(jeWς6O |vm$)]sQW9D!ڴ-RGP=RG`IyJr)O/ʦ,uǂ ޛߤSrIJ\P"][~eZ[7uCk1֜GnT^U;F @wĤ}=C6g9Qy)Q.yljKr<҃gWN "F;,Mnq^5ae.G{l ^o ;,9 ۬5H{tT^GiQzllEH*KL`ZloW(~v߳C O,XHskYr tw3K˲3KYV~fq]4{}^HY/UZH2v9->odc*f!yd紫W7Rꧩ-OH켇,%O+7l˕Mwnnr{3X6u_}J"ҢGV%*@f7,1fϋHyEk6t CךAg~q.p߲P?a7S O,\mߠ_wLav5d8fuQUߙj3\٥%ܪa\YUHI 3OIB}qWqo(ԇij*~B}*)$>uj'rb;^Lغ*k[Or,ײ]bhv+1iGՕzJ˲@(1]Ԏ,t<%\i-@Ybqz>oL& `?co惝XapD9qAo32[j,Bp=giic"hS8,]=ђDž-ylRk߫6+-z(16c}8Ioqd7@HfW"̮^&Ӛah6ne3"I4y>;i# \I:K3ώ&=$%] #WISW7-Yr,-4W۸@04{ OG\ώ.g O,yԫ|9?[f #&@<s۴nٲA%6M)l4ƙx 4;>isOg}ڧ%㔖8|j **y9?;2:*yl#G]A#&49g6->X$_6m=W̖^!;">c *Y1@VQwFB\Jy}m!>[է3*]ވ2swQnw3)►FKׇsivy[L7wÝ59'"䇗w'EF "RFL( K6%`h}w vwyVE:38BQΎa{ 2Q ,8,#uoچ2G[+ #JSo4S"grAӥ;ˉ$mϖ.ϖE6hSLSi; 6,<=RGF*u!`4RGG'pZ0CZy1s-[ }OK Q$Nl6[wfW$f6l(t=I$˰-1ݱ--$m٦nÑC~B45J ݇m淬NMƝ֨j62^\x4{%GdkvF֫QņBJy$ܹhȆN"-nfJLd2ug#nɣ =ߪn8Fy (O}Fg* 5zBݶ\U5#'Vbh6b2X# Ȍ<@ȍ<0Phw12`4;7e4; ۼ%`X>oɃ?ɋ*XOYrBvywYw[3X7J6we۽ 'n7ذ TcI/3*1*brg%$f#{V*ܹHLD@H<`^dLC y9TNSz RukSudV޴+)#y&udA`7KtSUpj$['kGю "Vpf#VH"h6rl% We[~ubԄh~z)H!Fw`05Y7O1l㘄-QuSs:.[- E9%Xkp9ws0$ "2p(9>+~*}|߲>(T |=$&@qldr'=( \ EA^/񤢀Jw, qtpI&&y( ώG>%_|c{l7[ƣ$)io\qeplb43*M9;O+uqgӥQwvᢈ_:^K/Iy}XB~ B~]ވ23R~](m(/j.9]>Qͮ_ÝmzҼ|R-n/t7E de/%Yrt Y7>^[r)]bnU7< "j"lX2( Ũ= ^DoIXxʃ'Ym) iO]E/I/!!^n9kȆ`XH;IXahW/S-\d*G\V]:Adm:0 %3ϟ𚅥zl&2,oy(dTn[NU#_sO)?5OKO]Ja3ȸFh'ʪ̘pLA,$ktvE:IfX8\N#;gIl^PgEp)) \pr8H Q[5'5GqIK'w'\5$0 0ORU,u8IwFjQņ ܥ%\}nj ٘$u2w;ݼ-S/ ySQ>.Xv$= 7< rQ$9\jI.\.u8I\bIn.eUf",yaM+G$ydB#,y`pg Kjvw0CjvV:4<׸-<Wr.'\\p,s(\\prɣ \.-$m.^%`,s9!|QK~z1I #߳P3lurgkQr܏7\.e\߉7sq9;,xYr7 N"⵹73{]3xjzʱU#U@EgN޸TH ɋNq :E:˴wk=9{}q<:2zl:3\j.<^l2'`Ą6s1y%5"syڔzQ\zp,s4ԋ,E8Jvs9%!}&b LI0gPf I']O}J֫{⟴ў<] ̦fa$& %Wˋt(rust(ܶ\n.82G# \^]Ed+ !N$k{-yķq͓ <ۂѳ9Rb(,ExFfđD <|kX\$Er)Q^Bu%.:U.RG/].uA~ FQSoRI2zgC%8RjT=a(dud(s1d6!ʒG E(vHBLW_w"y8J/qGdcѱ_"d~{gӨ~GP1wygW;Bs;Br㎐1ll'BxT"<ܞxӦ)=[ͳK _̿21LcMU(egDګgf6 \yu)4IAF³䑜 8 \c·6 >[Yx䁍Scls16Qc˧q9Yhx&FKsf/,T y)5963lm=NJx8<,qṂkRe5{q9)Ƴ57jq/{ώ\\sf/<.[-|b,p8/?1y} <7a%%ŲK U PZlvyCʘtlJxF?GRxF~ITxgwV{"Ў[ϊ,Hx6 d vs# Lwk9nDC/YYio/gψxZR?y C ܚ0cmʣe/jח*XwZ!6}*O\fG3(-E;HFn)יw$ reu 0m=3+ Gr7: sQk2#^ԥ϶^xb$ {aI%CdFL" %׈x80z)7J Mo 0a<IewKAhGr2Lwy87ԯтG{gݠd\Te#FRcxb%FǶKMpXI%F^L'-"Q28b>܋f#YHh6IYMZb,7gC( F6C$9o{9!|<[_'u)7K3͒d˥F˥ƍ^.uda%FJECLy%s#")^p#&# وx<u.y' ӺgM~z@rHԇ@ijh~zC !pird϶`xb˹Qr^Ո9rQ(9\jJ^.y$a˥E*yTaM(MFɜP:!28@$9azei.` \&ĈXo}H!1V'^jV6)\h*^.5 %'˫ĸQ% 8,{y<%^%,6rɣ kB̘Fk ]_ hofO)xfW=x#ظPr.܋rI(Ys1r`E].=D.愒˳QTvw$Qņ5utPBɜ㈌gB$LUȩ|ZOx>uzlFg7PxVd̦zXhx*ۺ^KEG2ҡPrre% 8,wy8.8а%M9HY;5['̷qC <ۂ9Tb$J ǂgF29̮lL`:0Xhx˲K2+gQ˩^OC(G/ ^.u$_ߠz i5[pMKC r䈌g;#MKs|l7[iTlS>1e$O<7(_WgLqDdH&.\>=KvuC2.yRUlCy5_FI {$C.ߔߛ$ˈK7PWx@7x\dBȾ "5/f1kE]WI*%o|ߪn\=^S&@>ٺ0Z^ؗ7j)G&߂;T^b bX ɹs/8E8 "Yǹ g&8#zdCx!Y?|;J CJ |g!`7W'tgw|^Y#^u[碴, G+{>1hr.Q咚I#FԶQƌJpʽ Gd\md%C\KfPrvwt(2b$qD/s0i80'(qq6 <#8$9.9K g; nt郸{C <ۂ%^.1 %m/.uI2yg[0y>jvx儒~Ԩ܋\L(l{(YriQ(n{(Gf[x??5\ )~3ɑF)6̶z>j6Fqqn,eda=tfc܋唇Prs{܋*yDA`KIeG<аCNe/<$erpOrBS&K@d(g=SFƳUF,y$Q`y!1 %1 i5[hvx˲gCc%Gn/o~I;V 'lO]<, F'EЌRQ(ń- 3JFUbJfT<2%l`bRz YsqR$p9%p9Kϙ\j Er1\x˻q9˫q}G3JqṆgK?w d<vAƳqJw 2%;Du!23]*OiWϘxye<'t!e Sd<!eRdoU4ύ] %2&' iv5fÍP~QrTRJf?2 8f#Y*F*- 1咣u˥&8,{(rs{(ܷ\*^.- %3*ϒGVY3JQņ9c5tP$ɜC{ȰGy1sՖ~yVS)&rp98)^.9 ^.9ۄ {9 ٌR1\x3J%x9(:2%;ϒDž!(.~:hW ;z+O/&Ӽxsp9K$G;&{xȘ\Cd`/< ӌRq'Dϔ/!2e_y)%DF/Vx4b뿪xv432{31 ?=<#ؤSŮޔ@f2Mǘ53E|SsD:02d<'~xzzO$O2ՋҊio{kf㊠qr͌b'Q~Qr5fq5A2咚PrHmBm˩D2YHÜ9ڃ$(YsG4Q5{I$sh*T9RpA)#إ w=˞O پ-w X}䢛'u9Tj(Y#JFaD(̤x@ɣzy`wlʜD8,{y<ʴ ydawQ^^%cg_e<7魏w,pA.<8ߩDe/<oXOsU$'ԯoYw]LRlm|b˹r/%G\L(yn{9Q2gV(3*ϒd(G EƳQĀ1M^^ͮ~^?Zxn 5\P,~B>!mf/Oc˥(8,{܋r(Ya/<(ҢPeaFi<g##JQhFƳI Y(0v'Q sFi~1^AԄ5\0-멧 wI@IIr,F3W Kx:nnX͖<.r6\+^x$Ѯ/B^_ZdCd|dgvAq YCd,y\!2Q*1>!2x<ddOX=w sa|pm\<㷶9槶oܰQ/oE {xKX\4<_@ÝX]uV:jeΫRߕwdSe4<_Kr#|#ַ,c5i#"k|IWGU/gQ#H͌W]~$ƪ˯A?R#rԦ2yhGs*O&[Nג_@ŬAZXe(^@I^r˵yϐ\\lŴlDž^Ny9\s #$M9T hF?1Tr lsYr|Bd s~nٔ"3~ܞ}Ș\Cd`/<1\Cd`/<~ %DF|~5CM;Db)w 2m YʸCdB{#2%;D&T0,*y!2@ָCd Jw 0q^i@/!2_Bdbda, ๝ҒsC6asD|\4<˃"L4z.t._sTm!_j|ᴱOm_0VOTc}"ƝˢiߛQ|/aUyg֙.>]ux;mOU5|DsOaV !^ļ.z]yGs|޹[ )ȂSYE^p0t}ꖽʭ Y?]R[kEo|&,WDŽo\K[|K@~-1k^g]}}ݫOcrU@10WHUWv~ G^k1 r ׊)nwyKo%m#ׯ39Kfw81jƫ=>~HD)q&!鰆k*3+"_qcDsIO x-I6rOYX%g,oYq/Y^^jxjI6C` w7#I`oOFb`XңFa(-G*sD"0`(Bx[IL/ )v/Y_d9޲7k\~[^uO܋y>Of)*#oF9_ޯ83JY֌% aFiGsIO0R%!-'O{C1r,`k` MynOyrr2Gx|z/QyN)kH#0-sHH5<[f{k`ythsJWa`ˏU<vykotXE/9!!֐S֐V%2:%2}>˽.%" RNhyW#s{ʀ/?Z$_>%{S֐6%Oמ41_gMWQςcHi:r$֐#GW|3:fϋFWO=b$ m[{|/_~FUK<޲]ý5]S(תg^JlgU5ȑtXCJ5Qe lyWdV|ynoy53$+b)_䐿|8ǽ5]cNע(yK5HS"?4ȑԐңF94 )=Z{Myn yhvy~D;^%/]қB]=~WOϢF/O_YMYLl )=b͎y.R:\?4ЭlАO)M ~Bn0 H8y#뜦v.m iR ~j :#H&~Nr{ syg6z~ƄN^0zTIB *omk5HߟTn9jV3p1-̧r|T|޹[̿)A?bRrR2-'t=#e{VGD߯<1{6q t/iuK@~-1k71걵{x5F HUŌeeQgn/o9K IH^>]hH|{cϿr/z(F7D"b#)fRfC/߫e!,yeG|2q/|w1O )=rdUCJI5\ϜX8q#FC1-K2+<~bSl2vOYZ%8!O=<ԏ&<e|/icL z4t/9|n1ߢ~&I<<47`~H:,#15lSJ#1-)K2,)%>e4C½$sʀ^ w}kk,ת;hsJUU`W#ȑe̯Tn0)kJ"鰦q/94tls(HyNӚ]@%3:ǔEYGԏ&ɂ<f`~䨲 g1n0o-`~H:,Ѣ2{%O)fW)_Kr#߲}9Zg9z Zr܋)CwfafF:fwe0nt ^qhQe{`>S Amga/UTIz NUxPKJ>& 7mga/mgaformatnotesUT] NUxPKjW>;-g\v smga/3dbypass.m3dUTg NUxPKf_>I-5)K  amga/S-curve_for_CineStyle.mgaUTMUxPK!b>QKYUr>b mga/GML_LUT.mgaUT.z NUxPKy-{opencolorio-1.1.0~dfsg0.orig/testdata/csp.zip0000644000175000017500000132612613223553423017423 0ustar mfvmfvPK *>csp/UT 8M^y NUxPK*>x@ ?Ȁ csp/gamma22.cspUT 8Mw*NUx͎[yE_*!$h!Q0Gπ=ֻ]]1Ճ-je ;?~/____v|z__緿??9˯ߚ__ho۷?~?_k_K_o/?~mƯ߿Kӟ߿~_~^ԟo?~7oS}6Kog_?y鳯ӗ4}+%M_AWKN_Aӗ4}N_A/i :}N_Aӗ4}N_AW?~JZ}It/%M_KKۗ4}Iӗ4}A/i/in_%M_%M_ݾKK?h##A/i :}IW+tW+%M_AWKN_AW+%M_AW+tz"9Z}It/%M_KKۗ4}Iӗ4}A/i/in_%M_%M_ݾKK?hyᳯӗ4}vi :}IW+tW+%M_AWKN_AW+%M_AW+tz"_[}It/%M_KKۗ4}Iӗ4}A/i/in_%M_%M_ݾKK?hyӗ4}+;KH+tW+%M_AWKN_AW+%M_AW+tz"0Z}It/%M_KKۗ4}Iӗ4}A/i/in_%M_%M_ݾKK?~u%M_Kۗ4}A/i/in_%M_ݾK }Iӗ4}Iӗ4}It/i/i,K҅՗4}A/in_ݾK }Iӗ4}It/i/%M_%M_%M_KKK> :}IWKN_t :}?i :}N_t :}+t :}N_t :}N_A,K"՗4}A/in_ݾK }Iӗ4}It/i/%M_%M_%M_KKK.+QW_ݾ }It/i/%M_%M_KKۗ4}Iӗ4}Iӗ4}A/i/i/iz"/^}It/%M_KKۗ4}Iӗ4}A/i/in_%M_%M_ݾKK?hLg_A/i :}IWKN_Aӗ4}N_Ak!#AWKN_AW+%M_AW+tz"?X/%M_Kۗ4}Iӗ4}A/i/in_%M_ݾKK }Iӗ4}Iӗ4}ICѥ՗4}A/in_ݾK }Iӗ4}It/i/%M_%M_%M_KKK.폸 }It/%M_%M_KKۗ4}Iӗ4}A/i/i/in_%M_%M_E4|Nӗ4}+%M_AWKN_Aӗ4}N_A.#AW+tW+t :}g]7[X}It/%M_KKۗ4}Iӗ4}A/i/in_%M_%M_ݾKK?ҾcKۗ4}A/in_%M_ݾK }Iӗ4}It/i/i/%M_%M_%M_}YDmV_ݾ }It/i/%M_%M_KKۗ4}Iӗ4}Iӗ4}A/i/i/iz"/%M_Kۗ4}Iӗ4}A/i/in_%M_ݾKK }Iӗ4}Iӗ4}ICѥ}՗4}A/in_ݾK }Iӗ4}It/i/%M_%M_%M_KKK8~tӗ4}+t :}IW+tW+%M_AW+t3y$t :}N_/}YDPW_ݾ }It/i/%M_%M_KKۗ4}Iӗ4}Iӗ4}A/i/i/iz"'/%M_Kۗ4}Iӗ4}A/i/in_%M_ݾKK }Iӗ4}Iӗ4}ICѥ}S՗4}A/in_ݾK }Iӗ4}It/i/%M_%M_%M_KKK.;ۯ }It/%M_%M_KKۗ4}Iӗ4}A/i/i/in_%M_%M_EtiC }It/%M_%M_KKۗ4}Iӗ4}A/i/i/in_%M_%M_EX}%}U~WяJ+髯}%}WW_E?J+髯~WW_I_}%}WяJ+髯ڑ: b˾ +/ b˾ +/ b˾ +/ b˾ So/Kb+$/Kb+$/Kb+$/Kb+85W_}e_AW_}e_AW_}e_AW_}e__FX}IE__їW%}IE__їW%}IE__їW%}IE__їWũ絸Ͼ +/ b˾ +/ b˾ +/ b˾ +/ԥKb+$/Kb+$/Kb+$/Kb+$/N] $/Kb+$/Kb+$/Kb+$/Kb+ԥKb+$/Kb+$/Kb+$/Kb+$/N ='|}e_AW_}e_AW_}e_AW_}e_Aٗ.|V__їW%}IE__їW%}IE__їW%}IE__їW%}qҾRn%}IE__їW%}IE__їW%}IE__їW%}IE__.MW__їW%}IE__їW%}IE__їW%}IE__їW%}qjf +/ b˾ +/ b˾ +/ b˾ +/ b˾W_}e_AW_}e_AW_}e_AW_}e_? $/Kb+$/Kb+$/Kb+$/SV__їW%}IE__їW%}IE__їW%}IE__їW%}qҾ-Kb+$/Kb+$/Kb+$/Kb+$/N]Y}IE__їW%}IE__їW%}IE__їW%}IE__їWũKY/Kb+$/Kb+$/Kb+$/Kb+85e +/ b˾ +/ b˾ +/ b˾ +/ b˾:_C!א_C u(rkC5א_C!rk!א_C 5א___}d_AW_}E_AW_}E_AW_}E_AW_}y)#ݗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}I.> :9Rї_%}E_RW_%}E_RW_}IE_AW_R~rY}I_}Ae__}I_%e_Pٗ}I_%e__Pg_A/)K/b/)+/b/)+/ r +/z)k/( /b˾$ //(Kr˾///(Kr˾$終ϾN_Rї_%}E_RW_%}E_RW_}IE_AW_R~m%M_P_}I_%e_Pٗ}Ae__%e_Pٗ}ICe_U՗4}Ae_P_%e_Pٗ}Ae__}Iٗ}Ae__%e_}~V_}Ae_Pٗ}Ae__}I_%e__}Iٗ}=_WK/b K/ r K/ r/)+/ r^/! /b˾//b˾$ //(Kr˾$ ///z(k_ɳ/( /b˾$ //(Kr˾///(Kr˾$}9K/( //(Kr˾//b˾$Kr˾//rkJ? :}IE_Rї_}IE_Aї_}IE_AW_%}E_AKe_՗4}Ae_P_%e_Pٗ}Ae__}Iٗ}Ae__%e_}O7 /b˾//b˾$ //(Kr˾$ ///z(kDh%M_P_}I_%e_Pٗ}Ae__%e_Pٗ}ICE_> :}IE_Rї_}IE_Aї_}IE_AW_%}E_AKe_ê/ib˾/(Kr˾//b˾$ ///b˾$Kr˾/ڟ^}I_}Ae__}I_%e_Pٗ}I_%e__P׾mK/( //(Kr˾//b˾$Kr˾//r˾GV_}Ae_Pٗ}Ae__}I_%e__}Iٗ}=_o/( /b˾$ //(Kr˾///(Kr˾$.X}/)K/ r K/ r +/b }+՗4}Ae_P_%e_Pٗ}Ae__}Iٗ}Ae__%e_}1 /b˾//b˾$ //(Kr˾$ ///z(kt%M_P_}I_%e_Pٗ}Ae__%e_Pٗ}ICe_/ib˾/(Kr˾//b˾$ ///b˾$Kr˾/ڷ^}I_}Ae__}I_%e_Pٗ}I_%e__P=}qWW_EU_O_EWQ=}%U_O_I=}W_O_I=}W_O_I=}IW _AKr_C]bkK]b_C]b_r_א_%.u!.uK]b_?<|t// Kr˾// b˾$+/ b˾$+/ b˾^$}ILt__W%}AE__W%}AE__їW}IE__Ce_wWN}e_AW_}e_AW_}e_AW_}e_W_ Kb+$/Kb+$/Kb+$/Kb+ WK +/ b˾ +/ b˾ +/ b˾ Sa/in__їW%}IE__їW%}IE__їW%}IE__їWũwϾN_}e_AW_}e_AW_}e_AW_}e__X}It$/Kb+$/Kb+$/Kb+$/N]گ }IE__їW%}IE__їW%}IE__їW%}IE__.헦W_ݾ$/Kb+$/Kb+$/Kb+$/SC;}+/ b˾ +/ b˾ +/ b˾ +/ b˾ :}IW_}e_AW_}e_AW_}e_AW_}yҾpt%M_Kb+$/Kb+$/Kb+$/Kb+8ui_}/%}IE__їW%}IE__їW%}IE__їW%}IE_?°/%}IE__їW%}IE__їW%}IE__їW%}IE_z>WK +/ b˾ +/ b˾ +/ b˾ SV_ݾ$/Kb+$/Kb+$/Kb+$/S'RW_ݾ$/Kb+$/Kb+$/Kb+$/SǺW_ݾ$/Kb+$/Kb+$/Kb+$/SV_ݾ$/Kb+$/Kb+$/Kb+$/S FV_ݾ$/Kb+$/Kb+$/Kb+$/SC]z> cCW_}e_AW_}e_AW_}e_AW_}yҾKۗW%}IE__їW%}IE__їW%}IE__їW%}qҾ_KۗW%}IE__їW%}IE__їW%}IE__їW%}qҾKۗW%}IE__їW%}IE__їW%}IE__їW%}qҾsKۗW%}IE__їW%}IE__їW%}IE__їW%}qҾKb+$/Kb+$/Kb+$/Kb+$/N }Jb+$޾zJb+$޾zJb+$޾zJb+$޾:4_A!א_C u(rkC5א_C!rk!א_C 5א___<9|}E_AW_}E_AW_}E_AW_}E_Aї.I՗}I_}I_%e_Pٗ}Ae__%e_Pٗ}ICE_Ӆ}E_A/)K/ r K/ r +/b //#ݗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}qj+/ :Rї_}IE_Aї_}IE_AW_%}E_AKe_ib%e_}Ae__}I_%e_Pٗ}I_%e__Pg_AWK/b/)+/b/)+/ r +/z)k²/ib˾//b˾$ //(Kr˾$ ///z(kֿ/ib˾//b˾$ //(Kr˾$ ///z(kt/ib˾//b˾$ //(Kr˾$ ///z(y +%}IE_Aї_}IE_Aї_}E_RW_}_Y}Iٗ4}Ae_Pٗ}Ae__}I_%e__}Iٗ}=_ ]}Iٗ4}Ae_Pٗ}Ae__}I_%e__}Iٗ}=_/'X}Iٗ4}Ae_Pٗ}Ae__}I_%e__}Iٗ}=_\W_tb K/ r K/ r/)+/ r^/$K/(Kr˾//b˾$ ///b˾$Kr˾/W$K/(Kr˾//b˾$ ///b˾$Kr˾/ڗX$K/(Kr˾//b˾$ ///b˾$Kr˾/z>W_tb K/ r K/ r/)+/ r^/Y}Iٗ4}Ae_Pٗ}Ae__}I_%e__}Iٗ}=_?1/ib˾//b˾$ //(Kr˾$ ///z(kt%e_}Ae__}I_%e_Pٗ}I_%e__PKr˾ /b˾$ //(Kr˾///(Kr˾$}՗}I_}I_%e_Pٗ}Ae__%e_Pٗ}ICE_]D> rN_Rї_}IE_Aї_}IE_AW_%}E_AKe_V b˾N_}e_AW_}e_AW_}e_AW_}y~y%}It$/Kb+$/Kb+$/Kb+8uiS }IE__їW%}IE__їW%}IE__їW%}IE_\}IE_ݾ$/Kb+$/Kb+$/Kb+$/N = |}+/ b˾ +/ b˾ +/ b˾ +/ԥ}Kb+/%}IE__їW%}IE__їW%}IE__їW%}qҾzm%}It$/Kb+$/Kb+$/Kb+8ui_ }IE__їW%}IE__їW%}IE__їW%}IE_z+/ :}IW_}e_AW_}e_AW_}e_AW_K/KۗW%}IE__їW%}IE__їW%}IE__їWũK=/KۗW%}IE__їW%}IE__їW%}IE__їWũKcq/KۗW%}IE__їW%}IE__їW%}IE__їWũK/KۗW%}IE__їW%}IE__їW%}IE__їWũKګ/KۗW%}IE__їW%}IE__їW%}IE__їWũ.}e_Aslh b˾ +/ b˾ +/ b˾ +/ b˾q%}IE__їW%}IE__їW%}IE__їW%}IE__~ }%W_o_I}%W_o_I}%W_o_I}%W_o_ujW_bkCtrk!א_C u(W_C!rk!א_C 5א___< +/ :}IE_Aї_}IE_Aї_}E_RW_}_o)///(Kr˾//b˾$ ///b˾$Kr˾/zv> rӗ_}IE_Aї_}IE_AW_%}E_AKe_{d%e__%M_Pٗ}Ae__}I_%e__}Iٗ}=_5}E_A/)+/b/)+/b K/ rr˾ؾ$Kr˾H%e__%e__%M__}Iٗ}Ae__%e_}=߫}E_AWwb/)+/b/)+/ r +/z)k///(Kr˾//b˾$ ///b˾$Kr˾/?5$Kr˾ //(Kr˾//b˾$Kr˾//r˾///ib˾$ //(Kr˾///(Kr˾$Ͼ +%}E_RW_%}E_RW_}IE_AW_R~l%e__%M_Pٗ}Ae__}I_%e__}Iٗ}=__I^}Iٗ}I_%e_Pٗ}Ae__}Iٗ}Ae__%e_}cV__%e_}I_%e_Pٗ}Ae__%e_Pٗ}ICE_{}E_AWK/ r K/ r +/b _ׅ///ib˾$ //(Kr˾///(Kr˾$}uKr˾$K//b˾$ //(Kr˾$ ///z(k_///(Kr˾//b˾$ ///b˾$Kr˾/z+/ rN_RW_%}E_RW_%}E_Aї_}E_/}틥W__%e_}I_%e_Pٗ}Ae__%e_Pٗ}ICe_///ib˾$ //(Kr˾///(Kr˾$՗}Iٗ4}Ae__}I_%e_Pٗ}I_%e__PKr˾$K//b˾$ //(Kr˾$ ///z(kt%e__%M_Pٗ}Ae__}I_%e__}Iٗ}=_| +/ :}IE_Aї_}IE_Aї_}E_RW_}_oe///(Kr˾//b˾$ ///b˾$Kr˾/Y}Iٗ}I_%e_Pٗ}Ae__}Iٗ}Ae__%e_}ꬾ$Kr˾ //(Kr˾//b˾$Kr˾//r˾V__%e_}I_%e_Pٗ}Ae__%e_Pٗ}ICe_n///ib˾$ //(Kr˾///(Kr˾$z$zJ(z*$b+zJr+zJr+/)x| bkK u<I]b_r_א_W_r_%.5%.uK]bלG~}e_A// b˾$+/ Kr˾ Kr˾ -W__їW%M_Kb+$/K$/Kb+ /Kb+zog_AW_t +/ b˾W_%e_AW_%e_AW_RE_{|a%}IE_ݾ$/Kb+Kb+$/ r+$j˾Ͼ +%M_AW_}e_A Kr˾ Kr˾ ηq%}IE_ݾ$/Kb+_/Kb+$/Kb+8}e_AWwξ +/ b˾N_Aٗ}e_Aٗ}e_AK}o՗W%}ItHE__їW%}IӗW}IE__W%}IE_WV_}IE__ї4}A/Kb+$/i /Kb+$/F/Kb+/%}IE__їW%M__W%}IE__їW%}=T_~W_}+/ b˾ +}IW_}IW_}T_%}%}IE_ݾ$/Kb+Kb+$/ r+$j+گt$/KۗW%}IE__ї4}IE__їW%}AE__їWPE_՗W%}It$/Kb+/ r+$/Kb+/zs+/ b˾N_}e_AW_t b˾$+/ b˾$+/ b˾^kq$/in__їW%}IE_%}AE__їW}IE__C}wW__їW%M_Kb+$/K$/Kb+ /Kb+z} Kb+ }IE__їW%}IӗW}IE__W%}IE_}=ס}}e_A/i b˾ +/ :}e__}e__}e_/W/\}IE__ї4}A/Kb+$/i /Kb+$/ѫ/Kb+/%}IE__їW%M__W%}IE__їW%}=T_XKb+ }IE__їW%}IӗW}IE__W%}IE_W?$/in__їW%}IE_%}AE__їW}IE__C}$/KۗW%}IE__ї4}IE__їW%}AE__їWP)Ͼ +%M_AW_}e_A Kr˾ Kr˾ GW__їW%M_Kb+$/K$/Kb+ /Kb+z}՗W%}It$/Kb+/ r+$/Kb+kc%}IE_ݾ$/Kb+Kb+$/ r+$j+wY}IE__ї4}A/Kb+$/i /Kb+$/V__їW%M_Kb+$/K$/Kb+ /Kb+z޾+$޾*W_o_I}%WүW_o_I}%W_o_I}%UKg~>u(:_C rP 5א_bk!:_C 5א_C!rk!(Ωy乛g_AW_}E_AW_}E_AW_}E_AW_}yҾ%Kr˾$Kr˾Kr˾//b˾$ ///b˾$Kr˾/zkW_}E_A K/ r K/ r/)+/ r^/7_}Iٗ}Iٗ4}I_%e_Pٗ}Ae__%e_Pٗ}ICE_g_AW_}/)+/b/)+/ r +/z)kϔ$Kr˾$K$ //(Kr˾///(Kr˾$^ +/ rN_Aї_}IE_Aї_}E_RW_}_5ߐ%e__%e_~///////////N]u////}Ae__}I_%e__}Iٗ}=_^}Iٗ}Iٗ4}I_%e_Pٗ}Ae__%e_Pٗ}ICE_?}E_AW_t r K/ r +/b KKr˾$Kr˾Kr˾//b˾$ ///b˾$Kr˾/ڿ$Kr˾$K$ //(Kr˾///(Kr˾$rKr˾$Kr˾Kr˾//b˾$ ///b˾$Kr˾/z^+/ rW_%}E_RW_%}E_Aї_}E_/}7VV__%e__%M__}I_%e_Pٗ}I_%e__P~wr%e__%e_%e_Pٗ}Ae__}Iٗ}Ae__%e_}W__%e__%M__}I_%e_Pٗ}I_%e__Psg_AW_}/)+/b/)+/ r +/z)k_l///i/(Kr˾//b˾$Kr˾//r˾//////b˾$ //(Kr˾$ ///z(k_///i/(Kr˾//b˾$Kr˾//r˾gV__%e__%M__}I_%e_Pٗ}I_%e__PKr˾$Kr˾Kr˾//b˾$ ///b˾$Kr˾/z>W_}E_A K/ r K/ r/)+/ r^/]}Iٗ}Iٗ4}I_%e_Pٗ}Ae__%e_Pٗ}ICe_ԫ//////b˾$ //(Kr˾$ ///z(kߔ`%e__%e_%e_Pٗ}Ae__}Iٗ}Ae__%e_};{$Kr˾$K$ //(Kr˾///(Kr˾$}{՗}Iٗ}Iӗ}Ae__}I_%e__}Iٗ}=_O_cW_O_I=}%}WQ=}%U_O_I=}W_O_I=}W_O_I=}Iץ>:_C!y rkC5א_C!rP 5א_C u(rk!:n}E_AW_t r K/ r +/b }՗}Iٗ}Iӗ4}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}I~}E_AW+}E_AW_}E_AW_}E_Aї.W$Kr˾$KKr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾85 +/ rN_A +/ r +/ r +/ r r +t r +/ r +/ r S /////i///////////N]$Kr˾$KKr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾8ui///i////////////>g_AW_}N_AW_}E_AW_}E_AW_}yҾf%e__%e_%M__%e__%e__%e__%e__%e__ũK՗}Iٗ}Iӗ4}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}I.2W__%e__%M_%e__%e__%e__%e__%e__%e_m^}Iٗ}Iٗ4}Iӗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}qKr˾$Kr˾K$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$SCϧl> r +h- +/ r +/ r +/ԥQ՗}Iٗ}Iӗ4}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}I.{$Kr˾$KKr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾8uihz%e__%e_%M__%e__%e__%e__%e__%e__ũK/////i///////////N]ڷX}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}I~}%W_O_I=}%W_O_I=}%W_O_I=}%W_O_ujW_bkC5סrk<u(rkC5א_C!rk!א_C 5א___<܍ +/ r +/ r +/ r +/ r r +/ rN_A +/ r +/ r SV__%e__%e__%M_%e__%e__%e__%e__%e_z@W_}E_AW_t :}E_AW_}E_AW_}E_o/////i//////////s/Ͼ +/ rW+/ r +/ r +/ԥ}C՗}Iٗ}Iٗ}Iӗ4}Iٗ}Iٗ}Iٗ}Iٗ}I.$Kr˾$Kr˾$KKr˾$Kr˾$Kr˾$Kr˾$Kr˾8uiO$Kr˾$Kr˾$KKr˾$Kr˾$Kr˾$Kr˾$Kr˾8u }E_AW_}E_AW_}E_AW_}E_AW_KMb__%e__%e__%#%e__%e__%e__%e__%e_zH$Kr˾$Kr˾$Kݗ}Iٗ}Iٗ}Iٗ}Iٗ}qr$Kr˾$Kr˾$K/////////N =g~}E_AW_}N_AW_}E_AW_}E_Aї. b˾ +/ b˾ӗ4}e_AW_}e_AW_}yҾKb+$/Kb+ }IE__їW%}IE__їW%}qj蹃g_AW_}e_AW_t +/ b˾ +/ b˾/O]ڷA[}IE__їW%}IE__ї4}A/Kb+$/Kb+$/N =+/ b˾ +/ b˾N_}e_AW_}e_AW_K/Kb+$/Kb+/%}IE__їW%}IE__їWũK/Kb+$/Kb+/%}IE__їW%}IE__їWũKЫ/Kb+$/Kb+/%}IE__їW%}IE__їWũ}e_AW_}e_AWK +/ b˾ +/ b˾rJb+$޾zJb+$޾zJb+$޾zJb+$޾W_} K/ r+}IE_AW_%}E_AKe_///ib˾$ //%M__}Iٗ}Ae__%e_}=w+/ rN_RW_%}E_t r +/b m}Iٗ}I_%e_Pٗ}A/i/(Kr˾$ ///z(g_AW_t K/ r+}IE_AW_%}E_AKe_///ib˾$ //%M__}Iٗ}Ae__%e_}n$Kr˾ //(Kr˾ۗ4}I_%e__}Iٗ}=_o]///(Kr˾//n_%e_Pٗ}I_%e__PsϾ +%}E_RW_%M_A K/ r/)+/ r^/7Q_}Iٗ}I_%e_Pٗ}A/i/(Kr˾$ ///z(k/$Kr˾ //(Kr˾ۗ4}I_%e__}Iٗ}=_ rӗ_}IE_Aї4}/)+/ r +/z)k///(Kr˾//n_%e_Pٗ}I_%e__Pu%e__%M_Pٗ}Ae__ݾKr˾///(Kr˾$Kr˾$K//b˾$ }Iӗ}Ae__%e_Pٗ}ICe_՗}Iٗ4}Ae__}It//b˾$Kr˾//r˾///ib˾$ //%M__}Iٗ}Ae__%e_}=}}E_A/)+/b/[:}E_RW_}IE_AW_R~+|%e__%M_Pٗ}Ae__ݾKr˾///(Kr˾$}=Kr˾$K//b˾$ }Iӗ}Ae__%e_Pٗ}ICe_՗}Iٗ4}Ae__}It//b˾$Kr˾//r˾///ib˾$ //%M__}Iٗ}Ae__%e_}˃W__%e_}I_%e_Pٗ}Ae__%e_Pٗ}IC5$zJ(z*$b+zJr+zJr+/)x+C5ס:_R 5א_bk!:_C+!א_C 5א_bk!rk/sjy>W_} K/ r K/ r/)+/ r^/\}Iٗ}I_%e_Pٗ}Ae_%e__%e__%e__%e_z>wW_} K/ rW_}E_AW_}E_?///(Kr˾//b˾Kr˾$Kr˾$Kr˾$Kr˾85㳯 +/ :}IE_Aї_}IE_A +/ r +/ r rӗ_}IE_Aї_t r +/ r S///ib˾$ //(K$Kr˾$Kr˾$Kr˾$SOԫ///ib˾$ //(K$Kr˾$Kr˾$Kr˾$S///ib˾$ //(K$Kr˾$Kr˾$Kr˾$Sk;///ib˾$ //(K$Kr˾$Kr˾$Kr˾$S ///ib˾$ //(K$Kr˾$Kr˾$Kr˾$SCϻ }E_AWK/ r K/ :}E_AW_}E_AW_K՗}Iٗ4}Ae__}I_%M__%e__%e__%e__ũK՗}Iٗ4}Ae__}I_%M__%e__%e__%e__ũK՗}Iٗ4}Ae__}I_%M__%e__%e__%e__ũKʫ՗}Iٗ4}Ae__}I_%M__%e__%e__%e__ũK՗}Iٗ4}Ae__}I_%M__%e__%e__%e__ũ5$zJ(z*$b+髯$zJr+$zJrN#Z|>u(:_C!rP 5א_bkסrk!rP 5א_C EuN#ϧQ> r +/ r +/ r +/ r SGV__%e__%e__%e__%e_}Iٗ}Ae__%e_}=+/ r +/ r +%}E_Aї_}E_/}$Kr˾$Kr˾$Kr˾$Kr˾ ///b˾$Kr˾/z>W_}E_AW_}E_AWK/ r/)+/ r^/ڷX}Iٗ}Iٗ}Iٗ}Iٗ}I_%e__}Iٗ}=_+泯 +/ r +/ rӗ_}E_RW_}_o/////////(Kr˾$ ///z(kߵl%e__%e__%e__%e__%M_Pٗ}I_%e__P׾Kr˾$Kr˾$Kr˾$Kr˾$K///(Kr˾$}E_AW_}E_AW_} +/b }՗}Iٗ}Iٗ}Iٗ}Iٗ4}Ae__%e_Pٗ}ICe_NΫ/////////ib˾$Kr˾//r˾W__%e__%e__%e__%e_}Iٗ}Ae__%e_}=}E_AW_}E_AW_} +/b =̱/////////(Kr˾$ ///z(k:%e__%e__%e__%e__%M_Pٗ}I_%e__P| Kr˾$Kr˾$Kr˾$Kr˾$Kڏt__%e__%e__%e_z? r +/ r +/ :_w)+/ r +/z)ke/////////(Kr˾$ ///z(k?㯾$Kr˾$Kr˾$Kr˾$Kr˾ ///b˾$Kr˾/?6$Kr˾$Kr˾$Kr˾$Kr˾ ///b˾$Kr˾/ڿ{$Kr˾$Kr˾$Kr˾$Kr˾ ///b˾$Kr˾//ା$Kr˾$Kr˾$Kr˾$Kr˾ ///b˾$Kr˾/z^+/ r +/ r +%}E_Aї_}E_/}V__%e__%e__%e__%e_}Iٗ}Ae__%e_}V__%e__%e__%e__%e_}Iٗ}Ae__%e_}7W__%e__%e__%e__%e_}Iٗ}Ae__%e_}+CV__%e__%e__%e__%e_}Iٗ}Ae__%e_}˫V__%e__%e__%e__%e_}Iٗ}Ae__%e_(޾zJr+$zJr+$*$z*$zr? א_r_א_%%./K]b_א_%.uT_sjy+/ b˾ +/ b˾ +%e_AW_%e_AW_RE_#'/Kb+$/Kb+$/in__їW%}IE__їWũs[}e_AW_}e_AW_}+/ b˾ +/ b˾ +/ r +/ r +/ r +/ r/O?R////////////b˾$Kr˾}~ r +/ r +/ r K/ rKe_///////////i/(Kr˾$PyBW_}E_AW_}E_AW_}=}E_RW_}]/ڏY$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾Kr˾//CE_Yo_AW_}E_AW_}E_AW_}IE_AW_u)k?////////////b˾$Kr˾}W__%e__%e__%e__%e__%e_%e_Pٗ}Iס}Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K$ ///:_uo}E_AW_}E_AW_}E_AO_Aї_}E_r˾%H///////////i/(Kr˾$P׾Il%e__%e__%e__%e__%e__%M__}Iٗ}/$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾Kr˾//CE_No_AW_}E_AW_}E_AW_}IE_AW_u)k_ ////////////b˾$Kr˾}ەW__%e__%e__%e__%e__%e_%e_Pٗ}Iס}EKr˾$Kr˾$Kr˾$Kr˾$Kr˾$K$ ///:_u}E_AW_}E_AW_}E_AO_Aї_}E_r˾XKr˾$Kr˾$Kr˾$Kr˾$Kr˾$K$ ///:_5b%e__%e__%e__%e__%e__%M__}Iٗ}/_//////////W/////N///////////i~I_%e__u(kd%e__%e__%e__%e__%e__%M__}Iٗ}/:߾ +/ r +/ r ++/b RKr˾$Kr˾$Kr˾$Kr˾$Kr˾$K$ ///:_>////////////b˾$Kr˾}7UV__%e__%e__%e__%e__%e_%e_Pٗ}IסKr˾$Kr˾$Kr˾$Kr˾$Kr˾$K$ ///:__}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ}Ae__%e_r޾:}%uJr+W_$N_I:}%uJ+WQ:}%urׯ"|_z(z(z(rkbk!z(rkbk!ׯ z(rk!zNWΧ5}E_AW_}E_AW_}E_AWW_%}E_Aץ՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ4}Iӗ}Iٗ}I}E_AW_}E_AW_}E_AWWW_}E_Aї^]}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ4}Iٗ}Iٗ}qj|W_}E_AW_}E_AW_}=}=}E_AW_}yKr˾$Kr˾$Kr˾$Kr˾$Kr˾$KKr˾$Kr˾$SCYo_AW_}E_AW_}E_AW_}E_AW_婗///////////i/////N]}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ4}Iٗ}Iٗ}qhKr˾$Kr˾$Kr˾$Kr˾$Kr˾$KKr˾$Kr˾$SC~o_AW_}E_AW_}E_AW_}E_AW_婗%-///////////i/////No:Z}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ4}Iٗ}Iٗ}q}]Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$KKr˾$Kr˾$SCνo_AW_}E_AW_}E_AW_}E_AW_婗ŕ///////////i/////No]}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ4}Iٗ}Iٗ}q}Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$KKr˾$Kr˾$SCo_AW_}E_AW_}E_AW_}E_AW_婗e///////////i/////N1V__%e__%e__%e__%e__%e_%M__%e__%e_zi~YKr˾$Kr˾$Kr˾$Kr˾$Kr˾$KHӗ}Iٗ}I^}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}IX%e__%e__ũOp%e__%e__%e__%e__%e__%M_////ķ +/ r +/ r +/ +/ r/O_jW__%e__%e__%e__%e__%e_%M__%e__%e_ziyu%e__%e__%e__%e__%e__%M_%e__%e__ũ_V__%e__%e__%e__%e__%e_%M__%e__%e_zis///////////i////K՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}q=$N_I:}%uJr+W_$N_I:}%uJr+Wg} rrrrk!!rrk!!rky rrk!rr95_9M}E_AW_}E_AW_}E_AW_}E_Aї^X}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ4}Ae__%e_r皾}E_AW_}E_AW_}E_AW_%}E_Aץ՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}I_%e__u(|W_}E_AW_}E_AW_}E_AO_RW_}]/S_}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ4}Ae__%e_rγ߾ +/ r +/ r +/ zb R~`j%e__%e__%e__%e__%e__%e_}Iٗ}/O$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K//Ce_՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}I_%e__u(<+/ r +/ r +/ r/)+/ r.}K$V__%e__%e__%e__%e__%e__%M_Pٗ}Iס}Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾ ///:_3Z}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ4}Ae__%e_rΝ`߾ +/ r +/ r +/ zb R׾Xo%e__%e__%e__%e__%e__%e_}Iٗ}/ڷS$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K//Ce_՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}I_%e__u(ܓ+/ r +/ r +/ r/)+/ r.}W__%e__%e__%e__%e__%e__%M_Pٗ}Iס}cKr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾ ///:_g/V__%e__%e__%e__%e__%e__%M_Pٗ}Iסۗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}I_%e__u(k~%e__%e__%e__%e__%e__%e_J%e__%e_:?o_AW_}E_AW_}E_AW_}=3 +/_S///////////ib˾$Kr˾}՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}I_%e__u(kt%e__%e__%e__%e__%e__%e_}Iٗ}/[}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ4}Ae__%e_r˾#/////////////(Kr˾$Px+W_$N_I:}%uJr+W_$N_I}+W_/)x~5K _CKא_/_/5KK _/_/%_/_/_Sͩn׷ +/ b˾ +/ b˾ +/ b˾$+/ b˾.We$/Kb+$/Kb+$/K/Kb+85t>w+/ b˾ +/ b˾ +/ b˾/i b˾ S//$/Kb+$/Kb+$/Kb+/Kb+$/N O~ b˾ +/ b˾ +/ b˾ +K +/Kc/Kb+$/Kb+$/Kb+ z$/SC߾ +/ b˾ +/ b˾ +/ z +/ b˾<~c%}IE__їW%}IE__їW%}IE__ї4}Ao__їW%}qTKb+$/Kb+$/Kb+$/i޾$/Kb+K՗W%}IE__їW%}IE__їW%}IE_}IE__їWũ| +/ b˾ +/ b˾ +/ b˾+/ b˾/Or_}IE__їW%}IE__їW%}IE__їW%M_ۗW%}IE_zi$/Kb+$/Kb+$/K/Kb+8Ҿne%}IE__їW%}IE__їW%}IE__ї4}Ao__їW%}qjY+/ b˾ +/ b˾ +/ b˾/i b˾ S/틿V__їW%}IE__їW%}IE__їW%}I%}IE__^ڷ签$/Kb+$/Kb+$/Kb+/Kb+$/N\}IE__їW%}IE__їW%}IE__їW%M_ۗW%}IE_:~ b˾ +/ b˾ +/ b˾ +K +/K2՗W%}IE__їW%}IE__їW%}IE_}IE__їWũ/Kb+$/Kb+$/Kb+ z$/S/kW__їW%}IE__їW%}IE__їW%}I%}IE__^/Kb+$/Kb+$/Kb+ z$/S/%}IE__їW%}IE__їW%}IE__ї4}Ao__їW%}qjh~}e_AW_}e_AW_}e_AW}e_AW_婗u%}IE__їW%}IE__їW%}IE__ї4}AoZKb+8}%}IE__їW%}IE__їW%}IE__ї4}Ao__їW%}q$/Kb+$/Kb+$/K/Kb+8Kb+$/Kb+$/Kb+$/i޾$/Kb+Ko/Kb+$/Kb+$/Kb+$/Kb+8?W_$n_Iݾ}%uJb+W_$n_Iݾ}%uJbNW^c~P P P 5א_א_C P 5א_א_C 5א_W_C 5א__ϩy7W_}E_AW_}E_AW_}E_AW_}E_ziKk%e__%e__%e__%e__%e__%e__%M__%e_r}E_AW_}E_AW_}E_AW_}=}E_Aץ՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ4}Iٗ}/:P}E_AW_}E_AW_}E_AW_}E_r˾V__%e__%e__%e__%e__%e__%e_%e__u(|VW_}E_AW_}E_AW_}E_AWW_}]/8_}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ}IסKr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K$Kr˾}GV__%e__%e__%e__%e__%e__%e_%e__u(/////////////i//K ՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ4}Iӗ}I=x߾ +/ r +/ r +/ r S/$W__%e__%e__%e__%e__%e__%e_%M__%e_ziȺ/////////////i//KZ՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ4}Iӗ}I^w$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾K$Kr˾8Ҿ`%e__%e__%e__%e__%e__%e__%M_%e__ũR+/ r +/ r +/ r +hǖ S/վ$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾4}Iٗ}qؗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ?w__%e_ziKW__%e__%e__%e__%e__%e__%e_%ou//N]}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ4}Iٗ}q///////////////NO+W_$N_I:}%uJr+W_$N_I:}%uJrU+/_z(z(z(rkbk!z(rkbk!rkbk+!zNWλ߾ +/ r +/ r +/ r +/K-՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ}/: r +/ r +/ r +/ rKe_S////////////////:_u+/ r +/ r +/ r +/ z r.}I$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K$Pѷ +/ r +/ r +/ r ++/_?/////////////iCe_S////////////////:_?://///////////iCE_o_AW_}E_AW_}E_AW_}E_AWW_u)k?Ĵ/////////////iCe_I՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ}/ڏӮ$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K$Py&W_}E_AW_}E_AW_}E_AW_}]/;$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K$P׾e%e__%e__%e__%e__%e__%e__%e_%e_r˾C////////////////:_u}E_AW_}E_AW_}E_AW_}=}E_r˾ew////////////////:_o\}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ4}Iס}Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾Kr˾}W__%e__%e__%e__%e__%e__%e__%M__u(k_/////////////iCE_o_AW_}E_AW_}E_AW_}E_AWW_u)kOQ$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K$PxKr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾Kr˾}ͿԾ$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K_$S/Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾@r˾} +/ r +/ r +/ r +/ z z r<@Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾K$S/O孾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$KKr˾8hKr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾K$SC߾ +/ r +/ r +/ r S/,V__%e__%e__%e__%e__%e__%e__%M_%e_zi?/////////////i//Kq՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ4}I3߾ +/ r +/ r +/ r S/W__%e__%e__%e__%e__%e__%e__%M_%e_ziް/////////////i//K ՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ4}I=B߾ +/ r +/ r +/ r S/˸V__%e__%e__%e__%e__%e__%e__%M_%e_zih/////////////i//KZ՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iӗ4}I^w$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$KKr˾8Ҿx%e__%e__%e__%e__%e__%e__%e_%M__ũs +/ r +/ r +/ r +hǖ/O_}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ4}Iӗ}q꥽7/////////////i//K{e%e__%e__%e__%e__%e__%e__%e_|E$S/?پ$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kt__ũ՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}q$N_I:}%uJr+W_$N_I:}%uJr+W} rrrrk!!rrk!!rk!!rky rr95_9}E_AW_}E_AW_}E_AW_}E_Aї^Z}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iסķ +/ r +/ r +/ r +/ z_[}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iס +/ r +/ r +/ r +/ z_ʹ//////////////CE_{߾ +/ r +/ r +/ r +RKr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K}O $Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾PKr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K}ϯ~ r +/ r +/ r +/ rKe_C///////////////i:_X}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iס8Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K}g}E_AW_}E_AW_}E_AW_}E_AWץ`Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$K}W__%e__%e__%e__%e__%e__%e__%e_u(k_Ѱ//////////////CE_瞓o_AW_}E_AW_}E_AW_}E_AW_u)k_//////////////Ce_ƭ՗}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ4}/֭$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾$Kr˾P׾q%e__%e__%e__%e__%e__%e__%e__%M_r˾///////////////i:_un!}E_AW_}E_AW_}E_AW_}E_AO_r˾Uޫ///////////////i:__}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iס=*//////////////Ce_{e%e__%e__%e__%e__%e__%e__%e__%M_r˾}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}Iٗ}I+'?o_I:}%uJr+W_$N_I:}%uJr+Wo;Ru?ׯ_SCWWtU}+U_Ag :_WWtU}+U_AO_ʾV_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+W%K:_ٗ4}+o_Ag :_WWtU}+U_Ag :_WWtU}=}]+/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+W%KyWWtU}+U_Ag :_WWtU}+U_AO_~6K:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+C?E4t+U_Ag :_WWtU}+U_Ag :_WWtK?EK:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+C?ETK:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+C?EhK:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+C?E4t>_+U_Ag :_WWtU}+U_Ag :_WWtK?EK:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+C?EK:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+C?E~\b%K:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Iס":} :_WWtU}+U_Ag :_WWtU}+_[}Ig+W%K:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_u篈^O}Ig+W%K:_ٗt/e_ʾ}Ig+W%K:_ٗt/i:WD/GW_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+W%K:_ٗ4}+s÷U}+U_Ag :_WWtU}+U_Ag :_W.K2՗t/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+W%M_~}#K:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+C?EҾVk%K:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Iס"ziMW%K:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ_/x\}Ig+W%K:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_u篈-߾WtU}+U_Ag :_WWtU}+U_Ag K՗t/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+W%M_~}_K:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+C?EҾ~%K:_ٗt/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Iס"zi/G}Ig+W%K:_ٗt/e_ʾ}Ig+W%K:_ٗt/i:WD/՗t/e_ʾ}Ig+W%K:_ٗt/e_ʾ}Ig+W%So_Ig˾}%/J:_t+We_Ig˾}%/J:_t+W/?PK*>Ba( csp/lin_to_rec709.cspUT 8Mw*NUx6;- *X!v`I!77)NqScΫz_[_ϲ;pl dQcGۼ|^6j2)-/v˜_⧔ϯZa-\͖ڣ3mB29]W)c>7ڴ78 wc=:Ve>:d>67] FZZLRO:[E.έ?hxe|9X䎰kV^cS!|81G1& :~d>UxcuJVhaIF,oSnVڙm7&Z?J*5vfsU}0Qh 2wxe# K/0C:V:cojiVCNZWy0ʏօdǖ<Yb6~ask9+߆A>,? L^2oegDM26]+qd5dṗ]Ƽ 2gx/Kڵ-q|>K oHϋŏy.wjwx)_z/C喑0˖K0+?\%С2gnqv9A^G!?dhlGO!u֒Qȇ`bkTT ~~txȠ7 77/sswud_bhk+#$.]fyׁ_  ҂dQaiN 5LY4›jNBij5UFN*BPZhgPB >gó*ǜfOjyU å.eO[0т?2vG;Sa#ނm8q Lh3fRUxʋghOφɸˉ)%Q+O⡪;ӠA&ߦݑf32f٫Q{p u.dU &cY8ڻWiNquVPG>]y5:2-)~SXc˖Gi%]W1XO?QD%O?QD%O%H3ͱ$mQCUF1D$}41vt%btG.EbBA7ҧ%*ƨt?m{%23-\L:2 /֚T,x,J4撋Utd&W:i>B{ǧM?%[L -3pj )D s46}U򆃦?21n3gj_ݏt]dٿȧ4܇;Hῴʹ]&:Q2gtΕ(҇%Z 21;Cuh-&%jj E}(uĘ>%:42ZhTh(ѣC[(V_fv‚k łƄ䫨(Ѡt)%R_EDjSHQ"&m t8D/D秆[ D?*V+DQ"fXEH{C&;.u%bHE D y1D&DQ[DQ@HQ"mD%R GS~D+kH?D D)JD4#O{Q"}(@b*׉%2Fa'D R!qZuH J4$/(h?md1a?y/Qp)YF-f e|͈т|@._YAҝ \bh5ōg.32R%Cr,4%P&'s[.C7j,,k|. MZg ^3QKĄ!ဥ\".UHglQA{}*{izYvtx^>xh;PoaOzc˚(bŜ#/Dr(DG[%bIq>&C)$UMZ DGC&W(Q"B-]>8Y!JOuL>FK2J?uiLY18Ԙ>(% /(SV%L!1mMD,\dAeDs#{H?|ue5нrd 7-J!ff\"NL dHAoxQ"B( k$M&"xg =1P1eh28$7CAu2$ ,<]t8"JDH#%A`1AG&΄NDYC,D qضF@b4-J4_g<im,Ja({c vB@hX @ D*bBQ"dhXlip(1OiFg 8bYVl1 ?Q"i/|`Ee-d~wT ~yo2p6*;7{w*|l)_?3>eP8||n۝N_ʲZH:vƯP̆hh/~(+1kJw4m/ lq(P卯geáH5Wfz=_^/az_á{-/!%Qs~Yoj~e7$f4v/>;%>e ׻ʯd͕_ƻ+g~ ]~U3 7wH>`{c_G>*:㗍^K_S{8sX:}_$xnh9>ij(bC د9W}Xq~{/ݽ9P j^1cWq({ίŐ>ˡ?lߏr~ŧt]|oW)~>eupyo<v+r:|4_DsW JWj_:hʫ6L _eK_**3jRWe#~ųdXifS~f4F/]E*ʟ-T~y gzeLE-rq}Bʯg_C cP(ʯxV^_ʿ! pd:/:'tP(ֹP80>T^򽡚C9RЛ߰LҤBasw5W]pUZ7Cq>LFm5"CxgX ]W*{} uazc7Ʒj{i,C~_ی˯(%kn/ K4DcPbPX0_ eK/8._͸JW49뷅_/^~/_xV6Rp˯>OG]~<맣.~q%POϺ1R2|C*Y +5~|yCv0ϊBu~nXyS34^1S~?Wͨz?m*W5([*k7 a%=y?eGT;*⇿C6#Qgo\~ _<~1zk}_N _{΢_? kq-Lj|}Ju_/~W-U~E c_[x| ]~_g+nEj8"*_ild~tϧzwԇ_?&_Qٴ~ZxP/Kgyf4!](⪈Gd%4e~(վ7@~BaPYz^~7ʡ_fhگF-ج_c#>Y~_yd7l^OG]~|˯wG}3lU~0uC/~oUٴatW PT_ϊB+CJh\XiϞWnFyJsT B<_{_JX~؈oG_&_d~?[cD!v'~CDWK*WJ+0ۯ? _r_Y#o3uW_J(>EVU/6?od+׷JU_Wa+ٯ_2Wl~M/*n1Q(`a \ (vi*/V(XiKtBjo ? ?ސ .1Hϧ/~=Ca<˒x=~zx|<=/DyF+~\[7$?i@+/[aVַ=x>7L'}8a^w|>?VZ3*_7Hs\(Χ|!Ez:ai ַw|Jgް_e}{گo3J7N@_oe~} -Q+n|MSj-yJz7گx|r|^k׻nXiy~/0Pי_H8?ga^x~o?y*_ گ_ڟƗoo$ _+P7_ $P>tU^gi<׊^ӽOSodc?eد_9_c\XCCNpzi9ïPzHP,IBʯ _oؤ -B,E|jF{J9?'_ Їϧįtk~yw~;*_7 ~r~ ~xum|pSշӂ ųkC^$~ Iz_OsR_oHY~@_cvja_WzCqnډ_`S8- tYq~V/_?%ʌ"sC]r^~<W_?}x~VM ~7~W:*ΑF^t/Jۦ?LW?LLC<=|.Vng?L6{0Az">f  ?|?׷{?L=_ۇ?ڱƻZ3^Wѝz?Ia^Iz7>VU a_S0}/5_Wf$n.a.%._~{X|l,~R u|?jC/hE|58-+Wq_gс&UտI_o"~X>k[cJD2~5Zk}gG|#Wo~+ wZW=WatUOvTD~4\/C@a}!U i|jnԝWz~_ *_(?گxF~Izw ͝j _JHn~@.ޯWan(_G\~>܉_^97* WmY y*wʯx0\'Ju*%GfXP">~Ug܌'^+ڞuoF磅9_bc$~ ̿zC-<&_j޸ZO^~q$~>LIzׇ_i/@*΄Y=Z= jLo+g {È  B=G~iW@͈W4>o=%Χ |o |7?rrW Z]y eVzF8P/+Ko3b? _}V/B - ]ٽ^H = W2~z#_3+ƓaIW.~O/~^˯V%!yMK7_Ư]~/#^@EZ?͈_fD}? og}t ސY.^+^~ZXjo_zWlY) ~*)#pFNo~WÙ>eMy˯p%+5/#.y(ҙ|YӽU;_ opFˎ_?7__DxoHczn{oAߍ/^|[X{翽QG=j:0*d_oȲ>|'JjWz/ +A-sz˯d|+aϧ_~d{_%H/@G4nFiTxљ2ݡUvwWMs9A3~C+?7ZXR|#A~nP7<[k| 7SFޞ?B0~ B߫48{E|#)[*[yϳJȯJ.q+7!D{zC7~P)?7>Bikٌ8QY_O(Χy~TJ/tj׫za~{>~+WÔPį7T#>PWN͈ooJJWį;7.)/~^/@9?}hQ䝖wktO#|_L~4~A-zFgȏ?-wޫި|S{3JO:ί}e]^ 636v:_膾7%~,X1IjDŽCPX5M|xFpZ}13EhzL {`}Y]ԀAUhWk&! f6CӯTM>M P7_y֜߻MOmudY6*և$.d +T8a<{ ;D}1ksHSĥ/G>_ b~UypxvTuHPTwP]Dc}hJ:xK6!M>Z!]zLջWg8UlDW?MXw7h.ޮCޫN7Ón;dZױO)9*]j %~͡鐦YiD"+- J2oafؐ٣Vo~ 5 Y<,͖@>ҼCO[ӗ~.ROm Y 5RǛӵL7Tyk0R5q5S5Wb]˴~J dXb|E4eW(z MgRﵥwLDBCY{C G@?wƳ: +F)ņ}x_.eGT_.eFbnu&t@g<.^VN\!NK2PL_ʳ+^׬g[uhԛ^^I4ב'UQnC^uo!{kL)7dA3&ʌla4X y2j:jcVyKchy5ȕQn:)!i@V 5IMS2$RAfZx/گҺ߰65) "Ќ2u{L_8tr%RVh{^L yO)¯cf͙ NMX8dy)spO C^1W{UAA~7)etMT K3q] [kcvn+BED'Tb=\&}XU5HWD+_nhcNI_͡ZfN+X3l)7\l=/j ?J +!]澃F(_ͯi2?Ս_k=8*i톖*^%rޤC䋢4k(x~&Wc9+d"t~BOa3c2ݥ[#X~02%Q 4zKjPtWbr ( }tMx5|` L kx)/]tczbLe{Vobί-<=OrnOzj7?lWE cgޘv~9t[wvlpu$x3['sTDBi_14j^r x u~iFϫto_b#X3]) ƍbX H0{Rv ʴ eVR2 i_z}3~Mj[:H>Lf[H”&[ ?*wB¾/<215MjςNEub2-TWrw%ye|ЌZɁMi =m-Or+tM hŶ249TDM:_iʗ_ ?c~QPy6?y& To$p_˛Qkv!5oUcͨjtGT޻3l+zQ_,$[)b !pcy(vwTmť{lt[u|eJ^4_M{廥>˯KN.w㱫FKFd‘m7)šwev@?PWĕ'<34@=_knB 85Ni/(@@&kH jbPx,r (~1_НRlM J֟a\fh:xc>4k?erOi,oM+ tѻ?5_>a.rfY+&XC,_u j;?-~87K b$z~wW$_?2ݑ̪EEZ/uuddГ ˚Q^ rfƎwڌ`/>uiM Y}z,.+h2Ѩr֘+rŧЇ% <{݅O+0n7E,{3{6fC_Xv_940WۯM4 b@7"mkZkiÕbDXw" ej% \P~y^k{s=G~JC!$Z/)Fy>3D]ftrrFk mfrOA 3Wv\<δ9Q㢀V*ӯ coz€IxA^LH2ih>yH#?ow3_{Ĩ@@_fJ{՚?4Z/jrQwkzop[JMi{;4i"\?oeڳnr7{G56ƟɫYzz21nY|jP,TF`4ޫ_(,7RoWn5gh-4'}䰏s`#|dc JŤ?&LEC@bqeGU_zCTTmF @ua{% }rI+Ms&zGLt~wyFA+uLa4~8痝<WƏG)Lfl_. o J`?+1wCCZ.w:<S(wZQ}l5d8֌mH I.Pڸ{MmO|Y5orvѮ,/B3|U,~8DgC\do3G8چAqpXNzir?H"PگD Y/ϳ؋B)UFѰWx ]6[荰z6ūb 9C"Sd# K@'alHM/0Y.?&6Ʌm!wbf~o v: zz>&5-`!b?l=0-@7Og{[uEn|; 6_VW:IM~qOa"4C}3~PAoRNTRĬ$CmF:pTt3ƹ%}W ӗ7g]b5o aDj,]2߉`mD%gIMBk!f &@+&RYև7̲>޸[H,NQV wZ lн ;7dJG2rZU~Jy-]-v=a,?~Q٘e7\7z?d@kPQMjj{/~PتirI*}Zd05IN6~`k[5؉D24+G ә<޽w%W&NWݬ*[WL‡އni/ Rf|Z7BeYB7R;ES(A7U/]qMQ`XfZ|[qV6YUW3TaK yuA=NeEɴ=Mkb,$O/*|6/ )1Ig~@Wk~Uv~Wݓ&b`A8W7a;<+/U%ZgݒYÇ<{*!82Qw_d$ZMeiSKbyCaP nx&e7FZ[0;+_uԸI0O& M 2hkɠfb^lg)x]_)>eZH5c/d5ٖՃ p}6_[xNW.1?k.{Md&hS +gmDw_('+maJ菹Xx07E,oS@JrţP$bY{囐Ϫ$Ee~(N=~ͬ] "͡oLڸuƝՏN1aHgRՏnrx@#{7c޳K ڼ>GkFF")M)XЛjsG\l,'VcP( K RSuSox+N<OgB/jZ4 -L)a]S+ Lt>݂\އPUE])Sd]'9/oQٽ/X}Wmq })dU$+Aɵ93~hYmL63/?&Q7cCB!]:_IqlU]O|myi~uSP\p0ߠ{UqfX?DVC)&ԣXYPF+vF ρ_}PjFÌv7- EWju<_Yu5KFʂ~1hM*ր5p-N zNVx](rUlQf9t3lLNftFUj CA)*7+8C_$M1ܲ-k컑a=z߰@+- Wo_&˘tX>+s6b!Nl:4h8og /8ʲ4ߦPVn6劵¯JcwTgvWW/Lt:+_/p'B?eZ4g`ӆ+l_mxY5F7jNQ^fl_6la,+~(QگB)*:?XHaLOE$SmXL\iYUr s1Fd,2@wC_äu>˄{J%K~ 7jreX/.oeJ^5C}@սDHu,Xs')- h{<֤zw,Unmfp|%dWݺߌjZcu~>O` v31iYglAT/֠i C.a+tKZP;=-+Vl..@כd*);-3cu}SΟe7,t)/U@7:VL{ȹ䗝vP(zf_:bq( u w[eijú|xJ&` BHV(~ X'@ =+lSg@wLJ.`P.,*y=A7õwO*(_v~g(Iצ׃_0 _Ӥu xoBky;nA%QS_G6=kz˴_y@l&Upk-⨀v6]z{A[oVН7('u#Kp-2gЍGM5Ϻ{\MJ(ҙĎF4Q6 w0O32W_+V\0C3v_u˜r]Nz>XO|T;B;>:6"B%E~ GzM%5M4J*!+)P5}:Y,/x➶+VoW?[\H>,is!sjz2xY!-Wf,0>PA}eo^Y/+//l?eZs\W_}ʌy3T+>Jy?e Q}Y[1÷T˾K[6 }CB2Ȳ1ɐ?F{CㇴhU%DcnGBKx\?t.Kb/S=>@IԐz]g]u-6ҦՏZ!e-De*_^J8o3C530M/DaױٯgQmm-YUˡcٞcϚVGhWɂ2~5lc:5(JpZ5n Fe: ka9L G7`GC]|DQOːg}juWB e\6+『F|->A 7-ַfBMVh㇜]~~"uXg}̃_liPkƯyw& 27(gf[\PV q$(]*(h_(bUyE̻<ᶤ>@ W emj\͠jS}Մs1ۻF@IW! {㽘? h!ayvK7< 죘-ܡ"8\BF{HU\y>UkaѴs>J ZseNKK`pʛ_5sR0hFo8t}Oe. ~m kY ד!zf=͚r%:p1{a(^7Dg4otg Yy߰˔~C/^[_yttJ~10|Pk + `$H>6گcشnƂ[he~kڎy̲^`s@ԯ Wz_5p}C_+j\?K]c#S3]ȩ X@~UW镅_<,2-\O( _5W!&=غ%XNC|ҘQ1%Q-Q*i(0 k_y5;Q!W)e+Z1HCK )eZvxs+5g!"nhns!<_ȏ}r,T˴j?Tuh|TPٯEK@i>D$Λ4_ FC@1*ϧln+;ɹUe/%X3J,hڐ g(yZriP75j@aZ\2=l4m`7O @vi8QGaԓ ^XPxWՕ ={/U(mjOyG!e. iy %bez߱{jP*x"v՝RjRw5Z $,7+\ٴ)fW2~Wlw_\rwD8h7SZZ gKT`5^دW4_:ek /o36"_eK 6)փmӼ¯٩~~')y)Ax$*(L\irȬ2kfч!6wɯt`*q 3.*_ !n_.55rR[n<_hd'0ǡ4DQ F?ӟu,Uꏽ+W_9=t헯tC_;jhVche| ~Uk,_4c2X \̓izy=>U1OzeZ%M8Yu-!\klmH"xְ۠¯jIKi?! 6EƍLzx k=3]uple:BfH2^kT)VJ\دJ^g"o|+$&j&4M/ůU%'*~ÞI48_L;FcQs8m7d_\?zZO}F)˫lt2S h`߫``Ô+ VGz"x+ɯ&{_~5%= u=Cn kBYMKR__CnE;PEэ%9J7SN5h[4%*[ox2H պd&ڊ7>b>x57~\lv!Uז?SSԒ˥^#&-N24>Akb){k|YH ]Wӫ6\͋bնjvn_FԪaaB~1ӂNս{_*tp54*D7ѶU?JtP߫UE}=x߻pI %x (Q_MjkFۋ_D (b'W9js,a+_bX擼ųBᄔɫUT7GЍܚ>Iyi&>UY=WVe/kƝ~Mr j$W T]a4e4Gk: ~Y_)'rM.;u<_C1/ˠv#h{[%nv 8%ZM(sCQīB(q kuN jyb[fJyg(^WW nu=k7D]5É>yirpwҳ|g0@'(yv5/׼ H&b}xiLტ\I*,c|ފPZm.1@+]߁W7Js~Y_T(;#8 ti/Z2_IQe\ b'r _N/=S3P&J.y覑b :V9ևe|eeWsur2sD3'z+0!Pn:ݥ0~q6BX; aV^IbuT/W@=/5')YUG#9K/n|k] CKӹ#?QZUQ_Oy;{Թ@Ro_^C/!PPu d sj6PN9J[ި>U! PvT}DZ\!Sn7{o5 {)iMz._9Jľ3'8Xzm7N5AQwv -6DKKA/@iϪw_h){ݰ8B3%˯iL~Qk D9W <,i6~1>D}Aja7PI6/[X34 !(͇N\ CcJ^oi> ~b'y/f*iD!g:W~j͘#u/<{͕l=eunqIdu1oz wNuC|2IYBf˺f'/{Hw&.c$y5E̎WmSrDԏR8}I?POWLw/S(+3"fTLɫ\g p"-1qn.qbZHG&͌K'j↵o1@k]3o(2rx<M(38-,FWwM|jA@~X xW~e?W[ʍp(#~7㇌R1{Yb>fx(?_2ٯCW Ԕe%ˤ:=i2/Tx3~Xtf*Seuj[/O)àKieR1v*Pd/{R8}]u\?,%j M^.kg|&˭uE?&e%^izQy/@mS@?6 '#Vj/WIhWn5_>^ZP\?flg99l`'[_Jv~e=̫ڼ'imF:Py›qz :DW@5/UzZH+n@7z_&78uYo;dN+u э+C}Yo;9,gj}8PlִE~!`u:d5~hCT~ME /Aw.Eg=vU2PMӲt<+ +99P|֟3ȧ2Ult_{擒]|eYl5{;YIr ߡW_;0{G]WMW~W/4bY6@˯4Mvu~uS :b/ְoN9Λ&WHACzxd'BssvD2i#9P;~ÜVl%Ni(|e0ɿsՆz<] PI$4)`@'9tWm4S3p|?UvI+D`i`Y8_ގ=WFY}l$Mf:Y|^\Q  סن9YE1Cם<>@+WƍF سvN_Hf/.y CWaƍ9PA{&b@w CnUن\j5YAPNQPPUMCm _{68^YEJ\Jkp/롷}eI!E/2tM1+l| S&3:p_+FKDҴ7c/䴣gZ^ȟ[bZ 쒚/} 5\˲>{eEu"/`3Bgpba;ś׼U~1.ibIdjMs|7*;ЧTc76 >Sx-U=JM. }c,uJ_9Mo{_ga Fުa +2g\Uÿד_^r=t]b/?<ZYæ$WuLl> &LNC&~3_}1_Lc[ܣ߰]wVsEWOq~O3Urjt_U>QUN՞{S54l_t3SYTx֜9ZC4eַtvXfO5{%'Iݯ2lsX_4w\PoFger甼l/c:@OIGT 84G 5Tب8 YprН٨tgQFaG~[!*ɟaD6YR|3zP>ڬW27΍,qq' PW9?t฿lzQrV'|Ji>F/T4L6d @3|eӆ[]ˋp3Y!nƂ/7s4y|C j *5KG/1͌|NeŕR_:ɞ<dPwda5bϺ*4SGaQ]@x_,U '?&4{uf:K¯1*_̬ϢV8jş5 p@+v>VU;*Н8(pydD{k!τZ-g*?lL#t\^o :Ek(O/f#['G8l!VQ_j{]}J<_9 iyBIBRudEȏdᓘvsfC¯FG꧘3 Qǯ270aF/'D3_tvJin;439 Dy~ÚM[csJ{&`}rր1ٸgT[T2s ;-g_,l.i~@4vvaWO4WS2ղxbԯÏ):5 Fs#qS;~q/r#Q3 _&(>ImrEQiPu~d+&V1ҟ 1RdYa9G@VMT9Qqf[_/XגOJky3.'S4U,Bim!#_W12ZN2j ?yYGE#I2V>jvبXlPqvG ۈ<)yU7cZFo_USkuo"ƪX~gpjVUk&|Weg¯İkM|L\J%EPvrIL{,U@w_YLvӈx@U{E\𞟪rUww(ùЧj,8JBY͠hJki1=Pcདr2lɟoEtSE:jD'] (Z?~ yR7_=$,P~!,P dr6 _ | K_{W=֝:WD{)^_VJ?-9UB~%!xF_#e9fJ]G=_~R߱!Y{GcH?PE7Qh손Izqj~T@TxA!'&$oFy,k^_VF/V b  c (qCx!u]QBc~+ 9گfs{_;8Ciy83T Be;aATm>{ЙlK.燉bHv%o(=()  u-q^šj Z׏ jģMu{iSfUm<~erDlEoǮ*onh '_J 䲞_ ,uv?6mf"q=kh1X7d31:C~:>D0?!'5&)&s+:ɼ3~X,Dy_[WqūF? Nh!U ='7y4X@&AmuUFI 1~ uxx,+1uxCztTި6,nCow2|$C<"@!wXYDW^=y)H;ڰ1F~W^L5>6xN\y}Q.aﵚ;ئΧXu8@kX9ohZ}ʧִv. WGYeWZEW C'ho0j!|DWY|0ǶF_ʣC D k"ߠM(y;ktSZ}ªzUدh!}~N<=~þPCĤ~k b~UpWqZyPJ^'iQUlMuR.U,5Be%~ZoHbn%"QտroBm/ c;,*y Q3hfhX,*W s:'koW^v!],֔_SPاR:t>yJ/Tu QFE_:lfџ\+W5辗=ԡ!k^eōa}Ck<=OKM=wD9cPMldQfԿ.PeR~KM=+=K\^]ː=/k!(#XTkfJf@c{z Bi#}1( ZY/*y"Ƣ8TwT3.=e/a&tZk* Y\PA|XzF7R z8Y_à/;A(o^P/ƯfPz_/S]>iA~ӮPz5*ٴaB B' ~5F6m/̵5k!kU;vJ~c7ٴ!U-t>U,щ~Ñ=%އ^k6sIdd:0Ưc`IEs(F˪a̗d;fj 5r_X~J/+SeQ6=c[k}:& 9<~~Q)/V3V(6la6m8I\ _~hCTj+D"T!gl@-MjjxkU+DvQ;_9^8X-51nJ*y,g齄_tQ$ ^{<؅v)8lZj2l+kF:qAye(~|`/R] (fJC)[E>q~QZeY/.15L7_?6-$lz?Y'H e74}D&Wf_ۯv2GE/WΞ<p >[+~fA5.|aL"ˠkS_͚Q5CyC j’cH HԽE@2z,{ZKPzdj bivHJUj:wFV6FPY2˸jm zz¨g4lǯ0orU;sHl;;@?IӏW(}{#14E,_5uߡ<OڭPA5a}25~WOjM+mBiykKS/Y''F.U(K!b^%&-u ew{8%_u|"Dh8A=VEnD2jo9< ѝPv̤}oR(/4_h7H@;]p:u͛{\B噟~MjQ_+¿ռ\3l|*#HL{V/^/nr6\P~HX Z9Rnw6{Lk^۾/f)ٹ;^M; e++?T#5M_))ך_o@*E}=,> 7#2F5(Ő?O1G@F~yW ,=-qmwPɋ,Yqr{%sQoؿaֽHcc[ ZWug'lGy>B~A5>šz^7%R#:C -V U5x< 2h(9f`k3_Q\v =c5N-n;+iGx*9T`C&@Vٲ,(d*HܨC"U#9ˠ~1MeΉdĽY;C ,j7x{!zc"z$'7}ʓbL6q\T5anJ7A%G?PV"k:WbC~q{aw`CT+_f-<(HNA~QQ@w"'}J5^_4(+g0_ $VI~E{v`_:>h'1 (Qȶ0y}beN@>|UȟyA?PXg#ՎMz!+1/@5>P7ʱ0LԳ*%wnHjev$`=봯✠wy1ްRޱe2¢d_C_Pw|/N{J\֪ PEQ|6e*yGU\5 j;,Pv!TϚi4_ub \(Vr0 翢7JfJ).:v>eZ3dWqb \@+`hՓZqW~_XtJcgY|1lj=ekC;uV^W;M)y9N~kFʔ?_qeKô6_d'@+Sq~yqȪ/qv7q' |R@ŢLrbnvθj+oԾjIKDqNul??-uL׬Oxr8_i:Yn88c˨ԽvC-hy~WzA-31/\_յơ& TZ=1&lݞJ7~uoFiGI^  (oe*$(]Ji&/UO~(}0;z"0H`7B(btɑFSӓ'~hb=&טԾbvB_UEID3~Z٦ =u#ͼ*Z P_֓Գ=DCʙi:~Ù-S M   &eJ2~UQ3&@αX׃5~f_ sQίIhME|CM A+ 5֊B%/dEoSM&i#ǡzCoNم h&8˚t՚.{t0xV\aEdސ# O= ~q9 P3r23x{?ksS%1j5nc!e@13~-Uӈ?_c-|Rg|cRJTYQ 7ڰw sS#>eFwT ;ev4C-eC#o0;K'bz6Dޯ/&*),ę}xVAx@wc|1]||H)@'/|+CH䔂2h|Dv# !R-"5Ƒkը/ú~~5kG:_/) |de~~pN?2?U6PF:,,,K#7]ZִM24~-S [,E۴%Q!_h͘ӣ>a> 0~(֤O[} .d8H2=Z_{G3_s{uoa/pƯfZG\ M7m^7(o sL/4 IYX@'\o4Ǯ h1N8_z\(i ?2!y旋\'W>^uK /?e@+&"E/MʸW<T!(VB}XDidfPOT(A5y(NA'~RYvW_~,6#V^Or!JȕV^ٶ7|(ռh}7L_GiuRc4oh]5ۃ>PӮO mNC :$U_rs\z^ԨȲCr6Cɇ͚V߆幰V0HN(6{ \$:`*W_]:/7\K;z>"vL @@~UWzA2<+ lsYqŏXgd,LjG|cjfOy||Bm!+g~>z%ֽ6_k\8oa;{ L4J[s/ƍ1D`@Y^Wg[+KWֺe~ᬼO_^Eey7a @XI}X͇}MT_AB@%/63z~m&wC/Sr CznVP͡^]g2uiP>gt:_ʇ(h>QO=c-H7翐e/ۦzD~dW.9.* WrpҔ"*n*nb\o<`{&__qPoN_/BR͏?q%DKҩBb)wL"Z(byV5 zr0 .6e='HKW¯bV.h/{!A0F*}컓E\P@9? PCUj5jecOz^垨_9Ǫ-|S^70Q_y_yAꧣ~ݛ]8|{ ((omƮt&Vl1D*Qxҧ n>6EUV~ U#~8ykm]Qu-XjXY׳\t@}FzE~k|9#T*:BmT&A- Q"SƻQ İʷjU/@5C$Y*\*9P(6ɐ^ `*X>GfNٖ?KW97u#MbcԮ:9@Lq'cV~Bu>!)h᾿BE8l_Q51$y܆RSUO).r`ۮjשEh5m7+)*yh8jiz 4L1t՞WzdxsGГvVR%O\FX6οK}X?]=˯ʥnkU5}br}PΟGHU8?ϑb[|4o>=S?g16NZ^W![()u+6.tC_Ux* :?Ϣ~MR!*(!ԃU$WikYVUc 씺SzegY}(8T뷣~AjC XVPùV/PXݻW|ذP{#!ʣ+;T7<l,=z{]~5sn7:#2 eqGoOW*Z CH v:t%/43?Г,8OeL] yQD=4uB]U>Y3S8pi0mj\fW^Mz}}Ih4*x6pT$M;sL=zH rS{%ⅩC=VyiJbjs{ﵫL?z4_zC=BJW86. qi0Jl=waGQ &\ /l4 CSdp܀(PSPCFeKWo'ohH=$gl?v_7^P͹՚pGЮr-ZqC~&?(+C{L{7!=>VaG$?˅OPAx3>_-91J@MCջ6urQojRn2 -oQ;xyYU%ï+ qծB> +N;:e vڹ$W(,Z?o5BPL NS[*6- A?(֫{Ν/{ggB$ SR'8_}5~L;5BqS aдBf,CȟlfvZQ^pi ,+~RK}[(=F07M_t(A%e'4*e'WS$51#lxh(1/\_FfD<DͯJr%7Ц4~ݫ/ ?^LϚo,1ːk+M~|W[xrpOJcf|~ӕ %f>l_.i?"M7V} |ۦ8_YYv0T5a1}"QYy^fHqއ>me()ʇn)|UV9_!c+coB ;_.+#kW MHcPzp+2@áE~-,>ظj B1XC¾U*Ǜf6+jw(mHPZ~2~mvWdiu_ 7L1ƀ& i4z7_LԯŨ!} z8_ 7 Blkh\齤ֲ|s@SZJWP,z~f#ŮO_ @Ş}kBefе_.ѹQ/U1lzy\ HH 8W9VMJ@ٴ P?==3P(K~U𫮭 ~+d/W*?\ʐ%:.ʥ_d5.]^XίpNUDX=5 ~cær7+2hbسΦ4+^6~<;H  =v~W*oTO݋Ro~BOW|vyR`j$U(Y"j2:kK3ڡV>BzolZoa$|+)}+ ڙz:*CzU+:.KR 5cLfuQGSRoHp7 YӪ5+Xf%9劼ZiE|)kZQޢ7tltB˶ΌPhMʼ.DR!%cںRo/굡xCu@/ 3ř_&$A8O74fٹaϑ 7aU}EV+vt G嗵pl_\[޲{'!wō_59 ~ٯjӲ@y)me6~P^cy!ml짧)oԻepn7R2zR魅8y6[_۠*/ ĔR_oN_W9@A AyE{= (bm*%_\-!~ح%F`CJ,(y%J^PP*喽J˺*) HVWݥY5~ؓ'[TbCWhّ~ - X հ< k Y|.(2Q[E}}+/: " _s_ˠXeo7i{F1ѨRZ͏A3!ZY˼J@ac01Eg !y%b}B^;b3$_pP[W7%9l˿׹cxV/{30UQكҊ)qh7~uQK M5:B+#H ET/4(. ;cG΢?Oe o/(ƫxD M ^('u,X!ʪn`{V_:C?j.`C~+FvYL@CoT8ݛqNFWPFI$rfl/>bZ-v!$QJ|蚝ʈc*U,3EE(2Pz#ʐjR /(Sk5~]'5: SҧĐ Qůʘ@G JԠ?7(2-!6O7*!=h3 ̏=. V{1~vU_e+ǴAZXr9Co8/Nz~BifkPmO|TL~X{݃7H+@5["qZ@^4#/7_5 y2]jfӧK_~Wk=)e1!KsxC^r p} ]\E4j3ů,ΎQ(jέ,_ r];ΌChy|0t?v@7fǦJ@+_J؁o~r]c_З_\+áh56Rk3$3Z@%/PpO6wT^A Z8^C+Í9@eW&v!7c4z_pd8|YİIm92a//*7.e=_,S3bZ:_93eF"Y^{G BՒT)48 ]>cFYx~X@cLP^€_odMՓF/N'~) O&M_ܻWA Y׳ʁqYyuT>믇&@aeAUCK@Gj~媼}⇋T,_v?!ZGmߘvڎtjh``&f:Y^?T/?|M%+m~mYnY8׎tSʯEz"y?d7˯zFZcPKCJC'䕔,Y9b&zZ\F/tJ}ӡ 8LC+Gʩzw [JIPrf tSDž/q Hcj-? nIS30aW=I~5v/Og bUVq]e͎+Bq {Gt+d:_W~1?.j뤯 }sYk[Ի^RD mKi1[p} S \r}-Lctt9Ee@+ :“24}ֺ7[XT5 ;0){Vm6%L5~_G:oέcLFz0[ҧD86J _8L~\d_^sQ >>/[23|3-|# yRvd_*q" h1/Јyv~Wd|޳gCԽ7~UCߜ}賿ܹP(}^q:8uĖ⇕k+}L=˚ثڇ_5\kO|a&39@'I|;D_[8ADޘ3}X:l&nXhlڠd9a2aH5Y R_,BBi<M%>_VG˲3*}R!Ok~{/HѱCEdR⡛/7MMe[_*:swie܀[˸Jf5Li9#bA{@9}P&;?S+oL*u8j(_to_h$_:jodKRѕf6}ce^-flߋH76Cͯ*'jw況p]_͠Ou+ga_)޴vo% ZHfMCXa􇐓OD\Z2}#f̟gk!vI7?V,ݡnLr aš1B|#Z7 O(@3%b1R>Q&Sϩ\g|dތYN$[ʉCΧ4W^*kiKRE{8_I9NȷUS]f >痻 @k,u(#I#J\k d8Wa4}{uQ밪‰WN15-0հEQXHhynB㓉=;{'o>BK})̀"e/64Qmr ͋ryF:$HZ ~UL 'q]-[cˎ62sȥm<ʃ m\ӊdQ>%F˨dS6{ZKp솟S8UVY1~^~U'FMlל!X"(ob_sŖ"kS$*8p<=>B}2 egysLBێB{A\Fr9PV\FS˕^k=OX+a_=n_7 }<eKU6NCW_X;;ϪmNSG$v,kF/#.nsvIFXs%/a!W/YQ~YvB?J"UZp5/[\TRoˮ},~]'fHVsV{rWzFmTyTSByٳļjAFD5e@9:?5{CƯ2a<Ư{Mk|^f~Wec{Λ_uEgBA9b{^7'gc|WV U(-_JgvR3j9`EZ/m!Ǽ+t`_ջg#|cGfАJjt$r]jyz_z>1=os?k'/ͶiFC7;¯ANrWsdH+G*mY60<̂S(ormohYM>I\lx ?Sc@ywo68P{'1ʻj8~d89%/{~q)*[DdqX>GetCop}__l<̫d(_xR\%q~T{aaȯJϭ3L_o4^2뀒)$rAϡ<6gXYЍb~W~^邦_IНMX)b] Emm/ӝS(%`;㪔n1eB9]Kd\(nExp<$r/{oԽ r޽$jz1?v'-A⠾^cTerh6_Sb_9Keؤroy<SB+5 da'>XTYE&TӴU~̉dsdy]jPylX4 ry5ic#:mi^YX]Q5~ r@97_;qpݮܦ (y7LXZΡO?r>RWw)3LfwT̃A6װ2s1Ds|ZuW*IE }CVgR/W!w!6pk jV@-WqݥS j!ɴsA98r:Y9_MFP0dL||2h&ұZ*]/7ULCJyͪR!i'LPp @6sjDy v"<^2)tWaM9@{"ZPȯ9.C{6\! U9We\lX2d~ʫPvUvfaaȔX޲V .a{PACQBrrY)KՓ)oJ_Vۚ_އ;"s7TZPU˚Aqv~>C+ گfZ))R͠g&\.Cyeެ+բ;JV%Q{VgMyZq`wlAWf"]W3ٝگaޯ=_9BpRKd?ħ 5T::&b.|DU EG"9 e,\U ϸ9|uRm$V9ь ԭ>(J\YuZCR?3_7D?g?x~/XxQLQufQ7lfprf5dr)O٨F|FVn'^~on+{yܹǡU6/3-S_o yxҍm˝{uKPo،R F|5~[%yA'sU 61yah!l_7 $hYCR 5ԡ{A0~G ^?j}AU2Jp~!nޡ>[v2WͰyiS1*^1i|(b+3.R2P6 /Y -NauC/xe ĉ;=2g_)|ƣkp gFM%~(PjeY(䳍V^Z!u܄A_7{!Ze f*,  Fjx~IS(BKWn }Y}l;Jg~Ԙi0b~WPt(>~:,l Sn;6~_Wԯ1z~nH~J^ʰa}gijl)^oxcc?8T{śך{6>U 6nXړC)*<D<Q8Bݹ˯%*Ư$~%hBklf9tkU˻w?{^H0APNg1wjC~v(uY%\1LI~ٙP@~I!'-oZx87l/Kdݾ Af5h)5Rɳ携sB/ G^͐"YG~6%*Ư7l1Dۯ߫)%~Tu _- ~O_.k5G ^X4~_ܗQ(>a}Cs?kBvj7W_uX*Z'p<4(5LT, zs[|pE*p TV,J~L*UZ.Ì`C~7~G uZ>(:nDo(t/8t-c`'BwJ{ͨJ^Bw~d|jPB78ơӡ4PWtC_PJN+=KW9–g$hV*% ʐg |z>e /rQ(5cbW -,Ymt ruY&0i?,:o7P~U72hn_SJg>:ѽoNVĚcO{kn^%oLQ-}VvT(>[rbVΞRWd}9kx ?,OC8 fWOCUJ)ױf$>QUklJ((oX Wv7̫Q GB?Ϳ׾cBg-*]k.k2 :˯S7r7kޒMOuQ b:",oP}5;CHpNQ]faH/D|cߋPliE4/{ﳄ_u^q6_߫G%+pZ{ɞ^d%ky~N" Z}d\Z}}>{֌ W1~p ˫y,Ѻhݠn~{ +ʄ=q(ODrQ|C vR3.NK_yfqGl<u1Շ|mvU5Ѳ< 3 t-~H=;@$̆[hfiPZbA NcWW*~uRXx7~8\bU -;Ӵ({CyR>J?>_A_կ6z~g&/VAOpXiLwI.1Eay !1Bx|ä(lyӓ*O$χu7xgDza3ݥgEvvSz=h~AZ̴P_ԡwN7U˯Η_\/xPLNzAy_7_~dJc/Խװ:y#:>ί-_5-@eȾe'aS>S NQWάܝy5'Qas#2>!XO1ۯn+uϱX?4=*˃{a}}_r[or*O4㻿L)m,q/nak=Gukᨙ)Nw8bCʀ?侧}a/6e֟kk9̫tP5ꝱ{~$ HV_kAv ;ʖT!|hLo~/S)i'_8n5e A<>r]_ `Y~/_]!+a5b_@phacЏȲ }VqM2Xqrin!W }_t}+|lQ/nexϷo| ka&@Brjunk|=_D!~h}"9/Bl|_۵^{/lcEIU 7Q'ҳ`YR/3m8٪nK^ ЯtZb觐_!%_}l(a/mŲY|5Y+ïfBN@Y_PHO|MY~H_GG/QT=?CgQE ԧmRJZ%,pywo뉞i,Y+Aȏ2]z>K3l*D/g?_J@?2ei~{2R3 Y6+ABRai"Jg_n_). ?\ u;I݉ZA+S-/6XoopYshX]l 瓡mMJ_?V~-&sTwq2ei ^i7*8r7jfs>8{>ğ\PlW~1oЏ%xI~7ʑ[[K&mqeqrmc|ڃf1A?q~&5j!:QCwB:q~Y.%m`=ߠ_v~n!-V4=ˠo~oai։~[wh 2#\~З_E Žx0*¯:Y-G_FR/~t$Oh~U7?P3@7zͬ>zjha AQSb>g_jF1z4G!g; !|QΈKFEQU%_5yzX%"o ZEjnjA`yV~Y~TqċePO.E~r*oΎ(o<5Uz/oa>.c¯[O/-4~1P[VF_9;~Oo7Ay@kkr= |8().=|KHfW5Q}ʚX[|Rn#gܡVHZT+W7acja36*jO}so^Y.oY=.5_ —ŭ^@}?̵Vs>Ø8}⇃%by@m|?畍_n9_Y\l|Q O>t=>{ |hz(t&|l]w,׊ YD oU{0hgA+97U9~MBɬtb_;q" _vU}cX160~k _%מv:oq(]_r_oZ5QH}NVk=s"?|XI/(RƎ7ste'_! ݣ_ٕNuwIڽyKr:jb.)FI5zڈʳ(C ѿ F[-}/FGVnk 2I_^|K;X/FGͩU7*f|H6<OÄ4@c21u _8$D!(>{qie4>*=? Ȥdz>_&:Ї_ۿ:y%3yk{C5\PosS"/.}GDF}3_&('"9֌ea 5DPgWzlkFc Bj9=@v {BDd!f`uugzK埼a5 _D1XZj؉K@-QC^&Jg2~QȦ AkLW^uw=,Tkʩ7oތlPЄ~5 (>j ^}Y}̔nrLJ_=H$^>> [[ύ )yOrA.ݿ׉ _dv՗dvo _HR: /^RN3k"k>Uz^CPbXCU|lk*9Q7?2̋b$+N_<4hHj_~abuALR?z75^9=lP8(~⇍IG^_%CQ9~Liggɏld](m S$YQX~LD}4- |q_9'DA#IjtC s+~xR|(T&U<~7yGo!e-]GWn>믧9T>Eldmk_HHռy%t(>-Gr4o+zeYڇ|eΖ-lygmB,Le3/C^bu_j=!g[H脺QoVxV +GW U- ZoRQ׭2QKTslRe䊴al@]]@?סkTJs~ٮvÞjr~w2cTN !lH ޖ1!mW 0f-DPյZvĖ7j9ҾTyˡ?]Pȼ_fe;\^>@&%#)U{0Dxխ2tYK!vflTˮ:A J!C镱]֪Ze`k{T)YT˞E@= *3:f@f- wJ^80n7Eelg%~YPs|u8__"뽡_Y3lA_mz۽W~՚_ ;v&Q=[ހ;ΞG6}/Bk*D/^m&iBOā_2ۄN l(/?=YFo7l"L E˟&[40@&IBP LG<ⳤt+yn/ D !&XZ\l4re'ūk2 ZT./ȧ?AB'ѫP¿]ǵOoHñp@RWa:m!Ji ʻRzasQ?аzC=h;j/uKVWZ:~Ԇ֟|CY+$qCZ3S7W3]J^= ~ZYV0H+O M \ =! 0•_V, %P?ź}jZYo1U\mh՜yCs9S >eU n*_yzYĉREܽWZH_e-KUB/erBBE2)c^M#oGIm,|j|7iiZO|BP(3t N!)BrO^flmxOn~J=_9>w@X~Ը eZ8[4 S(YDoQR/#TXM  p+@k+kO).9S(D_gߎzlJQeQxL=!(cJQYԚ{C o8 @M)2{h}X BA:Oe(Yv3!{_6(JZA'X7F`^-'BG|mmJ;{!ċG^HT-?Ttl/ZǶ S;M1~1 M=FQ.^вa\ -=LȖBx%4OdJph_Mf_YxRLۇQ [/Gy֢߈g m<|~*_s QjD?u4ø1l"ZcCMVg3j WZt/rՔ_7tV>?T^Vn[+wVί[D[ E~11U?d翬 j㇞󆴣>ZW^!}O_Oh8>QT2T}*v~h)gU( 1/TU>L_ʪ>QO-,ʔ>>LDFfWuV}"C}ո捩'ѽŧg~Bq'ZQ'{'~APލb/l^ϭE~A4tu%["_N"* tvZ_j??sUn]a5r lIGbG?m x@ &'믾C5B{f2p^jEzs=?7X7\ipqZB*o}oH%/gUt%<^΢bGbCHx3A\dveżo~ "u{oPŕ eތN89\2DɯiYZ< w1B,{'ßطBxFSx>Y9DpźfQR|N|r[֌bFG*uQ`4F}^BѝTCJ V//r:82dQxNg2;Z q_}nz.XJ_Id X_5ۯc74)%5S~u)8C>+늳8W_y .cW=B`\^^1@\a}W WuZcBBug6ݪ!]2Ưjo{Mf&B,&X;p߆svS_; e1?b~l.Ɗ:~rv/3'`1/L'۠y<,~C28oBZ˔DLƿr`3bl #ߐ⤗n~y3fOа9\ g5CGaX@Ɵ 0/ZcQC 7$ >{$ P( RyuFT,A¯_=C~ W21bx?o'Z5hd7<1DHvUoNPAC^&`Qz $5}YLCmeC~QtC$} UMF2\WM9 7l:$GcVsE$:Ѝ ,Mc%1k;J2~AFn/ց>x|J~d$sN{@X]@_ktm6zd:j"eWpCil+XsBc/ek>M~j9tܻdPWIpϠ jaA o(9/[RZwx~MFjXS;\5lPz0&чl3ȿ6_p ِ/ p K,ӡde_TCc/RT,,6_&*yڄJ&ZX¯iW`)SW~Keqi_&0s2KtI}WQΡcg/J _J|:a״#$"oF _D2 kb)D /QBT$%?_|9M5lxDz1c&ǾٯbWy0 hш_je;/JE'0K >:?l6$~쿮Yۉ| e! kC9Y)52da L]k@)4_Rt[Zf W %t}ʳ *=?B{[fTvvyiZY.=j:/ i!)'M&^It j<1`rpb)fAN]/ƍ}5/W~1>\P*coP'PJtVX9l oY]bM%!P<~NoM Z;O ỡ[.$]:_m=rϑDGE/--ζD,PvM5Uo,t随M*wܵ]~ח_/X3(ZH</} 3[Qplz5X/n:!_$ f- [ WT(JֆN=/6uJ6~ 2i4~gq #/['?vՌ*Vep4CkPR # Yif<ȝ5v(t UH'hB2pnqUBP~᪄ ;4L ؗ_]_ԯ}l6 CTsg "Pv_ 9_xr7~?ShڤP4 A³YONTt~!uWïlZcs/o pPkxY\¯afpWqӴv ϊҧ""_t݃ïN5c^_ Mf PDmT$J!~40d/Tc/o Vbُ*:]GMNV;Xje_Qh~_蛛2T}":ɨP+g8Š @? , @Q@=,6=j$&g7\¯UF̎IcLHï3L+ۊVk~5m' c>F/f/E݀J=4Uϗ^_R7_XzYUwGcT ΧNWT죷1mT`@}e8(ȝ I^<2u6 VXQVOx*}>_u to#PIGIyl KщLɔ'Ѩ"3]GW$P\yU_82d_ ed_C.(-IQR[+"¯jo'>IQGfeVDŪV^Ɣ`#kS~2/5_f^<%?_6?Op|_p'>rm`sFvfW7~ )$?D#hNJ >))γJ:U#%6qk&B1|a#\(krz]ʭ-}`$s &~A`QZ+Dٚ^xW/ipWSSEA%gaLk/TjJ!z2~e@V/BDBgC "UO!9螦 & WxE"ɠ~ejV' FSl6z:c^rfm6ҳZFIcrT+p7"zlЧ+Bi]q#Cοf_l B l9VI\^]7rk>YpI"Dk,~bJhMDdwT{Vm,5U+E嗴)L e)T ~/@7@~!~ϡ$* PU. f^|?,6c`W(Z"2~4ax)&*Rg|<ɒt/**Vz۫[3K Hۇ_ ه_Z __7%>BY._8&ѧBL~οk6R(JR_$~|z'B}J2Ѵ\Kl"_eb BrUϒXE@Aq $ڎA k_8H%R8Qm0K[O|cwrXl6bDZ:Q~fP %=z(^$o;)Mԓη_\=>[/hz,h|gᗫms‹)gthZdoQp)) : 2efdekBOtR*+])ROs{PO$S|~]Boո脼5LBk?K艴r%Dnl҅a?!7oy_+گje#&360ǠUk6~eHy( g|8+?ɑ.~AGt"71 N}d9gu_:ʆSxlvvίhnжkZ6ʯ?lhWS!|-*a `Q ihWk@wE!>'Л??V4Jdد V+/Cː7>JٳC.e@_GK'!K">̢[ar]g/lP@1/_&ks]g9~`/\[ ͠uj6;+iʲ_(F}3Tх__"_ځ5yxWV*y@iּ1QM*b3~xP(pDbj7&EgI ^~AXS?m"R#:RE]ߠL18sByEV$mzr~DcRFK_eXR56O|Q'>?koNWlQͻpo\p\J}8EO|1@SP& =]@O&0&ޚFAw>N|li1eKę!rbsqDm}Œ%]^c6yX.*'(*91woW6~J9H$c/aOS(a&qôߐ;/|1>n#L@ON^%hܤ[Da? Gc )g@O z`WBn6@B,@3~5J47}~U1G4BT "$~eߊ9dUu  כ('1aīBA>WoO~gcU9]F&^VRi.%6/Uy{r~y CXB :P0oHЇ/7Wy>2/ 0KMdz|~_&Kos+hB VWӯܼaB(V@\p"V:kW}6Y(8'kQ`+PLy#Ǔ6TOqQlӁRx!Jcٻ!4( ~&[h59>oѴ0Mj[ĿD]N;QOn? hҫf?e95ԧP_O*L~D3JIiE}/4Rau?E߀6\/^@Qٿ-V~z;'x>ք#-="WDx+Y11U΄<ÊPU 8suSz3hl\ik) rKlG#M&XXkHsxWRr<+ 1v%SX 'REjXazWI6 ig;Jt6Po~i"6~eBJlt[^u(Z'bR ݑĐT7D${󪲿/B,mOQ>ire6B2W#ҝTa IC2y2 iC٨#;BeW9Џ֯VbR^_^JVȪe7,aūeFuW ooWBrbP'KZ>l!Ծ/7*hY\x &Iklҵ*W~u5ЁPq_4!W[)[>P.%QQY4Kjr_h(4I/\?O1P)9}9M7Bii:_=Z#B]VJ)3 - W:iW@U]F BPЯ'alp_ L $=;mXi!uKDyP^H6BQ!^fjME v?bZ_ 9WjC~%$}M̡6\ ?u8wPi+ׅWy?_UJV]O\ /fCJ+&]@_7.uѩ dE4_aK_TH'ޮ80/<FiZ !+ֆh?DlHɉQ!pIEU?U3MjjR(CV= =ժ)c alW #spHKBG.quR4} 6k_hFg#dIw] ԝ/\Uu/>DF$˔w*( >W-;_F ("^h_T'JVͅ/WBp8>M???}hi&7ϗBKM⹤AcyyCxK_WӻZDZF'o),NL~CotJBEŬ!er]Jl\J,Y=oD%>x9T!6 t#  ʪa5/˽~o~]}"0wx~T'QD^U!#$rE(4݈WYѫBEŏQazY_CAy1 -Eꁶ`eՕe ;/>%Hp}ĺԡ, ;o-H$| YgMOxVT"X >:$Pr7;żB}m㣞'Jryg_~! @~-_?Dzp]9/^qe$e]kK\wBȏ>X}\*MG ~매@hDw>Q/۲ Bq@P'Lh!HH}/:˖E}vUHP!#aD}!>@Fc@IApڎ@TTZck@P 2ϡ?__Tў&-p=)W2d^5 JD"N?_#@_QT}bBXBIe]14xyWh [csf"ze 0rGԧP7<_5V5_GWLnBr  qzGKh1P?O8 񑇾eɟk&P3 k=IKt4.CF^!f5;d:PNLsEe~!n/*ZHܨ *o:\)zIMHAFeD&5ؿޫAj-B@^U+(& v7hW.ş˿㱗?j Bfreâ5fթO 췔Zn`WY솕k M~R9 A@}(S .^ ]5}U8[lη\+'6ܗ29 01u%]+KGxsk&M?ϫqfB{r.\K%$ddk>,N+W=hOݜuA1'Q:]A1'UvCV剳 D#DK-t*dɯ_'쪊C"JlLQ'n<SdRjȯ a8hqD] 7#$<(*o=DoLhae+Ccn2:rڕ_S6Խyc_^_wqR,,86b^Jj&lao_n:lӟPՌ|0.Ưb^ꄢ/*6hTf ;ɯ~MnͩO4C~B~mexAk-7͖mn'+4SjBp_`5̏W~eOKROV"ۇH+=B||:Ұ~A%G0ךh_v/*_PbזkaYh1Y6^ #bO-_6O@ Ey_~CcnTWd pH5lmWn tM&_ïrk?Db3HQA1F!>_ \*(N; -1~fW}M)jɷ;Me m7ڦֺp_HhGlg\/ d%M],7ldebSd 4Qg{rD9'ZƯM뿠Q"_S~B9PyՇ^_mr{C\tȯD]A˯PU T~ ᷄_ʔm_\s?DJ /6xB/( {w3utgI$_H*}F5#6p#>?2eL!u aV5[N7X+tCy`yQdC87b=cQ\_Mcy*kŷusE$mzˠ _]}mE>l/)/wr~u{_Y\I?mf!6Ǵ MԊPGxvWp Ve{dJ!E+-&~\jxõB 72uOma%U ;!~ honBNɶfdmj]eL9/bm#vBL W,>l{!׼W=k!~U;BWHB=r0?2d_~eH_>~WzX)+a^~I0r=H鿇_.(V~x܂YmpIY[;B۴%Tf^Q owgP)|5p_v:H/ rGR_WAN"@/!~ohJ>M/'|$LB+P3=#)Z"GVj|#_I$IU~~k0¯n+_C:\+X;'K4>݉Bhʡt|7?X٦b_!~3) 1[8?܀ YQH~BE1ӓ9?T|YhJ PrNvG*:LOzxv#~ YH?\˄>W__zg_pˡ ͙ڗ_o~{)%P~eFkv[HT*Gأwb˦[\FWICr![F^UR 彮⇘s-s |٤.09VFIj3~ Bv& f"e!f*9Lmʠ԰?DC!+9^>3/F sч2~A.M +EF0oTSJo4{_if$Q.])Vw՛l¯9њk#|_a)q%N|˥?!k0ïih1+q̵1W0LKU/j#항~-jHQ͏Z2CE_ju~2/S\,GA&U'+l$n 77  ]*OtIdPzm kC{M u&@=@¯lwR_(e-y9_9\@]HthS_8w t~ي&, Av/{_W Ŭ<<USWQYt?—_WI/|Iק/B@~bI5T-q()ХS(\"P^ZvU/E2`0,+ /_~!{V9/S PO;ƯxvRcW+˕˻i@ nW5/ͫF %RAï* ;G4MLC$+o?2x[L?#2ۯ Vyl}ʚ7,v`DD֊ Y/hDF@*h% Ga;!_8^T}X_ͯ;_1]_3߫DvU~ \}sh$.D jXh2+QP/CWATV~Um~\ɐq~Q,?6$*_IG/|EQ}zC?|Y?q~a/$:;2LK?>9f(`ד1 ÄH Lkg<S1?L /4ч5 uM+JEb}ش ;#N >lPV܌u(MA-,O1UC$%̡+|6͍42ufÐ CUᗉͽN/Vv¯e7fhq97D~-y~/JӵO%r6ȣNқrΣ1u M_a_*[0_! _ņꧬv?OO >6inoM z/!*^W6 "SDN"DGG%T rjP~z9J9>r♔oNxϿtհ̨lwlEe( ɲQ7Ia ~ l99%4ʯ_!>*VΆd´U$'{T԰ᐟ/g@Hn˛;Ky6~{ vZ1,>s4@̯]e{" 2rv? _&ј( E$?J|)3:ɏJlf^9_Jox!i?ҟpxC}F*l%K7[lu#e'Jr6~)S\K P:ԙr*?)N?*ket}#5s`UPH /Lߠ"/d E 1TGo/Hy"Z`WQ/B{賉>?rL}XHjc_($G~ο{=yN5{K'Ţy*ïkk{I$?ڊ TT*ע^OWϗR 5K'5l}ã1_˂P_rŎgsm9&" )5"_JJG _^uUk}?פ'-uMDFY'#d.VK+;oF|/H(DrZI~iWwOBaQu \[ " !!lJF8=+ЎPˤk;r0ͣ/(i/e~M׭s`(9iQ}. @y~@裡=H(hqv%A\7ɰ%*!Ov8;+*|_P}R=)~U^bOG5J]ؓwaJ^W& bؙ@W75aKƏ}WТ6_}#ĨsNVO1nsR@WQ~9U{ˑ)ox ީU+qh~|W"W shK{vFnx#WJ&Co @j}Ee"_Rb㷒^O%o5taᴫ\A"0D({@r'?'Bz>Ȝ%Ckڨh@(_lmSJܰ(Hsp*//*jB_#dr%C=@9tO|>W>?,R s(ʲ !m6g>GVe0=,Dv6|oy|C|UkohDEҠ!AVudV7΄|&!K[=g|>5lD"^ ~e."!>_Cv3$Np]^~=mQM SP,7>_oIlP4g{b2ÐHPuv>ON;5pP@Vf:§>bSw[Q-٘hvx} d T˖M< U!+ =!#%PlD;/= z6*گM Rxcػx6_ly$PJsD7 zTRnS~1 uyE'Px̽DQή"4^!mU'fjhǶw7~f–:x=Au@?$EW*5pdGLas!FL2=lU GDk7TraW&}6 cl(`# d0j^_YOKBA+oAA}qBA+W]L?r__}^~W>e@80*O~_%x^/FPkLRպ r&oH+S>% [G6xvd=/ZLQԯʐu_6Ic\<^q%!ї?[cJhhFOzNP0̠JfCD<6!"f*5ڥ9UX* d|CG5uEK6{L/{J!qVBկ&J8Bvl"X7Y"'d .V]hƾqmEa=["D'] ҡ\XD qٚKd;D˿6/QJKL oUғE;W*raꮻdWA.9ˇc7d}JCܕ;ѕ M.P|q׌ȴcU\O FEq׈%b}d 'Pu@EF'UgZrBmW§Rl8) SUJA"qvqq~K> +NT-(zbWKlmvik>yT%+hF/66 egEjի^2~Ј/~m ϟd]A 2qW4 KDG:Ձ Y_E-^/OLos*`>Pͨ_% bb/4:ޞX+0AlQB b=K$K+%TjBu6)KZ-pE3WPl'E"qf|~ް&uxt_J)i#N+p &$m;ϗ ~+{debCљYDM.)W :П -NO/2vw_lv*vlԴ_9 Ï͔SST&rx@"'2/HHvU2Ud[~!>ja>b} H_}sksW!WpHWH 3p] =Dӄ,\_koiЀ^žH|q@z'UR4DޗX plWjh.%_%zb)u07Rq%jM6Q/B4Ү_[2(H W?v,?P#zB_{; B|~CصI G9BP~aL~tc@@w=/?[f|)兠j4P3ŐuW+},w2UN\M!د9gy_Yp ۳ۛ뚥lhgg8CT}-憎DA}S|/gl_"kL˭C"?q OW{b&[ݠ ~4'7A1h'P˦5 ~~ͨ5_ ~B6  @z(їbߍF}"C*dU/Vz -tTna2:rB~B\h$-2bRUs!̢v+Xs~ ( (kWD՚&NOaBrNt:~k ~s_ռw݌/\ ˕+rV/av:|!'ZmY5a*W6x7mBNXN![5|?'Bj -tzzd?S!*zpӜz%wc_HeF1~qI~CGXː-祘aj1RqA1{)7_˦OT# -hCE8KIQ_͈8<<5qIR?T%mP,UQ&UC.{"_V.|MKڶڿ7ƯdPBʯPϮ'*_ _B_0/*4$u6|!9qyЗnx*( UP~g UP,B3+*u#S0S/xC)S iw|bWpCY0Zv(Ѩĩ$6 dH'LKt 4;;_oyjjk@gaAg|SOj/W9|ͧ_iK_6, 93:޽] m \C.QDw-9qqհ/TP,̆4UtN7Ö Jr:4l #?۲,Mv ?\2 r~?T:/y[&P%w. (vN8$σޣ4S6K$Stw "vCXP}L(=FtA/&bƲte7,U^P+\u@_"(ïsh.ٮ᷄_s_#(["\\lLOKQհpE{Bƙ'^pY6¹U{*z_5lF(㢼N:?__~WT&E9KޗqLt_ ݧ*#v'!h2(Y2ME{`ⒿU1i3}9Z7_=*_١p=rzXb- /Ѵ~jX^?<3H"QjZz3/![?\ ;vp+ uEwNބMoou{V~}/b2(Z~!SG+gs/M Ukbh%_tZH"lҫ7KƯI3>,z4j.9(,W_>8peH9!%2hE!_JJm{_PN`z@¯͵_~U|.״[*cMUâi\yoq!Tjnt -aW*:31&{˫'ִ#ehaIso8c#_E_ۯAȷfVV-l$o^.f\r~FdJfN}@XW"5~ ,o40B:8[Ø1`~-Ú_dD.LWMG^./qkKu=|N9Ph "LWB/Wbya߀Mo M/D&>Bd",#-/8 O˴| jnmFpت˃N,? s)#<zmXkʏ2D}"U/Ц@eny_{F]]Kȯ&w*.r8'Ch!I{pDwP*b{V VzWqMI W6(/dD˧7Q[NDч E#ueZ);:qj\R~~KtL^-=4]A݅nI}뚵RG8bECK2=>_Yz(kW+:H`+K By/2IᦒWG e|C^Ŭ!a!,;ulb͍T3}s(k6OԠAs=0}=ï z6j J|K?W_")^ոXdjd7Af#na$?jt'~(˖PX-Fy~7 UqUQWqG[&Jˊm|Sū VB5dq[~{UKW. ˦?DZl/I;)Aahg/{:7צ$Sk3NvW__~;RJ~)D -BگXQ,-/w`s_n dYU=/IKnyD$m:Y*Yղu%xi˦ (̏L2Y%h%6Gx_ 3*c(VU[ +Ja!'# 7aWsX_n6 a_ʑDoe3_Wv-QEsA/LxYye#-LvLP~%FZ/9"_j-]{گ@"4*_T6҇ZۖCnehhlJI @>.nmVU1, 5Ha49ߣA N)zW7i7R:1mӴm7;.>lI6?DڡBo!\o!~Bg#(atƬBٗ_(P~U J&] T>_~HsW8_~G yB~9FiW̺Oe*,FҽKtΉ&\9agJU˺/75>!9& 1Μ%r((SzWTYjZ (ǍW) F+]"4 y͍ /0m6qds"eZ%ÊOau5B?B$W'nJ^g6V/>K9CR.\[LM.? ~U?J }>KKD6L _VyG. Rſ/5.򥕭8 ;{\^ɯZ81xyn>W#W&WLۮJm~_WxkCW^P~I<:—_ __G4.ue k"ChCsI~/MP˯7es46x-K4 6oK^yΗhCIi::A辢i۔ЖYm%]H0/- =}0/XM bEy?7{4W}Wa+\WW1Q_:"K+JՈ'E'|VO~o@ f =vCg#røJ3WCĐ{66yJ0acqw嗾 bw8q[Yw.쿤mwV+Mjc.j*KQklu@TdQZ8q EyaO|CeZѯ4Y}&ѯ4 O1;z0_i2dj[F+I[5ha<1L>I:tꉬ=rj>WKغ=rf2lOo0z[ڻq=FnFL~-u҈_,A4o_RNMV˫e rkmoԜߋ5o"_ڨGe@y9pi?O_jr=~7cRm*Ic_bED 5P~ vF69R9_nHUk[Y)z6`S]4D'h8w|%拊$d6_ۛ["U@_¯aΆ5 簗_[k~ᆉ\x|ﮣkq->Wy-"_ L;dNگeaz;Ͽ2""Ud_tR^9Ú_S8/ tjT(Z)jvU¨AJ}x\%z~ ⩙*-$ ՉaVSi乞:1H8z}Ͽfu(nT(qxB'd<_>G||V"B@"i_PHjMHdqU^l_ ʦ&~+{7nBluο2oazU%/a&wcEڈ`>=Jbש&GvP,x9O%P_IbgC-D@1c$;Oη޲@qJgi_ ,P_ )fc٫S_ h EԲ]~E\$%ȯc6˦"VЫ\+zDP|R9./'̮4g bEW'3->/GO ~mްDtx EߍNHgLu@)@qa~$J;ruUwGV_COkw&vճjݫUTxK%Qe;s2=I{+0O͎b(דglГXCOf:B1^ǡÈLb\+)~~ 9[!DAHfU BaA3IxBe`BUy!_7D]CZbv6Bʄ 8)-RW#to6d='/0V`sͣP8QqSΡq遂W09T/#0¯G_3,**_8>~w_9E!sOJ²C!%U.l6$aTQWjHWɬj!e@V%Wj}>;D&թB%> W/Q&+j:Yly>N[6.yvM ;J7$iVY7:QHyޗLh01PP QO VřW`|ǀxU(XslkMKR%=> SJW4%!s~4{r4#M%/cX^f'cL;ɫ^?-ù=-#c'!눋T@c^xd_rF-Q#$_|u;wuDǦW\Iu?\hu5S,ۤjҮ/W'VF|__aI_k::V~SxGBPBh^)U0U:>rCQw(!S\Y ʀ #_.4֣|f7[0uM ėrv.3ߐ_hEH-'46QDC:ickF}6>jS]+ԛlrߗ_ |vܴBUG% E ! S\V4bV)-w6K++ ~}n_2vM}`: c2v*Z|nx^=×/TNT"_%/)5ӭY~NjD qhm-p?#w6yiZӋFb1ƮND~Y6ϿfB g|J8Qkeˆ|`P/寒W?:E_%h|Ӥ>7kW MjNUakAVЇU/*NI~[_7w* (|Z.;9zdBO/g2@ d}=#@Ay|Q'P7 UW{^ѿWmW>AGAg4ǞfBPs_hP_ECBfU"RI,)JJ!5:}#\a+ &sȏb}g^)N.g+lH-WhWt䆰_QUPE~)\PѪ !QVrU§RB| MϟZ =)c_FkaP&#)FIZ=l}$:ó}ߑH&y0_J~JBqBXu![A㮬8x I+ FB:Vv3\%QK?vsDo1 b?og˅v' ; g!)KZt/ۭFI`l5˯!+*=>lX/a#ʄhE 9z;qSa6緶A_AvGBjq{ _%__%B8@w6D%BcrzFx9*d"LT kF3S$2sC;A3.oi\%ʯ39$sM'#[|..s̨7LDO3ؚ}F('i_~G8_7mUOi}z8/;_v {U'zDWBxq`P؟p\ՅؿEhVoB}ԕl;/@E5CzeR_E_ ?2.t|q.Sߡh_O_=ZgU+ʯ !+u?E_ 3 G5e3(S _2۶!DP.[΅VekNG [췌Pppxi+!%_Rd/?\-KqV$X"?_ ʁD_]'/O [_'j웡~ PF|PDqQs>PD]Q mÚ> D~ >PmO)9=PK? i' i0' 1s'*4A"'jm2C'_>!Gl>9oqFunūFVtϣ%ڞ$\}Xfv o%R~uʗD ,/_W!WQyVj@B|^JMAKy2_Բ#7ard6dL:P&_~;xyb+;\ dj?AePްIUFq ɯm/;B s.$i$$S)dHȟ/i=˯[ѳx+6Z*: ׆ ː D/DPKRh$:aEX+/8,XvwRmU?Ů6f.^f{~ Y8Ηח_Э8~̢ڮOٝjG J rD)l}4Kz>/{)AS/Ӿa\ P h!02ai~Me5L<=.߅-ˠnKPNoEgd/%b?zdrv]Ѷe-lm@E|^ F5:/nUkF?fÉWNhHm"DyCTdlQs5n*ODltClZEF8_VwcCdZl&XdW_OԚ:ֹ$LTLvq uۚ5r],K!7QWpܰ%[npno ZlM AN~JKUÂi;M^7Rmz[N~s-!ο5U5}lԓl^IC_6\zRb a;s}Z &!U KZ84_rQRپ/oPD<`D/͐G|WqC-Y+ۚ%NBu4|Y` A 7R4R|L~As[H_<(P ph~!W5W?DfU k_HUMp_eI>M e > rG*})9tfrW_ӴƦ;#(P:_-zŶD!s-хq65Η-:#9X_H@U~/ׇ%ĀKr~[ Rvծ&DW=9E2(Pa/HQ(W^M1 _*_>a{ej~5_P]q 5Zw8ɯn3ﻶWb;@|1"$ɗbk:'xٝ ;jC€WM׶Gn($퍃o. @MPrK 9ϫSrq~@yk,5vR `/CHHe *XȝJH|A,1? B? L*Wi?eR@G߰zL t ˮ4X]lE˄R vYj}_ \P~Vj*׶0oI50V!s q!S7dCE{-?>)Z*%_CG |XE.ώoo$OUi15QK swU %FGv~u@~`$C)8Qm6WoQP)ruX)˳@ס0O)ش*a sI|g#V_#?4hDH엍p=^ fTeWn(hrf jX%k[Qw(bV]uns}ˬ_t o*l'Ưe Y Qd菭_4me/&p_5/TOFj[{֢kVOQ[~jfJv@`+b9Wq(R7Aa#ˠh$}m#8T(^uU=r_KX޹]0BZ6#^]5ULʭՑ쥴Y)m`~Kx4NTO% a4X=r&^FTjPK|CUHQ/\U&M$a~)c/*:ze#_P6E(_"eYd1"(bgv+y*+t/`0ae- K B>BM __w_lI2dBG0/kC~QA1~Y~k*-~Vr~K/aJ_+-Uk؍J3luZ0C~y| `56kã%_bkD` ߐ _Ҕ=~qgGӆN5ʯALpeKt2o8|Wv!1pQJŲٯ?U9Ws% !*s y y裒_n_޴A!Y+g#H|nF-$nH:`$pswNֈ$J ]@uzch1nju$n FeڡE6Y(_ Wkiq>6CZ^~ο_W~I5\Ǵv8_V/L{ Hd%^2۲N$( ~Q͛fQ3c.?DR@zQɕ-􍳵Q(f[3qA-K-@ǵM6 AU}Xad.FmRrQگd"_3yɏ{0˯d#\2_ȫavesKh|G Jմw_T׍otf7~dː-8'I!$KK~W%IH[xUCȢ 9!BXE,\:.e8U 9WgCڏW6â=ίVE^o3_9@017RUa>l:}_}Z{MVEQ7y6D%?j~G˯Jn8b@r[߰+ ɐ iQRKq}/ O~%˔ѽJiald-zdU2.*Kp|YԚ܊4~MBk*VВU%W7C,$25 d!ya}Jk>lkCGcbzA6"~ا د Uɪܧ4:dP ~~M*)ƒR#gTceRx.\6m/_~׷~<% h%6ɔ~OdAx'˺oV_ }"qA|%?7U*[ߛ"_.u*5e/]Ϫ]e)^ -#QA~h],VO+MuC} BDդ`QM_B_YCcV ,^Aq'&2-"TgӉ[3i+B8Ԇ_J^c?ABioWHK?LdDeP~t-+=y l~743m*}sF׾/S\-~O@L_m {]xb,6 7+3m˕O3u%vU/Z~^~IgebX'՗b͠e|6(g=@hO|>7##:/7>_2pBa٘qa<_l ;FE|YEe/6ZdeTѾs,lo/2ױ?$dKm_ PV߀tE$nR@䟌zh/)꼪Y& Z_~ ٩*TgR~upJ"dQn}J I7~j&+(_ ?YQ'~X+41Qӓo՟aAIï-hn!ݚ̛j6!JT-dE=6Q/*y]Y_ಛtJUں\NJ c5&iHPWf ԢeP;;^E/iTycƓoU &Q֗PB:yM6ŋ8  á*ݑ_l]"s$~5je!ޯȗtWs%kPa- _h=* h/ d<%F`&_+='Y9 SDŁn""Ǽx\ǖ)yJIb'%PWi~?ٸ t?CTr ~1G'>߫鵍HJM{6ΞkWUN\l?Wz,yD >=K[+=@oWŎ!+s|h#+N~80:=1NfKJ'!$Ei cag]@1n#Ab/%W?E _򟡯r|R^p.c_%_Z_aa#)? [DkBu@ZD)_Pi.t!Īzx.6Iqy7h|_a3Q I8ofwȪKșMxUWGB_Rw^hW# ]a6ToW -s_D0W 量kUs~.b{˯P!](О|`:N#S՚2L骻T !C|?7,f8u/gRH cZZmEB̳:6jDyݵM_ūopt6pi[ UPl6e_A1[S飓5M#xC~ӆ \5_xaZe#ॏ@R\e3l( < #ՙuE$]Vw7D~2ai^U[>  ` vN!nNb8>A؄i{߂^S"Ko(_p .Q{O ҫ$PgPu[g480_qܤ o0OĘ1?ۯdǫ&F(-l5_}\54Ƅ[k0gzWNOI8~U(_ݯ,zb/ВN! ~Am6E(]5 !%Nj#*aldVc7ϳjIJw8#KѴmx;'-/ـj&z.- wl8TCϫ!_;g$%Ul zB"J\<GKj '%zuķe~齳sCtM @=_Ш8_E}=| '0}ȴ_lsŰV]u-B3BgG<Csk@Dq; 8[?r7g觴yEH{T_UBHl;vf_H&++PR>ەL/NZm6:\6cU93NVAB0_/eU.Cʭ% _Fbı?@Rƣ&E?H `Moڬ_n!x%ןq-Q:>rg~/\/D"JԆGgHF}.kaS6#(&cNT1oNj{G~tUަ?%Yʯ# ?[F&ƕ: kA\J/IkAiv3pPiHu* FJ)yWE{C9$_8gث $]~{y_{hjD!Wjpa7/+ɴ CeF5<7F{!ty=PV<A GHkW} l>J_Aˣ&?,#ljZcG5 2kl J/ 8=ٟ\',UpyH(db#+DDp3QIoa_2~QZXtN?M:pb 6Q]&70K!aD_(y-%U|~ eֿʐ4ȯ oUz/Tjj4cf~ [}թ7~VrY+BR3oZayF(WkT^[Moag^krz1>Pæ.V tx6d}ͯW8&z;_ P϶)^V@us5ϏJK :u&;{U]lJUCƯ_*t|U̟Aߘ<;B]4aeE~onBY?jfTc B5؄=(ض{Y;HXDG~fC*r +=7<?/T 5@(=b 熾( jg!^~_bDO$_f^5-!丗+/G.AHWBh4[l+eE%AJw@L&@!RL?%@E^o[!Pa|DڏBL ?)Y&ϧNGaB8 a>{U_VreJ)lК~p7V D_M˾BUlU}@5?.FqK~$cůͫ9E{~_zxר/m"h/=5%SO$zRżes\jr%D$;@f\BƯU_+w@*|E|#7B_0;3H(c|'JڿC_+4 b ;s bZcM+Cd)u@?]Sʅ0:[_n\֡7?<g_~sbyXp}scu( ]oUgWi*S/d8t  o5s_՜ˈ+_[#?sM5{ak_E}mzȯv_0B9!/S(bvE}ϵ}hj9e~MYt.CVA~BY2:j:T?D1ex5%~{'˯M-K *{%O^??G,:w%Z\F~퉔_ d5 |kfZ֟f_ݠ >+\$6HiD/$6klgN _a 7-~_U~)7P-Z=ݰ_6#ˇ?5 cE1_HXHy/TEut~q7W?t0緟o'~AT_χ_Hk9]Ba V QC{VWKpk0ï-yf~F[]MRf{fx)_*a6?ݐ|휢u~P(Yx[ѐ_xB4' HwY裔ʡ*CcW'CƂ뛫"w|9Ǿr5/On_ u}UnEsk2~ ~:tWدl~וJaˡ_p *k 7T~٫laa GH/\klߒo E(9k6V^~Ma_ȵG#\_I"}]~OESEZVD˲kЯT/̆lLzIdهYldF i?lB6Q/ ËJMoyUmÙL uߚ1$e>bb~~3BW[#\%Lː}}Փ cHM ZH. EoYոlR \Q.v7bR@;ֳ|2 /R)[:trPhoT^퐛ҽB '_C˓n( &o8NT?WxkeΉ4@6.[b#޲G7R}aгەf!*Tcɀ"HƢT5~0߀ab RCNM`{V>Mm`5;_7T_YξV/w˾ y +ND!G''˪n!xNewjVO_ oZ)k0c_~S2kWջ'2~=dɒU7Eepath\PDvejurl6ztͿ #Jo{_o|:ЍD/lm~ZhDh<:>?|}z#L+siB'.~_c{~*,ϖY(&@񋿕,`. dQ**?fԾ&et:>|-PzBb%:/tPa _.kuŀZy:2W?*|D }?2ɳ8ڮWdJh ӏ*荩5 'j\~WN]&β_GnGP.{%,@6lX$od -Ot/1J iߨ6_tk8J"Ga9idDXh/_hs{U;G$vgYKшUH̊xFl =W -JCo|YUWïfzma9QW@Bot7BQ'/ b[+< lwE_D݇_ob|($,?,jP]ZROt/65JAz1=4e}LߛyUfɫXq Q};_V|Y D"ke;?4,_M/~_8:"_~׫B c0M&/bP0솑)Y zxBo0ָ%w7>![n2TDP"*P ӻa_~e[=1_qïbf Qn8/9l_6$ L*L?eL:fƯG~_0cr&Pнj/k~!v'>_6wRblE#G1ᆒ[|z|IvY⬮5&تX\W~CU+S K`d#5ӗ2͑YՒPrq/4nK'21kjcNa0(TW'd_?S{_,A8dLb~@2-ߘˠF 1V ~e4˯l5C.A18`гHJbP6׳˯S}?Lk+.QObE᳓:czS$>گcnU {_LMCmh k>&_ˀLK7( _Ր!_ 5*,x  %g 7˲XdkȲW"|Gc_& 4Ux_,~.o֨6&(cTC`@oо =(*. 42d4ΗsW8O >rUV#Gmz"eEeȞC |c4iQhO~TƱj=]2׎sx/ r^"~wQf$A]) ora 8y,9peQ~Wz,X|&[:x/tT*+5<_庬B+]'R_oxY/pơ3rGF9,_tJ~ NVɏJ=,KsD:YȏX=_8bA3DW5yڞF~YO Юz/D jl#|u3J'kPFA7 E5 PD~uOihK+ҝ4"td a%4.L-| eBNaQ*U5ӇNE=WˢxJ!"V!_ % IE)ٔb[f&4^~QT'ÄzX;&JUO~o~k>a\kgՑ;Q_9D.>Mo<^k40e㗝/S'0TzqiG ~UC?_/vAO} bPw۟rdߓz{f(ғ1 u:dD'b)PeM$$ZY`Et*/6 n(EJ gU/jtIl҄Г$/MvUD_Bґ5n$oP ?~#@4Lju#|Ֆ?r0''PN鵭8Q_Qi+#d*Kr9]+/Ix)TZzq[I1"*BU#_P/^X4 D[=Qnv%ں7 "_S#вb?|Y6dhD$'&@qjr]_6&d&.*1˕Jq]+$1 "+ 3QgxL ?VO?d߫dzoH0B{nSq_)z6/xDrk?|^EPK8IK?2QDsl8H/O)}QM:z~x*0W%d} _Jo&bcup7JTW%xǂa;ÛftBDUϧj,C`j#D5W%|Dk89V٠ &yW6O|f9:,@$xa't=+O{5:0>qln24?%AM(BJHH Ì]bhQTT_!ʯY~w7k6GF_u(F^y"xYj?脠VyMJz>п師'.@|f~Uμ-!/-f?l6b&)"hhGQ[`JFY^\3RLZ"hI@mc.P"`WK?{WVZSKTDs~ ֡?NM$DNlQ_o]/|l/dD8 B~Ԅf7n$o~ U1z-FE! ' 3i0A}RSDN_/_$bEE:+?Bܑ)lan$Rp?[uhCK]D˅ D xtF<|z1‰KR&?)h"*j I#P'0â|_ >Q)FxX5 (8r~Mt?[=5o [Qh/l&*]J qD.tm4Xg#B'B*@ohF Ak7,Hi^bw҈eW*|I5P2(_+g v_jqu۾%X_ίE~DՁ渪jѹR5ZI%IA?E~F(%Duj J*hiz)b~mnO 9CYG'㽊"z>,_+v-)L@.Vw`r@jzFFGjQ\>"dγR#ee/j_\7_UB6QswaOʄs_u-f 4_[èɯV^?R-E#DpՅ_DjW5 y::Se)ӟkp$~5 t\{_~ UfOvK{ ]Xw 5X7Wh'_.6/췶}7MUނWCl Z c_*-:y (۽?n~hn]?%"X2,s_&HeWU[ccP-Ưް~%ޠ)DT+7T~u~ma/@%.4%9܈֘CҿgoH+|?_n%φ `5³"D2u* SK93u/K$ 4'T/Jsf~lWMh yDޟMhy|^_ߴ%ͨjM~N%e;|.&i86K=:we_X{"aw~M@}Ư~ea$(Hzw/J[AsaLuW/\PWtk6Q?)r]PL!C/ï2d wBoRТ6@yPI[¯m}/7P0e{_vb\6շysT0?׆_*905_K?DfPsc:H:re9ζd;4>}pbY/"f _< D1T'EZ~2ݴ/seV"f:Y:z6ژȗ_ݠz_P7ߐڛAMy;re72~s]ב'!Pa\O_jM75m"}}%m+\%0.o-9qmp7*Matm!4Px\TKDR^a/-zV *%W$- ^_GAA,a!D2 |yn7|^M< oUyP})7Ygx_ҍaN{LzR2>m>4(ROF2ѥ/Ϗ0{ײY-_~'~@6aRSe۩ٶoݠSƯLr3}a||6򫘞ӳK~nP)/{o\l#%[O\T_9)mVd/P~k͡e4 T5, C5j|~jXه7 [PJO?` 4eͧqВ[}d զ/^崢>+*2EzpV~gڧ0VOzX_!.__}".y|^1 )luo0fR`gRȯA.F~F!ET i}`kG BAB*Q̏B$_xx-R^+.PǡYyՆunso LBA1.*\)DlҌW5/~ٲ;n͎9̼a (=`r__: qq?Ⴔ KunV? NW9=-&گ,\w~6%3~-} 0HAaa17<kcP6_~__9Mο|$g?5LnmdV_Ti5)$[;$ /W/8 Rc-} UH͟߀2xѦPQ5~N؊pIb5>^_i[uو2M>؄ؘŭ/$*0"ea_fʏ2>_d~A[^~-;1F^mRL~NU^vƏJl&}8}e|~Ӆ6b &޾sO#/͐ #n"g{+EꗥEe}_n7wRv_1 >/7gbS"_ղ_ U+9_l0%J^~ؚLnܦNWBR/eCL zϿ$^>0Vj!M>Rf+C燫~A]گ}J|s&\5x.밽!reaнz}뗩MK`Jn?6@U6Q kX_K!J,E l4#WR܄,HجDȟgP9ꉤ!HC_\xKID/^!`0=PJfB+B"C[.(;Og4ɟgk}={9鿑}rHЖFdhݦs%~ZW@ -׫r֟ZXx U()RByaaT"yEQrȗlc(FeFj?h$27dž@fnyVq*BrEkznW6d&C/:`U+/ޣveF<]:D'CjlE:f&SI8s)5S(gM'qjk#賉a<;) YvhOG/)3[-J#SB3vuiT_6~+3>v#ӠEz@pڨ }dYMtߠ""0^<:^ sOׇ_xҫeT+ &LIP* U+P)9saadK!ԅ*29SmWyU|6_pJV:oYN_~ AZ#wyUCZ|!uRou| `ZK+6Bl_{=kCZwPaѫs_91]keSuvu΢ɦ Tf~l*^^a#envEZrf],jQ!0Sc7F )l2S0xr~Za"+}xd{ D~#t:9FXyʒ_/4;NGަRjDTϗ }N‡xZ!z l+|1'cM_ ]]D d5kL5Ն#+sgaaW'`>q5q>u&( ^0T?̄~˯P[f'"4+ݞyWĜ[IUMqJn#V,C+u^ngTxUS~Av :Us&>x8_=rE$8ȷ42Ȃ|n=+_u@;aձ׻’_y)DJk?vFs/4ϳޒ$m},,y:}n(ʯ3mcF[e#bs*KrЎ,[WQ3}%_tڏ: (&\%f_l/m_=N@v՚²Q$ȔE[2 oȨ^hZ}%MLaZOC밲xrІr$ ʺ 2s_v~{C4h|UÎK`zTa7ƘoQ-;r+'#=W ~Tho@:sC)P~3h6K,'B~DM ~QLb[uFxG%@LmoyD7\JW#4lO .lsT r*oސ$oP ~{?[~!ӇE"@0wp9+UHI}} i' ~! ?ϵ _ r'߫f3jPR7-W^KeÇaA'DAFk:d,_/?_6~adE;lU~`g<s~A qK r_rN8h!4_Ơ4?7~qHe$/lsJ]+1UֿZ_fO4tM -. Q؏[FI}s(ƭfW/"Iֱ;>Nq豩ԧ5J^,,+gBK&h_Ml$nO\L"Kj.gO@4wu"z> _cO/^.#zN1-DYpzJ(bC]0~t0u29/'ׁKM]!]|oX_I[וrIOv'@#CTD_Hr>C>HZWxˡ/x^RW MfB'3sD_7t}S>l܌)'@eDU2N|ei?_E)Lf{=BL8_\˟w/+\;;$} 6q}?YBTW&Y"O"_F?AE5|2/׮"UF;N~'<+;??|ż8!Ry:_hQvI~+^fre\|_2_?o [髆&)a@YH$gW3HZϸ[]vL2$_X4ai~IZ?~ؤkJ4m0ְWWڶb]u8W es\x9O"_f_2} ky~}2/J|ˈ U\qʸz^]δ_ L617cNGvM$ː~K NΉM:vpLQE nJdE+@8b74~UdIPu۲1&3NZhU/$^Wa[X5ǏD$j<.ѾҴGh'sί+eGH/]}"W2wN mtp~jU~nX_ՠJ'ˣ:BfNm{ME=mns tgƲRJT!u,@6L+(&4a)若bݾ'BƸ`bU\^6=?BCY u3Tk> rM,n+3whW)sa% JLbϴ#F/;K%KD,kY_x@tK}zh=^:YK![8zP baWbt/$˞iw{_ 5f:DMƵsHpe $\#񅖔0f/0!9d#a )M5̡V[3P|TP:!5/kg~/bXْ4$ap?U KpfxF(h_%PYF&dNź/+]6ʯl6uS#r~Q^M^~ATT`+_~ke*/=rg6z$u~L/v q@|fSC5@_90 Y^5_ڡa!t|m창h[\]Gi"˵SX?3_ M:b@P{E,`L?j('/k_-]ϫ2/TjP._ߺGE_Wxˢs[an􉺩P"?l/a"_#Rb>?"~|'گe 7~u"ͅ_䕂i~5J\k 50ïkcRAGn9Pm=˱6p㗮 z{ႊYGrt9E~I9HC,xC^_TE_DQGģK,>z=^-Wja 7?r4m د_vy WX¯ivYu&rW]HZWztO.Uzj}LY5<UKѧ/lK_/*I=Q/*ŊfdtU/bIPίee2Ӎ_W d^ k*:5,>8BJrvȷ2Ohy/+æï7dWGN/0ïjϕ<+z|zU_ˮa¯e+ZXW!KFz_p *\DBY_siz2~Q\T!<\Uj/Ve[$)_~IGx:TP_*E5KjW-"_vت yWyNY|qW$> oy%sK6BRKPpE|yDvez&͉*q(*>Qo|#\W#T^J4jabgr{Cd˲1R!xUa/D%ॗ(@K|W5&sjo#̍O KN̢_,m)lgF/C0K1x)FBe Wȝ.}W2_i,@=4}"P(7rM~ WP; ׸#~O\OpG?thի ʔ~Ct~Hż?tNfsհި8%?eӢK,RӦ_0~APL{!?jG/ؔ~MX~ ?Kڴ[QލbmYFkr'_I%⇐/>k\j9Q ڀ>+]CƂ rx cWsi0R %V(|{5X eC~P|o*qlͤMr7(s@TK+Z""6Ѵ~xWZ>o|>g]ïMlo9Z"ײ-ռė_{/ޞ#K| /f $_ۓK_)Rcj%5, Q c[!ꓥrfUHQ^5~@f _7dI)p2Բ_vU"f+es/^U,'m6W׺*_i_[3p\m۾b?&/*Jv~%[ѫTʼnV– jWG ]Ͽt6gK_/|̥NSU9DA WD-uI^^,~)siu_"ĭY+f 'O&_Pm1bcͷ>*ֽ3u Sk?ʯ ÃћBTuDa߲g~owykx_~WY7sF~ φ5& ¯Nf*?B;l2%Wu˹E=L*ҡ[s0ծWѿW_ hVJ{7vWZAj`B/4S؆Ha@6ohFF(R)K/Tњ~t}gcBZtP8k>w8SPPɱaJ~kn/%LY7?,vGwo'"$d#BJ*#؇oECT7fA!UB>ԕ7J7uOTQjaEn𿆽J%Er~[>Du&;Oy "q@u )Sl[tXpu`g`TeUbFtQZlpx'9;pnaJ^E*kR” @Q<ؕ Eu7[?dxCo8`_XRcފ[]T\ʏ[BH7ÙF./v75Y۹a+)إ|EFZMq}uCIV(pp] abթjz*y:pZStfT+#7^%k}qW?pIWUPj'循 CWy+Oj:2t #Wo@O-DyIs ~JjcU)yzNGmRel-MTūvC}V'ode"zJ7(s], +c*JDOl#<,E;o\7j_7+lvF#C( T"\_뙿 X j_#b_OT!§,~_/Lz*bDXxexwII:jRo=7d"+ܐ$o0|yaCwK8&BV _4_)/|}=2}m/ IdUt%,>dUߨtKNᆒ i)HfM ˷k} ׷*&aUYْѣTĕMy.#f|/js"9]&Od W}Ode/ kBbhLf_\itJN4l8IV=h0gb<'qJ_kL|7$GjV? ' tc2?[ZQcGsz&K\6ᥴI HLBǂȐ8|YfIyf ٔl&XxIppf|O2I0>)3ϗ[1 _A򡅃8Ͻ)>f`ɇݨ u?Wߋ[|Z_o.,$ƆK%Vd|-IK r q7þcɇ])~36$OSʈsu[ߣN]4a)a #\8'Tׇ}uHp}8G9 V)K/+z~堄yf"PӸH5ՏrKJkaHCj7o-L C)>D[J'J|"ThHz^7#籕Z?%?WdyUf/Ԕ'BB-[C}Kk d(IoRE oԧdC>Q)7s4Y[_)/:u[i,%( tևZP(5I52 ӍdaR5?D -e?^{Wmgc@kL[Z:.Jy?O-;ៗYU8Z੐ڟje6~JOo'Åo97\~TVxpBH >>9v[/(wbY\>Ddd$ 1x (E\Du}!l`Y}-Ԇ=QMP^f>ہF ġ}1vU"Uî/͌} q ([ZZo*+xI>$̰`knedT,?ŒZZpVK li!~C"#[Ŷ_G|,1Y[7)Ҝer2P^tcïd {?/m'ER;x3Z|=YKЈFe߭-ñ_}=Qwd5LtD2#Ru  2r_|_iu*ɯdIKZ9D}-@ROtK|JA'ɻ>79_'r.9)P^eV)r>?d81Dr"?-%¾}D[םmf!_a/dc缾T&KO/ϪT[>;tolA0_|qƓy*ch/aXSj&{&:|=ue!Eh_HO_R}$iGj/ Ҁ}qF |2A2gk yEd,\3-@6yJLx˙|*D<_Bo(u ?ůq/TxPWvEPˊv~%aqoHQp)#HKJ_3S/Rk^NBRܾ n_ 8Ğ-ܾg"/^W#5_ Á[jKRՒInM~UҜp-{T/ѳAZdGi^{>D֌7$_o9ll[z/ݐÂY -?[hY?þ025'̾W (n k21K7\J{%KJ"q&`_QKxRK]e2/}UzbRQj_Gf_.9`_" }44cܒؗ.I\5b_˚Q2 @"!â=|꯲UotٔfIfصɒݰҾPXbX:VI%>,pb(5x ӿ1x`; Bׇ* Kp s*U>{eW6O9j{no2Pb,-ݾPe.c_B2͈7eoYDǾD)+KRI#Hb_~ bJhaO^g_ͥhU4*!XwݥP>kNįeҾ/&)+5 7߫ 6þ 4(h0(ol'_ ܑؗ $}3"wH\aΐH ׏UՎ/2""I۾Be^,='rR.O!pe/|H_Ja}Xà}sW)?JtomE"s\ƏqKb_2_I>\)H}9Cm%6o{ˡ74F3b3Zmka-~7B󯁃](/vLS,GA̾Ќ,lh¹unYϱ/FqBnvCeWs"?,v/\j_Y:)0S>l2iWW2Jf_d]J5H}Sv7CZŔ\^-M9A,/Ҿz/0¤<Ԟ=jw/b}iDt>7x,/pP:&} jʦT} ʢ#ܿqJHkQM1\j_l2nE:_lofoR\:>^eh-/}8Icԃ$ҬAi%1ž~K {xd.mf /ExoyXC9O9˞e^>u"վJ;_SK_ iF4SUkW5~Y h_KyRt}oR@M ^[WU Gh9ڗIvlkE5ǩiܐOl u;>CvWOo*vD0ڶK 3WRk>kk%ސ wAqO+g_3/rjVj,x}!Ҙk/V__=|^h''eKH)ؗ%9%*"8|󂵲`?$%!_vتReNJ߲(9"n\Nx?W-?`#׸5ˁb-y묱˾;yC*j_*S4Jx.-ioǩ/[/gBha#/mk_0"I.E`)[҄_|}(qܾTK_H4l3[.8.h^}}4} jʖg}f ސjb_9/XP;l}萯'/|SSΎP$JJ? F\ľ5#ln͈,F7|ڤ:ײW'D̺‡/ԺW4XjT+E`cş8eKK_>NJ+ujLZ D^,'k=/d6(<);Ps>AnVÛ窾S+ %%T䀹_YL Pl03%ye_ @\9Hl͔m_8 V;?MOS)e{)ezWhq!׶e c_yW/Pބ@3$_¶})S37aM*FQJzNHhf @'y|/%$Ͽ:j-'%rC WâȼB, MC iZq0>jMO:K J쨾;6o%6j|)}qsnUj5~W[#帮gևqe=~vH(r{_LqjUgn(dTq/"N %t Akx^&cڏ],<l5 ]$ߐM[fde9;Do8Ѿs&o8KFq}mJ0AgFN׾ ':!Sd՟EXR_`X#d 2UcڏJm3$BhbA⣆uoz{;p׿Ϋ|xިۚߨ>zs(YP_?󀿈6l.-"-MV}mאu 6̵hb%Co( g/)N>(}=̤c_{DhDZ;S}BƳrEq}CF`X!vN"&[X=pr}8[&oJ+EjP6[åg})^KއuFbl{w}F|Xc}ޞ}%~}f~x\\hCpW@ ke?`D{ .Ja9j_YeBZkRvڏOTVB%%eTm_"Y ;$pCAɒO$ed(B,B7$ڢ\([ӵc>@a?f'>j2P$8 1RmvU\4e ^?NaJE6d3оex{ľB5-z|TU^ ~f 4&6cذlp)FohKq0z Nf3IMEX3uةJ2ˏ=>>Ez $J3o ˀs=ʼn@^|7iF_F^?KQ׏@@f ګ}- k-@/0[}s9Y6*>˝Wq.p|Jɣ`|_O6]<ΤZ}8C4#MeӾ6oWhA,Ul.Iy¯t4l-lfC*2:%lz?JNr:Z?ʅ7;nZqq#~-g_lTKOͤgqL R}և Ǿ8R-&s_9 ?_kt> |0e 0^;Kž$.̾ )e0:Wz fվxUXdCz*˰ft hKl\_RE*/~YcAk eb__ XX|TB˳h5 ܏o&,>d}圬h/Jz"}〷}u8E*qjB9rFJyXG0W!a5W}f=AUlTNo.o{\z WIU3Ēx@DB}<_YWR UUln~[V2I_7T2)l揤տo{I\o2I_7,X:f~~KO?_v?_~3-nU?_n)RCIWh>~0RvJSվm9e RjH=p&_9HL69(vU7̲[ "6cM{5[a}ݹom%UT9].VE*PH~S-Τ?L(}Y Ī߂o J_ak-sD;(J"d7l!EI܋%pAHW bʛ AN Tx{h3ԛ)ݤ^e ߲$}H~ 2}zyu% ga5´@R)G.>Ͼq2U/3n@4VK۾y#U,SҸKMk|0%+1 FdRC 3F;( s42ƬZlŒ$JYG Q]og[(Y>j_nd>W3؈WmxXo|ZhFCo5`0n2kvgu2^kB*i7e[#9MddqXo`E"m\u(&/-^ַsB.JKa=fo1^K_݋O e8fj~en̾-) dY[˛dF|hΗO-eĸ%J&W[DX6>2k{O>/aCKs% 퐏LT S SK<ɇv>WMaX]{a)[9a}edћE͆n(4]0,6 ESݛe>WxI45oɺ@k;No〚 ;OF ?ض j Ǥ-to$Q&qPW3ʴ/FA=W*kp4ȼ%_8j?$t7a\J}vOvCWfp"lkUx/t\I4=SʘSJ/Z}yG};vJhB^ɹ*N 9@FZ}|z ~do>ZQ[=PK}m_3Giop%?2_3xÊd-@Bo[$*눒xԾԊϵ႓İz/$${W9NZ#D7 _UV)`;ln8=uOJ_Ӽ%9گ4-mîB}ȫ>\-84:1T*JVI毁QK] ¥Un4rևIQwԏ#m|U 7>D?\ 7f=!3^g.1s*7~' hps}u=b50~ж0..QjU ߨ 쿈Q/35"(} HӨ-ob`**8bI!볢îj~`N :QS[P?}TyU~BjmFj'2)v}F i_y?2=%B Vy=2 nKv.ˌ[|=)B1A4PxB! yYKj Q^+dyWl^ _%K,Fr-,ubҐC٨Q6 UWt-JTP^_2,DjƢ*i /^,47/Էɵ?H籤DAI+ȶ%l95>2Uߚ/G>7fB$e鑸7_bOGN~FkllX%)I\CHoh"L"6[ωܿ e._9k_V>{ t-.ӉZ+"3N/V#iM⏴$!F6\?_4P1zoÊ-UOA-L~^U=YUK~J폄|"Oo㱽=Jے Fq9sKpMYRVnP66ެR <il~C&˃#`_\✙2J|ׇض +צ}?tWx|ۗ 6 /%UWZy=E F$+no:kLl*]K}0-{+Gvi2?i++Ҧ}HؒƷA?RW|Cz:j!9^ji%9_B%Ui~p hmI[Ub}tnMP;aWQ(]j%E&='T:'&sP^_Wq7zXű@m=,tOf_eX\UW-uWڴrW蘽 4RU~Z2V8tI>vB㡆I9c\$JcA%ы%{[krIH߄ɏnߛrIs!<`XI -=>ϗȊxyh4R+:*23yCĂ~_Z;'/5{.]צ#tB Ɔ)5mp [g2Oi&mEG2}.Qe #pȒ%9[fAmH69o%lͤM~oX1o9H|H}C2m\RVۏSϾ :lۘȷY/:PvLG>[!h:/uWw&_S!&TiVL L!K#/NR3y~hDa|z) ~ewf1#IV_ԗ#-WS#M;N^:M>vlU DA;0S=l5fSpج7x5U_pK9* !]R|KDĚ;pkȢSN]Ue#TBV_VpMl0 , ûszۗ"h+KOf_eԏZ&%۾ke;Zn:L.$/7_HkH?5><1&XF_WڴR"($Gr_&mT{d~@>3G|ED&e;8/OwN P"C^ib86=\3nо0)x|& 5'V}!;vx;*_BPrSR+e} =ؗl0_(VZ /X8%~m/_${¡/3#9kH‰$DoF VkJ}Dz=W" /R}fJm/g/n J}l|U{B md-5uUkϗ7*oZWn'q֠}qsƆþ?}07QY 2WXjo쒙˷<&Ҿ=_nعayqZ*=f_R)S?EO~N} Orʹ?̾_Nײ=ѱ/'yrDa?W^?+G3iY݌A*$3uVq*f}ҾpvC_6S㺒}>X|XC*5zYUo+ LB6쨅E^ k܉Uk ۾&?seO]x}쪒G\ڼK_ُO!5&"# #}koRMm_|aeo:.cQjf_٤f"#}b鸘pRBܖ'K?#SR3?09&_H1Ӟ$MZ~d/G q-_ ^ 7ߪ[W,. et ?2CTן ń&}i{M^g|I|o{Zs#HB;J%/w_GbJJt |eʖpq;V9Yf_r&9ԾI6+]!i_?Cke_}]tf_٤$FlIn_喦ߍDֽ鳯e}솓4$nHƈKW(gXlћ&zˁbnDc> K}y~7(5Dzkf+-K kf T#D-.SUșރ}Iqn;8 ސ/ {eG--G%*qN|Xds·UKeLRXΩHf_cs"ajR s|.J:Mpg_!3YM$m><+AͥϾ0-$51oI!^Qi#Rw sJ _`eK3ٜove1 McIe- {}ұ2j٢>TkRk۔۾j"/;)Srј}վ³Z?4vY9k|h_H_>7t3-WCҢ07쪳>4r Ө_:*Eվ`ѾU&W (g3ҚdƋ}-6" [Zx.t2hLJR:+ؗ _{e)o/ㆭ1*Xj}oI }ILwԔ z jU(y@cIeDj_;Ӗ_dc+95,ǩJnDf_Hf_96˹f?t**/G[>Ʒ֌Rľ0Nb_ 'fjc#~$)JX[ qkj\}A7ܾ¦d5lF4u%ĐR8_Q}IqwO$ F8ˎ/]k!kq[o(4ʦb1%n(YhGY-ؗCUlHa ٸJ;J-Ӿ_J;ataֽJOY~0k{wCa>=ve_~U 7Wt}׶qP`a6R2s׾:;GﱯE  _pC/$}+o5_/8IQv{_-B7l9 R M2 ;DJ I>.K_8iXa/t^DR^G: E)/\h,a_Ƞ9%h8t:\$.;w!_{,q}H J7f_-ϭ\{_6ʯ,&=ñP$kҏ}%kƈWzaȂ.'m_8F$B)n9žWyUFCc۾(tm_}Xw.Xg4_?/DBF3ܜGwwׇhXQ+SJ69p,SKUC%/Ή}f֟>wB-Z~ fOz>J.8xc*C 5!U{0d}uc_Ů?Uf|_}ؘqC'erJc!_ êkj5$eu>vI}IڗU-ؗpCI 'ouY}ik5ړ6*Y4elRփ}9Pվ $sU1vNPSG;\_ߪ! {sܱ0?0<2(V Qܿ+sTz(,x쫕m"{_g5M3oc %21+B|$Ӿ߁`XZw\ian̔Qd#,ot.?ꐚejm_"YvmR\?Nm7e>o-OIlk!/+ ˢt,'y K6=r GϒlW//6>՜-EbLu`Ʌo`OAN(kU\}ʓ?,6s U  `zZ_T[((ݾl%ke# ůdb!%&~Ko8jH+_zz(qsJ{Hl4b m'V/pms~e), 1Ǿeb_Zw>6@*-gַANhߘd7~4율}aR\~c`>=ƯJ_P1o$oҷ-WZa"kcoHBod-1yϳw1~2okK /Y7`3Kf%T /~R$x3ؗb4(*;%,J_F"ľ\Bh.%]ί|n  _yd[F}QY$8X /]q[~xl*00 Ezׇ@H7~#U/NN*t@zο__ z84(VT ҵ{_FΔF}_-X\V:!WMjg ګ}m ԥv*ظn͖WYUޡ bdG/0ق33[*/T㗒/|qN RM9UUVmHS3[ž 5e 5}5< Y ΅tTY 9xY mWGBH9^I8!S+*q(vo)Wlv՗F^+W_J}nWE3wT|ϨhPڳb4_p+뵯FNVL~,(p/}3=lV!aZ!}5 , #UMY~xA _50t¼Lj_-^$@ I|.JzH^5q7ܔ싋d&Rrf5ޡJ%,T*2H R̄VĔoUMa4{Y5萼ҵhlUJMxx)ibO?? FBF@i%6&KxJ'X[c-1WT+%c>]:~wiψ:vt|P#s}AWR. V z?J m7D * ljZUԷ*1}LC/2bHcc8zB]LB|ēQ|ƦcqIK؇-\pc$$QJv~6î*S(R|Ծ \ErQ{պ7c{&ۯy+7Bmoiꑺ87ܩMqrV=h*hKBCU8.T!2W-!|T;sϷ~reP3Q_NNK,/F)F5[DZW}6>W[ Dű$J-B ˞ofjF5ZF56 p"Z-|E?7KnD~J~o2ueɱ7:2\AhQZ% 3H׷]s$?}^`6dS2t/d!I*a[1.n 'ۯfR+"c}ǥoY/r~JpVq2q(jūB*l8i)haB-k_OX$S}e[Q{bqhH7pJ(#>)۷M,iD48L#Uʗr6ajye=~_0=ׂ}_^Nva;׃}I>t}ؓRڗvtl;j,?2FdQ0?9$=d(4b $O]T8I(-NU83 E{n%e#DB-0=9yIO wc .VƷCՇ>TzIPv^i:xC9^RjԽ2;GB) Au+Cyd3JCr};JSNBٗfcS:J kQoȡtc3F4mҾ>0kvgJk4[fr.=qxJ)8+%o%m5uy$!_glKV%J땊DHnGc_n8bɗ K~JķK/]u5b.iDYaGbϷ@(or+z_:}\%j_VVH%ŁK eG}Յ<XCPVLW6Hp297[uo|:%u)mgQԾB/ʰ9YH,(<2#r~a>:!°D2:eRٜ!< zR&볕NWZ񶰣`fԃ/W|KZ|7lk~|ܾ>\ #kШa,W%RJ|!zƴO}Li׾,s_/׾H&[}d|a"Ui˷OIPet+̷hl}88_ U$K}H 0- reK^2I\ JGs C R0%gat#491ϫHdSB3PFF⣒3G3*%zr/w7}}RWvꔲi|Z6Z/=yyR0'e%/4ضE푰' z\ՍOӌ]"N6{?ֽRi_n|_ivb(LO̎q.)%z_V:rFAj_r7lpӾ f,>|/ mރf=|#rR_4W{vCbIa'z̀b**6|Oci6rh; C_{ROLPB`RC?$5,s(QVCQ_ X訧>6j\|}ۗ<0o7e۾ %KVorԔ}}*ι}9  n_ {"/'yW2a[R4;I662o3+7cipS|֓֌|6"UF[ [8͘v׹t#KjDg [ePڈm~amYGe/ ||="C$FZHqv|$7Vܑ'%!&𿸉(_vg[Ή} km ܵh|lWq#̱OJ>ݾI3HZGZ0#$\*Ak[ se o|V)+s%zӻGvYwB\jB&uy30 y7$LÊL.QQQW72~.%v|fSc_>)2MY}ݒ_`emZl}O7[}_k-*ū>r$U)1=%9/ZRȟ}!)Oaa^ZP1 ?|)3Cs["eEyTj +TQY MKŶ۾e!ai~zYx4q/,9~"}/PaۗxΉ)˲2[X* T%_,w$WZ!ؗA</EM9Rv4),bAS򁽌o'L 6U_@U鵯~lz HpWfDӓtތ5kW0emhb_ͺ7.ue-\RdL$.wb_>;Ub/pXhJ҄kbO78z=ÇݐZB%)@_+}}c0/[2[ -1fY~+`xH㙿>@1;)1a?j_||X6=D~5OiJh{U #Jb]"8G*}f6> l8(vT4[;Nm2{g8}Q7V[ћJJׇ[uH G- a5Q/ؗh_jFű޸쑐`_ce4cN[:?l,{sv+O}D)Vg=bǾsdih7[X<{})Uņ/u(I5#]tׇPI}ݬ鵯LGj,{?l<#̾-۾8 E?/|ml=VgqX Ө(/^XU[KZ/"|zsR J}MH '/$AjRaDf_r"|i;xC8_-&} ʦ60ket'ٰAؗðf@yF2$%e`ϗe_8S)M+r^OF(D%[.//°qv"xk7_%,>{+U c^80G#׸K$jF#2B٢[yؗuo/4C_? Q,#H}- ѾUB7}Z:˷& H_O:WT<+)e.'Qzc_}'I/s3)WP Db_,b_+Dq}UHӼspik7"uJ\fgrk&H).ω$_#U.Uz q_*I/[I(ٸ_XK#V{( Jp `2l)K?vZpK6 3^^_}~VdZlolHo#a)yUk_(,һioA &Vßl/g6->2RRZ:]2o/ 37=(T}U>ˁkYNK _#R _ eazۗ/8;0UˀbNLk%[aeE|=AUYJ'_;_eW94+eWf 2BF1H"c!\LይW6X)Qx (5|DʏEh09_N}oE02RpM65E\H;-O摾at;C*V5ZbGF_dd}eFljM/^3) )ьBwrBzU}5H+s*9#XcA 6MʿZU;@|yR&rUHVDRͣLο&B_eB : b^7= ]Ê1R1: ^ھQJ< RWyNǘr+.8-}^x,hVG[Nog(PFI:NZ{7Av+Kv'!Pg J)]& kPj햔5)H9*Rf} ZXW >dPr]3Qr f )k٫ҷoIOI_QyI_qpI '#ll0/)/ 0 ɒ4XZ~Kb3@E?ZZoH%3,tD} gW(lR/KtJ?tRU)qj_sl7\:g/J蘿bT xÍ:&EؾQ`_kqwC1{qÄɍE[mJt.\rcrʂN?aHDΗ1jTɉ[Xmzu窕۽%NLo!jJFx,*Z`C.noTX7?hջ#k}>QdX:NW Ze@ a{>K8_7(/ fP ߨ G{v|[@~J!:}Rt!6joQCj_L=-V_:*+lž˶'Jz)CJѾtF)0YC$Ɖ}`XJBAY0Ѿ5;W [Bq$;Rr쓚te|B+zth)"[Ɏ"ۊ:[bJF2kQjpG&WM티鉶fSZO_W[t-\ ʼn/^PjzIU gp^@3 1%UվsZ=Q~/g±/c_Yղ9<_6)u9ux_݌hþtT/lxIùr7 u&_˧[*w ;pj7WB&W^օߪ8J [;[w/,D>Q:*JUe %GFΜCGn:ܡW `Gkd6`*v?2?7"xH/$jR1^ơD}rb KGHƷ-87S/o}YǼs>ԶrM^>AYD^~R3?Drl-_؍* }Z6kX0( DoU?!@$%]P&J4J%Z#B"H}>4 3{Uݴa%~5Oq&IJKDd놬,\; 9X~/|}WUyn 캽WqqKjDoU׏Kqq%/?_n X~7D,~`_ 9JolJ\uֱ?'ܰ/S/<*8 SWd7F^I62үTY*A*od_ΗߘW4#f djh)(UD7ؽMM- %W~nϾp|I,{~ѐ,߼;x7ߔoccwO\7}  j/5a)0j_YRJњ;gfar"#q''-{ %ȰC0%e'G%!m OfluS'[=tTsUލX(~49w#[%'ԷHu f}6.  JV׌8}KS9(7^X}:-V, k43G^P1iI sʷ?*wMq\M/KPj_=79_/=**MaĪyx}5vu}a;%nT-%º7&^=,6y(pJk -|7G%h,ݶ?%{OAx}ٌ7+?/ȚWZ8GBdi*՗"0,$K1xXz?UVi 9Y?;D==lI=zxmwHоF{!QLO$/I갯5~/l4'  W/ܘ>IY4/2\/%vFi5ސzJ6X; Ŭl}D*aĹ2a)cRK?8(qV}5>3?aA6HE%6f v%1 GlUsK[|Hc!$iaj|C==X;3ԟO?6"+8|s_vw RCս>[9r \UD'هܾ|ʔh;d< lk e["~Z9y,h^ٍ6HOjK}l2m_W˾=ԟWײ;솣 3jX1}H֏*YK(I1P_LZV>WumwqI+m9! &!ots=P#-_6~uQ*\b%YKӽیE>Q=)ϥ =9#f_"cC? -3w4jQf_`5PN }7 5R2#Z)+5>_wny*\ΰ>4\UWo#%F?_ߒ"i_f_󧅥Ҿ[wDD=|[b|. =Otu܏4 |KZO$/ނ5-ߊU!R28 C\*iMg}H)M @=CPl-*}};ЌDD,DNc+D~ $ld9`_RCxn/G*E?j޲WS^p#__ٺ[AcZxmmRWNf ZٲԠ)*sӽOY~Cv_m)9˅}rPn1ӮYFʀ|p~džWՍB:+J8<'R^,&* Qw(ߗ)۾$99_ZYnG_;qۗ29QٙT޷})V)9SAp,W$e޲/2kdcFdm5.UQ'K-sqO Io!ybdQ_;Yɣ%QNEdPN~)դayV *ѾsbP|Fb_zϗ+iM%}AV8 %H*Ջf9|خW}G*$RH'9YKvNaR mg(a}x_Xٞ(-3z"쫾ұtc_$3Wm"z.*;(<_Kj|r?/JU :Ob_dQs򞘾Z>ZjƝܿ1![c|kUңn_JjAb,9XD]cr%%Ga)ŭGzؗD]c_s?_>%ulV?*}lXj_[ӾD/ǼWSRtQ延b卯Uj_$<+iiqwZ^7Ej$!228 qV+̧QַAP58 ޗ|2u|Y<9*5Hu*UV)K_v r/qpuۗ@i)U 8ևx!'(!b!lei4ؽ8'rٲ]õn:L.ی} ^[jHJҳ m3{H_jc~{}Ҽ%/k}UcoIk[Iؗ?/״_k;me'6 HDro}!4)GOoT^԰Ͼ{'8K 7܉`EeR#>j6ݴGnysq WZW/RK,/?%=_o"ƻO.n*˜ii}e܈OtUn+o)j󻿿#+&DolV&tjQ5Hb_Ño}l=~K̻6j4tR\EaV|._(1=\:MFg^vǔ$BAq><(/7 hll0: f]:}UHI*ļKl1q}'z;񵅈'""/TٮU%as|nlXwB>ɷƯLvFd儲#5W mBpihװrעWGшd7J$n8Ub_+ؗ5sk'{`ž"e4o P'2VbK_V? ,5#$_p˯lamw/-7: mRkG><e8G%uWYR2#8M!Y8`%"Q1QvUr4ܾG2ۤw}%0zR;`Rv5Ʃ.DjGEiݽ}祸}!I^elg_aZ}*pj*ׇ_±yL`utҫa&$ bgvsWb &$$*)fd^Y~_sj/%Qg9/e3vN$;֙·2bA:%p~j]eVD4a/X"_YInD(":!5YIFtX{0ž19}e}LO %w}xab_x'-k|G_oևK!+m2#Ctڬ%,؋= m%O3מ,`_(ꏸ>kk&`_A=۰]ۉ5"gp2_mC_NX^f_lfaĂ40񷊏Nq@b{w RmwS&ihsOlW̠c_?.aWs͸tl@>5~? N% J@M2ɷ7:H2jJ+k_B)T ZsOF]/I3SEnj/.ǚ 6kX8շ-8ە_׶z6JVKgLiAjO,<)V)،iΉ}Nɿؕ$/wWPW}  J~˕ik_! c^򿬣Fh~JScJ&+֬*IPs}o;+"1dDq^jte/`-c_h~/+[=;KH_~}t᧠<ׂ)g(d >:|oib~%af뱯v̽V$;F>23Vj_laO%Nd /'^ CS*'VDJlDrgQHА56/3mߘÚs쬱U;Ա%Cf׾Z>&DW򥴸ғ/{׾ 瞥{*;/-x.+h5T*F~x<*2" |5!1T˯TRwn%/^]tHoWbW̾t*ΰ>1=\Wq6V 'eeO$e, 0B27Y.J4sq^DF6Uo/_OݾX? "wշHyՀI(&aYPAU6qkeW;o=WAБH;^5$)/<0>,Zy(./Co $s*U~MR/|4^[2>`ͨ$l-|!Xױ'1KȒ!nY_tV)*)f_f 5ԾxC+pWB*e0 {F_JoChyhV?%J>$\6Ila qZs2+ #P+g35Vt3+kqֱ|W PAgH|YV4ݤf5c_HϮM2ެ{k0O1&`#-X"pF&ab-eWū4- (YWo؂DBl5C_l<GwđU)}K(UjG&X?Vn=W Mg"Hb3 쿥5}Ĵ~_GoW}(t_J ~K[_|o)\RuTa24u$aJayh}i+o'D @Kڌ$ /ej_#; - z;U[Wqr&9G 73OjUTxYeW5Hpչ.@ZXY7ȳū)!H>L(;YJh0ȐUNVaϣȼ~H*¤% 1BJ5*" B3m_Qo!KoԾ9*=5HgjzFg_ +M:PAQoIFM݆W-$9ƾI6 z& hK*FgORNZK)`DWS@t FVT_&NcU*Q= ̒7d)54Η$|/ۏޚwCeWMb. W]kū1_\%H]6ޠ;]snHe뻦KXFQ_4a{Xcb}HءkI=5_>ݍՌ P b%X'R#jy[VLy㷤:HwBDàx1̄4^%3{!JGb4=eԨ9wY ,]HO f3Q%,~9Y/ ku SAi}4jb)\M8/J]7#sT /o er&P}l5aBbҰGFWCFM8 fLf]G ]+YþB {Mq~g \yy){cu-WB=y󾘆u#/G-~4y7-kRǐm~6*i8xD}qVXpj} )q^. Ґϭޭvl|*q:;myU5DVP_F|y򆜗|b inu Z .in)6q`X 6οOSXߍ*R젦( wy9-J5#u?Wa1yKpoӇ N͏ a_\7yʐPJ)2tC7+)Mm\H^7쨜,q*VRRS/kKnעjpppj _Kj_HNGI-&o/<3ؗ 0j\:c"I0ί$je69BJM+qDoA HA-a¾pvL`_pQc3~#窼2H+ z%e~ 臯{v׃Zr~|_G DG4 z={KEZ~&iz۾l0ĸZXq.W~rY7) KydQW5c*f<}sh9l+ ޺zc!p]ێ،oۗYzN;æRV;kx|@]TX.l5|yQb(/-J\Tw5֪s`3J]bAq/ r0| R7CZѷN@Zo=zC2DԾP𥉉RW8Q~JݾԈ9le;?E _F?hqy<2CVDN6YC` FԙtLߟVda7|ei7d a0k$н}J*Jxﭣ=QHK  ~ C*axf{SvK:87*QvUD:qy3"a<롆顾Mji^msC`_ Gb_z V_ }[>K p=ӱ9X@D>XReWuq&RעDItU؍؜cIh$9þ&L_~a+o({P_7mkv/  :RfGW 쑖՟/m&ߜrF޴Z մn +=Ej^X%))?7/O3`V9NͮWͲ#:mxU۾>$jkCA7Jo94y Dp|2p)U4ض0Fd/6-ۆ(FxUhD;p2Ԓ7Wߢ7U贰/&E Z#iO-y}Th_m*'K,x4;k<3Ѿp4I,-7OK- )fձ4T$.傱~/T\U}IO#KF]8@ ,P?z4_RDg73w_"1k`<Gif_ykM6}wQW F鋔&oxG(Шz`XscH\nIT848-pW2i%Fī[a<\3:b8a/h-OM%QqB­ȗ"_ĝF i|m1$fML5 }p'%nh__Lj"_k/Ej _ DeRq8RFҜAM1nk#4>vD ^_ip[Z)-Ao-OruZLWryK8ʵXwn5pzK#þ6niCRS/z3ׇ>2 !>|p&x[LĘSb,{phae K_yV%$/_W3wz H':Cmql!+N؞(Xm9OaC3S2#RS1)шWQy}JJrȗIloM}^?V"_`\VcM>-_@Ok?RtIO)%=@Z[e?Oo|. .kEm E\W&8uABܾ,l!n::6tǾ 8/"+a?trF I`_R?^_RuTϦd(Λ{&jUn#rZ=E^vb(+sIzR#Ȋ]0ꏄ3K{H^ZX H(ﯵmmf|Vi_Vp]b}UNS"ǑWZAUOanӍֵl]Z`Ͼ!ʪnRf3;s>y4&gP8Iӱ/ *_i9aEC^@q\U嵂} F=A -Z˙\nD'o/O%߫27' [;v~i9R_f˛/ྤCTvp}|ҐDzJR+}'VNx _j'@IxՂ8D7:I(;_ Dq/ĴLXF־K/l*h^7j%'tۗlok9/F٫î=Q3>drNׇ$3o:`_ڻ#)?_#mm/CJf_.kT~$QHJ/s_,rfC?˹Y{5S!7c^oryg+!}Iڟ!ojZl>si, 0p#N x}y-s,>+r-}9fc_!nDj_Gbҏ4h_NV_9YQ2If_F2ϧ:BV}!A|aGfL;xڂ,|ki_%M |d`Pjο P3[վ-5Wy>sQÒpؗM})ؗ }2}}F 0GPM/NPC_(̙6G/s| lQ*_':.ߚ}#p^e|s WyIkY /Q<}^7>'}smoF}e6p )߲۲Z吺66á̼[(@$n L𿌊@ k0Sᅣe\۾Iw=h|e}Q @ 󗤨2ˏu#ˎ2wib+mG;${Ֆ}u_v:/ι}i_ lO5L|=* Q#}X*[R IN~+XGr7CJvU 9MF7,nw& 'kjwoHF׶_ek`k>iU}5 >i/vߣ6aHKRs{pCbڻ7̖0б/)faeA53][-W4D]UXeǾeDǾxȍ5M%7?L. jUj&~dU#2[j_٤${Sܵ}!}j%|ľ6}'Q4X?F^M f.f9Do-?\a:ΗY_/sh3>,a?!ì|}7}%8MFh*%vjV/9Yjqع?__Fg8R@&8lub=9ѱ/dqծ~rs2T2oCHǾz~nx7-Hrg[3ۗ\b_m$u u%K%{)m2 e[tl }fo*g2&K/H컯l){[@3l+/:HZh_>|"H}aNS&%dG_|YPo6nRe/?-})ʧ6mRk:'})ˇM}i!m-VJLKI|~ؗeٗ( frjg)BB, 9H3MKo(a oV ™|sJ |֕/Ka}x_s~ʠdZ#WɗHղdj+_UOL>N$S@rȗNw;$aV$w9&|3BarxY {"=_^&E#WJ?Mʯ}!WZt׶ވ7}J/]kG鳯e7ܡb_r<쫱{GIksK_?;;zF9 T SB Ef_)/X?/,x|Ԥc8}I*%(4}Y"/WX?d3,Zs!R3F_oXE,(=Q!V/ՉW|Xc-]Z"mo4|_myԇT)z!aڌw}.FC]aRľ_ =} >׈36除Zo͸,k=_N4$bڋn9 \bP_o c_{"BZJ\:Kj,`_듲{EV=;'c_NrH_(c_“\N}m[$?_nbD,}7@do벙_I#dI|ήݰCT[U)4>}=+qCb;>U5_^J[N5 Qף#ȫ+'Yߠ דRA՜׏>_Ƥnz|=A2ѧGۗ&qD&GuH\~x]F/9cFq})jʦ#'F1vNkd/ C|e/wPޤ_Cԫ$i_:T .n(9Ͽ J _HN*5흿?׾?˾rVܚ}e$/"e$x̵6_ΰ)#܂} OjJZ1ڗ6} #j1V ՙFo03A)~/c_1Ϥc_ߦ{QO|du8Y ؗ، վxUgaOB(?Ů "kKLɏ+5RW}-o8_%_8l#«zk#|/,nEqk6+bTzubR%~(ou>wǕ&[GpY3 d?TSWUIRw269tg4Q$ʂ3-,) A:EolH_sIP3P@$Z%k,xtdz/ Y\ef_xܬ8* ='p _2̾ރi)RUmGܷN\Fq(v s~+޴4OZ}}HFq(9،'vU ҷu\T"pe/%moy*'B`+৤`_!ǒUR{P$c.jBDّVCz: Hy WaMr$uJo4S2)2+~7^_ώ҄9H!"[J0a[T9R0e7TWS /ƢtRh_% *{R7 _K5B3$/󡣎}IerP@!/ CW6EjUE1w')71"2Y_4kRUe\,I"jRb34mX qUeƊI*MH1Wq^tkco~s#@Z}z9KsF !DsQ_v@`jaR`ؤػ#] Tt9bPVJRGFGIXJ)2/U-De@FޛNRD[oઉFςJ_OhևQMOx)TХB% AH +X./V qKʻř G\ƒF ]r2 /: ɏj_<vU[P7grD)$f=-,>| !2鸫`(U-ÿQa:복)&D:}VN36D+e2Ծ[dCQR\k7hzxNJV v>ƌԂ09hTk=3f=6'@inߊ^/V>$xkz̒=W5*|mćH_~ho.Ѩb-K=OW 9nH1әS&$nep I[(CS;h0})? -a~juWF}Jɒʷʪ .%0t{SոfrB.u4>O$LpeX7tPShR^ӽ`!}ϰ2,G`Jꓺ6sq^u :P] tlվF%>T p hɗE?%#$ o&LIOr >8/_:nR[zRYJPSX(u:& 㧤5yc?$YH, 5.5L"A+%3з4+U"H0,w[BFk. O+Je!fgrYoS%w=}'n:˒K(~k- %~U z˒b? $3?cK8J0 |"30/l5+wR4*30 ȯ0 c]U:.Ia_="f ft +ronX CZs$eɿɏQg/{_ؿL%B>݇@};sL:{ +ݮTY~(8.T! ʩ9K>Lg#6^Eׇdžḏ(ߧ E}*qjD{+X|/ 24>1&qb( !z>!X(]R^o U하pn1AZ# -\/KZ7JݏL\X]}^%hվ*^A 4k b[ [j/Juò0IҲ]5}{Qqp(}5,D\7쨵(-͐$Ǝxzh~!_uۗ{肃w r۞%GA;˗s'*Ky9u3y\Ca2C;xPBzV5֢Mxٿzu@0~T2ڑ}ZsCƜ#儠kG*?Z[0o`gҭZgbo#T5o ~U$ؾDI}l_AitmlOo $oX9{}z*2w;rBM ^7+ Y}9 J 'HkRs`!ؔ z(Tfp2'J> " Pe`}9Y",Gg 7l|_s}(Ϗ4 |[m—PbPA 4| *t-a;ϗ{[US Vܣ$>8׬;ސox#Hx Qj_mJ1K|#%Mz$l|IG kvn[4Z%zmCͣAk{T3p%5^U%#Pf_ l?5C؏fLŨߛ!/2kBB,nl=˜m/ʄX廛dC_i|odUo#RנD&KN솕7Oa6~/cUEE -/;IKAlUUP(5ߋ[BaG\_\?_nI|-!#/);-C [Vıv@wFWI3 %NBo}mHE~NQo eD:L_ /|M$)n5|}(UxI \S2){&RWDЧ84J$V?J?\eGin^>D@H!,k91?eG>_iT:DR;-5㧴h ZLտ$Y#c~|2ɯġ- W:V#!A }zm_y% %Mqڐ*a?10 ;)9lݷ} ɋ7L>mU|jf_Pڑe*sbW8W FbRu&ulSy:)?7VfWjV0D^#CۤJ_֬߫E%UW1?3-ַX 7VQxKXJ~ʘA|Dq-k[/|a)u@ /oK_W/ bK_[O=5,AΉ~_vپr4O;LJC^v5P>IG)Oj3p/K* 秔WVf_y#떖?DKG{X^} Tx%;L|. ɼmHTB9}^;+IG$.kenվf|KrxbcׇH}-+P3?T}[p ӁI&/f_Luf_Qg -nxZ_ݎ27x 70|f}m; qVJ6#W׶|r>IبL_VYG!Do0U0zU6EW1 J/~ZV@d?Ulݯ2K8_WR7Է9}hs%{7zo/}ݚ]^,H )Yf_ے Y[)`s"'Rb 3 ۗ%Gjb&'`Ǵ㟧 cma?/=,5szۗHK>6O|"p ޹U±_!Dl}W3Q`D?/_i K~#qʑE2DT#iGipK|F]' ?$;Ӈh)Di 0"h V<:-o{!bh#nY7i_R_8ABGn+ؗ/;_V˱/sGlYGK'(}KP|_9LXצm4Y38Wr|&R*n6j?W#[2G/fw-,o8Q2>Q+VN>O2tUqI{'_뇫d NC`[+3q]ׇxj6C\U[_R`g<D̨\`_ZyU[ZOJZPQ#~_tW4ܵxd#Jx}b:}/˗sǾc^d;#5sCZ[cIxHnl\i_s`=okP?_PZn䧐4Gem_=rRMBzľB( }%f>[Qz*W7k1_۾:'߼Bb.Dqpų|ۗ$Z/, <ŝ/#"ˢ#FiWibL}9ʽs/Fom_N圯5: l#{C2 0)XWoos}9wo,//d.85Laоk%^J3K֘}mfC] loʎB IQ_|YWOk,K|}5- ׉ؐE;Cްx U)>_BkZLWcVXϱ/q' 1xL`_F.c_r\ׇXD_V)n_f_ú$_/$//2f} J/s}J)[KGa>ò~o&ȣG^*-\q T >B0ZU,`_q}(I?/ַv5--?YPM /e<T/ˢz;ď9#}[} ʷ#ؗx\܁eK,x纖u3=>4԰':J"Jt52*wpX sd-ڗp Յ:* I5_gq6*Q՚E`l `G}5In*{VoUzSߐvj?j_ I؜w26+E黱e9G>̵8~/o9g5=b%Ruײ3)/EM/TYİ(s"/yV#s^OJ%8_R4~ DWf0WcprYNLQ$1އA`G :嵅/ xC#X_d8Dd{4c}s}/_)zf~DwkE[\cKVGeHe[2EW(T#A_3⬇c_$ bؗ?7(eڒW޹̾(- wN] ^GWNlDA"?JWJ+ ¬'/r[o`>,)HS`JϾa} "B/+C@o"zLҹnflFZݹ3*>/Y k?a0Lae8 /G~4h%B/Y)ؗh<}-JvԂïv O ht:#|Ռ୳BюnܵU ^Gľk:lDd>J?E[c_n~Z } ~KwcwK}vjṴ|4~Η% t>>c|SWP<#ؗ }es%ۚ6е~_2K_z{"R"s~_vJ%z듪En;l|\3-8Z/*VUвq;{Kq_NjlM k_8+WCΗ0^k|\:o>rte7\`ž갞8:Pnڗ/jH*6D~X}lg, 28j?^&v󿆝X2[ˎWݏ^$KƆNkBjvLׇٗ}$/A\$nb_WUQXJ'y٪rZ|or\{!i|= ѵk}'T:r4T,&9E{UҭQr~Qâ0[]}:~⣔%?ORaĂuP15>QɝȒkA6GϿpC#JɬH:WkFз*a9!V,oz/f0KdǾxC&Y>bVU6s4#I^b_/LvJ6I1r66>Wf  \/,idp|lI}!]>د}F"ZoD$AN C})ѥTiiH((F hᷬt:7,I}s^CP䤅:*ow72)~Ao82Tl ,.o1U+A&i 9{ɉ!`/.`ִ/kPeiī>) sKf.n?餸0娎? *+뱯簂LRykH1X।Ä(7J{ŝ7˦4q4iǾ:\p{ؤ%m BRgI@X~*(۝ֽ<-)~ iv$9x(\Zi%U9<~Z2k0EҙHǟ+Iƭ{kx.9>dK/Y_ևiWI4]ޘ#H#[(2%?/Q+JnxüU0|.K\5#EsD* >)Sʫ}(,8j7u2k`RRoRU#J-&5JƵJ !$ b*x|GEo-T4!u/'?n~F|ˡ Q fWdjJW) u_ɀb|O$<\Ruw3F,ž<{~K SJWoo?}Dl^aá3FR|`6| Ͳ/pdȺ%LSP -~[:(ˌDU(u6ҡ5;<)-Ue[]>R۳z緤^2֢m#ӿd B5K"nHX!L{80 E:Mxއ8?d9^(7y7d Ub؄m{.F7\cg& r>> f`{5Q_rK~T\ͨH)7R/q.sK[㾆kY oC/7^ -fMPwmȽ{jDQ6 U[ <&?d%Ю%^j_HUiٲ.S[='؄>X]U~8(7.7WXj~35\p'K"0ԏDOD!>J_*W>/pWZ>ܥ&?r$8)N$^ɡxpL-alp6z_%ڇE԰o*x-VfDg3h]b+Ӈ| |AaA}CInX}rlLSjrO?w:L.6Z<>)"!ϾuhMU R8(a-*ExB@ Osև_>/A5O36n'C*ڄ}-'^di&./bnͷnKF쨖p&9ca}yϵA3ߒ2j_D?\R!\bcc^_=^Ueȣ$Æ08l_} J<4a6E>\iD>/OX2BT)UH'*DxA)$ 3~BÓ]B,Jd롨W HM 7DU7 |%PdIsC*eb%MLms_t-J˹ `_٫tT~:_mGB3c6IUb-UT r7`o}e*e-'/*UcG&k9 NQ*I)F\^[WMCv+/I/H ~QY𿸕Nh(ZC|RD%.H, j/"όUe>,W2Cf&d}rGZO$SCL7_%-bm~^"HR[[BBِHS7W!85X~"NvQ(m~P>W{jRLk熍S>z̕/81#HH#|{-ַ5OH^L 9 U\p>TlILR_I"aߨlQ"vc)S LJil3"/oN75Δ_lṪuG%2 %9>/j)SUCsW\lH%H+UMz{՞.L.TiC&Q`!v^߰WmlHc %  PaXW&O^7QHRTM1Du5 1,Y}E!]}oWco _:k"y~eK5)|F >pUIxI̯GR /$}p=ߋ}%髜H?˻HmjFf0~Uo$/sI5KO-uTN?୯{4P!H4C(԰/LRKYTӇkgSPU]oϫ#3,~V@}Q\RΗx2WR_Xp߫'4xܾ:;^Bevvi./)bUūxkQ?UFՁ⍲[A[}Jŭ6'zWZ6\8#M!% (HޫŒǒ >(VyZX<$L^F1Ͼ?Մ0UC(kUʘe.qsi2>_rxWf_ϗh)m(U[ ,ŠkqqO [*]O/0qX~h_pפ}5uC{&~*%lT@.q`w/wX>)3 KjzsH̯D\aa~ RW?ϗ[/l;UaQB .|I{02i| $-U֯F lH k?W-! k?E繄YU(Ayjv`|=B$2Nf9t )j\Sܿ(ك# +=!5!M8%듈IڅQf_!eGa (a2Q-|9mrg" JnY~Z}P̾Vz$̑_URa EO\5a_uoco "rNb/w}niLŪ8S\폄,FVH1oK.̖ OLVޟP_Qj pnox}27dAVɞ MʉׄDw/Mn9g Hև5u곱ڷ})S e;|R<I)DՂR/ƓU-kRV_fa2|+o0 5=:PH\_鑪Pp ˇez$U(K+4^~nOϾیޓ{r_p-~_\?_:@BFk(n/}oSJ*D'1V]Z~%: `F/;k7u`_ X/<609죗S.5K̾|*nJ RѾH)֌Ro#PU `R6RRi\m֟JܟRl*jd#a%{U4-4oiW2.[6ipհƾoGtqIlW%5ׇ:lvɌ_vn [l˫}᷾e0-eV%_ޞ|_>(-CΉvMK|޹a EءrNEDՂE$6#M+rZ]&r%i>6#6ׇX#1_ Fi|1~ T ɃZ ߍG~yT/--&0X蒾-^}&-MoouěŨ}Z/se%3K^̉Cy "nJS 9Q2'f)/l}}& 'rDƯT۱J<jrNo LRks1ONo`m푹֭.I}Ql"5ky`_( PG SX!r]VW}C5&yZ;9ӖG%HJw"w7b S=/zEzW*"} ceGcuLj`_2ܱ/dcؗl_6DK|Dj_~Cn_WV)f_$"~ӌ:\`b_mZoX3OϲH6g_{ޚVX ̮2ײ"6xZ|K_CX_ClĜo!卞kvqk=e`c ք}= A2K>HzΗ\2ˆ qaW97eK%:/ڜMRX:pQ6z#f[Rj&T0}ܾ` ڽ)HPH3JZ Y沯l﫥vK2@ҀB,?[|7K_a9Dtc-9y|oT51g=T쫷h_,cMyeg3+Ejd`!e^U}UOxa±ʚk;U-Ή,L_ٌ|nb/\ 9W>}eRJmk|4=/%լk_8>E#?u ȈJ~do@-Ŧ[ݹ3}c|d/ YV2n34~ool~t\O$/AHn_R|'ELH_0c_kxnŷN^`C;9%0,sHV_vJY[?lgUl.[o>W>Kq^aa`}qi53.A\W*q8(Rׇn8ׇ>\^׊7}iom}}HLIm!HYvLż_qR'מvm5`_}у}I6ś0~BDb!}ȡۗxDǾ@؏͕]ŷʧ6//8qNJײ%VWaWIWjp,}ukF ;~LKGшi4s:ȳ3dNľpUڗI+^5F1ZZ`CDm_h*X8" $"p'Ϧ/Lm|dT2OcHHOfpFO9_ !IWY^=O_Rn_"1x%m&*rVXX_>wUZ6T[&ɢ[=?/ )ؗ7>;6ǟ,[WiW[v(>g"YVJ}Շhz{ rF t[* kg/X kwZlc$*Jy{a/\,c?DZbGݾc%Pև)żR/ۮD󩧇::nq̳rr&̩`_GJvs(k_0BeN9\$su kư*D,}UeRӥiI\>x5Ja$gf7k_e˜(c W͚]uYcÑg?R7$ z|z-k_tPŸxCIU7Qb60O$/۾ )1Se  /su&Xazx-P$zvB2 km֐Tk_k30վ\(:-t/Oj_,a?zިv̍窾>촯l[*_\,>լj+*7a71C);Ǿr-=_NwZ/WҌU ګ}A2|WQ)3jQ|5 &Q+7j:=~cCbif_M<)Me4-8}eH2@%L/+wۗ@xˤI7$a|?1[3lf__W _.EW^^WjA]zrd^Wa0zT߽Bk)4>uVx8b~ _,!/ҽt->SƯp%TJvNRRuo!.!tTiAJ8)>k7Ia|$$Ȍ(Yb@Jhn?/.j-oxo៟={%鍊L7Q^f)e#U uSRb 6Y]vo8?`$/V @96d ٙs= ipwe^Ѧa0ABa{,e䅥0t#;5 -G"5ȳM+;`ԐGUUԩm ,0#riహt(+(#W=*mNf㌧%+*/ s\vβ VA< |&A FqzKGqN%=yC+ ARo!l%^mHAvJ oyn*\amʨ*HM_&5" ؗxI6 oԿ18|fKrԾ68}(ߛӕpUA)fC&)ͩM())uDU!p6K{\>A͘ jTpcd|R)OWnsuVq ׾HQLdC(=99 b 5JXcK`#SR$<LGRj_DٖΠW\c!DboQ[h%oU7ܥj-}lB$pTؾ?-LT:)* %/9H ) kٟ Mn.k nEeƣ75&6 y+xyH@Q(P6ѱkv\c(Mx!O)ҫ0s׷,QgIDiYgY_q(R׏2h7#oHѳ)>8ܛ|=p.\ JrP}qP_j;p$J/S|*<&U I!  :]ϋ]e v%bw& BbsC#+R |D՚+JWKXQ~^e/*3H|d:=PUXk|36t}xh / ]  _gKlD/}Ub(vҰ,ԫh$N* f,|}AA LSr5W&2kK"?,*1Zr;?_>*qe{4#N^ N|":{X+8g6/E;<|^<(gS \8D>C 'yIX8?`gRT&KN;}1I9`eJ>҄ШBNai1myl8]\7<ۜlJO_xLë5p"6Luķ|s%P_XPڐy2M{uf0G##n8 FR_%Ta/i@MNkWQ?R.E>?R(20R``zgG [~M^LHaJe5Z2J8%#͎ cW;7n3RޯԈ߫qW}h%R`Di|*c ز.*u{ܱ~CWERfQR |SqȤDT>,9u~;Jtϗ' Uua6/k$UӚp(9XJq.Q' V{@0lTW?IH3o?Og4j5ci) Ϋ uc솹[/z! fa_3WB0KBTb Nĵ#(B W_eF,̑\Qn ǞjO৬4 ϯA8W\mR<%)+o =?eC֙v!A~0űЃ}5.DQ Cλ4?4}2QXbhHz?=_F=:y.|( _(qOq+uXJ^CVzTRWZ/ɋ!m50UNP`0VHsоK#>,WnPl `_?q s>ׄw[f RY@|++aO$lG`+}:JQuizZP5J"oE+ ^-UW&|Xl%;3]k4Y[}%m Xlf_RXD)1-_O"9,J"qsȐ!󯆈_pՙ=(PsQRВAGaJJ+U(^,~~|"Қ^d þcx>!嵙sǾNDUePPq]_\ jaB&s_@?1)AWjmO/j)T|X)wߨ(~Nև ,o(|@3WXqinHmCoEJf0",&9Iו8D7sUɜgvT;|"qqpAm~_,#@EoT7{ڍ J$53?})"P9捯 J/`j*7 7l/c=o#e]ԔIW!0LJ:/DL=RGQ+mXx%x`UWUߛM?+MDYpOޣ4 ϗII +y}:S*b8i'?H,/Iy+gb9 pizVMY6W,X98_Bž<~W YB\p?IO5?Rjĥ#sb_nmOAp⟢e&U]IGWVc~X_瑥oHقԘ7nA]JA0z$3UP_&#]KVXf44p,Yv6lL*sQO3&s+J:\틥$#_XQ|Mw$NYɾ7(M#^ׂ40{~誒w{"󗐼Hy{_(eR=Q-nʭ)3Q`Db*٤Ls(VUw?L%7Ll~C| ugkz%l$g}Â3WxLk J\:Jp&u ֯4&Z<7Z08 -8ibů B, i %(DqKy/ oᅣe(}^`_m +쿄5aE|r扒Y:KlK!De }z&qBL[z6#'%{!˯Px.kϿHdꏔY0+Hm 'YA8i_a 4'gcRhGꈐPTq|XidɬGW/J GE(_+u`k|b^[_v-/FpuGJӯCGT}ѵ3EC%·-Ƽs׾vbA*s,}-Dw%,Ծ*f솋s%,j&q:v#}?L+5oSWZ#yZPOWڈߐQf"߁#z̾E%5>#-s}~_낷LZH<NGbGVHW k|MyeQ2վ: 2<Ҙ6.tNJ{Ea_HSU%TP ^W_v =w T)7_}NbDeyJ#Úc! P^%ߍ2+J5"?W5^;J%7# 7H^߫iB.YNWh0/xR'h_x!_%nEDdcFb<2+/^)0 _,y篳ږO?ER, Nk_ X ůcA/Ł}։/1"˼3_G+R]@E5ޯhkZgHdڗ#܈ˤ|=k0O%PэOi|[X:H%3=(H>J6n &z+/[tj>%((xGRWfĴ_>YeKʋ%/'y9?xV/Y/Srmt-ȯJg/OtJ'<""+qN_yz&D8ܾ.Dj_.e8k_/fER~$fWB|oˎrq}XO볡K6G&; !D5o+zU*9 \毪$/#7/KK(c;=41ʚ@pDylC />~ %Ajb}x_7vnbnv|RZeE,DmRasδ'u s׾xek_в=/[]rȗk_Tׯ4;~e忕$m! J5oٞH;~dc_#cpH??[[׾\2_ ,% .̚!|f6pLVz!ݵ|X}_eljO/X%/ jl"ڗl}|V;~pǂ7TaB8Jq(Bɧ߫̾Ȇ䀿hA& }sQ%e/%E6+%^|!1o;5o_HrW/@k8džd )S/B`_&4AAqCX}_O9Kj5!*%_⬇Tj'"EG‡ץPyۗlUyzt_|.wŭ v]}m c@qZ??M- k+ î*žj2iH>r~%/0}5knڗ(K{7iCJ_?(%HF/}.gp" ۊk_{4=/1~}:\:bj/&WK_%ؗމ|?_ _J][;(Ob} vmk@_%".VVDhbRaÿMNŌ;-~c :J+ NXmHv5W2*ZX~+%~kX3}'c_~k ~^ʵ/A }0$ V߆<́-PM_LB٭k2^~JYDj@ׄă0ٚY&P@,ljaRf_"9/FDe%n_7k_h%ig7%MkP23vaKls"/ܙ-~CG%нsّ M7[$LFT#wmeĿa$hW0Ê} g6WV_ K?IbeV R ֤Gc9O$|ׂT-7;THSV[ X2}ɩK=.+£E[ihC #j_x5HݒoU&)D,} Ja&= D[5)=P;5vU$?L [7 6kU;W7~n^t[ |6.St$/mTeūm8I.p| TꐬXtG\JaUg*6hir쏚^ %e,`_RÍgHev<~@22\R y+\U2{E.@" +7ҵ<1$-ڗ=WMrG[1 &Ӿp~!!.þPX'3 U>'V`zQAA|.ZXn[KY Kؗ6C_kY j*e2_-T')#SgUf-{/kp׶{{K x[y77Ƃנd5?_V܀@/|U8ąܾ'5DpU>{ Ot$%md~6hIvP I! Uz 7uMEHwXm}R?ߗI+6J>톟,Mj?G/}a)O_zTDx35\39ATD¾*yR^\P2wmL] /4Cy|/LG_(_/3c}ᑳc[iUV _!al`>\[8s76z>[$5l1G$;LDo,Z 4~J]/v7|󭿑)8 ZP*3g}OR\ [!R< 80EqjeRJ_ätةnvFOPK _679H_%+2K/2I_GZ-?rI**9"+H\2K3_K/#()G(-2K/cz-(/d>=nԂ՗@ta%(Y!_%t&dsM*_$V=)bb[dЊHI% }6s.o|oo0QnNVL$lFgL 6j*Di( nvK&̥n+R^0rJC9@@RD7#^YhX (<'%ϫ}MdX;B|XmW|Ëus r+䐲{bDL[#leI]R^?\3)y$]2ۙċFRrl|Y>6{ e5l&r^cAi?UFlԾt>9U]QSJ_lxZJ[3eHOHS%+u~*_iz!)iNf MD8H XG-rc%޳~UboL lmYM7J㯴7_Qnfx ։~֖x%sNT׆|=WmTףg𿜡 xxmS[gX*!r.S|k}f_lS|.VWB/+zs^AJ\j_#5P~+Rq:C_vB%o5+^_?KW.ۼsj_C[˖@+#cdA/fDVoL ;֟!e`0}_҆] G~ !{X Rv/ԡ-rvP:ӣܰPv.!6Ͽrz.>j™Lނj{('3 F{_gk;lQ4^_k_hnBî;mTkBj& '?.,~*@e&]bb4(`023㣊5}'#?qTOpKڬJ*5Rc}WbsJ6B.B3@<۰)u|\é+{?2BGM kW?5Pq}=ߪ4:O 5eՅG 8BoG2U]1 CM_bL3ҷM~6z̆cD /cY/,?;) 3V^(!`3J_TFob|/B;.YTZ1 MJ+\2n e&u_YvܱW!~cHRqWL?B|s9ӈR"A~4cB<}W/ZrL\-*}a\%G|={n8+}_8ͱ=B3WV{=lK37P7H(_(;%NR(ꐰОM*+ƆaIqn M$Wc} A?k/d(:A*⯔@jQB\npcJD+oVTPWĖ/(bU~^KDQcF0dB # 5?}x2Vu(=J.-^uz ˂{3KKK_?;D,K_[~ܾyU7r.^Cj,,̮}ՉR iR8ˌŜ!(Lj_$F-2shî?WJ~ 1.Γc_WOJ+!&˥~arMWrި3JR`5緎-#25; y9#_oظ|mU5D>Ś'NkZXj;) b'픐nF$sQbo.|L}a Uы\iDŽ<-$9t??Œ#z0dR/ϼa mC0^i$4M6EiFEQ_ӌV'g6xQaxN$Q&[ܟ8>^m X`3zE,-/Wc缾?nȆ|L#ؗbkU M[cD"eeQmljOwi}]}{շqTIL$/!mٌH_|.(n9"}앸tTW*J\:ʶ}zmѵo!H$]&HłxeǤ}v&_azcJm3~W 2,Q?-/Zj+"鹟n~ >f_z(E*'CI(WĀ"d)2'G/VeH,n D/!y'p׾D xFo}I)} _KY&(;Vz֏bo!Uuk<º%c/>>r9žt-zU[b-a_(+~]_iѾ#Jhl_#aHOWB`ұyjRZWQWB5}U%[U(% p1>g,eʸ*r%~0A[c~_zZ`_s^}I;l2 Y|)} /VRE`ɎVJV'kצlOY&ed=e|^)s}?#YJ?7tM-֏*ZJI(u~oXѪ/{)HeWC #N\pd=O3R | #Je 9({lMa_H^Y:kо /ox*yoJt~9l /%r*\Ղ}m t\BqʍMr>|3g$r% k, %˯D"+1IYK{dk~lm~Ѹ>$,WNoLgSH6Y# %}ebљ27|Q3׽U_!/g*Ʊ1OtJ~/ްd$9QW?|և0杋/q\b3 ô'߳f /Rl&ҞƳPǾX+[}CT!Xsu8PlЈ}U*2=̬>~og;J9ǾJYOW6nKa%ۮGJmyԷfzԾn_RG~y|K$zEVY\Nk_" (wR<'ri}O7})O?/P.&׾.g":D 3"秼BOm=VҤ}UW/jYDvÒOHF]>+q2>#-O$4rÉ}oVc/G]wu~I /&J ڗlDfd_ӣR$, oшu$Z%~˖X/~x_(̾v j\car╭"Ce3mYesWW>W2ƤV/8ӾlT3`_ǀo"RO4"l9#_6F%\ft܂}9x˖s׾e3ѵ/la$oXi_3Ho0ܩaG2Hxx[V6!fa!:88x_#K@홭~ 5R;nY/߼@b-S9߯}d^k_R\y[[W*)ι}iIf:_Uk_ʓc_R |Kfz2ka/ܾ.xDn_eS\1ߌ2шd?W ~~ /܃$咯Em%ו-b{_|0nhLb@G.?%X2ϿT xcMߛ!M+N8&9#{/yfDrN*%Re:5KOVf:_O_~*}9O""+^r]~R\}9˼sRJ/uٞ rF} jf_GriMA IL]+}9l ՆhU8_ګ,;H{fH)!ߒ*?_o1HΙ}}'wַfȟf!mi2/p|B3}0ƶS)sxYt}x܊eRzKtea?,bڗakفZra4ˊ2Ѿ6]ϙS[1j&ׅ|UӏdI}UԾ{D'kHEB.lY(mD5 %|xڋT> %] K߬{,U<;q %ˇHU6F/4^lݲk\- `_ع a?׾0bڗnZ+ؗڗs}2ڗٺ7Kn_\rH̾׳4Ӥ0}e{Ǿ־^ar[5Εq_}4$S/T@ /iIָ| J>/k M+n"]bf_Rcʀ}H\I%/.{& })S[EBT⪲`_b$P+҃})`kKf;%-w$DH}]ȗr\-8X$h_R\ 2- ֥.}kMk/ F6և-|W-?!]W/j,#_\w/Ih/NRc\>Q--$x4ׇ+V$=\8%O$/z_ FR^1Zr7P$1K _݂'W/8k_B%8"Y\j_l|Zܾ[\XPb-ʯlH}zümkYYi ձU;d7JHgZ*WDο繮}-_F''_}0^*bj+(_<x /4ԬVWT}%Wl!Z2$H" /^UMHHB Uja}(/>wg b>ѵ#3.Uc~O 0hcQ_Y-'[fĂUI"L7>R&/`k6otԃc*lHʍ/%=%Rܚ|X*zW>POًaM _gu6WR_1+)kSQDzzM_u-T5 K_pCY3p`/`M /L]oju. U;V`/˥_=r_-<:^)B+mxC1+ǫ|Zx_z}`l9 ۈߨDU 9 ֏:;fްp\%C CjWo Cϗׂ_Ki VͨH@RP_/k*-XRȥ `G,Oo40t$%LOa"F҂_ʮoq5 D*yCDU M3cѹR%\uڡUV_%C˭ntffQ||G^>oy`ʞrͬ7&@i4҇h mC1KC6|X67慒xZHd-BV |}#%>r 쪳!#\x0IJr2M^/af +oIq&HPKja H8&8X+DUZ(|P"!?{ J+oTnG}[;5Qd^@^[O,{YcuiĂ^ Uech01rfi=ք]H^ĩM$VhypH|@Jb)Zjpj_gqbT;t# ʺ|$l,YYkG 8׏YN7ǫwҧ~Ȍc:YP";WbǕgH"Dj_ 4+K/[DCOYxT/ K_%_oa W!^%+ ~+=RBC>B;čm!e\Uo5APi/~ egkUo $ HάSeQGƋ c 󕵼.LH{-lVH1=>=ᬞ:Ŏ< G RJtU!3xY U&./Ѥnğ1.(8" U2fo$$BjeD7(-F1-x?7Dr,BQ`_psGJCF=7L ?R'?%aeJ؀W)!jłO3΢2Pd-^]u~ QURl~\ _UJ`FKWkzPjLw$%#u$)ݽ70cggMO`i3D<Es"Õ>Re}R.lZxu>-#~Y槣6xnКV:kaoTG}֠x͚|_/7<#]-՗+{QXVzq6Zpu`_!BYwh*9(aQ}PL6R6N| kJ_9̢õKC1&gaz^>ԟW5'*5Fr5!-\T "Cy5͈>[e3FcZ ;Kh}!_GpqOD_-;4Jb!HHmEh5HoINm!jQ:IQ~'9o"_HXI@"gWұ/).L $_ [qU̷(ݸ|Jr{U2M^ )O7 j7[ k[_=YU( cm@ҵ3aJ9QhKBJ޳m8!&PN9ub8&hlYQ` yآ>.At>u5@JVdkYY~ee3BcsgI-3"E$HFGU$nC>0.*J4̴vCF%׊.abb&&!SNo7#28a_S8!$eY~iV"/]QP5$=U|nYN_ienDb+f#/5%}ytGUJuxuVK?}K_f_U tR>v49)kS昧/k׏UدX˯tbDkmt/;L}AF^,_2?O}|J>\AלGBC4Y&]╵ƚg0K"ii0H5[F,$5<7RRviI 窆[z\x%({UFi, k9pCdn5}}(e.*f3* Up6>\p-i$p}H*?(JۣO5Ra~~,8W8lG!U_!VhnR!_"%WEWX)+SBDHLT83Fʼn</ )G/*'3u֯49$h;ҵ䷬Yi<:Zg2|0[G^Ei'Q*8SH delDt^ _8~s& j`+~e[J ~CV? p%)c/K_*RvR/ @ѾW_+=WM(䰃k68Zk=Qu8ʤ)k3&U|iDe(!3% 1?RvW^ZJf_s\5; Y Ab"m!9Y9؜lA|$MaH%e!%X2JA2#E~e3"dL(D2 r+ fD_BWۣȫ_|ݾ fiBXJ4Dӥk_;!;18;;_]c!8`O_cc8k@D3&";܌H_vgϘ_i6+_υR ۠W{$oSRF]_it[Jz[ ͏2 *#GB;)F|Q 鐏ԑ"gD"`yu6v2#VDV;/J:`Sy'9\M<9_O&?O}əG.?U;ki}׾DYu_)ۗԫ]_Ӿe˞beX"{\L%6Kaa}oUϧ#~}.lBY"Lm/J$ /+a?5CnR`ga+4>W9Ȫ%U<|K?ICr!)OK;J>{nYIzi{ɮ:1%o;j?ܔshEI>d|X{o؍UoPTR/l{C|JHƒt& jm}jܥV_0X #"GZ¾1/jU,g+JEzݾ$̊}a^9PRճIuHeE$_n/Z i,{%/^K}d|"G]|_if+BDZ$JvSX{.}+ш>OUnoجWmxrПto| 3L >k [4) 7Y5k_H wga?׾"Z 8l{ k_.5짙}exBY[}E f_@}`bh)]>H_Wyg_/K#E>QuI^[~!i|}MoK>HfE>H>Wrj \2|"c~oP5P k1/ܰ#XG93O?Vf[_ kï͖k_GS}M#Jgs}Z|_YBOu;ѾT^__9Qa`_~izX/Qׇ$d˘\>]~AX_O#}y֠}ܿ/Bs!~{U5[5tF%'.T2[Y]k_%UUI3`=j_f9g9y68a r_zUݾRb(&8+$Wψr1w:UH=ssCTap>lZh|_%%uâ:jk VՖ|8;{*ĵ/Oӫ2gcױ`_0H |sѾ#/;I=ؗ+KWvt-{|"kcAd 5}ѫq׽*H>7,f_ތbN sIv)Ct[pCaC->u7daאY J+ި|yǝ]|w-qdUkd5L# SrJ|X{v95+%X0P^O_T}:^DqGMm+E5__F,D*K)֊79ѵ/aWM6-?51ܱ-gWƷNS5>Wst}LFtk%ľf["m)\:!ϥo|/b{j!vRVUK*ǾsXhk._u/it-;|=я-@׾Xh} bz^Lʋ/˽m"pQ_v_eAQ&bkX@#;P O!as"/Jkۙo3a 者(Mn?oW}W+Wr&)|%]}9,6}^Uj}Q} ,%I2%ؗEm%r,+ؗ$cj/[MTɂ.Z-ؗXEYrM K_ڰɫh_ .k_b?2"JT fiMI]~ zc ns׾~} v/0Lj_f4{`}|m`{vɍΗs`|s,E!_Irɤ%g֌h)Rٟg|cz=}_g| mu*xֲЩ}m?/ݾ(U˯4$&5׶e?|"6B%3ؗf#(obzx lEbj=zPѿ!Rcn(ݾֶ(P}me}ImM;&H3brXM6޲y*xJf("*>M6tI<Q`_8dEo[/vf*9*tQ׾P{M_?yy$]W T{yn׍7ڐUQ REϷ`rHE'fo=WιRi!/k:3Ծ[yvm>@<j,\i^ݘl /K|_VEݾ}4P_ηilΒcc4EeG@C]%PKPJxmYu^UxHI_mL5HrJ_|z*m oB*sR%A YjxgҤ_ו~_W_5P_Jj6#Wϥ/6M:[e/E_|5a erW]I_l2_9}1ݮ}xVQG>+ݚt`as>[h٨B|_g[ӗXcuƤ CͯL -rS[ 4q⟶r^F7RI0 ] 6Ĉ bDTT Jj5 g 5\5 Ü Cfb]ׇ|PX_&WDB*"*ϗ"$*-H5}+և-bB ,go3 :*|Paij**J8y$klRuy|u9qHԎð8ĕ'"d/W%VFi-fO,EW}cv\pcL-gCWm-y(e2ߡ+3]Kf4-) 1Vf"oS S*qonG16" 1Icp% 06ZI' sU#d#jGpV6 /3)oU:.k%otx9äf t ),P%peBWVEhUm/eq+2C\VUb7etv)o3I[|dQ=eHMboTkVz4v6xhF$ԫ̓YIR.JZ̚qz_:B%/7,S2uAPrBЭu>u+D5'K-'L}!/p.pkʽ+F#`?_ЉY&S5j Tf^u2/YO4;%:?)ww} +ԾϦdqh);9_OgX!sΫPDfb_"X|7{WYz /úZe/wDH-[޼JV\>\R`(IkH: AQҝkf7DQ0۟q&ZgQ:a8?RP4$\Cĝ?z_S|Y)"MT' ?_sxl 3BuƦ2Q6TIc }MDfh|ٗhN'Ȃ ѼswR02]e^ď#g /Cg;8xkY}6f !&lwDX$ dbg–7p^?{+ͅTW}sÄqih.:>=9+4~|pU}{2w":l0^i~oZhYGY߆^h1s%}]?7%N%{izaS!igKo8BiWVfHi :zsU|XeKJ}5HH|/V/z(R:b*W_Oyp%(vON@רs$$H@PQ*]/>Ƽ>dr{Di2qᆅ|"$ 3O>>z. P7g+5Hi2~>ܰZؽܞ7M~$ǩ}qg# $*\H }^BlK>I_gqlU_)u `_mWʐX,zl-/Z(e暁|[)cQ.!vf"A1%tGU6_ַ7_gO$.K 3WJO)yPȯCtv/߫8n߫&_˷ )?%KeDb* |~؋. >a'NfGWjbpyuڗ~/` $2:Ӿv(H5{rH.$|%Gn5WyK+W 썺73L׺ BnIB>ẇ=/?RI8  > ԙo^ !ubf;J̽~qgi_H/J!.fXI93DZ>ĴuI^mWMb~JH< {d8q$" &k| %`9_~o#%_ 3ipH}}$TW^5ȯlh1G"`w}$u_؀[b#!c3Q:2B&:pR_kA63+qjb+?R԰>,de x mԷY8{IJb;Ҳ &1P%p8$?G.yRg|o:66ڟf9&Q>\%1UDڽCcO$/ LC o.epb}h)ck/Tןa}&ۖ6 Q'j/q˗',g"D'(mH׌H_" er}؍E88Y WB; O#/r)M/~:cA>L'ޗK(E{A:cھxK-9JGH`ȎUn9ͤIg lǾv4IC1 / o!,ƦL)u/G q^4ՍyDgYFe?Ϩ*΁+$Eh׾D*\`OgSoȂ>/6+;j)y}Ƴf ̹x*7LRęj=!J \ ֏JWl7v)+-ַ敶W@1~r?E/KRﴯQGZpb[zD8,W|َ}ˡo/o ǣu)M!_G<.3$:̾0ΧAu?KCk_2T'pE7Rʔ(|9;%q&1[eF_ͤ5 (PSb_}%R3>L#%W>ʼnӧ_(GJ0&U>*O)3i_8x yYDIGj #alk}nxvqHԏ:~ GU_!MFׇ*wa'I06n(nçS!:1ݾdW"bо<oJَZ"_ON׷a kswWOw.668kf=9/ $~E͈jMTia6UW(&GD<$T}&m,)O WK48{ 4p^:ԕb׾1ӈ&}uCj %Vd-_)׺%?3ؗds,~x@#SƦԂcAkR6z >l(A#$,Z8n3D [ +Y2aQRc^iFK\&Է_ V FHmR!^ r[VU["Gp-JKbC8ڿJ2bYfWr2p#%ڗ_2e`\Tk)Y|T]qZFӍų Vv :DH2!𿐿lD׾}/X;wzG`3|}"Q/kPLa&HJ2 Ө8о2iP2BUoշ+-gKWxRWJOi[g ki&ۼR3~J3Kۤ {*1xfV'пY01`_IQJ$)o[}6c6 #M׷1ItgK$N7-_!Q}HKa?'D21b!𿚹|K9KӗmV?_3x"˾c×l p]EʒDV2#r~sHWJwG2~Jaב?mVI2%^i3~l/vHp5W*ȯRV#I>Qf"Aۥ36 3Q  >9 %ijDҭ%/J. |sѧ7ut^k9ZXĘVSF]: B<בrX6|Ή5u$_K)?T4mZ B˦k_դDj_ˤ6Vx/Z4>AnUkdC9<2ϗx([0~c#Ip#?0z_Y+ Us%N>ΒJc|tT3a^[Ӟ-/د}q9f#1D _֧( 2c ej5/˭fd.,~D>Hf)kk;f/~Ek%mr {EaIfzU2 оj5D|/DAZW2>38O'z?_ CD"5h}-[U $XIT\'-8SMqޖ\cyd_oG%AN YcLdfd{$3?!qZL + 5bהҰ>\or Fs}Q,SV_"WQ܁e{XW sŏ~kpjv)=ak*IUPE;ܝ^} LDr퉮}9˖s׾e+]fLc}aJuBD}MfNr5~لH4z]':V*J%z(XkJ(Էw!/,W w:\o.jJ^ 4/4cf)K~WܛtD k_2T L2|_\2;lkk_|~DR󈻶 B;Z HGSdS/˜kr9}9D׾e˹k_"7~ W*߂$5M1?˯ja8LIrB(o >vsE%WUR)1݊7ެ0 "}74̵/:d進V"_ c"v}흃}9l{l/K#ؗ+?|"qB}V)'e׾b""rD?VvzH9ѵ/dVbݵȩ ϛT԰4RעJ?2rwZk_RWuֱ!z>yte:P|}͐]2j_[,s} k_\̨>V_<~D If*K Ca׾eegrD |K_ /1qED/yj8_ KjkRJZZT"}`N8\$/ؗ1.n/6N'yTl0W$7 O&)=?RXp[q;-a-*J|uTn*\pN!<\f_a6Q=ªI)n&D睧WH9r8qLDG: )} 18/WV 2@gsȗms+Rk_Bc"UEP_@0v.} 6|s)mnڗIs"NJ0K( TjnL7]1TvgնSJi =v3+Ǿ(5̝ !G: RvL'+%x+c'G7/4Cp*uV&΄풔Z'uM+/+/B%',f/ez#qjcf뵯n, Kʻu Q'z_f_"_٣CTVN("uA;|sb؏` b_zƅΉ$4ma,xC: RK2"ոJ\*J\/GS4Xe=҉L*-!Wv1=Jg42 :N2 _U,aƟ/k. kT_I_ 7TV_A]+ATëW zeϵk o~CmJ:6YF.R5>reRЌmR?r°QW4BɑuT6Zڗ7=4>TW_B \Rg>rJ]K7=Sz԰Nzp)[Oz~oKLQotUܰJgo -mFCbJ!KB5cQjƠQ";P-ōV4&k\vFTf,F劣~ȓJ~-|H}+0ft`ī @ GkHh-v:k;HUcEd90Y_PSra+$I /Ivf8_]IZa_}%xH<*a-`i_$, o%C:" pWBjر|Ycez#j3U>"Q]4~CGꠓ5 ϖA$5:KZ_яt6װ+x?P ymjNSU"g%j xn[<8mG\ ѵ(ARtȼr9eF1~CD^?P@v״/g-u-H7Y~jGHd3O J|}KBϟ_uY 0և};̤OAaG*((_l@ξ !:̥c_8siDP$<WA@x.ַiOGU볍ar_*톨/$wcrN,վ %W!]8cʖ_s@u )?wg /|De!bsE.p_K2Z^5Q^W#{<RbA`9u dg9,~f2Y|o +_ q)%EH e\b{O#?U_ mG{!~H^gbóL^5;W&sfssS eFǺҵFW7T0I]U0l椛 (UpFz>55vl7__gu)o"ݸCfRɴpó> f_zx'W/Jn˯g(72‚9>˯dO4i_BD,,~XuJf"f?nFD=WX}%5JtGD1OnHwSN.JXJstʖ욣6t_@ՒD1 lHx*72Az|@)RFFеs>\uҾV|MWBh|($-AN'c|`}"Qr0#_rH%!lfP^_?C]KE3|)sup2V\ܾ>4XOB[= 7߻ׂyD=N`p`_8+QW3#r[rjg@H:H/g.IeW&[2ۤg#3葐z)kBٮ_屯$=>$/8=2X"/4bH=īe\gqG˂4@z6?tӽZI1@V+ǰT"85 4D=r(0J%&sCI}/ >i9n*$Fp9WH,-_ nKŒvLh_4|"𿖽Ϗf"qsʔp$?[$Y!~TI%\u6'ɚi?Ef#]*y~C?^ qj6I7-$%#^ )PP앐P~*Gb| 3ydx5v-s# %|21^PFG47y54LQb"q)y QpX$5 Y-_0ar69?E_5"&fF +4# T#Śژ׻)Jب _C G>Rڴ׏DWcG7MHL^ K=Ѿ˼6#CM:%nXaX_!l&Rעu$UW>@#^[s'; Cr Ks 465ϷھR8"k/+-gC+ƸD%!s}IG*_Goz KҕL,Y@cœG*`lAy{Styel8XGm]t9H3R {uɩ3ye5uԪn_gc+Qg6 Ƴ:$z|& HL/Ye*3嶫:Xe|q]6ɧ:8( Zt aL_ikf!G#UaJȕ>3a)|k<FHM>P_Hj4CX6r=o<F_?@ȁ!毎Ͽxفa%tݗzDRc$/i ״cSuW1*?/[cނ} *޹kd 8k=ipנ;Ir߰׈4Re/ºWJ?}=R2>)X5J˂}ӌHB>)6W+!~^K}9JsZm}$|!(GZtIܳ#0+QR6dWPf蝧B8H դ &n}6Vbia;5䱺}-JNT7$̧z)"Ih$lݣ}mq y_qOU)尜D)w& /NfDY(Z'a!_+_דI49X_taRTɯ&H\%s\j̯핰8?C mzHyɯܟ.*~9ZUJ=t%qo.$oc_j"= AO|UH Yo_NH ԔCwҨ=!$"NUWH>.O9-/ʦw1 {PW$^r.laƙHDl<@5V)/.kNUYEJo_OJf_ݟ˥j$Cy<0^i_PvPp`I5>Ӆ$_YlCCyZaX=/ϛ"B&yבXw ??2 ʺ{$!~NHd"j;@&]c"_3I~zdp} " /sb뙋;ͷe%8EJ/\(kLd|"oFNi` Ix8!b(?R䧀 paX  MQ篖o$/lҾP>)./QZ)(9_" d3w=QWߙ^/KKQ"s~+_+W̿JtRWBѼc_y m{KJ%SP()&7`; a_֟gYi5L8EZcևF K_ι8Rg8s;1_WD/1ܽtrPPC,_QTDjhC.G\d%enDG0"V_E_%8"L/a/Bˆhw&RrFk&qŦxi4WZOc?odHoԜM*ֽ";U>)8_^1d˭_C{7<+<%Ztw$KBXdoolJ>Z /:16ѝޚe9>y`_c&D>-JZ_K%uxj(-_ /D /#^kݟD>`wv. ޹2FOe{?_6q\rȗDzjCkHܐ/:5LDjBU.I &*o*+#ևF ] >HMBƻ>2LgKQ//)*\}핸!46xK/tZ}9X"R7𿘄RPe%̵|YJ)JJ8052]9Qu/[*-~ Xq}(/?keKǾ}9˼s׾ecO64!el;b 3ؗ_ep+}[l/Pks%L~CV粀ƙ,\8_F$,+}ʾ_|SO9DfWIvos-ד+Ѿ+{hKؔܚ4}I5j_:7hmū ˛ &y/+F/sj<j}]y> aZżfL /K`-a0cD GE xI~KU+ι}d bĂۗ8l9ڗ]e5\Psr`Xj/ Psg/SIaοWѾFӓen(gr!YHH/+U!-W]_sRX6w967*I'&2FU:_8ϽXֱfRNBHwlIf zgB 7ɧ욶Kuu'jRU_0 uUe[,5Qr_b {2I]eWmpI5rV/CI,G@Rc3zn gU7[wYD‰Ħ5`f 덳([ 9Bs8fʏK N8Utjћp4K-VZjm[`BmK:#_w*8; ,$ZӚ?uMB`@$ @X͈s8!*U8O0,~C,SIU*}XNo㋼B.@jRasU« {+ζT!J;  uIWZX:KY|)z_Բ ?/JpMKO }uJO UC+zCB̓zeE=MSQBM9_P~A_5R13!:X&5g75JOd2mX N}ևUS/ky"6e⨩YHWWyVx _ '^UJW)w2Qw e/k,C Q jlO 3MȄFI u<_hd|c.$;BK~ I^Š"N3ޞΗ: QZ\BkԈD?? #$>pHNAQ5ewlYdpHz[G= -5p qXNA=bnpR0I h(.U;ҐT#Fu8>I:}HCBűx3 '^#~=. v?c=HWȯ\$ԫ\^>RFiLQZӪB Ϣ3i )4>^U) v (2f,"[w(;ҴRaÙ\&ޗ^ \oVv/J WoyHpgdT|z%k%ԦQ8 '%qW ˲Ⱛ0zԦհUئZ)4LwHBIXiq!ݑ  w0#DRfDIÕs2W##yˢI&辪 $ ߒ cJr6gվ2%iaoӷ7ׄUBġI@]_|Zj|d΂j\ `zsCs}KF!Q2qbCYa?gi^3QB|2*E[gn)ѾΔHe/FmΎ" ^_)ʩL4?ϹRjCuQv b~JP~6tMrX: Bj__ G-U"pBaWꌟpRE(s-)ɨߛEMQBpY[|_T 3ևs{qkRbjsp~BhӥWfBjDEx^Vェaj,p-+ֽU`q緄5P&Iы7f.֪=y'#;HkayKdz𿈎wNRJ+eV}NuOddrny ir5.!׉XnD_5ZJE~P ]{QW8ߛku`5þ]z%T퐂.=I~5JRM[/JZ ַ47և#R5n&9!|64 uՑ,~~U򶯄itj熛U0<`}m<HPz~-?SW5iD }^~bGMy)y_ob~J"j0/] eվ[gÜ[! #_ONm^ܾxCi偣bLs)kRIZuN| j,#uTQBG.~ Q180Phik"k"ظW"!%@# A+#N$[և[u/}jc성-|/U\I:%דl:f׫R#FU_pVa))Uy 3nDUi!2+1+'87d[V,GMIcw־6ųG`0d|=l }x%a8B3n< 9-!0M]YJ GڅG#fF wIW4ӾPO^%óQ*V>_Jf!;]jGIwbGS /u>yR &=ll R5'BB)L헟«Pl\ _/<оrZr_hD5kDP*X \'B$siM [G:ME}l %ol++o,9.1ky6cr}|TGhIoL_D2="Gr&n QF"2N+pb ϷGMҎQcco[׀TyF|c6o4f0\Жs f)7PFQG8i_(oHH 9*ni_$ܫ$w5V\X mj7HwJQj& &HzPQ\g3i}K) M_1 Eܹb q1~%tD:#R!Rr`_tlԂ}_R"$א8a6Y.ڋ͗8;pO_+JƁHp-Ld˺PW}Hhcӿ10;Kv2 ޒ&WˈWں7d3|ymaϬP MφīWB޿5:篹zfj8+<)bRn OԀI¼,ciIJ;A%-JWaHBx}lJ\"v rl5 f!|搒;_Z5)'-YxF 6b8_ w3t,W {ϏI)D j(F$/^YYثշ)v=0Hw錒Rb,~C<LʢETGAJQ7zu4_Y'pWQ~™0biuWN#M$*aZ.T^TP׏}\"u=Ge\I=/Hy[!x>׾lU_b{JyK$Ƴ~_/y`_B)sS Drza&HE`Dr]łgh]`nT:>}JO|6>Qxn|=pK@3KlO3)[:HzM<}%Qmi3y*|ǾpD{X?Ϡ~StJ Iy"6<'JW2=ܾ(ٞ}uhAK(Da}-ڇtC\M; 5(' /rڗ̾Ҥ}iт}bW!W&FV߂GG_ Ja|='Ym2Iʌ{%$I!^Ҧ}H>UKbþU8J_GaIK_ hHl n9>n_5b5n@c% a%/0v.27U;,b!8qWZ_/^r=/J_4j"L/ n޵aR{ 5;h?W(ܐ{Oy%OVe|w^ ^}dV93>ё,Z|Y_,[P߆utҮ"hOn#e[hc}mH\^"ggB|}ȫ8[C +`Y$ɽuFd{~@f#qe"Ib\ %_"*3H>lI ʮ4\, B`_Bײ ׇեDOdkD-#_/%Yy?%+OTo )*GјI 곡~ևZϿ>{TD/qkK=kh_g4V7Ӗa %n}݃}Ֆz#q̬򿸡c>Qŕz_%S;-HŎ[ {/_%֟W)eU}Iy"sM2&.~_6D1}d뺏})}nH# Wˤ$J-kcZ!^/},YAwP+RCUshF78cb|ٞ}5H wqjZll |=94!)/%':;ynkW8!5:U49/6_R vRDΑ"5/ι})B+8ܾ{"_:˗sn_"uۣ}#}-$孟RpF5mˉڳZ_T_#N2%:"/~QNBxcuV9siG!UJR9ؗPTx_shmmeד^J- %5ؗDY\|=Yh}qU9W)|YC~N_Mmk'x} ]HM$;žڗH>ͿI_OIׇxwdJ걵*Ad}n(57hᶈŝ}N\*"8 {kN1q jR;fOY:^\Zean5}X#6򿘰٪_ ?_!)ڗK|ₓ ]/i%/$ω6GG—`_gL/c&Ql7e:l-wNbdW OtQ&KW+& }-NQA/Rlgҙ9LEe0ӹ'e-~_02U_ؓ[91gCzJߐJIf_4`S[GqT/Y}9#al/R)A9_")򿸀9_K_lP_/,a?n_U"b!aۗ-8pR /pȗ{Ծ$p± 'Vו|̓o&Z;I;HR41 /oAo>N 9ѽ߻7t( Nˆj_%Pg3q~t`{ԝŽ^=pAܿ/ˠi׾:$"HB|jc"˻AR^1D׾z9RQSE}BVkXJ^:YseXu$Z [վxմ\Nže'ͫo4"X k&6UmO$QQjt} V<K*/i3ªS?đҾ(q>ui0KF.!~CJ]T^IR,-iڟߒ$K_oi2念$ [{CoDx{3+)k ?M?Զjxd 򿬣2ߒ# )y 7PV/`)y'Uf/xߨs~Ґ`0!|xFmlH}&MY9Ty@!I!+s.|fGe*%bK(p.[nJ)>xUה&1x!g̓ǎ P YA J)k6Z$ d3UE'a$* Y):qVz,hw{dDG?zk|U>-9WM,S|s :no-\9N%7T-pzSk$-$"A<&p p sKtj[^ ʒz`j[oYV_7WH}Z'!~r4>y\Ug?V@$& ǫ" QIDB;U# &2:k:< /jJj)gJtm׆W5ַa2ӌUYߦfGU /)kagcPxHI(2Lk/^J =r% I%\Nξ'RTxƟm Dc'ZxF*Z;Yo+*IXXd7GTgŗCGyۈb,Dj_>)>U$[# 2j ¯g]Q=:ևn9y԰c_78:h 6XSM]+UO9C"='CJP}}:GəK q˚Bu6}Td>||)ސ`rG"PJy'`gT#RDפb$QO "ߡp}xWRվZfj_W2Y[:JeƟUٰq}%D]? 0y{)*|^Gyސ`N]upj#;彁fLH0 J;#?Ld=e1oCG]:j5@H{}RYT7ṕJlf"Uxe¹k FI[/H2`Wj{?Q7f &?WUei4vF0\vՑtmsأJȽǎ?_۶G&pP.m2Z_k^s瓰=@|NƳ2qeȤ^}d<8R!g$r!ڜPf}?#*#b|Ʉnԟ)=l_^~zc$;K†!҈Db@"x(a>ՙ+KѬ K|j+M#&#)cDir l$"%;gW5b\{PF,'t|%u.J8JtvoؐҏO,H?WM63=ߎ" ,y_)[~τh ÆK//0)}p]2~o^3lX|YJ%h}PMUl ѻˉA()~l %fQ$q,`_B \9Wijy^i[2Q e3"?_+?ّ]'q9"$2F %`5Λ5+Vns|>P[k9E_/H??ǽᤤ_sɼWQBq{"'sVL8ևs܎THBVF) eo~%ۜ߷QU@JxUǢ]Tϰ9/7;Jfڗ}qr[lKMO6 s,Lf"7o}D@2>j3"Ξ?!_UʡH8lʈ:u8P NF\򱯩_ȋ:V' v_}>7,j.!KaCT~D>=]u$WBi7Rj\PFi`55obJΫK8xUAL0y_Y{s3a_ e̟ȓ{CMζw=ؗ}r*վtD>vD׽8"_n+[ qhReVúWD&UfO-,mY}Ql9/K0xAD/rI%2ZH&yJV +al+Ũ5a_8п7T!H^R)|5 v%DY ~%lΔTz el|b|@`mx.ԟ @WBԴtW4z *5|%S}*3*l-d(l_#Syr"7<}+ؗ:gmaAsq}4!9Rb&;x6֏I#ڬxcOa퍖RFb7/ /Cϣ7cA$,O|+]Ń)^7d,,_ĸ'h|trk;Rk6 ,/Z}xC,e-']\ ^B8; QVWMR1blyӞ;H i`_N_ヵqɇ]?UplЋЪA#A ?T?WMeeW([FzVibХACJsCB–WHsKDu-Q/ +8?E_b׏V/Z!UT\֏j·ݐ2u`^WfuƙlyPƳ,~/em4"&aZwJ׉\Ӄ}}_UJt#*!I*(5'"3pD+eJ>@* Ծ D FU{36Jj.mK_>!G2^E`eyWBWi>v2K@p;3%1UuF|/k?R -hDB47$fZoh &3!|j_R`ʝ-q _\uWwפUu.HWJ8O,M M}c˴/l^ڿ|_5i"K]_-J gIW+-/;+ؗ:\Fq[( krot016-ai`wׂTx EDP2#ڗ)'0%l(޹qN s(qs&/C#DI R|",.fW”-#BFAeW#\" H>jf}QjF8k 7lj߫PJH#1㼂 ؝c_~kԐ2*> >2ٱ#GcWj2xe J*zׇ,N-T{ׂdgC00-|hR]Jla v|_fR._ς9)x_JCz}:I=ĜWdFT% - cL_3$eI4>lW3L-FH86GQJz >4$W1Eʧa?#121W%Z~k L='kKbm 7L4[l枟lb'W!ь]qKvB^Ѳ}/(/?.!Ŝ|K /!ymK%%1Ր~_udvN㋗QlĂWdDtN6 VT["IqFk%_6 )jg?RCf'\ߛ_QvT_J"WBmωRt 4Q"E_WֿL"D-lF8\>Q3O۰|3Kƶkj|#"k_||=$ %.9{_;w$GupTEvN⫛ulW0x ud/^_2{Bͳe a|eC|WڋC$lIR/þvwFPK',{ t兵#%bhdf=KkXIޟYNJt/e|B|BM̱s C|1qڹVa~(EFffk5d"Y~>9_D_EVqDi5Ws2|܎B?ۅaQU+Zy9 _ ޒJp-7G–#9_}ĝanЧE|QKjpԠx,x}oίCi\Y|a%ac" UW~KꏫUSG/v.eُ"P_'}H,AgvK$"__P$9s_vBFm$ HoI|zdnzOI.dƦd|Q8zW a8mo$6}FrF_,#gdo/.O2M994%guk__y/m®A{/"6O/+b/kn|ɴ>t_[#+k,UJ=E/A8!^_DD u|_Ư {H?@*ė47#R2~|5W&e,+~'·cK,Otv-HY4ܿwQ̧q jP3,^; և5ypjn7 o|݂V_Gʶ}V1|m7YF}I1dB|lu^Q)}&LiY|ȯٹh!5_q~R+.'Fc}HZ|CvvJp>+Y|5Q& 8ۊn 5M^-/bbW_'T\_f H&E?@!6͸csäl:c*4q_{CgD7b+č=;QZ"ޔB|kz_ udE^c]/b)1eɒ0DJ_ASOiyBaRȯ_+wo_7}]3怪|=M34M. @Non {tZZz|V/1*JaWc{5vz}/ 67>[!^Wfp_]8=+Eڹ2,~ˠ6D/._6#A_T_ a<;_^ /QćMC||og%uWJTWZZR__bì~;W( =˲"%@oQ_êvϋ PP;_>' Q+Be"k&H 4 s>?Tá[| mJj񵾟O\ލJ^_^/n/C̳ q*~RYKX u?5ԜB|YZlR De'/ P6TqG>ve=/*"J>ۨb|W*?㗔s-mgbƗClML Zfk@/$jJ$6jg)\~j)0`*[8;GE _bX!WZˇ,$6e|Ǘh9B2Ǘ0HQX/љo_d{mRa:`F򿘧1Źh)a~(|=΅ͼ, /0ABYŗ<:T^d{z/K,h|񄖸H%l:';ɤ0ܨ,rϊfs\|+/޸w*+p/bY޿\YKJz\Š.nIؼpbWb^%\(:V|jW8)BtFn_N4(uNhGa~&JpXQ@7T(5R@$L:ɜFsp&Q =W '*bDyţ ='jf1Se?<H})M Wu۪ӎ,@P(0޵PUy ~th;3Y(Sq_1@jqei.ew;~ | pF+$Oe!̄WSURz{L:?lt%}(TR/KZcJh$CQ/fgֳ2gҴF%~e, Aʮz{{ kunz`{IFg$ӽ=Qxޘ׆-:kK:K#(. 'ۦ[ PuV)Ӿ*p:~? qgu(\D ~.QWiw;k%"6Nua&$9y}vJ fxӻQ~ʉaT0ŒlF. Oo:O<\ ) r7B+U$ Bc}lP[x>+o6T?^yC?rfe2bJN^*ğ;_h:RU۶{*TxxOܲl4HTI,z.pV}nT~8l: %_s\.ReYhW؟;9~sE-I\. !7>?49Zl͇GH_FaX IU$`+5}-_tkDFWh0H,ϻ$%+J_<Z煘Pߛ2Z{v4?%^MRI +U/B?k|U,=ԧM㫣bLO ~# /mY 7%c7frm/F_&R3FI1(ːN7c}2 vl a OzQj U1Vޯszzy+ WpP"I_E\|k~厽Q-+ UyZd/P?:KCėR>Ff| B']'5:?o}ihz|__ܥI&R-lB6oؒ1oAjd/ҭb]P_|q"қC>QvB۬"xR{&+eWτ [>+:_gޱMV&o +()i7?RR?R|ni}> 1IH Ol2^ t)QiQu;7 9N5TM?Z^g^v<4d''FZW.I&_v4.>/O [|]՛%0J"k._Q, YyeUyQ{|4ɢ]Q!p%t6)M͎I wΗ?P$L⯜fg-Y^h MB3Qil/$^5L*IQ]y/JL§(fҀMbϙ ޚM(5\(f Fys ;%IWQ83vϼl}b3ee2 5k)(I k|y!_ =lUv`z?KLٍo# "o~^ŝj5 k0@P2 !A i2&KЀ,Ad3fbVG~%yїA[!c [YW$G*`MC\;[|xuyXGBlPz_bipŒ/T)p5?RE}lNks/^#*^<$=QYZ9Q'g-͗eugV{N kjs_= o|+/T>W ?1%9ʐ h3I|3& i1I{;%U$Oh]l_N^ܭЫh8#R/3Lي0p@;_!M/Jl_u4@]H)TcURHء;HƯ}q]&! rAqJ 3W"\1%Uߛwlگ#%Y\ʒ6el|%a?%Wv%LQ*vsٻ7 վ74Ϧ;'"jjp[oӻen+ kdWLJ le+~t{u%WgbV_Հb6Z7$%Yyf/W_-]Î~Z$/9l?L^h> QPJm}Uj51~.T?{Sʯ7+,4`'(W(] Eie+9^ Z񝣴ӮnUO)Jw2 xsҥ_ٳA>~>?&23,%`$/X>TZb?%>cOJgx3a/I1A>5JVSK͆'R3п|sTqUL/jJQZY3Ff+uyBJ`"s F%CrWbT_O:_B]<'p%|Kp 6LE^1.Q?Rj,!~wBdF|J+JmY~'y<~|K|֭`pVO궭%}VK* jifJ#Y#mdljyZJtt^/HIX| J+ėL%n]>ёb@R{8neT8VK0SCBiHV޲Qp)TҹeafrFT>hYJi3!; 9Ab@B5'H_pGaLt|N&e%;딑XCHBtc+Eitp 0/]*gƒ-UY/BP_{eu#tWqDBq/ᵼhqi1/_]T9?D2E-os/k>j_hs*k"\_g#S*AE̻9 d|G?[t-Jcڋ'J|XR3Wߣ&-W=R +1vbut|1[Ei H=hJ5\!}`d)Uw׵{?J{k?6 RU/2_s5!\29|9 NɔZ|t0ƗH+m0s[ԠkqHeȳsń$ U8ÚHͧs_BKpH$|"($nɴO ըMH`|ΠE%^w/^)-xH+_5>0e`|QBF*#~fL~J52xC>R^ N|M}C*+j| eY/46$fKWR \Z!|~ v%=YX|H&W*!b@QB|IY~H:r5,w3%=8qٮQ@ak"L-܍/1r.6F gq̑9?\@M9L';/k =4('P m^^W"?bzJt/ޤEQڄ˘h#Ք@#-sjGj؇ݲ7?6:hg 2/,#I}Y5TS ί k1_'6?\i]!&gE{K6kKmgH rY!7*y>^A\1τO2DLL&k:6%m$R ~/:yI-}$2z1°0迁g{y6QQwM Nk2(sWbV*_y@Gec~81y|s4;+g R=I-8V.iy_rfYA}Ou洠K_= 㗟MHkOղl /c(zHq /&LXɑƗ58a:/~3he<[5eS갣y^lbl+M6Wû7H_akߣj?_ et #R?ҙ~c~H#u$%ȓKJ門j/=ac4)w8y>|37C|~(/~$]YZW$&r](tl, mg 87[/צT=a*]XvNRbD-%\eGe|NɦX? _kAQդgN "bFkt;Ϳe UA5 @|H ?l /Dţ&w$2 %乹j=4? ?5be,6v#%W*zќ'!hEas%;xld˚0m 2M(X:|ꤳ5_?<›-3~jnQ_5$jv.lo~jfaBU |X-J %h0_GXfn| Yz_="uD?GM2+Y|lZ|$T " ܢ$:VT6;*KҼfԉ_RԇXoڋ Q "f}z,_{ҥy,d)P2Ta@>~ l!ZU񕳹&ҨD +n }6PK.zʦK_RB eGe,]IU JߋWp(mWΰrI_RTxe`fƟW$/G9WV}$^,R0widfe7gC_2^_v7 aKߣkpЧ?Q!R; 3UOPX+F 94E2ᨄE!2e'DP8ź.㩞QEGLgr ,I/mxTAË ɅD|!_8*?[ Ҁv?;?IjIo4BQyHeda'P$ld*6i& HpiQg', O Xu0uF1?Րįח_kpD EΖ\I6Mtv~%0u 7JJ#zmj &KGnSIu+Uy[4Ьp7ʙM+8Z/eyiQXA˼n2$u$sK ėCWI׷ʩy%$$y^(a.j|DW))J&xJ*Yۀi%_̇RMyR'U7\%_8JJ; TBy&}$lAVDKC+&>*KCK+"+ nE2 rv<(/iNP݋V*;~aIe[H;I߇jQQ3lp$Zo 5N{_օ"cK\j i!WY*¡Q}Љ/*_ C؇OX9ߓ# _kF ;c9 Хu(i+G*ko?妨i24 Y[^!YyAiJި^QhTNk@"RsH&װ?5eeEED߀OH\Q6Hr(φP&\k_FmjRG z%T_n_^辗K,Ҥa)QZJpqk]џP6J^ *)߆Ԑ{Pl N㫢1@ , fsᕀ.ߝQDN+: ؏%s}U&9́OfNnkdrR:^hBł_GbI|wu֭UJ V-={72$d5נQxKhb%%t+T(O0j`.lJ Riȯ::\zy!`V5#F`8jcZŏB>섭+!e#M~ _ifEJP(ZLWʌ/ij~_[<_+}-q\ ZeyGv/)&<%d`^+ ^"!JW_ "u@ 4U;1m2 D70<)yD_v%p+wZ|Dۮ)랔0wD=RbaOYmWl=A+ b6H믒W E WF~Okp)ć5&/^/ʎyuft R~/2i~,iRVݟGf;YCJ+y> Y:$;w_RLoe-X5{7s ,H$MRQ#R(PFWmQ:|!_x-/G "0Bz}b|_)(p+51EB_t[nдAy?R#a!Jֿ̒GlYeU+Il4' ;jkFV)q:~Hjf_xL4tNOtBrĪ`'rc_#zo9r-5_ButNhY8H;A4)4je1ŜCaHϪ4c.="{m\3}5 WnW\ ̺_N׉A݉YB*8H v/~p'B??vYs AQ'~7Ka'꼫μ&?ԗU_-HCۙg:ߜӺM _#Fl|47ze|qtWTt*%yC  _k*YE>H6NZO(DQ R AF5V*QWKO`2*%{zOjخDZhיaa~ذH@+?_iZ@b|^ݰH@Ƽ_ޭ|ZWӛJ|/QK_#uќo~xm?+WVo|3o)ײַ6ǯO_Y]Ǯ8u*8otHKq s+w~(hEVݑ_Y!lC-xi&HKL,H|+ӹ6'8SWTS:H_3dHcCl$Db,m|=L{^i6ob!=k%Eâ啰-?'ߛD],S`o0qJ> &uj1\amWfl!Ҧ?@j\wGiH➎*dl J'*kF]%+N*S#-/ŗy'_WmYƗx0_"%'/!u&_ȏ B_s_ :H$эҰy5UC'8Wb(ǯa7`3?@+p۝7)omTcZ߀1H`8qZGv뤯ҩ:Jq3H%-RJ W+94`,/jPOo) eC^5e꼧=8 ueƗ@ ~HhM(%nWyK UT 24ėYr)D񋸮B$?J#glMU(qӹ_]$ќ]UBdDzXtצ':\BeW P@ZoH:WH, "NlTVϣP*R H|"ҚD='[j_ydG!677t~eԬ~]2OTWjrzU`I1$_% '.H)yU/+/_O`#;_3$/G񄃓31l$hৰu"d@ar 7i(?R/GGB\9?0iGZÉӡm5Ka~pESf{WR  o4pT4Y}/:gl&%Gf7RzK_5{?4orHt],6SX Rl}_}"/|qǗHs_5Jjy|nzU5m:7-f I$,%nX WƉWg\,/Ek~H^;Uz=B\:~O |pjc H{KC w/Q_ϒ*c6,^Pze:~ۏCy'י4 HX3T _B%XXAC_UFZ5_n|35gב|g/ >э/fb )ڞsJC@_Q+3?s:QYtH6D.^a12h./83O2v n҅7+|xK2 b=>KsH(A_eRonI]c^!61ˈϦUgX 'Y{r>l!luţhRB|M i?QٍP&S!f۷;ljj,:vƗẋ_$ 7 fI/k.}_Ho/E[_ٖE+/6Ϛ([|-:aC@ JZ!!bCN&nEsH8kdC1Gp\Fj#E>Q`ȶ_{~.[z_٤BRCX7%WG|5c<7uYW|"r_r_KXޟ2!%f{_z‘DJ"C\>62|#@/٘jOt$gŗl5S/kv|KA 3E\h0-||=E$%x\0&%,1ٝ;*XW)_OԕХ.{&=~m#b/1?VM/(S{6,_{CZfl|%y v)?z/)kU_bVKcφײ_"}_uXU>~ k_u؆u+lu{y0&_6~_tzmm^#H`_-_K|IEt~8%46%Dz>;DŽ0׹m2 _9E@sTߛ'Lɡ{>nT,u2{R9*nx~C_zCV5uߜ`pbi1ٳ㗤Pq&gZY,g(`=靭>?e$Z|=I z{j8 _בlggs/k1~n| ZBuj65,A2(Rƶ/9W=FX\8 F"=/X r>3vB=WJ;Ikm/'DK.˓[ IW  ܼG| V!DEZKګJB|I"7ΐ}-)יYi_)]졛2tצȯ^!Z!"C>qX*_{6نu^/Y_|/ "VUy| ,_KJ!,0u|_$)&^!s/p#FZ!֛4D"q]bƎjj$$f`x–,Gl9 S耪Hk8J uVSخ '5ėzlufQ)W_V9R!S!!wX_ݶ՗ W@o⫯qKr/PY!26")b(Ɨ$DbƗ8ogz/o܍/,F/|yigI)js*_;}B)f=!g_3懻9^_^Vo?)){:{i!dagǗ j/G^2Hb|[35y~cQHc|=eEr 񵶭nOtHb"8?&#q-!._tM|_.|l5q%X+ p5>Qqh8/&f/[ݴ/[&WrDdE%,DH)L*ï7ϣ&%_}2 sg= )5W2 |k*ӟ&+Hy|olJTGx|-!ǗFcgǗl"\Zw' b9ė@,Z |XN~_VKX)JdS96[yT1RjRlF%j<}Q/WHȗOl~vfsT!1_IK߫zy:B6 Kk`P0/^ʐACOK&%,pl&ٹ|N̟Xf5o/8~w#5"J._OZfA/'_b\Pt:En| œotJx193_h%U-euV,$>F|svj.?0 }L.?91JjꆃƟK_wNo0xle`j%mzͤ~/C#K_C^Xѡ{)F ~gΑߍJZm'`'Tף^n(W["_M_U >'K&_5]Ɠld(>!zv Piə稄ݥ~&P!y..΄&l i+/4gAˑ *evBKzF$t]x5tR5IUҪrS9J _% o.+ף^) A>Ch7Phw(Ix ^*|ec)o ū5091qIWSm36vT:(,ϻR˯q!u`%*$D @0ۘi<4^~)6qB#̖2$lI%m#ֳJLLT?}&s]SoeӖ(qQS%k.YGe֤AK _َ{P64nM6ZKJBAPh|2h-TG1 *iPeW-J`gY,G'; dCjY3s . {EQFtgቒٻ%&+ިV,=(;N>?v"#+Ձ_eu~%$;\$I,_2c-~pzpsOd9_5 ZDVK Y䀯bPB {Ōuo0a߆x;g*{z7 .]RqYUNn(IL8 ȯW\Dժ_<VyRP}%(E5RvZB)5`-u-s7JGX%Q>*] 臚HoSA~eo|FGF rwCr_x7m6`+g~Fι:'ן Q  RR`  TFI% ?NxA۝ÍuJ|?Ӓ^;~ 30ڐ+3 lf|e6dCpf%aٹeh_ (U66q1K|f=32: w"EȂH >t-y=)Y]^:(hWs B+$>l#؍y~$6)K2 f$@R_ )fG" A.Yz2ПBWWB&}.LrP9!Zeeע4KFrJNO(6x4 :˓n/?ɵ=)YսXAD^+9S2$Kv7xbҭKWm6Hy|U~VL6LؐEa<A$SRpMlkTw@`Àh/ 3˓*tKWP$#?-rƆ#q>?d::/JH(x[_Ɋ g?G_Ia,E~% #p焃3ŻJR2<6gع5AP)-l3 ,%֊jRmҲ;HJG9]K$X#gM)sŠqQRj:J I#ƗV kR4x9olH־P'||Xqx/wH(}/pڳ1 Eg,_WۆYg/\pM_JN!U.MB6Yz~H %ԋ[/BF:ח_C`Z-Pjp~%&I #Ā+) ͯTЄ6vHԾW6bW#sUvRK 焓8׳_aW {{y=vc/JjSQoöPj+|k@B_d8/W S[CPr򿶙T sX%>4e/Xmx7$A7>m$Bd9= -gCg#!4HWoGB~8~{v+J}%;H\Fåz/Y4MjJ@gJ.7j6GO ײ,>e+D<*P3 _$Htk@*~_, P^٤}8_ҽ'kr4+CIJ % ޝOT!u2yȏIbRӻ7\#zMtN0%.=n~$O1FO)H:"Jug?'4.`~H`.qI}ڟβح*uZ{3߻ U "DguX 'ʍHo|G 扯:4ذ*D9oTJ~Y_|lz_ |5PoD/ _%ON5GbC:_)Uܝb6&nLς= 2ӟ!_ry7F_u ,sH#=jd7HVed|q (WEW+_ ƞbUS#!fz_֣@';Yvg7r uY3.sƯg%$kZ|H4ϟ\x_?e{RXx_ n/:4>Qqt`5s7*q>X!~_z7_KJ_K;~MY!f')7 f\_ݔ_3ė65E3kꈰ f(_e\/ަ%|_&5_Ie/NElM_Hs:)D_W  FV{sZeHџ %Fh5LvH,{JV'DBJ԰30V(q}v$wPiyM\mёfk1O_Dh}_i3iRw/ Qkg~z|; v WF "-gDv+EDuY~cftߧJz3}%3+q~رJPd|u {wm#Qe|9 yQ4t#!y֯T&Hۯd/ς?LGBG֎@XA;+/ILŸy;V@ˬOb"yw{F Xn| K _ ԑEo_{NBD_=l/X:l,@ /)|o"~%dPc|Ie[ %hiDcC8?DbƗDXl:_3DZgRA$WȤS^y*_o4(u 9!Mh"IpRc|呶P/[|1i3fRe p/[6 I_aSŴ4x [nY.B?1 c6ö$6LkߔƗͳ>Ɨl\X/iVU`w5neVq"tOar4W,{exK` "_ a<;_x0_S,'9;G"/&7`}Нa&+>{zVvJnI]_k+QL Rm+FYhl!FBn 72 ־_ҿ=JD7,Ԩ$S\@=׻|1fguA(!"/c^f [!j',@ /ڹ5Yl>=fb+7JN`Oq`֑袗Cb!8aM_5Y|;WQhʻ|"#yd|K%sJ = ɤwlE7~?H1Cu~o\Ok1wWPc|ae{?NKy_.UKX:ElRL!tKz9%8Ʊ/Mya%ho?B/+-4}_T<>|=3-Ɋee'\' /.6w-;wK`X/Ռ`c:_F_7 $jU76ǃXEB|%*>%5lk'ۚ+kWi1/_Gf y2DUfis_װy+$_6'aČMy/O/uU+$/*D~e^|bA#~X6[#+Tx|Tl77Co'~_&R+nz!_:7T*WgWR,& :B6T6yYС|=<'Kik{e6yIG31gǸY~_u \˶7ȜBP/qYJUd|n:O_E) $~HA\qˊ;~ma_$2;_TG460)[&L^Ƅ:=&Y0<5Rκ. Se.oZuyc#UJ3;O /|y+ֳjQmP{l. [4$l>/UU*h|Єx$dx]oF4'%_g8) VLCS:sh؜jm7j†kUry=6rHž |Hݍ|XmlId&QuVHRE m.tK{ <DLbwզ8;Tˣ_k_'<=͗=lQ?6[:MŵwF:{^1B#UYW1Ca*x3|y>|ai_MmRgWj| ]ƀRy*ݽ; fe->WA"Eh0YXjV]+8J t+w^< )>0ӛE(\^Tj|I%!T7oٟ ՒgљbwWx7:?b04T@/KmSY1tZӒD_ ȗB576Gi _Fx<5'g6 !ѯR ?HȘJR?y0IOlPΙ e2KgSet6r< Yw~JçWEm+eS7HWcB$ e?9Y {iA(d K~3#pFY=?^~%M  &%'_$%^Ȉ/+(~d Z&+TÖQ.x1Xlvtg!$`.0 jP:%3(v/.6tqa>6gOj7P'Ҳ;_wHH=G/( w"ueٹfb|yym eJsw~^[&Mip*2}?5r(Yv2 '5˧UPRヽoNH$ӔZRDDʉ9J4v%!W\I@4zΉW36 N ~y.k?k6eW F|6HH*G:?Du=hEKBmW4K(9_%WN9&F3 4Q֑`|ZI\OvW,%|kCF_WJ e.Fʢ߲WDLO@eCm"N**ؕ/e~>z;h_Ioy5uܨfTz4(mQ:?{+,åPs0 :D|ڤ 7Wɿ 1z_G!7uϪhj88hr?eRqHR(R/{RLʼBWj-J-m$ Z| dV>'lxq65 gZ>gʹIPp> dbކXe#Jv~ %کɚ+AgVb[!& r|#a8 .F}YJޢ "e(O|G1R*Lz;M-.O(5}ք'J'gW* T0ptQxMYxl*U+eaW)x%jȘh(`\Y~"H\|?N믴QQRTނ"C6Ub4ލhCF o-)?k &~+!I8s„$X4ɅWr&0ga#|~pr@jD"1}$F/4k!:ybJ'%f`ŽJ/I^- DĻLWY+Y~c uI^* !Mi,ϗ:>'}i2΢ş,z%ZWj/3P;T_^}^A꽇i2/䣤 ؼ__B~_TvHG_uHLޡoJgg-6#w3VeVS $ yZ%AWv]Ÿ9>h#eDR $0k; KzV%5u0 }Ⓟ06er6ȇE#ux꭮SJ>gQöHxzGʨRی U8H9]KL6 GaI &?%k>╖|eQ5J%\L&ײ k@ ]95!Q+@b,pu$.O$hn_HOgפĥ /sVn)^gHv[7ߑ4 RW J<+ ]Ng'phm]OȤdx{]jH= ^iXu?{./D#z0"{%P}cA| p%1zQ댧5f_@Zh,A YƗܨV'88V`U>tHtZ;e_z"eRpڐE+ӍS4X O(E:5 #bTZI Ц, m"5{(m5>\ _Xb?k"$%va&λd_J4y%4OyGJ+_ 8T(k$_ Lᄋ|=侞Ώ?2/{p!އz 9j%jVt@[!*ߚ?6F^[  >p t$o̝g[ lry\FZA7Mq;?E[?z-.0ƠEɦsX]>䍹NYOxzbHD֓HBMQC|]}!_zT^D=G%>l71T`'?=^{9NE"l}L̥k |=D2&/Lޣ` | c."%xqHxT/2-|WŠ|~8 aŪ5a~(hjQA}jC^FthoH9z7vyA_+)d^-J5Qe|Bw_e6 o~=$RB:alW @.2:XQ!:R=zo|uδ,w8 D/dT{Cs6~5;XPJ[hl,\uIHDFYL_ݩa\f΍c^1JJV~Jbɞ!A%$"YHirp¶ YZ+%ϳ##QuC^scy{uW}Flr_8NkPʗR!G>/2D|W/hTµbKkˠdG/iI2w >э/.-=;_"8yZrX) oh0y8'dYV,xle1duھk-䖄J9O^vu^ |$4{SWj|X^ s*+~$Tֺau.|=<] wj2!Y{JlIƝbIV__ A$悫!t/AM&1MH+ZX5b r9稑r|D%X'׶_WQi|5J82NVe/UҧW|@H%dS=d*X 8WAVjK& >/8^NVcTKZ#-dN|UV??WJWK"H:ܜKG.7|E+l C^+;/$ ⋐-o_vB¯*)X:C|5C iy/& 㗠X1>ar HIeNfVpKܓ*9>_"YN:B1GJ\BNfHy?6.Qݜ )OT(amA$^e 2R2ݙ\Qm-<i(!Qx d1:/#A>l^ (a~غ՞2~x !|E /}l&=ƥp1W;l/ I \ izj$ŗ7j J "/& Q KFOV:}zs(!!{x:ve?7fó /Ml}_8}"2Z-l=SglgqxB6ؚi9mBQ}H*1Kb8)wX|DU^Hzig6sѺn瑤*+KGҿb|{v…eQƯeK{7_1ÎE8Km J] {ʾI 72d]~n\>AM CADkD/A&Wycp mI 7^mb! /5'o|RxK_ós۔O/v.ؚ(&+~~8G`%D;hDREyzDP G9*Whk/ä y\W*lP(4_8kyc^a].aK:oUWQWD0?u_g^ӺhKivdԊ%h0M.T>/xiw/ 9X%C{_;#[ /z묾+7HL0;_Bu>6XidL4*4ޑH_ۋD;y>R!!??lL3m~K_iR%h0[xΥy.kP!?/RJ\m)FƗMps7$ =_$_6Vpkۦ+ė;!:}_ )tٹ5v_L/Vf0x6BޔC1W 5H9F~^Ab}o/CkE9㯴Wބ7_St54h1fҀN$2g%px7TjX:oŖ\`zo2.c.㞠-OW_9nX:1%,@bX;wK:94m좳dIC|J'z_ZDF޶>K,W{~;_v* m$DOIdc:kƗ,8k$8X|x3o()W7hO~G$F%+W&= ƿy7XX8bg/ My7daC aB+čnUq9t'c /yP!dc!$6[2'՗eխƲs5-:l“`96%#|/ nРJTNC|9:[o|-kS^) n| n|-1R v%Ā]K`=@ύRXL 6[_W$F|"5?tM^/3I\J/Gٚ(˜i|#QD3+,)H'z%^S*eQIM{TtT7@}b'eBڗ6?Dt%R)o_gLߞ',8K`p_K_YPTLGcK`4m8KƗXZV f\}~"/b(}_Rh4_Wf,'x| kjJ,_QYS/NK$s4Cb!&C5f_sHdu!_o|Qdlo-ϋ:wB v]UWo`a+$`taZ| iB]yIyNK_ %+w:Np㫓71l_>ޔw,we_G㫓s_u=K;.)ė%'e7l9`) ٹN8[f_E7rȗD_BBE-4Wjolol{Ub6$G>u&ND2$)3.L:nr(|> E~#P_^xD]R/#4)(eU{EIJy70~]iG.#Z\2)j,+~$U{We? 7Jv2]Rߨp5Q/`֐NWˎR=z8x|R-@M=*hαe˄_p^Oi"P ZOi:= v0p>8luk*=7)ɉWFCR.g\X L*ULv70ǖ4/_#x k_B?epI5\F~4"J0Ő5JX_#ZmH풌gu$ ^)Նj]%UJ$xIљ0ehË8-< <+A{8AktW qϡ=|Ի/QHvfw *u : N:kU2@3eГwHg11?u-%8 묾_}ra82Qeq)DE_Z[ܑu(^.>A{2KUףdIh,ˆ[WJIۖ&"٪[I\.'LQKt-YWD%JXDH~ʼt Q-ؚG;0eI:n20T|w PpZUeގ2 kea}tEB^]Ҥ>u_^Ưz9᠄Jh+dިJOT1qUSuiFU~pQ?/n+SnbxPrS_0K? +E/y1uv^Z0 8:3)aDyƊ^e< NڙrtB*Ҹ5ar,y ߫+{o/=F8a[_| C/E Ya:lRBD]x¶-GR{`WlR*Ai]ڒCFGa# LkN{{#COISN*LrIZ FAhƞd&lIzz6;5Ѻ_L5TmH)!N*cddx-CynCȔsGTreʞ0/ ־e4tN=ϵnQ3+~7llܲ.QǖҰ/^}C|I5d{|%V mRܾ,޹&*jcO[mO p:\ )8{ˋ-*6TƊ>_5B̙(6pj|m:JL~3JUgנF;J(_֞+0{/#-]v["WvՐ?K4W(aGͬhIMqgjPWyj1!!V_.[c20EBVDVsTHT*_\xo/Z<~J<_ Vj,3801ӊ0eIa~I;ҝ).52q:'M&̯y⑹`:X G|!le_QFFJƤS*gkRj1TUZ(x./bL8_0|s ^sUUKڛ7gٓIxlmOGBuHbk~$B./L8+Ɨ@v?lfenr q[<*qp?/UD>!g R>_َBYCX|>b:>,%NqK 4m/,vsHQS3j{aywOCHmkTzܨ3 ZNswݐtپrȊsBI)W؆+C>˂ Il35;gd*N ]HglLIziGaڳл$ŎBΞ`? _t]ԙ#SD_|4j~_`^ WBEyDuX7@g5طp"dn>P'tAi8QegG*˒q7L{_9}`{\|Eŝ|K{k+J@No-^ĝw~f`Y$ߓߨRWZ71 an>᳦m|2gt_R5QjA1CS2&jF"?$kl\_ _(b^fChuT{vcDYrphcZ W${J&T: 咼v+Ƈ#уKHQ * sN4p3a|&[Y稄LR^Þ22͕yO  iVQ]Woa2 x7V?{띵?ϣXt"W>~Usܒ\ۖpjI)1{Z| լ=$F"at<ļ? 15EMqt: OؓU7T5sԙQ>*m{U)鲫8O+2x GMYK\0_l l)hQJK_g+[{ӌPyF^޻H_qs7V$"(^!@ti١^)A(PZc()b_WʐVjj{ň9/La_Y 352}vWHt_a-6yHdvk-<&V'R:لIF= I& ?+a <خ*y-_mWM4}[<+5ԋe. bj֙z,K0?i~ Qm6_k\3Ʋ ͯl٢ y,{/+ijns72^z_:J3~9%/lί$\;xTgNo!U˙#)B .gm$|=3ߋaq3YCbսMPWF"'$Tcj~~"cJ;2tKhRX./)c7( &h/PgUg@'pd10~y%k/l?{/CN| v%N|C D x^ _.~FsѤQMl?un)P˹(Ԕ9@RR6ZҔb!} Z|JG H5=;<%[.}D>_ ѣuf۠Cjbv :R>Dəj~C`>Vy#/ FfbnMJ*|l6y5_)RPc;P,4Z_H$9>~)iQW(ނ}$ ϬQ eB땲a1? RT†Yf{{|K__{1&V_M,YeZyTf%ƙ./x3I' ieKbLFsg JN_#WR_Y WR&lCxB>l&R>тm 3mJ(_H;=ϊn#*fQ8Dr$Xh|M7vZv*r!^y:J/K(4*`ѾRٌoI8ӥ49?$ ex9sBlWm٢۠ N_ӂUkp&MŜ{ )@WZĒf_ 5 y£ZL lm]7[߆'˥?@`IqoH6{vN e-XpWI!dp@LXQ|4_44rn e9A|aK(TX!C'*m {xSm_~D# q3?v'lΉW$2Z!H3c啰a-涆Ws 3HH0c\a3/%smI Pj{B_gڒ?7 0c(2Q c4Je k8gvyp)@3Dy] rd_ɏ-uV%z`&@b\/ Yd9W p8|~xbF_^SDֿ#QhAԘ{Hɍ|l\3xeLOeWe&vl_X\Ւ:׸'&IG( 񅲍W|/PlUpN|a}B>$'P"15G`yK%3tJʽ+WO_ #?lƗ>A[=TKh-Ɨx1Iĸ,og/1v+-x$Per8_w }"ɶ?~_dvN㋟'eقHx tNB+EF"̊; "ccR$ZUi*yx?lhGc[8H~`vzinp49˰D؜q,5J1`?os.sB4Z^ 8YQ%bLWZQ=6xy߫9TP'lP $ jk?Q=P!IȚ@XKj"5( ˑw~\G5 -}RV[uVo/=MD|=y9dvN7%*eS_xuIXɠgvGB@_&fG ".^2jhXp*ʆ2lz^DƇ#P"-Jy\Hh^rWB`RUH 5|%6m)~j|"7yG,7 ?$:Nս~^]ޔg u rj?'5o(\Vq! /y8PU}Eʶ'5_\>?cO%@-E':R9/|eĂf^F\kXFײm~R-z6a_ "ESP+|DX8v_Wc8dy9Y?[F6'>e& _ Ti^J>[*GJ=R$x{| ~^_Y%4rl!dfEPk5{^N1?n| -)!$jmXy'@_G^:YpKŖ 3ympQP)$|,Ω/nZXpQM`- +@N_ڨKE ZިVP.,0Hˎb8{:lJ4GZLˊWW_ҷGa"+^F˖h&q'47J }U,{}nh0nPiз0Mad[oLaXa9`zZ!e\_uKXnQSNCk.HxDYJquÊ/_R A7AI[qB~Kb8k"9.9apa>%:A) F޳a "PQyQbGكeaf*$L̄{q]2LGB W&_)g_/Yf' E__abƯ#u[״_R5_S2Q=?M'Ur=vJ2z_״+Y}V򿘄ڹ_R6ȝ,7#ˉ+n|Qao S_UܝDDP yIvyyZbAE$mlM^dEǗSd$1)ͽ`#s&]dW6~J1o\₷#FQvb fM;`gV%>iy# ^]uɏJ4Kp?E+9_o(+3%+ y}hϟT_֟Ba߸ RSnW1<{Mc5~cC"+s~e/, >U,I:R֑q ĂBRGo|I/{Y;Hʓד~|favknUtM:1¾ S7D.s/ m Xx_.\cX~#S*ӂzR Y&Jy3[!K{Bo"z4?^#סN87Hޣ@e:Q6P{gߘ_x/Q'$FZ|!UJ_J c|a 7bZLRpµ_(qy:75S1Z!^Vڴ:=2IyV;%;ch޾/ KBEzZ"?,aOl~_LGX_K, k"D (9?R#5nL.m|=>6U:Wņu>+1oyʟ/BH&mp~eX|-b8l]ukƞlj_bF=Wߛ3=Ɍ:A8ܖeЊ+V7~C̦ 'j!:kѷЫVS_}[^>//_BV_r-_d/kZ)5m6 Db`k"W^t.xrڎ! TUc{Fu{5I^bCaF;PG$%I)/Yw\·v&`$?du!eb4,>l#_c,O6kZ3ė߀򍯝*8V\Ɨ~/T&WCD Z\#IKR_%DS]z% Vӷ/;-[d0?+2f~_Y`G~>mX/bZn|qagD7M-g Im ՕVC~? b]Y+EV4U>Kבx%1d׶Yi2/)G`J5]C%b&8g\" My/ˊO:slR{S PøT1_48ڹE&/qXłǗ3%LqJJB;𿸠cv> _j9D9Hq: #B5^~7аe|⣀*[WJ_G;PG Hz|avZ.^p/Hy+5,%mqҫk/1ϙ>B|8?l+gaڍG-R򿘫žD/qՑ ~_`msW=΅K tm_2)`/56:D/fR3K2L}$2Bqi5Qu_jH˂hLg5PK*>Iy!mcsp/rsr_linear_1D.cspUT 8Mv*NUxOeq)jt &D"",k)x6Y1?s>WOP7~W~~;/_>~}O?>_~gӟϏ?~_>??'O|ӗOӗ7w_P?<+\(!c6KZGj-%@P@>P@%BzTo;"P͈@բ\(v{"B[ۉP@7ʅ}  V\(z!5ʅjn PFP@2#BQJyP@B>T{\(!5Xf B{Dx,%@S,A=VKjDa PcFP@5\(|"B3W PgnT-' uFi P>Xԩ!b PG?vuރp_J{P@FT@vKUWDv!ઞ & (,M-Eq>u>!Ze Py#B<PrqAnT[;"P}͈@#B5O]@"BUQʤ#Ug ;.@AGvSƖ%@DjGD:}(,6: PjE( GjQ.P!o WvD(VZ.@5ʅ^\(`Y\(Vy#BK Wy.@(g P#u}Ttd!ODZ!kDё]#( 6{DΔ$"Pc>!#ʅj=\(ڧ#B巚%@Qۣ\(Z!=ʅj٢\(V{#B[ mґ]:ܶ(_;#*u&!~N(,%!9%@ & (,LeP@n PgW|K:/"BscD?%ȈP@.@rq!Ԙ+"Ps@FjW/X%@AGvtdx"B="P!:@Dv!%@;_6: PT{DB5Ejo&XÈP@f Po#J T/oDN@Y]OWy..@QTtdF'"P}@5"BuJKD֊rsG+ﶉP@Y$ (,tdڈrcDj( SM#Bz 3"\-L[NO( ވ@Y]:HDKGvj-"\  (_V3z+V߈@QVDfrZEj( GWБ]MK:<!j@="B15w[^3"\k Pi P~Y/uYT(_1.@y{l PW7NwD(|Jm Pg#B-K:3@0l PgLhK:*"P~ZW9&Bo%@WHYT{KDz]!:oNDfm!ZF+!r: P` P#BT{VDCGvL#B53"P{p՟MGvʗU,꼥D(Bs Fj9\(NW=\(Ϥ#+u&D(6JDNcGDfrZFj( +#Ubfu{;K:Z@B@ͷFj]gDZ~pJ#*uF9"PDP@="PDP@gGj=Q.P!jTy.\(_uӈ@B5֌i"BV^Q.\G\:#c PYԹպ%@A4K:E3"P~D!+u~!c ua"Pb Pg(#B[[oYlOD|#B uD(|E_k/XYX7ݬ%p孝.@yc PgZπ-j!j@BD|Դ3D%@,|P@{` P/D( >[Dƌr::"PkDP@#BU3U(_Ѵ3$B%@^#B5z l3"Pё]WC,^ґ]έ^wDF!:@Fj( NDGvYT-td|Y(DP@Gj>Q.Py"B Ԏr:bDZ~fʦ#+u&D(jDF̬.@͹"B&S#B~&(?b PuБ]έ>@>#B5{ oDvrpԩT.@%@Q."P%@z(?n P}"B凛-+?KlZ(_Ѵ(`ZT(?7f PБ]E8kb P# Ԧ#U7(,j!KKkE,"B/upK/X"Bkg5FX%"Po[W4坘%@y[b Po̬.@-ʧ25[ru*~DYTy.@a PSBdu@B5ˊ*Q.PpuF( Б]c>td|Y'"B( GDNGKDrq*1[.: P>sEj7"Ps@#BLjW˟ϳ#BW,tdsEj( 7Gj( ZD:D(KGvYґ]eK:\DFruDj( ]KDuИY],: Pn Pg(O0-\!:-j=%"BgDI0K*^wё]έ(!gWE2.@1K:> (_V3EOY(?d P~0>GC,6: Pn P=! %@+"Ph P-!-(Kʧ D(|sj#֖ʊvun@R%@gGA,+_ B%@^P;ʅt!)%@|e P>3 OK1 P^,ܺD(sl PMBK:"B5G5"P͉Wtdtd| S"B !{Fj( Ej( GĤG\,.: P~z!έ(K:lD ,+H?k Pؼ%@1K}sE]kD‸%@BGvʏ[[.@K:#RDsEY~\(⼎%@KYT_td|@%@#B;FU&(KwБ]UfKF'u@ʔ%@F+,,4D(>Τ?"P>sEFKQ|3 P^\,icg P=,j'"PY!j=($Kv y#B[wO0-\!Z+ʅj7"\TtdYԩD(YKSb PG6,%@NGv6m P Bb Po#O*XToOD|;"B壜%@DQ<J#_d Po# Yy"B[5(`ZԹ"B_k P$B@f PM Ԟ!Җ7(LS$%@f P{p7YTtdX,tdIKYi=#B壜%@Q"Bߩa Pӑ]o[ӑ],(B3D'upS8ZT(N5ǥ-jT: P` Pj?W@[T-td%@GZxJDQ.Ps@(g P{׈p1/K*3f!o[Ԝ-"P>([h(u3 Pc Pӑ]zKEp-v![ZO#>U(_@yh PqwrOP@j#c%@(V5([_Q9z*csp/rsr_linear_3D.cspUT 8Mv*NUxQ$a]7=)liąI"qe盻Q;^:]u?__ͧO~/?o?|w?~O?/JϿ????ˏW>տ?Oo7B?}_/~O/O9#q_Ə/mˏ6f_[}>;ٿq 7yW |&f|&m;ٷ63l6hm _lv fOf_k}k'l6hmv e G'fOf_k}k'l6hmv eg' ' G}mm>L8>{}y—o([|#r }~i2G}mmn>;37-xw>p6f 8>{>|Cن|[}+|mm>l->{}[)[ pfOf_k}k'l6hmv e^}&|K}p6fτ>;''|u' n;6f8>{>|CقGW'6}6f_[>g}G}ogo(۰O>y+om;'|G}oO>y+e /yy~z| :{w6f_[>g}G}ogSy{~ }~i'hm;pG}6 e03̓O¯> ٯ> G}mm~I8>{* ʎ~O/O@ϯs㘸f?l ?.pY,W3KНτ o%h>6 ?73}~.>?ӧf?' gm3}π73}/O@)npY >geL3ML V6 ?3l>Ox?3} m3}Of?' g x?^3} [m3}Of?' g x?/3!'|[I8,'|&dτͲgBOgeL3M㷥τ o%h>6 ?73}O@)m3}Of?' g x?Q' g\8,gdLͲO@g;o?᳝Ͳg;o[@Ol- '|@3} GeLpY >y~| >e6>?'l3}韧'!VGe<}> ge<}>og>~6uy}.>&6aUpJ8۬mVsA|&TOؿPS>gf?3|>Ϟ) 8ڬ'|'l ?Tp VGUO@OmV>?3|0W ?pJf?3|&mVS> ?s? 2GUO@OmV>?3'|?.>O@OmV>?pYOTπ['ܷ[@Ol~y )Tvޞ/>O@OmV>?pYOTπyL3|&mVS>gf?3|>u' ͪ''|6 >_/>O@OmV>?pYOTπ['ܷ[@Ol~y )Tvޞ@]|n 8ڬ'|'l ?pTOf?P>gUO@O >c'_}Of?'g$mV3|O@O>~qy}'[pY ۬8۬mVsAmg' ?3hPS>6) ?'~P>GUO@OmV>?3'|S ͪ''|6 S>/pgBOL8ڬ|&TτͪgBO<'|/OP>GUO@OmV>?3'|g' ͪ''|'l ?峝O>y+o[ķPS>y )=1\|n_ڬ'|''|6 S>wcW |&f?3|&TτͪgBO<'|O@O\6 8۬'|g@O<TOuͪ''|6 S>y )mVS>y+vg;o?峝)mV>?pYOTπy~t 2GUO@OmV>?3g̏|OÏ[!mV3|Of?'gt ^r >׭6>?'l3}s+O@)npY >geL3M3!'|L ?3l>Ox?D^|OuͲO@ 8,gdLog?ӧf?' gm3}π7>τ o%h>6 ?73}?a.>?ӧ f?' gm3}π7>W ?pJf?3!'|&m> og Sp=8,gdLͲO@' g\8,gdLͲO@g;o?᳝Ͳg;o[@Ol- '|3} GeLpY >y~&q >e6>?'l3}韧'!VGe<}> ge<}>og>~~J/O@?7\ߚͪnf?7\/$f?7l ~@ϭl%O>'ྕͪgBOL8۬|&T''| [mV>?pYOTπy&O@O\8ڬ'|'l ?s}L)V6) ?3lPS>O O@O<.''|'l t\sT 8ڬ'|'l ?峝[f?峝o-|PS>y{H).pYOTOf?P>q_}&TO}+ GUτpYOL)'t''| GUO@OmV>?3'|o.>?Sp]h ͪ''|tvg;oGUv '[@Ol ''| GUO@OmV>?3'|^|§ f?P>gUO@O >c'VGU pYI>?g~Rty}.mVs6z!6aU\Pne.yPS>$mVS>gf?3|>c/>?Sp h ͪ''|t#O@O\8ڬ'|'l ?s}L)V6) ?3lPS>O O@O\8ڬ'|'l ?lO@O<Ƨ`UOf?P>g;o?峝;YOl-l[@Ol| 2G}m)xf?P>q:\}&TO}+ G}m ͪgBO<'|?'.>?Sp=8kUO6 >).p6 mV>?3|PS>y 8kUv6)Tvޞo/>?Sp=8kUO6 >y.>?Sp]hmV>8۬'|g@𙿦>$T B8kU O.>?ӧf_,g\O?g gBOܷp6 O8,'|&dHdL2G}mSp=ͲO@\' gV|mg=)x|r3}π7>τ xgf?3!'|/>?ӧ f_keLͲO@t>$m;YOL8,'|&d>?ӧzpY >geL3ML珂O@).pY >geL3Mvg;oGev '[@Ol3} GeLpY >yGdL2GeLpY >gZ䓐iq+Ͳ> ?OͲ> ?O73_O? [pY ۬8۬mVsAmgBOܷpYOL) gUτyBOϏ.>?Sp h ͪ''|t3|[I8ڬ|&TτͪgBO<'|'>?Sp]h ͪ''|tϳ]\|§f?ͪ''|g@Ol-|pYOlٝv YOl答o|§q7>?|'l ?W ?pJf?3[UτPS>O ''| GUO6 ?<:.>?Sp]h f?P>?3|PS>y 8ڬ|Vp?Tvg;o)mV>ڬ'|''|t=''| mV>ڬ'|''|t 6'g4f?'[U P3|47O7+d\p}k6`}k_l Yϯgx?'m}&dO}+ Geτom>gBOy~s >׭6>,gdL3M>'ྕͲg·6 ?3!'|D' g\8,g|k3}π73}u_|Ou+ͲO6}6>?g dv6 O|;o?᳝۳(]|O}dLomvm3}π7>Wτ x|[L [pYOL 'O@)m3}Of?' g x?v >e6>?'l3}>$m>gf?3!'|@dL!f?' gm3}π73}?/>?ӧ f?' gm3}π7o|> ?npY'!pY'!.e_ˏmWz\^?7\ߚͪnf?7\/$f?7l ~@7PS>$mVS>gf?3|>'/>?Sp h ͪ''|t#O@O\8ڬ'|'l ?s}L)V6) ?3lPS>O O@O\8ڬ'|'l ?lP>׭6 8۬'|g@O\_@>'ྕͪgBOL8۬|&TY .>?Sp]h ͪ''|t3|[I8ڬ|&TτͪgBO<'|O@O< x>tSͪ.?𼴋O@ϭͪ''|'l ?峝[f?峝o-|PS>y{)mV>?pYOTπy).pYOTOf?P>1P3|~ hP3|6> ?'gwF'oMf?7llY??V' ?pJf?3|&mVS> ?P>׭6 8۬'|g@O<eTOu+ͪ''|6 S>τ o%hPS>6) ?HTOuͪ''|6 >.>?Sp h >ڬ'|§m[@Ol-h[ķf?峝?P>e6 8ͪ''|JنcL)V6) ?3l6) ? )mV>?pGUO@OGO@O<.''|'lS>y )mVS>y+j-ͪg;o s !f?P>g}YOTO)[|_|§ f?P>g}YOTO)y,?$T B8ڬg$T >ڬg$T Vzz$m>gfm>'-HdL2GeLpGeLSe6>?'l6h3M3!'|[I8,'|&dτ>Ͳ og Sp=8,gdLͲO@3\|O}dLpY >OċwL Ƿ՝τ>/;m>Ox?.>?ӧzpY >geL3ML' g\8,gdLͲO@>e䓐iq+Ͳ> ?OͲ> ?O73_T\Ps 8ڬmVsBmVs6t6\3|[I8ڬ|&TτͪgBO<'|o.>?Sp h ͪ''|t-''| [mV>?pYOTπ򹾀|&TO}+ GUτpYOL)'tD''| mV>?pYOTπy~ VGUO@OmV>۬'|Jن gBOܷpYOL) gUτmVS>lO@O\8ڬ'|'l f?S6\_]>'ྕͪgBOL8۬|&|o e O@O\6 8۬'|YOTp 2GUO@OmV>۬'|JنTv6)O|;o?峝P>n|''|6 C7>q 2GUO@OmV>۬'|JLO> ?çǭ6> ?'lͪO+[گ{oMf?7ll6?|KކgBOܷpYOL) gUτmVS>l''| [mV>?pYO|o)e oa.>?Sp h ͪ'{UO)p}L)V6) ?3lͪ'-HTOuͪ''|6 mV>lwO@O\8ڬ'|'l fπ[@Ol-h[ķPS>y 䳝R ''| mV>?pYO|og@O<>L)V6) ?3l><'|O@O\6 8۬'|g@Oy )mVS>y+vg;o|V<''| GUO@OmV>?3'| TO2n|''|?n| YO >_{I> ?npYI> gU _>>p}k6pg l'_x?mx>fO}+ Gi gfgyBO<ϋO)np >gI?3'}?.>ҧf'`Om6'}fπyL>$m6}&i gi  ?I?Sp h?0'}6>g@O<IVGI?p >|Cنim6}Vp?i|[)[0'} [m6'}fOf'`O ef\}&iV6>fτfτ?/PO)np >gI?37-x~y >׭6>'l?0'}| y >y 8lOl~y >y >y{~ >׭6>'l?0'}|Fs >׭6>'l?0'}|'aO$m6'|fOM} =PK*>z. csp/v100.cspUT 8Mv*NUxK0WܛoY]2"T[D!X}` ];{js'?ﻏ\__ފwTJęw""EU:WBy85 %l|ZnMIIAٵWлA5 Acsp/UT8MUxPK*>x@ ?Ȁ  7csp/gamma22.cspUT8MUxPK*>Ba(  ?csp/lin_to_rec709.cspUT8MUxPK*>Iy!m /hcsp/rsr_linear_1D.cspUT8MUxPK*>Q9z* j~csp/rsr_linear_3D.cspUT8MUxPK*>z. ,csp/v100.cspUT8MUxPKopencolorio-1.1.0~dfsg0.orig/testdata/cube.zip0000644000175000017500000011242013223553423017541 0ustar mfvmfvPK q>cube/UT  N NUxPKn= ]j cube/crosstalk.cubeUT +M% NUx]=J^ 苔xgN3pm.}UA?}9T-U?7׿?O__?v_?a}?7toޯcC~Wt|9|m9 }oXx??nC߿??| >3^o^vnc8_mco;~ncx ο9cs܏|>sC\>|._?+|<~_n繍!mF/?_8 yw+ys8 |75s\>׶\><{}| 9(.l>>P\>c_lcXư._sú<ߏ6u#51Nr 58 qy{Euyk熸<W@rn9rw1!.߿+sqȞsqv.۹|]~6u9m 28n}Dqr̊'.?g} .wC\~_y (vsx͹O1;s(.ǫs/vD!gnr6u9.ί.n>5 FIP\>0^>75Zfo;_q>78͹OP]>9|=omrL>1=1o6u9^sú<]6e̹o}㿛'*3>1Tscl!.Ǒ~rmSsC\:>Au9Dsq~>8߶qư.?kú|6u9e7|69{.c} .?4w9mx^7K9 8j6cvܷrL-m|nmcI6\t!|.;~;džrs6{E\s8 ׸A\~F xǜ@q}ۍcv.kú/ư._gú| 'gk\ 1699|a|.c?ns|ۆ<9<籢Ƕuysú|6u9osݥ x.;dϘl.ss?㽢<>7{>r\CιOP])œ@\~{=>Aumr}ݦ!}|lc<\wi0>q .@qy1OTP\s .k>qn{\!((. NJ{y.|rm y<11ymcXwl;__-s=>mx8,-:ht٫ECǙ JZ4]KgWբ'\jѯͥ qEC\jAuEC\jZtP]jZ4ĥTZ4ĥ qEե qEC\jAuEOԢsZ4ĥ qEե qEC\jAuEC\jZtP]jP\ECqe[4mP\Eq=RMK-R-:˶h(.ۢl-˶h(.ۢlԢ!.蠺Ԣ!.hK-:.VmZmP\EC\jAuEC\jZtP]jZ4ĥTZ4ĥ qEե qEC\jAuEOԢZ qEC\jAuEC\jZtP]jZ4ĥTZ4ĥ qEե e[4mA\EOԢvRԢ!.蠺Ԣ!.h(.ۢl-˶ .ۢl-:˶hK-RK-ze[V{e[4mP\Eq e[4ĥTZ4ĥ qEե qEC\jAuEC\jZtP]jm.1՝=Ԣ!.hK-:.hK-RK-RԢRԢ!.蠺Ԣ!.hK-:˶6Z~RԢ!.蠺Ԣ!.hK-:.h(.ۢl-˶h(.ۢl-˶蠺Ԣ'Z]E} e[4mA\ECq e[tmZ4ĥTZ4ĥ qEե qEC\jAuEOԢm qEC\jAuEC\jZtP]jZ4ĥTZ4ĥ qEե qEC\jAuEOԢ?kZ4ĥ qEե qEC\jAuEC\jZtP]jP\ECqe[4mP\Eq=Rj.h(.ۢl-˶h(.ۢl-˶ .ۢ!.hK-:.hK-RK-ze[fvߧ-RԢRԢ!.蠺Ԣ!.hK-:.hK-RK-RԢRhsEciԢ!.蠺Ԣ!.hK-:.hK-RK-RԢl-˶ .ۢ'\jiԢ!.蠺Ԣl-:˶h(.ۢl-˶h(.ۢRԢ!.蠺Ԣ'Oj1ٟSW;v}1W9Acu}x*-:hyh  lEn]ӢNբiA-,N^:J>yEE5WMe }~s(-:EOԢ\jZ4ĥTZ4ĥ qEե qEC\jAuEC\jZtP]jZ4ĥTZDK-sV{pEC\jZtP]jkIԢRԢ!.蠺Ԣl-:˶h(.ۢl-zͥy]=Ԣ!.h(.ۢl-˶ .ۢl-:˶hK-RK-RԢRhu==-˶hK-:.hK-RK-RԢRԢ!.蠺Ԣ!.hK-:.6ZsZ4ĥ qEե qEC\jAuEC\jZtP]jZ4ĥTZ4mP\Eq=Rg۹ڃK-RԢRԢl-˶h(.ۢl-˶ .ۢ!.hK-:.Vm#.ۢl-:˶h(.ۢ!.蠺Ԣ!.hK-:.hK-RK-RԢRhs}=\Eq]eZ4TiE\Eq eZtiE\ECu]eZtiP]Eq]eZ4ĥ}eZ}\%\Eq]eZ4TiE\Eq eZtQ\jEqEC\jEqEť qEť]Z4TiZ]jc{K-(.袸Ԣ!.袸ԢRԢL.2-˴".ӢL2-˴".ӢL2-sѢL.2-˴".ӢL2-˴".ӢL.2-˴h.ӢL.2-˴ m.ӢZeZtiE\ECu]eZtiP]Eq]eZ4TiEqEť qEť]Z4ĥ}eZV{p]ZtQ\jZtQ\jEqEC\jEqEť qEq]eZ4TiE\Eq eZVZ_=R.2-˴h.ӢL.2-˴".ӢL2-˴".ӢL.2-˴h.Ӣ/L?oj.ӢL.2-˴".ӢL2-˴".ӢL.2-˴hK-(.袸Ԣ!. m.Ӣc6vn}".ӢL2-(.袸Ԣ!.袸ԢRԢR.K-˴".ӢL2-B?c}/E,\ɫEC_KjEc\ZtiY]4F_hw1jkސJ.|\x\AcWZ4GW]4fg]~ׇf~Xps=&Eql.ӢL.2-˴".ӢL2-˴".ӢL.2-˴h.ӢL.2-˴ m.Ӣ|ZeZtiE\ECu]eZtiP]Eq]eZ4TiEqEť qEť]Z4ĥ}eZ/\Eq]Z4ĥ]ZtQ\jZtQ\jEqEC\jE\Eq eZtiE\ECu}ե=^#.袸ԢL2-˴".ӢL.2-˴h.ӢL.2-˴".ӢL2-B˴ZeZtiE\ECu]eZtiP]Eq]eZ4TiE\Eq eZtQ\jEqEC\j\E=L.2-˴h.ӢL.K-R.K-(.hK-(.袸Ԣ!.".ӢL2-BK-[]]jEqEť qEť]eZ4TiE\Eq eZtiE\ECu]eZtiP]E_hsE\ qEC\jAuEC\jZtP]jZ4ĥTZ4ĥ qEե qEC\jA\EOԢ_kZ4ĥ qEե qEC\jAuECq e[tmP\ECqe[4mP\Eե=-ws e[4mA\ECq e[tmZ4ĥTZ4ĥ qEե qEC\jAuEOԢڃK-RԢRԢ!.蠺Ԣ!.hK-:.hK-RK-RԢRhsEs qEC\jAuEC\jZtP]jZ4ĥTZ4mP\Eq e[4mA\EOԢڃK-˶h(.ۢl-˶ .ۢl-:˶hK-RK-RԢRhu=NO[4ĥ qEե qEC\jAuEC\jZtP]jZ4ĥTZ4ĥ qEե=R>j.hK-RK-RԢRԢ!.蠺Ԣ!.hK-:˶h(.ۢl-zͥ]=Ԣ!.hK-:.h(.ۢl-˶h(.ۢl-˶蠺Ԣ!.hK-:.~.I"-w>+FOW;<>69A3K@sgqNqx]KGP%FCqt+F=7_|hY뛃y}gb446x=#1XcF=އsFOT!2hL5:2hL5"SL5"ST*ST!2T!2hL5TGV)GOʔ!2hL9:2hL9"SL9"SȔl"9 2l"9ȔZv@=*S"= 2ۣl"=:h(2ۣlL="Sԣ*Sԣ!2 [ll )HCd A)HCd tPe 4D T4D )HU )HCd F }LEzU" HCd*AHCd*tPe*4D"T4D" H" Ef4-F"}~<$2%V4D$ )IU$ Ef4MAd6IC$ EftMPd6IC$T4D$ )IWXd6Iarll& Ef4mAdICdjtPej4D&T4D& IU& ICdjF&=3L"Sl)JCdtPe4D(T4D( )JU( )JCdA)JCdPd6JW!&JOT!2UiLU:2UiLU"S"UVi(2[l"UV 2[lT+,2[ll, Ef4Ad6KC, EftPe4D,T4D, )KU, )KCdF,y{Idғ2uiL]"SL]"Sԥ*Sԥ!2uԥ!2uiL]:2uiL]"S02u&<;@ ӓ2iLa"SLa"S*S!2 2l"a:̆i(2l02A&LOl"e̖ 2[l"e:̖i(2[lLe"ST*ST!2 ̖1}w'[eJ4D4T4D4 )MU4 )MCdJA)MCdJtPeJ4D4]ad&MKs2̴鋭2ӦL."3m̴"2ӦL*3m̴"2ӦL."3m(2iLm(2ԦadM٤gDfVEd&N8 )NE8]4D8]tQdtQdEd&NC8]DftӋq_)N>-~} ~o'9cVw~8 }>׃19wˉLq Yd_(NCc׳Etxy'ɹ%NC09APzYihl괉|±8]adc2V4D8 )NU8 )NCdA)NCdtPe4D8T4D8 )NWUdӓ2iLq"SLq"S*S!2 2l"q:i(2l02#'[ePd6NC8Df4Pd6N8 Ef4A)NCdtPe4D8]a8=d6NOl!2!2iLq:2iLq"SLq"S*S!2 #3qqo.3qb"2L*3q"2L."3qi2L."3q"S.Lq(2Eӏ".3qb"2L*3q(2!2"S"S.Lq"2L^E8=c)N_l)NE8]4D8]DftPe&N8]Df4TEd&N8 UftEd&N/L~j[e&N8]Df4TEd&N8 UftEd&NC8]DftPe&N8]"1j[e&N8]Df4TEd&N8 )NE8]4D8]tQdtQdEd&N/"Sǚ\2-2"S"S.Lq"2L*3q"2L."3qEӏsM"3qb"2L*3q"2L."3qi2L."3q"2L^8~;O*3q"2L."3qi2L."3q"S.Lq(2iLq(2ad&N?wO6-2"S"S.Lq"S.Lq(2i2L."3q"2L^E8oc'N_l8]DftPe&N8]Df4TEd&N8 UftEd&NC8]DftӋ02׳M"Sl)NCdtPe4D8T4D8 )NU8 )NC8Df4Pd6NW V4D8 )N8 Ef4Ad6NC8 EftPd6NCdA)NCdtcW['o_JNNχ%N|d4teΕ8]468H8]468q8 K|]t8G&&N~V44~ Wh8]46N;4358] @_q=&7/9qzFfwGL*3q"2L."3qi2L."3q"2L*3q"2ad&N_V!8}UftEd&NC8]DftPe&N8]Df4D8]W.Lq"S.Lq(2Eӏ'L*3q(2!2"S"S.Lq"2L*3q"2a)N?BLqbLq"2L."3qi2L."3q"2L*3q"2adDwB Sl)NCdtPe4D8T4D8 )NU8 )NCdAd6NC8 Eft)NnY@8=*S!2l"q:i(2l"qi(2*S!2 鱥kBd6NOl"q 2!2iLq:2iLq"SLq"S*S!2 #SUdӓ2iLq"SLq"S*S!2!2iLq:2iLq #SkdLq"S*S!2 2l"q:i(2l"qiLq"qz\?;@ӓ-2l"q:i(2lLq"S*S!2!2iLq;jl)NCdtPe4D8T4D8 )NU8 )NCdA)NCdt)N~qzU8 )NCdA)NCdtPe4D8Df4Pd6N8 Ef4F8}=$2Pd6NC8Df4Pd6N8 Ef4A)NCdtPe4D8]a8=θv^dLq"S*S!2!2iLq:2iLq"SLq"S+LqzL]v^dLq"S*S!2!2iLq:2iLq 2l"qǛo5NO!2iLq:i(2l"qi(2l"q"SLq"S+79qؑ,%NO7߿Se44(44.H%NC:qzs_+\q;6N=N8 g~w4[Ac"8 g |8]ad8?vdLq"S*S!2!2iLq:2iLq"SLq"S+Lqz\SfHdӓ2iLq"SLq"S*S!2 2l"q:i(2l02 '[ePd6NC8Df4Pd6N8 Ef4A)NCdtPe4D8]a8}~-d6NOl!2!2iLq:2iLq"SLq"S*S!2 #Sβ'[e4D8T4D8 )NU8 )NCdA)NCdtPd6NC8]adӲ'[e4D8T4Pd6N8 Ef4Ad6NC8 EftPe4D8]a8=NtY6rll8 Ef4Ad6NCdtPe4D8T4D8 )NU8 )NCdF8yY6dLq"S*S!2!2iLq:2iLq"SLq"S"q?F"Sl)NCdtPe4D8Df4Pd6N8 Ef4Ad6NC8 )NWXd6NSk8="qi(2l"q!2iLq:2iLq"SLq"S+Lqzyw'[e4D8T4D8 )NU8 )NCdA)NCdtPe4D8]ad&N?o7F"3qb"2L*3q"2L."3qiLq(2!2"S^8,-2"S"S.Lq"S.Lq(2i2L."3q"2L^E8/L."3qi2L."3q"2L*3q"2L."3qE;/w[e&N8]Df4TEd&N8 UftEd&NC8]DftQdtQdE)N/L~3{$N_l8]DfttQdE)NCdE)NE8 )NE8]Df4TEd&N8]R8=}=Yab8]6񘟸N;!u:!Autи{'|: }yu:1S1៏ULЩA :u:DCU^R=t4tޏګN w^MuMyzզ< )OClA)OCltPm4Ħ<T4Ħ< )Oզ< )O ulelӓ6iM}bSM}bSԧjSԧlb}i(6ۧlb}VL~酱@}Ŧ@]uQl uQl E)PCl E)P@ fu El&PC@]fb%6opl Mb"6SLj3"6SL.b3j6SL.b3"6S+lPh"B06/L.b3$j6L.b3$"6Lj3$ؔ!6%ؔ+l&Q?ǁZfLj34"6Ө!65ԨbSԨbS.MbS.M4j6ӨL^ĦF/ZbSbS.M(6Ej6L.b3D"6Lj3D"6L.b3zf"w}6f*VElRJ f*uElRCJ]f*uPmRJ]f*5TER/VL~sݵTꅱL}f2uEl&SCL]f2uQl2uQlE)SClE)SŦL )SLXMzY#ĦLԩ/ԩbS.MbS.Mtj6өL.b3t"6өLj3t  tꅱP}fBu El&TCP]fBu Pm&TP]fB5T El&TP fBu Ջ6 l el*Փ6jMbSMbSTjSTlb͖j(6[lbVT>{A-eT=bͦj(6lbͦ 6lؔjSؔ!6ڔ!6Zͦ+kbMzզV UCljAUCljZuPmjZ5ĦVTZ5ĦV UզV U ZE ljelՓ6jMbSMbSjS!6lb:j(6kMz5VVOT!6j(6[lb 6[lb:jMbSMbS߭ۿZ=&Hc0}%gjc7?U1B3I_E/hL.cZSIEcnV νO,kW_;Z]9O5k>W7w{ɩEc鶷Ƕ5Z]t<=zfj8n3zalV_lZ]fjuPmVZ]fj5TElVZ fjuElVCZ]fjbu lV/ꋭ6SL.b3"6SLj3T!6TbSTbS^V7۵.MMzfk5PlVZ fk5AlVCZ VզZ VClAVClյ}xKllVCljuPmj5ĦZTj5ĦZ VզZ VClAVClյ¦Z:.MMzզZ VClAVCljuPmj5ĦZTj5ĦZ fkuPlV ju lelՓ6jMbSbj(6[lb 6[lTjSTk%6[Ǖ.!6[bzfk5PlVզZ VClAVCljuPmj5ĦZTj5ĦZ]+l;TT'[mj5ĦZTj5ĦZ VզZ VClAVCljuPmPlV jy˺626Vj5ĦZ VզZ VCZfk5PlVZ fk5AlVClյ+b,6['[lVCZ fkuPlVClAVCljuPmj5ĦZTj5ĦZ]+l\VVOT!6jM:6jMbSMbSTjST!6T!6ZaS~?.MMzզZ VClAVCljuPmj5AlVCZ fkuPlV j̺6llZ fk5AlVCZ fkuPlVClAVCljuPmjufku Z]ƦZ=jST!6T!6jM:6jMbSMbSTjSTkMz26Vj5ĦZ VզZ VClAVCljuPmPlVCZfk5յ¦Zd]jujdMbSb:j(6[lbj(6[lT!6T!6ZYSOp|fISh~pRg6[I:z_|6Z {LZ4e#ȩ|ЮZ >fN궩0?VCcI::hLۦVCcjuVTT'[mj5ĦZTj5ĦZ VզZ VClAVCljuPmjuV߬K`S.cSlVCljuPmj5ĦZTj5ĦZ fkuPlVCZfk5յ¦Z~f]jujdj(6[lbj(6[lbbSMbSTjSTk%6[KllVCljuPmj5ĦZTj5ĦZ VզZ VClAVClյ¦Z=u lelՓ6jMbSMbSTjST!6T!6j(6[lbVT?G%VVOT!6jM:j(6[lbj(6[lbbSMbSlp׺l.PlVCZTj5ĦZ VզZ VClAVCljuPmjuVYZ]ƦZ=jST!6T!6jM:6jMbSMbSTjSbVTǵ.MMzզZ VClAVClPlVZ fk5AlVCZ fkujuĦZ= wV/,6-6TbSTbS.b3"6SLj3"6SL.b3zfjʺ6SfjVElVZ fjuElVCZ]fjuPmVZ]fj5TElV/VL~~/H^[mVZ]fj5TElVZ fjuEVClEVŦZ VŦZXa3z.ŦZ}ŦZ]juQljuQlEVClEVZ fjuElVCZ]fjb%61YjLj3"6SL.b3j6SL.b3"6SLj3 u lV/ꋭ6SL.b3"6SLj3"6SL.M(6jM(6 կ^ zalV_lZ]fjuQljuQlEVClEVŦZ VZ]fj5TElV/VE|0Z3s~KZ]6.?Փ;VCRk5t~hkuЯ|gNwjhlp>UzLk54~wjh\"'AKLҩ`U5_0UEǼ_Z I`VL~L^[mVZ]fj5TElVZ fjuElVCZ]fjuPmVZXa3u;.ꅱZ}fjuElVCZ]fjuPmVZ]j5ĦZ]juQljuQlՋ6S!;L^[lEVŦZ VŦZ]j5ĦZ]juPmVZ]fj5TElV/VbSǬKMzaV_lZ]fjuPmVZ]fj5TElVZ fjuElVCZ]fjb1κ6SfjVElVZ fjuElVCZ]fjuPmVZ]j5ĦZ]jbu lV/ꋭ6SL.b3bS.M(6jM(6T!6TLj3Jlկ_{|m6ŦZ}ŦZ]juQlPmVZ]fj5TElVZ fjuElVCZ]fjbomV/ꋭ6SL.b3"6SLj3"6SL.b3j6SbS^ZmV/ꋭ6SL.b3"6SbSTbS.MbS.M(6jMJlV~/,6['[lVCOoHb:j(6[!6T!6jM:6jMbSMbS6qyZT'[mj5ĦZTj5ĦZ VզZ VClAVCljuPmjuVK`S.cSlVCljuPmj5ĦZTj5ĦZ fkuPlVCZfk5յ¦Zd]juYlVOlb 6[lb:j(6[!6T!6jM:6jMVbxd]BlVVOT!6jM:6jMbSMbSTjST!6T!6ZaS~/MzզZ VClAVCljuPmj5ĦZTj5PlVZ fkuVK`S.cSlVClPlVZ fk5AlVCZ fkuj5ĦZTj5ĦZoqkqegꅽ~sՃv"Wߛ\.>o٤\ ǙMEM.Mcs{woy+W}#WCM.:w6+W *'WCUNW\})W)WѩWOԫ!:jN::jNSNSԫSԫ!:ԫ }uտ&]^]F^]F`=٪S!:!:kN::k(:lk(:l6)XYˢzEg5-PtXb Eg5-AtXCt*uPu*5DbTzLEMguYtX)YOꔬ!:%kN::%kNSNS蔬S蔬!:%ꔬ }uJcu{:%2:%2:5V5Df ѩYUf ѩYCtjAթYCtjuPujPtYCfDgNzL+?uudNS:Fk(:lFk(:l!:E =c h]ej=٢VkN::UkNSNSTST!:UT }u tetet֓:ekNSNS蔭S蔭!:eꔭ!:ekN:fkC_8u] 蔭蔭ԭ'[u5DnT5Pt[n Eg5At[Cn EguPuֆv!Zen] ד-:l:ΆkNSNSS!: }u w()\)\ѩ\OT!:kN::kNSNSTST!:T }u*co\ѩ\)]Oꔮ!:kN::kNSNΦk(:lΦ : }uJן#蔮ˢ,:ۮ'[t]Cv EgumPt]CvDg5Dv ѩ]Uv ѩ]CtjAթ]z:ۮDŽk.S.Sl)^CtuPu5DxT5Dx )^Ux )^CtA)^džM2:2:V5Dz ѩ^Uz ѩ^CtAթ^CtuPt^CzDg뵡Nz g+z]Fz]F|=٪S :l:k(:lNS蔯S61mD|}>LeCW벱Ϳ7edy٨6Ϙt>:>68+_CCgЯ{} qkhl>uuи$SkvF|;2^W|{9]|]F|]F|=٪S蔯!:ꔯ!:kN::kNSNS蔯S6)_?Y$B|]F|]F|=٪S蔯!:ꔯ!:kN::k(:lk(:l6)_HNN,:'[t6_C| EguPt6_C|Dg5D| )_U| )_CtA)_z:ǯH$:ˢNzU| )_CtA)_CtuPu5D|T5D| )_U|mSkuudNS蔯S蔯!:ꔯ!:kN::k(:lW|}euudNS:k(:lk(:l蔯!:ꔯ =ODguYt6_Egdk(:!:ꔯ!:kN::kNSNS蔯S6ՙ|=ίL^ 3b":L3":L.3k:L.3SWgu&_/љ|}UguEt&_Cՙ|]uQtuQtE)_CtE)_E| UguN\]|蔯uQtE)_CtEt&_љ| UguEt&_Cՙ|]DguPu&_w3?=G%:FgLت3":L.3k:L.3":L3C_c'_/љ|}UguEt&_Cՙ|]DguPu&_E|]5D|]uQtu:o Nza)__l)_E|]5D|]uQtuEt&_Cՙ|]DguPu&_w锯5G\:љ|0:/L.3k:L.3":L3":LWg,L^ 3b":L3":L.3kN(:蔯!:}u&_D|L^[u&_E|]5D|]uQtuQtE)_Cՙ|]DguPu&_wwgEJ>~5녍iQ^|}߿=~3 _uP7ux|| ov6+_s,_ g5Օz/|To5}Uu`:slp>x9?|;ՙ|zL^ 3b":L3":L.3k:L.3}u&_}s-3zat&_/닭:L.3":L3(:蔯!:蔯S蔯;ՙ|}ȵHљ|蔯/蔯S.NS.N(:kN":L.3k:;tc3Y$¢S^[u&_љ|]Dg5TEt&_љ| UguEt&_Cՙ|]DguPu&_w3xY$BgL^[u&_љ|]Dg5TEt&_љ| UguEt&_Cՙ|]uQtu:9-DL^ 3b":S蔯S.NS.N(:kN":L)_BD|蔯uQtEt&_Cՙ|]DguPu&_љ|]Dg5TEt&_љ| Ugu:'D蔯蔯蔯'[u5D|T5D| )_U| )_CtA)_Ctu׆:#D蔯蔯蔯'[u5D|T5Pt6_| Eg5At6_C| EguPu׆1wˢ,:'[t6_C| Egu5D|T5D| )_U| )_CtA)_ꔯj.S.Sl)_CtuPu5D|T5D| )_U| )_CtA)_ꔯK]2:2:V5D| )_U| )_CtA)_C| EguPt6_C|Dg󵡯N]l.Pt6_C|Dg5Pt6_| )_CtA)_CtuPu׆qeww蔯蔯'[u5D|T5D| )_U| )_CtA)_CtuPu׆:h蔯蔯蔯'[u5D|T5D| )_U| )_CtAt6_C| Egu׆:*)_)_)_Oꔯl:k(:lk(:S蔯!:ꔯ Gqfx\׽3Q'_co|]|οj.'/=OqLK|53R_e~W~ k>W~SYӯcӯ+_Ccuy~ gFkh\G1uƧ~=!ݧ~է~]Ƨ~]Ƨ=S!>!>lO;>lOSOSOWݧէ]Ƨ]Ƨ=ST!>T!>lO;l(>[ll(>[O{\^TT,>'[|6aCل gvMP|6aCلT6ħ )aէ )aC|JuM}V&l&2>%2>5V6ħ aէ aC|jAaC|jvP}j6ħ]g|j#԰԰԰'[}"6ħT"6ħ )bէ )bC|A|6bCو g#v)b'ħէ]Ƨ]Ƨ=SņV >[lņ;Vl(>[lOSņT,>[G\>[1>[,>'[|6cC|2vP}26ħT26ħ )cէ )cC|uƧ~yJ|X}e|e|ؓ>ulOSOSdžԱSdžԱ!>uԱ!>ul(>۱OԱԱԱ'[} B6ħgC6 P|6dِ gC6 A|6dCِ )dY|6dK~!!,>%{gK6-P|dէ dC|*AdC|*JvP}*J6ħ]g|*ٟVSS.S.Sʞl)eC|JRvP}JR6ħTR6ħ )eէ )eC|JuƧ=PS6VRvRvZdO-SˆԲSˆԲ!> >۲lˆ-;϶l(>۲lˮ3>P[6g[vY|egcdl(>l1l(>S̆!>!>lO11κlS.S.S͞lfC|jvP}j6ħTj6ħ fէ fC|ugjwR35{a|f/십>L.39">LΆ39!>S^=~dV.]V 39{a|g_lgŧ]z6ħ]zvQ|zvQ|E|gC]gzvًqDN㺟{$Kn7_Uҳ~Gӳ6gҳ'V5<wt۳ ڳcLzz6ճߙlhL0fҳy/rAkl_=jֳsOqgzgO=O=O=O={է gC|AgC|zvP}z6ħTz6ħ gzmI|X}e|e|ٓ>lO=SO=SφԳlφ= >۳lφ=ԳwMSS.lϞlٞ g{6A|gCٞ g{vP}z6ħTz6ħ gY|gM֛\>۳1>۳ԳԳ'[}z6ħTz6ħ gէ gC|AgC|zvgԳԳԳԳ'[}z6ħTz6ħ gէ gC|A|gCٞ g{v=7L^ 3=bԳSφԳS.O=S.O=(>l>ӳL.3={qzzn>2>ŧԳ/ԳL.3=">ӳLφ3=">ӳL.3=8gI|ggzL^[}g]gz6TE|g gzvE|gC]gzvQ|ً3>ӳzL.񙞽0>ӳ/L.3=lO=(>Գ!>ԳSφԳS.3={qz8YorԳԳzSϾS.O=(>l>ӳL.3=">ӳLφ3=">ӳg|g9&]V 3={a|g_l]gzvP}g]gz6TE|g gzvE|g/LZoe0>ӳgzVE|g gzvE|gC|Egŧ gŧ]zsmn!=O={ag/,>->ԳSφԳS.O=">ӳLφ3=">ӳggϧ&O=>ӳgzLϾ3=">ӳL.3=l>ӳL.3=">ӳL^gcg?Ԟէ]Ƨ]Ƨ=SφԳ!>Գ!>lO=;>lO= >۳lφ=ԳǮCX}e|e|ٓ->۳lφ=;l(>۳l=lO=;>lO=SϞPKn=n2pcube/halfred_iridas.cubeUT +M% NUx}_UX-|MשS!!""EA q>yv#*WWյk_w___׿ۯ/_7???/~???w7}}}7_ꟿ?/W~?_|O'7~'_goo>__~_}/@ww__Go_?o>|__o~ÿ7ͯ?ן?ۯ??|>}ۀ^@ v?5s8e;0^~<8W<WD[%R)*E[%R)*Eo\J8ץt}T.n~yTh}@Khh T@Keq28V)*}*E[el~cO*E[h]*E[h]*E[mR)zT.O\JХ/t2Rhm@=@@o\[eqRU4εUBǿ*-JVh T@k@o\@/\[h ikm {R)*E[%R)*E[%R)*Eo\J8ץt}T.n~gG@Kh TZ*E[e28VekoUU4εUBsTh T@KeRUZ*sm^ƹJV8V)گ7@[|W.]h@[|W.]>u@\|NY*hm@Kh Tz*sm2ЧqRU7@[|W.]h@[|W.]>u@\Uh T@KeE[eJq28V)*}*E[el~ TZ*E[e2R)*Ism^ƹJV8V)*cwer+E Uwer+E tTweqK|W~9ߕ@Kh TZ*E[e28Vekm>sm26>^NOU&zWYU&zWYn\?,D/\?,Dƹ~PYW>,MOe F"=odzP獞*xB"=odz>y#FS~ULϪEzVJm+ҳ*EgU"=RdzV_@2=2HϨ dzFe 3*EQFTJY"ӳ*AU)2=RdzV%(ҳ*EgUH*-LϨ dzF(3*QJQgT2=26ģ@Ke 3*Q)@gT2=RLϨooJV)2=RdzV%(ҳ*EgULϪEzVJ7գ@Ke 3*Q)@gT2=RLϨ/?G@gT2=RLϨ dzF(3*Qh RdzVJPgULϪU JYn~׵gUZ_'LϨEzFe 3*Q)@gT7@[|W"=r+EU9ߕHϪJQgUw_ T2=2HϨ dzFe 3*EQBo)gT2=2HϨ dzFe 3*EQF]hJQgUw(ҳ*RY])>k/SLϨ dzFe 3*EQ@gT"=2wP|Ldz>T|Ldz>T&2=* Ez>T&2=*s@ Dz|!H/@L"=_>ezBS*E[*EP 2=J9THϡdz"strSe篓*E+2Yn\gU"=RdzVe ҳ*c=oIhC*AP)"=J9TLϡRDzn~@Ke ҳ*U)2=2YHϪUBG@gU"=RdzVe ҳ*U)2=2Y?m"sC%*EP)"=J9THϡ/t+2R@gULϪ DzVe ҳ*EgU"=26UZ*UJYHϪ DzV@gU7@[|W.]*29Twe89Tw_ =2:HϪ DzV@gU"=RdzVe ҳ*cwer+E Dz]*2}*RtkvUZ*UJYHϪ DzV@gU)S@gU"=RdzVe ҳ*U)2=2Y2V9ߕK|W"= Dz]>ez])Tw)gU"=2Y"ӳ*UJYHϪͿտHϧDSe"󩲐T|LDz>U2=*Oʅ_SyT2=odz^(F dz^(F\72=odz^h?ՓJYKJPgULϪU JYn9MLϨ]LϨEzFe 3*Q)@gT柟V)2=tRJƹ"=RdzV%(ҳ*EgUU2=RU2=RLϨ dzF(3*Q_ 22HϨ dzFe 3*EQF%TLϪ]*EgU"=RdzVJPgULϪt ߺU2=RU2=RLϨ dzF(3*Q_h*Q)*Q)@gT2=RLϨo4ߕLϪ@gUwe8WgUwe8WgUw_ ])LϨmLϨEzFe 3*Q)@gT7Z "ӳ*AJYHϪU)2=Y"ӳ*B5*Q)*Q)@gT2=RLϨ/bzFe 3*Q)@gT2=RLϨoOU TLϪEzVJYHϪU;@gT2=RLϨ dzF(3*QGLχDCeHχDCe"PCe"27^/ Dzy#HZO|T"=odzBq.H"=oFϱI*AP)*AP)"=J9TLϡRDzn~@= DzV@U@gULϪ DzVel~P)"=J9TJ9THϡRDz sC_hϮ@gULϪ SeWR@q.ӳ*U_Qe ҳ*EgUZ*EgU"=2Y"ӳ*U֓J9TLϡRULϡRDz"sC*B2Y"ӳ*-"ӳ*UJYHϪ/?GHϪUhU@gULϪ DzVel~ Dz]*2m*2}*Rtʝ2UJYJYHϪ DzV@gU7@P9ߕHϡr+ƹLϡr+ǹLϡr+EUJY{U@gULϪ DzVel~7ҳ*UJYHϪ DzV@gU7@P9ߕHϡr+ƹLϡr+ǹLϡr+E;@gU"=RdzVe ҳ*U)2=2YwT|LDz>U2=*OHϧBSe"27^T"=_B 72=_h=H/Dz}|!H26oȟTHϡtC%*EP)"=J9THϡ/tdGHϪWU)2=2YHϪUF-I*AJ9TLϡRDz"sC*B{vU"=RU"=RdzVe ҳ*U)2=2Y=Se ҳ*ET@q.ӳ*U)2=2YϓJ9T."sC*EP 2=J9T$*U)*U)2=2YHϪUBǓ2Y2Y"ӳ*UJYHϪo4ߕHϡr+C|WsC|WsC|WnN DzVh DzV@gU"=RdzVe ҳ*cwe s@P9ߕn\P9ߕ\P9ߕg|-t_2Y2Y"ӳ*UJYHϪ/S*U)*U)2=2YHϪUF]*29Twe89Twe89Tw_ }靲T"=RU"=RdzVe ҳ*U)2=2Yw׻DSeT&"=* OHϧDSe!2T_\7T2=odz^h?Lz*Oe FqH}~*c=ZIJХRdzV%(ҳ*EgULϪEzVJ7޳*Q)گ2=RLϨ dzF(3*Q9@<U TLϪEzVJYHϪUڳ22HϨ dzFe 3*EQB{ U2=Rt}OQ)@gT2=RLϨoߏ*EgUoRdzV6Y"ӳ*AU)2=/t|GLϨmLϨEzFe 3*Q)@gT:t? dzFh dzF(3*QJQgT2=26|W2=r+U9ߕn\U9ߕ\U9ߕg|-tLT2=RU2=RLϨ dzF(3*Qh+U9ߕLϪ@qHϪ@qHϪJ3UJVJQgT2=2HϨ dzFel~73*QJQgT2=2HϨ dzFel~~BJХRdzV%(ҳ*EgULϪEzVJ7Е2QJVJQgT2=2HϨ dzFel}ez>T&2=*"=*LχBLχzeG<>H"=odzBLZOe F /t2=_8yT7z]ܓJ9TLϡRDz89THϡdz"st  }TJYHϪ t2=2Y"ӳ*UO*EP 2=J9Tn\P)"=J9THϡ/gWe ҳ*EgU"=2m@/\[@gU:Σ@gULϪ DzVe8Y^ƹJYHϪoOC%*EP)sCeR 2=J9TWVe ҳ*EgU"=2m@/\VSeO\gU:>Qe ҳ*EgU"=2m@/\[@gU7@P9ߕHϡr+ƹLϡr+ǹLϡr+EZhLU"=RdzVe ҳ*ƹLϪ 2εULϪ DzVel~ Dz]*2m*2}*RtkvU"=RdzVe ҳ*ƹLϪ 2εULϪ DzVel~7ҳ*UJYHϪ 2εULϪ DzVel~~B*AP)"=Jm*E/\J9THϡ/S*U)2=2Yn\gUz*EgU"=26>V"=*OHϧBSe"28* OHϧzeɏOe H/Dzy#SB/\/i~*c=I*AP)"=Jm*E/\J9THϡ/tVQe ҳ*EgU"=2R@/\[@gU7zUJ9TLϡRDz89T^ƹ. sC_hϮ@gULϪ DzVeJ ҳ*sm"ӳ*U_*U)2=2Yn\gUz*EgU"=26z?RDz sChCeR 2=J9TWVe ҳ*EgU"=2m@/\{"ӳ*U_@gULϪ DzVeۏ?@/\*}2=26_@P9ߕHϡr+ƹLϡr+ǹLϡr+E|}~dU"=RdzVe ҳ*-HϪ 2εULϪ DzVel~ Dz]*2m*2}*Rt@gULϪ DzVeJ ҳ*U)2=2Y޼SHϪ DzVe ҳ*EgU"=2Y"ӳ*Uh+C|W"= Uw*Rdz])Tw)gU"=2Y"ӳ*UJYHϪͿտHϧDSe"󩲐T|LDz>U2=*OʅT2=odz^(FL Ezh=L Ez}+FL 26RdzV%(ҳ*EgUn\U)2=Y"ӳ*BǯbUZ_'LϨEzFe 3*Q)@gT7zؓJV)2=RdzV%(ҳ*EgULϪEzVJ7О]@gT2=RLϨ dzF(3*Q_M@Ke 3*Q)@gT2=RLϨoONUJYRdzV6Y"ӳ*AU)2=/t4G@gTZ*Q6LϨEzFe 3*c Qe@Ke 3*ƹ"=2HϨ dzFelV)z~U"=RdzV6Y"ӳ*AU)2=/G dzFe2n\QJQgT2=26|W*RY])EzV|W"=r+EZQe2@gTsEzFe 3*EQBo)gT2=2R@qHϨ dzF(3*Qh+m])EzV|W"=r+EU9ߕg|-wLϨ T2=2m+3*Q)@gT_Ce"2ѻDCe8WCe"PCe"27^TZOe F 2y#SB ǹL"=_~*c-;RUHϡRUHϡRt2=J9TLϡRDzn~~Th}@gUZ*U6ezVe ҳ*EgU"=26/UTJ9TJ9Tn\P)"=J9THϡ/gWe2Y@gUsUJYHϪ/tQe2Y@gUsUJYHϪoOm"sm"sƹLϡRDz sC_E@Ke ҳ*-HϪ t2=2Y"ӳ*U_h*-HϪ T"=2R@gULϪ DzVel~e'TJ9TJ9Tn\P)"=J9THϡ?MNU@q.ӳ*U)2=2Y2V9ߕ"sJ9Tw*Rdz])}BƏ*-HϪ DzV@gU"=RdzVe ҳ*c yU@gULϪ DzVe ҳ*EgU"=26|W*Rdz])2=C|WLϡr+E;@gU"=RdzVe ҳ*U)2=2YwT|LDz>U2=*OHϧBSe"27^{|*2yH72=/yT2=/y#FqH72=/FœJV)2=RdzV%(ҳ*EgULϪEzVJ7q= N 3*Q)@gT2=RLϨo|?m"ӳ*EgU"=RdzVJPgULϪt Uh dzFe 3*EQ@gT"=2Y= T2=2HϨ dzFe 3*EQu_*E[JYHϪU)2=Yqg|-tvQe2LϨEzFe 3*Q)@\Zh*-LϨ dzF(3*QJQgTzگ7@[|W"=r+EU9ߕHϪJQgUw_[wLϨ dzF(3*QJQgTz}s*E%Z%(ҳ*EϯJm+ҳ*EgU"=R:uϳ? T2=2HϨ dzFe 3*EQuk/bzFe 3*Q)@gT2=R^ǹnw'RdzVJPgULϪU J83;@gT2=RLϨ dzF(3*s>}ez>T&2=*"=*LχB^ǹn^|@ 72=_|TLZOe F /t2=_|qT7zI*AP)*AP)"=J9TLϡR:ut £@gULϪ TLϪ DzVe ҳ*EgUz*c=oO*EP 2=JV 2=J9THϡdzqK_踩U"=RdzVeEgU"=2Y"ӳ*sm_t< DzV@K@gU"=RdzVeq26z?RDz sm sC*AP)zT_ > DzV@K@gU"=RdzVeq26U"=RdzVeRdzVe ҳ*U)2=28~%6|W"= Dz]6ez]>ez])TwN DzV@K@gU"=RdzVeq26|W"= Dz]6ez]>ez])Tw@gULϪ SeWR@q.ӳ*U_;@gU"=RdzVe ҳ*U)2=2Yj=C%*E[%*EP)"=J9THϡ/w YHϪ DzV@gU"=RdzVe ҳ*cc/2T|,dz>U&"=*OLϧDSen~?x&T"=_B 72=_h=H/Dz}|!H26O2O*EP THϡdz"sC%*EP:~|TJ~%Y"ӳ*UJYHϪo3J9T."sC*EP 2=J9T DzVh DzV@gU"=RdzVe ҳ*c @gU@gULϪ DzVe ҳ*EgU"=26z?RDzK*AP)z2=J}*EP:~2Y2Y"ӳ*sU>ezVe ҳ*c Qe ҳ*E[e ҳ*EgUz2=2}@gU7@P9ߕHϡr+ƹLϡr+ǹLϡr+EZhLU"=RU"=RdzVeq.ӳ*ǹLϪ DzVel~ Dz]*2m*2}*RtkvU"=RU"=RdzVeq.ӳ*ǹLϪ DzVel_TJVJYƹLϪ t2=2Y29Twe s@q.s@q.sJ3;@gU"=RdzVeq.ӳ*ǹLϪ DzVel}Ez>U&"=*OLϧDo\Se8T|ͯWﴏOe FSyH28WLǹ"=odz~*c=RdzV%R)2=YqHϪǹ"=RdzV_Qe 3*E@gT"=28WgTsEzFe 3*c=RdzV%R)2=YqHϪǹ"=RdzV_hϮ@gT@gT"=28WgTsEzFe 3*c 'գ@gT@gT"=28WgTsEzFe 3*c*EgU."ӳ*AU)zJ}+ҳ*EgU_>< dzFh dzF(3*sEzFe8WgT2=26U2=RU2=Rƹ"=2}+3*Qh+U9ߕLϪ@qHϪ@qHϪJ3R&*Q)*Q)@o\Q>LϨo6*EgU."ӳ*AU)2=RdzV%(ҳ*EgUkvU2=RU2=RLϨ dzF(3*Q_;@gT2=RLϨ dzF(3*QhULϪ6l$RtJYHϪU;@gT2=RLϨ dzF(3*QGLχDCeHχDCe"PCe"27^9ǧ2BL"=_h="SB ǹL4ezh?g>C%*E[%*EP)"=J9THϡ/tC2Y"ӳ*-"ӳ*UJYHϪoœJ9TLϡRULϡRDz"sC*BǏ|*U)2=2z"ӳ*UJYHϪ/t2Y"ӳ*-"ӳ*UJYHϪoOC%*E[%*EP)"=J9THϡ/t\*U)2=2R)2=2YHϪUBsTJYJYHϪ DzV@gU7@P9ߕHϡr+ƹLϡr+ǹLϡr+EZhLU"=RdzVeRdzVe ҳ*U)2=2Y29Twe s@q.s@q.sJ3UJY{U@gULϪ DzVel~7ҳ*-"ӳ*-"ӳ*UJYHϪoOC%*E[%*EP)"=J9THϡ/ʪ DzV@(@q.ӳ*U)2=2YwT]e!2T6ez>U&"=* OHϧzpT:#ZOLϏHϏHLϏh=ƹ^ƹS):#4uFړJёS%LϩRtT)*Eo\gzN8יSuR:= tR):s tRh 6uR>uRukoOғJёS%LϩRtT)*Eo\gzN8יSuR:~NxTHϥRtRHϥ2RmLϥ2}Lϥ28V_Qe#=JљKe#=@Keq3=@q3=@\[el~矨T*AgzN#=JV)z:sǹ*E\J7q< tR):s tRh 6uR>uRuk/@Gz.3=@Gz.@o\gz.\gz.^ǹF]Hϩr+9Uwer+EgzN]):sJѥr+_S\*-3=@Gz.@o\gz.\gz.^ǹF]Hϩr+9Uwer+EgzN]):sJѥr+ﳗ@Gz.3=@Gz.@o\gz.\gz.^ǹBo]HϥRtRHϥ2RmLϥ2}Lϥ28Vh+9Uwe#= UwLϩr+EgzN])Tw]HϥRtRHϥ2RmLϥ2}Lϥ28VG.BgzVe#=2?%ЙU>ugU&z=rPKn=n' cube/iridasUT +M NUxuTn0+ Q[ 8(z hjeHb_]V=H>Ԥoʩq\Զ7~cŅV(DAg-!&tj`VDt2:B A Xa%i$΢خpY.HU=la#CSoWy 7pQb)y T@0q|酏@!֓7i: rC^\HzK^J{peVe+Sdp+}6Zڞcr *Aw%6"ΡdQ TqpUPo'db}s~|٬sgܾc>=d1-q#d&v5iEcĢi{RS4<6RT àq? icQ 7bةg~->SPRA5Tm) ;R_˜~a5[4@lbr}}JyF|9GG;j1/ Acube/UT NUxPKn= ]j  8cube/crosstalk.cubeUT+MUxPKn=n2p ^cube/halfred_iridas.cubeUT+MUxPKn=n' cube/iridasUT+MUxPK'ӓopencolorio-1.1.0~dfsg0.orig/testdata/cub.zip0000644000175000017500000020620713223553423017403 0ustar mfvmfvPK q>cub/UT 2 NJ NUxPKn=Eec%cub/crosstalk.cubUT *MVMUxm͎Hf}^E }-mh9AF#An_F7kdԇ:O%'i_ۿ{O?O?oc{ye'~k@]3is t<@sl(=2i03<@s <2i0'.qk9ϯ@_4P9 e`{9 6yN4yN e`W9 zg`C4yN?׸5М`ů@sl(2i0=<@_=3is ʆ3is <[\lhk0`k9 6yNn4yN e`G9 zf`C4yNޙ4P9 d=.~ 645hwk05<@s t<2i05yN e`W9 zg`C4Wzyů<] t<2i0`{9 6yN4yN e`W^i0;<@li 5yN e`ů@sl(=2i03<@`w9 6yN>ٰ+.~ 645h5yN e`[9 g`C4yN4P9 ] <2i0'vyů<.~ f`CW`[9 g`C4h? a]?6[їέFo;6z7y;60yѧ}p}ΣwmmKwm4G.==}ߣh{;6oG8|F_;66y;6wϣ?a|Gߣї=ÖG}~hLxsy?^|.]cEzsu|u=luLxcoy+~hLxn3~9_o? s=l}Lxxn}?y|e\ƾq.oy@\^_n׊y{(?O܎>|/q|_r~._퀸|}~.}}+ca3az|r?<[bE\^7a㹼\a㹼\ary|ޟe\n3?{ so\(.k~౻qP\s@q9^X?8l<=l:l|]ޯaya]>~ȉV5s;su9^<\߷ykEuyv@\as@\z.u8=~Vy?c%p@\〸|=߶x[rkg.0< .P|kEu?9rfP]^a=>_c_p.LJ\@\~.<8j6q!ןv؇\^e\7Ʈ5=~g^+2>qP\k .x6|?l<ױΞk .B˱̵X6˱^_a]^?>8N.pu9^c}^x͟yLr\q9}}瀸sTq_k'MsqSsWTc)u?l|]>oau}a]ƞ^}|8w8^h .r@\>aൢ|sq΀8lF]>ZuNfvf|?sq9>r5_a3N.ǧ?˲._c;wcn|=@qr'.\@\~q_*.?\k(.}}\@q9^qx.oe<|!9C.o]y9ú'FeWKsw M>5 ]kE\޶{;5>P\޶7uyq9>'.o\@\o?X _qy؇uDa]q;ú|^4\1>us]ZQ]_׹||r|UP]v|%\ k9l|]8׾a]a}ya]ckvc6˱^}w؇\y؇\ru؇\goaz>._c-u؇u9._*MP]۲=/kX\;^+qq9!'.a} .< .\8l|]uy헩|q؇\z؇\~&e;*:@g>qk~k9>Auyx@x r\@q9m=c`x]:l<|a].aX.Ǒqoaxn7+S溧ĽECc3Μ m?I{F[teBZCƄhhL8ϱp mHZ44vTޢƎ??IƄZƄ׹(KGGޢ3 h.-:h%{Ro.hK-RK-RԢRԢ!.蠺Ԣ!.hK-:.hK-RK-zK-~RԢ!.蠺Ԣ!.hK-:.hK-RK-˶h(.ۢl-˶ .ۢ':ԢRԢl-˶h(.ۢl-˶ .ۢ!.hK-:.hK-RK-ze[mP\EC\jAuEC\jZtP]jZ4ĥTZ4ĥ qEե qEC\jAuEOtpE?\jZ4ĥTZ4ĥ qEե qEC\jAuEC\jZtP]jP\ECqe[DZ8λ=Ԣ!.hK-:.hK-˶ .ۢl-:˶h(.ۢl-RԢRhuw{e[4mP\Eq e[4ĥTZ4ĥ qEե qEC\jAuEC\jZtP]j\jc;RԢ!.蠺Ԣ!.hK-:.hK-RK-RԢRԢ!. .ۢ':Ԣ_n.hK-RK-RԢR-˶ .ۢl-:˶h(.ۢlK-ze[8^}ڢl-:˶h(.ۢl-RԢRԢ!.蠺Ԣ!.hK-:..qs qEC\jAuEC\jZtP]jZ4ĥTZ4ĥ qEե qEC\jAuEOtpE\jZ4ĥTZ4ĥ qEե qEC\jAuECq e[tmP\ECqe[DZ e[4mA\ECq e[tmP\ECqe[4ĥ qEե qEC\jAuEOl.EC\jZtP]jZ4ĥTZ4ĥ qEե qEC\jAuEC\jZtP]j\jq qEC\jAuEC\jZtP]jZ4ĥTZ4ĥ qEq e[4mA\EOtpEO[4ĥ qEե e[4mA\ECq e[tmP\ECqTZ4ĥ qEե=޿qE{?NP wĜ婴EC,شhhGk-:h߇ ;UƄٙӢ9[Y y k e /Jz [CҢ':Ԣ_7@ץ qEC\jAuEC\jZtP]jZ4ĥTZ4ĥ qEե qEC\jAuEOtpE=Ԣ!.hK-:.h辜H$A\jAuEC\jZtP]jP\ECqe[4mP\Eq=w{pEC\jP\Eq e[4mA\ECq e[tmZ4ĥTZ4ĥ qEե=-˶h(.ۢ!.蠺Ԣ!.hK-:.hK-RK-RԢRԢ!.蠺Ԣ':Ԣ_:RԢ!.蠺Ԣ!.hK-:.hK-RK-RԢR-˶ .ۢ':Ԣv qEC\jAuEC\jP\Eq e[4mA\ECq e[tmZ4ĥTZD˶g#.ۢl-:˶h(.ۢ!.蠺Ԣ!.hK-:.hK-RK-RԢR2-s2-˴".ӢL.2-˴h.ӢL.2-˴".ӢL2-˴".Ӣ!.\E_YҼۃ˴".ӢL2-˴".ӢL.K-(.hK-(.袸Ԣ!.袸ԢR2-zGK-z,p=R.K-(.hK-(.袸Ԣ!.".ӢL2-˴".ӢL.2-˴h.Ӣwtp}\hE\Eq eZtiE\ECu]eZtiP]Eq]eZ4TiE\Eq eZ.Ӣcۃ˴".ӢL2-˴".ӢL.2-˴h.ӢR.K-R.K-(.hK-zGiїmۃ˴袸ԢRԢR.K-R.K-(.hK-˴".ӢL.2-˴h.ӢwԢ~#.".ӢL2-˴".ӢL.2-˴h.ӢL.2-˴".ӢL2-zGiї~iE\Eq eZtiE\ECu]eZtiP]Eq]eZ4ĥ]ZtQ\jZ.Ӣ/c5<\ѢL.2-˴袸ԢRԢR.K-R.K-(.h.ӢL.2-˴m.77}ޢ9 +g9Ak~ޢgp[tјp^K.ܝ ]R༷袱-h,(_hh;ҢƄ47hLwٽECuuoEc%hoEiihhWVe\EE8L.2-˴h.ӢL.2-˴".ӢL2-˴".ӢL.2-˴h.Ӣwtp=[\Eq]eZ4TiE\Eq eZtiE\ECu]ZtQ\jZtQ\jEqEC\j;:Lۃ˴".ӢRԢR.K-R.K-(.hK-˴".ӢL.2-˴h.ӢwԢ+K-(.".ӢL.2-˴h.ӢL.2-˴".ӢL2-˴".ӢLeZгeZtiE\ECu]eZtiP]Eq]eZ4TiE\Eq eZtQ\jEqEC\j;:L12-˴".ӢL.2-(.hK-(.袸Ԣ!.袸ԢRԢL.2-˴.vguEť]Z4ĥ]ZtiP]Eq]eZ4TiE\Eq eZtiE\ECuK-zm\jZ4ĥTZ4ĥ qEե qEC\jAuEC\jZtP]jZ4ĥe[DZ qEC\jAuEC\jZtP]jP\ECqe[4mP\Eq e[4mAuEOlޮ{ECq e[tmP\ECqe[4ĥ qEե qEC\jAuEC\jZtP]j\jя~Z4ĥ qEե qEC\jAuEC\jZtP]jZ4ĥTZ4ĥ qEե==uhK-RK-RԢRԢ!.蠺Ԣl-:˶h(.ۢl-zK-R-˶ .ۢl-:˶h(.ۢl-RԢRԢ!.蠺Ԣ'Z]Epݧ-RԢRԢ!.蠺Ԣ!.hK-:.hK-RK-RԢRR~=Ԣ!.hK-:.hK-RK-RԢRԢ!. .ۢl-:˶.~Z4ĥ qEե e[4mA\ECq e[tmP\ECqTZ4ĥ qEե=r8$ҢWcdcs9&1:r/rs|$ qȸKƄ#8[nys{gqNƄoNǧ;>1ph] #S(SlFCdjtPej4DTj4D FU FCdAFCdjtF?L9zU )GCdA)GCdrtPer4DDfs4Pd6G Efs4F=xmdѓ2h(2ۣl"=h(2ۣl"=ԣ!2hL=:2hL="Slޢ 4D T4D )HU )HCd A)HCd tPe 4D ]ad {n< SlHCd*tPe*4D"T4D" HU" HCd*AdHC" EftH?ߞ`dLI"SȔ*S"I& 2l"I:&i(2lLI"SȔ+,2_W0eIOl"M6 2ۤ!25iLM:25iLM"SLM"SԤ*SԤ!25 #S3L"Sl)JCdtPe4D(T4D( )JU( )JCdA)JCdPd6JW!&JOT!2UiLU:2UiLU"S"UVi(2[l"UV 2[lT+,2[>ll, Ef4Ad6KC, EftPe4D,T4D, )KU, )KCdF,~yIdғ2uiL]"SL]"Sԥ*Sԥ!2uԥ!2uiL]:2uiL]"S02u&|5LO!2iLa:2iLa"SLa"Sl"ă 2l"a?2LezEf4-PdL2 Ef4-AdLC2 EftPe*4D2T4D2 LWXdLxizU4 )MCdJA)MCdJtPeJ4D4T4D4 )MU4 )MCdJFf85(L*3m̴"2ӦL."3m̴i2ӦL."3m̴"2Ӧ"SԦ"S.LmzFfXMzId&Nl8]DfttQdE)NCdE)NE8 )NE8]Df4TEd&N8P~۷/_ӓmcVe4~fƪ98 o8:q:h,*ИpVv44&HVoGwrvω198tИpﴉИp>X02f2V4D8 )NU8 )NCdA)NCdtPe4D8T4D8 )NW'[e4D8T4D8 )NU8 )NCdAd6NC8 EftPd6NC8]adӟkB Sl)NC8 EftPd6NC8Df4Pd6NU8 )NCdA)NCdtEf|>2'[d6NCdtPe4D8T4D8 )NU8 )NCdA)NCdt8}oQfVEd&N8 UftEd&NC8]DftPe&N8]Df4D8]tQdӋ02M靭2L."3q"S"S.Lq"S.Lq(2i2L."3qzݮtQdE)NCdEd&N8 UftEd&NC8]DftPe&N8]Df"&8UftEd&NC8]DftPe&N8]Df4TEd&N8 UftE)N/L{SM"3qzg"2L*3q"2!2"S"S.Lq"S.LqEXd?X]8E8]tQdtQdE)NC8]DftPe&N8]Df4TEd&N8#3qzyId&Nl8]DftPe&N8]Df4TEd&N8 UftEd&NC8]DftӋ02:^wL."3qi2L."3q"2L"S.Lq"S.Lq(2EœM"3qzgLq(2!2"S"S.Lq"2L*3q"2a)N_Ǜq'Nl8]DftPe&N8]Df4TEd&N8 UftEd&NC8]DftӋ02dzM"Sl)NCdtPe4D8T4D8 )NU8 )NC8Df4Pd6NWͅV4D8 )N8 Ef4Ad6NC8 EftPd6NCdA)NCdt=2[%?7f%Nl8W ɜPl7?|Q4t{]@'NC7k0;Z|n8 ssihL=6NƄ{M3w4,B3 t44&@1|8]adӏqeӓ2iLq"SLq"S*S!2!2iLq:2iLq"S02qNF"Sl)NCdtPe4D8T4D8 )N8 Ef4Ad6NC8 Eft)No+LqzU8 Ef4Ad6NC8 EftPd6NC8T4D8 )NU8 )NCdϏFvӓ-2!2iLq:2iLq"SLq"S*S!2!2iLqԹm$2V4D8 )NU8 )NCdA)NCdtPe4D8Df4Pd6NW鶑'[e4D8T4Pd6N8 Ef4Ad6NC8 EftPe4D8]a8=tmd8="qi(2l!2!2iLq:2iLq"SLq"S+Lq}wHdӓ2iLq"SLq"S*S!2!2iLq:2iLq #S~6dLq"S*S!2 2l"q:i(2l"qiLq"qz+@ӓ-2l"q:i(2lLq"S*S!2!2iLq PdLq"S*S!2!2iLq:2iLq"SLq"S+ϏF"3qzg"2L*3q"2L."3qiLq(2!2"S^8}m$2w"S.Lq"S.Lq(2iLq(2L."3qi2L."3qz 8UftEd&NC8]DftPe&N8]Df4TEd&N8 UftEd&N/L]yy8UftEd&NC8]DftPe&N8]Df4TEd&NE8 )NE8]"8⾎W靭2L."3q"S.Lq(2iLq(2!2L*3q"2a) Љc'+7fecשӓm?Yiyy/ -Ty}>yUƄ14yK Aױ~: |: fNgFLЩs{$NCg>FWSLЩHtN~N)OOڔ!6iMy:6iMybSMybSؔjSؔ!6ڔ!6ZaSrtdM}bSԧjSԧ!6ԧ!6i(6ۧlb} 6ۧl6ӧoSp酱@Ŧ@]uQl uQl E)PCl E)P@ fu El&PC@]fb%6۶ l Mzg"6SLj3"6SL.b3j6SL.b3"6S+lPhnE`3zal&QlD]fuIPm&QD]f5TIEl&QD fuIE)QClJE)Q/VL^6fViElQF QŦF]5ĦF]uQljuQljElQCF]fb%65x9Q/,6E-6EbSj3D"6L.b3Dj6L.b3D"6+l&R߶h3zalRlJ]f*uPmRJ]f*5TElRJ f*uElRCJ]*bT8#J06wL.b3dj6L.MbS.M(6ejM(6eؔ!6e"6+)S-)S/,6u-6uԩbSԩbS.b3t"6өLj3t"6өL.b3zf:6өfBV El&TP fBu El&TCP]fBu Pm&TP]fB5T El&T/VoܑP]ƦR=jST!6T!6jM:6jM͖ 6[lb:͖j(6[kMzlx-,6'[l6UCT fSuMPl6UCTfS5MRuPmJR5ĦTTR5ĦT]+T}瞄l.cSlUCljZuPmjZ5ĦVTZ5ĦV UզV UCljAUCljյ¦V}626Vb5ĦX )VզX )VClA)VClbuPmPl6VCXfc5յ¦X=9^ j.cSlVClPlVZ fk5AlVCZ fkuj5ĦZTj5ĦZ]+ۥoJ }%gk.c7Yϗmh졙Z]ߢZ]41ey$ꢱfV ֧VCc5իEc{.z?O9}>W7h1a>Z]kjb;ևG c3zg"6SLj3"6SL.b3j6SL.b3"6S+lVnܗfjLj3"6SL.b3j6SL.MbS.M(6jM(6 jx%VVOlb 6[lb:j(6[!6T!6jM:6jMVbzb,6['[mj5ĦZTj5ĦZ VզZ VClAVCljuPmjuV/MMzզZ VClAVCljuPmj5ĦZTj5ĦZ fkuPlV jTT'[mj5ĦZfk5PlVZ fk5AlVCZ VզZ VJlV3l.PlVCZTj5ĦZ VզZ VClAVCljuPmjuV?^/MMzզZ VClAVCljuPmj5ĦZTj5ĦZ VզZ fkuV?r_jujdMbSTjSTlbj(6[lb 6[!6Z=%fkuYlVOlb 6[lTjST!6T!6jM:6jMVTDZuZ]ƦZ=jST!6T!6jM:6jMbSMbSTjSTkMu} lelՓ6jMbSMbSTjSTlbj(6[lbVT_ܗZ]Փ-6[lb:j(6[lbjM:6jMbSMbSl~侄l.cSlVCljuPmj5ĦZTj5ĦZ VզZ VClAVClյ¦Z=@㵠26Vj5ĦZ VզZ VClAVCljuPmPlVCZfk5յ¦Z~626Vj5ĦZ fkuPlVCZfk5PlVZ VClAVClյ2Α_HVoOٟxϒVZ=fg VCg&j_7S.clV/k,¾uH2+ȩИp>hWƄיSsﶩ0?VCcI::h,{MƄjuVhS.cSlVCljuPmj5ĦZTj5ĦZ VզZ VClAVClյ¦Z626Vj5ĦZ VզZ VClAVClPlVZ fk5AlVCZ]+lկ[K`S.cSlZ fk5AlVCZ fkuPlVClAVCljuPmjufkb,6['[mj5ĦZTj5ĦZ VզZ VClAVCljuPmjuVs626Vj5ĦZ VզZ VClAVCljuPmj5AlVCZ]+lGK`S.cSlVCljuPlVCZfk5PlVZ fk5ĦZTj5ĦZ]+Z=Nb,6['[lVCZ fkuPmj5ĦZTj5ĦZ VզZ VClAVClյ¦Z626Vj5ĦZ VզZ VClAVCljuPmj5ĦZTj5յ¦Z=εTT'[mj5ĦZTj5ĦZ fkuPlVCZfk5PlVZ VJlkAjbSbS.M(6jM(6"6SL.b3j6SL.b3"6S+lV/ꅱZfjuElVCZ]fjuPmVZ]fj5TElVZ fjuՋ6S}V/ꝭ6SL.b3"6SLj3T!6TbSTbS^Z=V/ŦZŦZ]juQljuQlEVClEVZ fjuElVCZ]fjb%6Os_Bl c3zg"6SLj3"6SL.b3j6SL.b3"6S+lVgK`3zalVlZ]fjuPmVZ]fj5TElVZ fjuQlEVClEV/VLt?^ RfjVElVŦZ VŦZ]j5ĦZ]juQljuElVCZ]fjbedê՟ڟqRVӏˍɶ?|j_TjS:hk1S1|Z _e^i|Z S]:h;$Z mZ m`Vy[Za3>ꅱZfjuElVCZ]fjuPmVZ]fj5TElVZ fjuՋ6S?ܗfjLj3"6SL.b3j6SL.MbS.M(6jM(6 #;%Z06SwTbS.MbS.M(6jM(6"6SL.b3j6SL^ĦZ=>s_Bl Mzg"6SLj3"6SL.b3j6SL.b3"6S+lVwK`3zalVlZ]fjuPmVZ]fj5TElVZ fjuEVClEV/VL_//ꅱZfjuElVClEVŦZ VŦZ]j5ĦZ]juPmVZXMZTwTbS.M"6SLj3"6SL.b3j6SL^Z}VꅱZfjuElVCZ]fjuPmVZ]fj5TElVZ fjuQlՋ6S3ꅱZfjuElVCZ]fjuQljuQlEVClEVŦZ VZX-Vfkdj PlVZ fk5ĦZTj5ĦZ VզZ VClAVClյ¦Z=3㵠26Vj5ĦZ VզZ VClAVCljuPmj5ĦZTj5ĦZ]+lGK`S.cSlVCljuPmj5ĦZTj5ĦZ fkuPlVCZfk5յ¦Z}6llZ fk5AlVCZ fkuPlVClAVCljuPmjufkbMzզZ VClAVCljuPmj5ĦZTj5ĦZ VզZ V j8ֽׂZT'[mj5ĦZTj5ĦZ VզZ VClAVCZ fkuPlV j'%VVOT!6j(6[lb 6[lb:jMbSMbSf݋Z8{!za-+g=~fxs~Nj|etetד:kNSNSTST!: :[l:k:ǫBetetד:k(:lk(:lꔯ!:kN::k2M?3Q'_~k{&벡Ou٘ll5u5?{,O ykw_| ^r|tm8zcN54&F|4N撻zlytC5q|mW|Q|]F|]F|=٪S蔯!:ꔯ!:kN::kNSNS蔯SS~suudNS蔯S蔯!:ꔯl:k(:lڮNz|7)_)_Egdk(:lk(:l蔯!:ꔯ!:kN::kc$e|]F|=٪S蔯!:ꔯ!:kN::kNSNS蔯SS &:2:2:V5D| )_U| )_CtA)_CtuPuPt6_C|Dg]_瞛D蔯蔯蔯'[u5At6_C| EguPt6_C|Dg5D| )_U|m|y&l.ll| Eg5D|T5D| )_U| )_CtA)_CtuPuv}u&_+Rcy//_/lEzac=Dzgۿ=~2/h(t|| ]~ l{._ Y.^f5t~t1|TouMn?qVE{.\/'_C/L~=qԙ|0:FgVEt&_љ| UguEt&_Cՙ|]DguPu&_љ|]Dg5Tՙ|&:FgL٪3":L.3k:S.NS.N(:kN:c!$BgL^Xt;[tE)_E| )_E|]5D|]DguPu&_љ|]Dg5Ttc$¢S^;[u&_љ|]Dg5TEt&_љ| UguEt&_Cՙ|]DguPu&_wWgM"t&_/љ|UguEt&_Cՙ|]DguPu&_љ|]Dg5TE)_E| )_wWg8&:FgL٪3蔯!:蔯S蔯S.NS.3k:锯Q!7D|蔯uQtEt&_Cՙ|]DguPu&_љ|]Dg5TEt&_љ| Uguw}u׷wnS.S.Sl)_CtuPu5D|T5D| )_U| )_CtAt6_)_߯INNNzU| )_CtA)_C| EguPt6_C|Dg5Pt6_U|m|=Ul.Pt6_C|Dg5D| )_U| )_CtA)_CtuPuv}uh>^j.S.Sl)_CtuPu5D|T5D| )_U| )_CtA)_)_?& 5_)_)_Oꔯ!:kN::kNSNk(:l :ꔯxU,:ˢzEg5Pt6_| Eg5At6_CtuPu5D|T]Og8{ 5_)_)_Oꔯ!:kN::kNSNS蔯S蔯!:ꔯꔯfNNNzU| )_CtA)_CtuPu5D|Dg5Pt6_|mW|xJtetetד:k(:lk(:lꔯ!:kN::k~JOqd_3Q'_c?w|]v?j.o?s<zoӯ::h,wyկm 4 puuLx:!7·Acӵkh 3R_Cd>Y3>qqy}X}e|e| ؓ>lOSOSS!>!>lO<T'[}* 6ħT 6ħ `ق g 6-A|`Cق g v`f>l>l.&MP|6aCلg6MP|6aէ )aC|JA)aC|Jvg8xw+g6gvvdO SÆ԰SÆ԰!>5԰!>5lO ;>5lO Sî3>55+acaa)bO!>ElO;>ElOSOSĆlĆF:S~>=i%>El>E2>E2>UV*6P|bي g+6A|bCي g+vP}*6ħ]gي=e!>elO;>elOSƮ3>eݳVSS.S.SǞlcC|:vP}:6ħT:6ħ cէ cCَ]g|دħէ]Ƨ]Ƨ=SȆ!> >lȆ!;φl(>l!φlO!!{^ׇ1>!,>['[|dCْ gKvP}*J6ħTJ6ħ dէ dC|*uƧ~zJ|*X}*e|*e|Jٓ>lO)SO)SʆSʆ!>!>lO)s>Ԕէ]Ƨ]Ƨ=SˆԲ!>Բ!>lO-;϶l(>۲l-϶l(>۲O-{v>Ԗٖ]me٘=1l(>l̆1!>lO1;>lO1S̮lrB|6fc)f)ffOT!>lO5;>lO5SO5S͆TS͆T!>:35]>^R35{a|f/읭>L.39">LΆ39!>S^=ܹgrvY}&g/񙞽ŧ]zvQ|zvQ|EgC|Eg gzvE|g/'vzh}G|Yz6QUI.>egN.sΆgOp ڳk^mφӷg]ƄИp&==~@u;lHφcv*=ڎȩgmپz64&jֳ1ŝ]g|}X}e|e|ٓ>lO=SO=SφԳSφԳ!>Գ!>lO=Գ/ħէ]Ƨ]Ƨ=SφԳ!>Գ!>lO=;l(>۳l=l(>۳O=sqI|X}eٞ]ٓ->۳lφ=;l(>۳lO=SφԳSφԳ!>:챼&l2>2>Vz6ħ gէ gC|AgC|zvP}z6ħ]g|[||}X}e|e|ٓ>lO=SO=SφԳSφԳ!> >۳lφ=Lg7L^ 3={gԳSφԳS.O=S.O=(>l>ӳL.3={qzs;|e| O={aglg]gz6TE|g gzvE|gC]gzvً3>ӳ8gzvY}g/񙞽gzvE|gC]gzvP}g]gz6TE|gŧ83=y$>ӳ3={a|g/읭>ӳL.3=S.O=(>lO=(>Գ!>ԳL^ŧ=k7}e| O={aglgŧ]z6TE|g gzvE|gC]gzvً3>ӳǚ&]V 3={a|gl]gzvP}g]gz6TE|g gzvE|g/LtI|ggzL^;[}g]gz6TE|g gŧ]z6ħ]zvQ|ً3>ӳhs>gg/,>ŧŧ]zvQ|zvQ|EgC]gzvP}g]gz,>~ݧ]V 3={a|gl]gzvP}g]gz6TE|g gzvE|g/Գgx}=O=O=O={է gC|AgC|zvP}z6A|gCٞ g{vgM}gcgggOlφ= >۳lφ=;l(>۳!>Գ!>lO={PKn=YNcub/halfred_tiny_truelight.cubUT +MWMUx}R Nx_%(ߗ ٙN)cr vڨ!^3oi$\MK:y.Ws6C- @PyF;%6eCXaKb #+Ö%\ZyÖqʹʯlWnTGFC QPKn= W7"cub/halfred_truelight.cubUT +MWMUxnc͚Xy^E57R$5vO}.U훔xVd88\HrK /?o??~?>W_Ͽ߮__?tq+~xow7;3Y4Yw>Yw1Y4Ywt}]>>⎮ceqGϲxϲϱϲ6\x}Xя wg,h,},c,h,,;}}]>nce@ceqGcep⁾aqG?.Xџϲxϲϲϲxϲ/Ye,h,:زgY,;3Y4Yw>Yw1Y4Ywt}]>>⎮ceqGϲxϲϱϲ1\x}Xя wg,h,},c,h,aqGϲxϲgYm,h,sL,~އ}1wg,h,;,,;:>.ce@ceqG1鲸gY>⎮ceqGϲxϲƖůp⁾aqG?ߵXџϲxϲϲϲxϲc,2Y4Yw>>>[nއ`qG>⁾&>>>>~~gY<ИtYu,6Y4Yw9&]> ,;R}1w>Yw1Y4Ywt}]Ƥ>⎮ceqGϲxϲ,~͛|跏X=菒X=菕X}w}/:[WzՃ^/:[WzKWk/W:suÛ/:[WzՃ^/:[Wz~bEsÛ\}ѹߺzՃ~=~A/ Ճ~Ճ~]W ?zՃ/5X=A7W_tuo]=euE~AsuߺsutկC~txs~xsÛ\}NՃsuNՃ~Ճ~]WG?zՃ/ՃՃ~t]=A/suE~Asuߺsu կFcX=AO?W_ǛOt]}џ3p|A/suE;]Wzt]}cNՃ~;V 럾ROE|slumq]o۹ܶs}MA۹`>k l:^_y9ʫh*ESh*ES趝T)u*E۹NS'?< 4 4T+@Ch 4Tm*}l*ESe\Sh؋JT)*AJT)*AJT)m:U>s*AJvS%TpyVh 4T@CeESeJv2vR4Uz5U8* JTh 4T@c@\@۹JT};T)*'z5EhMShMShݶs*E۹NS};שtZ~7~Vh 4T@CeR4U*ݶsM>sSM޷sM2N~5 4T*ESe2P)* n۹@۹JT};T)OW*Jѩr 4URt+]s*@\=e 4 4T@CeR4U*ݶsM>sM2vR4UOW*Jѩr 4URt+]s*@\:fWe2P)* {M+n۹@۹JT};T)*@Ch 4T*ESe1iv2vR4Uz5U8@S^):U2TWN{evS^貝TW~@Ch 4T*ESe2m;Tc;T)*o*ESe7z;*}LЏD*},2ѱGe>s,2v~Tɿ{hz~*'2=y"D"=O[ 2=y"D\'2=Odzh>q򯯴JYHϪU):sEzVJPgULϪZYeO 3*Q)@gT2=RLϨJT)2=RdzV%(ҳ*EgULϪEzVJO~;ҳ@Ce 3*Q)@gT2=RLϨh12P@gT"=2LϨEzFe 3*'zR4ULϪU JY"ӳ*AU)2=ғhYe2LϨEzFe 3*Q)@gT4F@gT2=RLϨ dzF(3*Q'?Ѱ*ESJYHϪU)2=Y"ӳ*=.Uh@gT"=2LϨEzFe 3*'+M{(ҳ*JQgUHϪ+EUW:fWe2LϨEzFe 3*Q)@gTtbzFe 3*Q)@gT2=RLϨh 4UHϪ+EUW"=rEzV^):kO)gT2=2HϨ dzFe 3*EQ8oVLdz^T&2=/* Ez^T&2=/*"=/*y>2x*'2=|"D2y"H'n2=|"D󩌓*ES*EP 2=J9THϡdz"s_@JJ DzVec;YHϪU8^OEhC*AP)"=J9TLϡRDz@?g@gU"=RdzVe ҳ*U)2=2Yq-[U*UJYHϪ DzV@gUO EhC*AP)"=J9TLϡRDz@Og@gU"=RdzVe ҳ*U)2=2YqͯQe2YHϪU@gULϪ DzVeD{er*@PW"=2u;9T/sVeO ҳ*U)2=2YHϪU8@S^):UHϡr Dz{ev.s+E_| t2P@gULϪ DzVe ҳ*EgU"=2N~2Uh DzVe ҳ*EgU"=2Y"ӳ*U'?^h+E29THϡr tez{TW~zO!=2YHϪU@gULϪ DzVe7zEz^U&"=*WLϫDUe"󪲐yU̓螟@Lͧ2y"@'Oe @'2=Oty"DS'?kzQ)2=tU JY"ӳ*AU)2=ғ}NSe 3*E+"3*EQ@gT"=2qiU ZV)z}U\U)2=Y"ӳ*=ٟU2=R4U2=RLϨ dzF(3*Q'?Ye 3*ESe 3*EQ@gT"=2q~xQ)2=tU JY"ӳ*AU)2=ғh22HϨ dzFe 3*EQ8ר22HϨ dzFe 3*EQ8@gULϪ+۹"=r tY{Δ@gT@gT"=2LϨEzFe 3*''*EgUN"ӳ*AU)2=RdzV%(ҳ*EgUz] dzFh dzF(3*QJQgT2=2N~3*QJQgT2=2HϨ dzFeDJYSJPgULϪU JY@SLϨ dzFe 3*EQ@gT"=2qyQLdz^TLdz^T&2=/* Ez^T&2=/*+s}Oe HODz>x*E2y"H'n2=|"D󩌓5vC%*ES%*EP)"=J9THϡғh)P*U)2=2м@LϪ DzVe ҳ*EgU"=2N~qbRDz sM sC*AP)"=JO~9*U)2=2{N^_I"ӳ*]sU8)U"=RdzVeRdzVe ҳ*U)2=2YqzQ)"=J9TJ9THϡRDz sC'?? DzV@C@gU"=RdzVe ҳ*_@gULϪ 4TLϪ DzVe ҳ*EgU"=2N~29THϡr tl2=2u;9TS^9S*U)2=2P)2=2YHϪU8@PW"=2б*@\PWN{u̮@gULϪ 4޳@gU"=RdzVe ҳ*yO!=2YHϪU@gULϪ DzVeD{e s+C^ez{ev.s+E{ YHϪ DzV@gU"=RdzVe ҳ*[/2yU,dz^U&"=*WLϫDUexe.y~*ODz|"HO4@L'"=躝|"Hͧ2N~O_THϡtC%*EP)"=J9THϡғh*U)"=RdzVe ҳ*U)2=2Yq"s*EP 2=J9THϡdz"s2Y2Y"ӳ*UJYHϪ*U)Z'@gU:sUJYHϪC%T)"=J9THϡRDz sC'?Ye ҳ*ESe ҳ*EgU"=2Y"ӳ*U'?> DzVh DzV@gU"=RdzVe ҳ*'+C^*@v.s+]sC^):k2UJTJYHϪ DzV@gUOW"=29T\PWn2=Rt@1*U)*U)2=2YHϪU8fTe ҳ*ESe ҳ*EgU"=2Y"ӳ*U'?^*@PW:sC^躝*J_}zO*U)*U)2=2YHϪU8oV[e"ЏDUe!2yU,dz^U&"=*+'zcOe DSsM"ӳ*U'?^*@PW:sC^躝*J_͔@gULϪ DzVec;Y>sM"ӳ*U'?^*@PW:sC^躝*J_] DzV@gU:sUc;T)2=2YqݼU@gULϪ DzVe\S@gUO4OC%*EP):sCc;שdz"s)SHϪU@v.ӳ*}l*EgU"=2NU"=*WHϫBUe"2vLϫDUexe. Dz>y"H'"=Odz>x*'2=c;|*Eo2=O48^?yQ)"=J9THϡRtl2=JvS%*EP|2Y"ӳ*Uh DzVe\S@gUOQJ9TLϡRDzc;9T>s*AP)"=JO~9*U)2=2Y+HϪ kU8(2Y"ӳ*UezVe\S@gUO4OC%*EP)*EP)uC*=Ϊ DzV@gU:sUc;yVh@gT"=2LϨEzFe 3*'z|EhU)2=Y"ӳ*EgU"=RdzV'?М]@gT2=RLϨ dzF(3*Q'?I@Ce 3*Q)@gT2=RLϨh^9U)*EgUJYc;WgULϪEzVJO~< 4T2=2P@vHϨ dzF(3*Q'?U LϨ 4T2=2б+3*Q)@gTɿ*EJPgULϪ۹"=RdzV%(ҳ*EgUz]^YeO 3* LϨ tl@gT"=2qRY{(ҳ*JQgUHϪ+E_| t}2P@Ce 3*۹"=2HϨ dzFe@7)gT2=2P@vHϨ dzF(3*Q'?^h+EUW"=rEzV^)Rt@SLϨ dzFe2\QJQgT2=2NU2=/*U&2=/*۹"=/*"=/*y㕹- 4@L'Oe D2y"H'n2=|"D󩌓h RDzRDzc;9THϡdz"sZ*}Uh DzVec;YHϪU8^?TyQ)*EP)*EP):sC*AP)"=JO~9* HϪ 4T"=2б@gULϪ DzVe@Ǐ* HϪ 4T"=2б@gULϪ DzVeDJT)"=JT)"=Jѱ*EP 2=J9Tz-? 4T"=2P@v.ӳ*U)2=2YqͯQe2Y@gU*UJYHϪh RDzRDzc;9THϡdz"s_@JYHϪ tl2=2Y"ӳ*U'?^h+EPWLϡrC^)2=Rt@* HϪ DzV@gU"=RdzVe ҳ*yO!=2YHϪU@gULϪ DzVeD{erC^)2=Rdz{*JѩrBzVe ҳ*U)2=2YHϪU8oVLDz^U&"=* WHϫDUe!2yU'?^9=?SROU"=RJ۹"=RdzV%(ҳ*E\_| t}Ye2LϨEzFe 3*Q)@\Se@7)gT2=2HϨ dzFe 3*EQ貝^KM"ӳ*EgU"=RdzVJPgU.۹{LϨ dzF(3*QJQgTl:U2=/*LϋBLϋDEeHϋD\_|W}DO4@L'"=躝|".۹S'?//*EP 2=JT 2=J9THϡdzvS'?rSxVJYJYHϪ DzV@\SeD׷"sChC*EP 2=Je;שғhS? DzV@=LϪ DzVe ҳ*EgUl*Z>xVJYJYHϪ DzV@\SeDJ9TLϡR4ULϡRDz"sC貝T|$2Y"ӳ* "ӳ*UJY.۹8ר2Y"ӳ* "ӳ*UJY.۹+qHϡr Dz{ec;9T۹Lϡr*ʙ2UJYJYHϪ DzV@\SeD{e s+C^ez{ev.s+Ez,U"=RdzVe**EgUn2=2YqݼU@gULϪ DzVe ҳ*EgU"=2N~Z/*EP 2=JT 2=J9THϡdz"sBzVe ҳ*U)2=2YHϪU8oVLDz^U&"=* WHϫDUe!2yU'?^oOe HODz>y"SyTŐJ9TN"sC*EP 2=J9Tz-^> DzVhJYHϪ DzV@gUO;J9TN"sC*EP 2=J9TzUJTJYHϪ DzV@gU܎U"=R4U"=RdzVe ҳ*U)2=2Yq*EP :UHϡdzv.s]sC*=ϑU"=R4U"=RdzVev.ӳ*]sU8ר2Y2Y"ӳ*ݶsU躝@gUOW"=29T\PWn2=Rt@3e2Y2Y"ӳ*ݶsU躝@gUOW"=29T\PWn2=Rt@1*U)*U)2=2m;Y۹LϪ DzVeOTJTJYn۹LϪ tezVe ҳ*'+C^*@v.s+]sC^):kO)gU"=2Y"ӳ*ݶsU躝@gU_Ue"2yUYLtez^U&n2=*Wy;Sq{Q)2=tU Jm;WgU۹"=RdzV'?;ɳ@gT+LϨEzFevHϨ tLϨ"ӳ*AJYHϪݶsEzV躝+ҳ*EgUzUJTJQgTm@\Q8+ճ@gT@gT"=2m;WgTn@gTO4OU :ULϪEzV趝+ҳ*E\U)2=ғhYe 3*ESe 3*EQ趝+3*]sEzFe 3*_@gT@gT"=2m;WgTn@gTOW2=r dzV^Y{evHϪ+E_| tLT2=R4U2=Rn۹"=2u;WgT2=2N~qbRdzV%T)2=Y"ӳ*EgU"=RdzV'?u̮@gT@gT"=2LϨEzFe 3*yO1=2LϨEzFe 3*Q)@gTO4ߏ*EgU [;I۹"=RdzV%(ҳ*EgUz}zO1=2LϨEzFe 3*Q)@gT_Ee"2yQY(2yQ,yQ̓,S|"DO4JD Dz|"۹L'zezh>q~|Q)"=J9TJ9THϡRDz sC'?Ye ҳ*EgU*EgU"=2Y"ӳ*U'?o/*EP 2=JT 2=J9THϡdz"sZ~{VJY{U@gULϪ DzVe@*U)2=2P)2=2YHϪU8 "sChC*EP 2=J9Tz-7gHϪUhU@gULϪ DzVe@kTJYJYHϪ DzV@gUOW"=29T\PWn2=Rt@3e2Y"ӳ* "ӳ*UJYHϪh Dz{e s+۹Lϡr tez{cvU"=RdzVeEgU"=2Y"ӳ*U'?{ YJYJYHϪ DzV@gUO4OC%*ES%*EP)"=J9THϡғs@gULϪ C!U:sUJYHϪFoտHϫD* WHϫDv.2yUYLDz^UɏWOe%=?TS趝kMc;|*Ekz~F۹S'?RT Zs-9UJm;ךS躝kMϩRtuZ= R)Zs Rh tεR躝kMϥ2e;T'?돤%=JКShIϩR4Un۹*E\kzNvS'?{³@Kz.5=@Kz.@\kz.۹\*]sMq-= R)Zs Rh tεR躝kMϥ2e;T'?o/*EKzN5=JђShݶs9U۹*E\JO~2ВKhMϥ2ВKe2m;ךKev5=@\Se@?_S*-T\*-T*ݶsTnZs t5UOWZs+-9URTW*JѩrxOYs 4T\*-T*ݶsTnZs t5UOWZs+-9URTW*Jѩr~^*-T\*-T*ݶsTnZs t5Ut+-T\*-T*ݶsTnZs t5UOWZs+-9URTW*Jѩr+-T\*-T*ݶsTnZs t5UuqLgUZӳ*-Y^BkzVev5=2e;ʉ7PKn=`Q:"cub/halfred_truelight_log.cubUT +MWMUxM+Kw^?ln0,Hdٰ%{$oD2ywY׹Uܱ,Zw/o.?w_?\?ÿc{<G.>hnotޮoÎupx}yaGu}9vt_;zÎrᰣy;zݮ{ڿtmy<.v~^ =_˲;z>thv}.M=neaG{鰣z>ߞ[L-Nm~|hq?;Z^8~}rÎthZÎĦÎ^z_^MCC鰣y:4lWtQ^ vvaG~/ݯaGz}b:4t94޷9O=~[sd:hޏ =[kg:43vU m鰣׺= B_;j#CCm wphy_g:hko gӡ]o ޚA;ZrP WLmv~CCˎCCph]pQCCz\84Z;uph>' mCC[Evthx7 ?K$>w ]¡mm/ У~?2juphskI;z¡X.ڶm¡W9y.˅CC׵_/¡>`.j#< -phCCk{jΡmi=<z-nϺn5ڝ794to! =}thhY]84\e:ӡֽ[>= pCßsݶ ЭCCe_.zCCKE<94 vxOl:4x:4@kk_BjoօCCR1 ]84xl#ӡ>b:4|ǵ7m}|i9l\iK{|=|/N[Rs 9Lӟm7p}o/i{N]i}iM_o vmh/O;ݖg{Nku|smۏL=~:%vzk oڟK8>|i[unzroN;} ~l>i~Nӷv=ۯ1vͧ?=}cs O%v~N;mkk}^M_}8 |}|i[^i϶g}|z/N׶<|vo1p}jMͧ?׶ܗ} ^n=i[]O;ݯGpzkvwihI8q}?2tm>tiwOo?w0vl?_o>t޶7}}Ci}Oo>m>!^9ӛӟs׻۔tmK8z[4tm/1v_̧7}>~vzoϟK8i>M7ZNm77m\\vvNo|kyl:}y̧7}n۝Ooޯ?ǦN׶u޴|zeOoNow=籼ͧ7]\ӛtzm>׫ ͧ7m7޴x~mϧ7m̧7]owNo~nh>}h[pz)O֧כN>|ts]{, ?'?i=:{QKhruQvUu{rV@r㧜 ,ZΏL)GvN*EP :TJP :TJVu=ʹC^u*̷ʀ G**ECe@]e@[9PУk ˹JPn~Ih Ch Chm\JѣP :T\JСқh22R4TUԟh ?V5T(*ECe@rR4Th22R4TUUʀm\㑀\Ch ^5Tp?TJP :TJP :TJVu=ʹC^u****ECe@]e@]h h+*zs[ ˹JPnoTPWPW)***ECe@]e@[9PУk ˹Jx$@^PYCeW4T{e@CeW^Zuʀ\z|tPW)***ECe@]e@[9PУk ˹JPn~z hJѡ+*2+Ez h-:T{e@rCeW}vUUUʀʀs Gʹʀ\Ch ^5Tpm^PWPW)***ECe@}Ҁr2G9P)*s 2@^PYCeW4T{e@CeW^Zuʀ\z|{e@]e@]h  um\Ce@rR4Tt/*ECeNg}TFQ_*#2TFs2TF(KeB^ʄRoȥk~UdzQH2=w@O'dz(L\!=dzxU??ULϪJY+gULϪJY|G= LϨ JQHϨ ʀLϨʀLϨ 7?R4TLϪU Y"ӳ*EgUBzVJo[e@]e@gTdzF(gTdzFe@gTBzFe@gTh522 3*2=R3*2=2 3*E!=2 3*t}R)*EgULϪJY"ӳ*A!=RdzV7[e@]e@gTdzF(gTdzFe@gTBzFe@gThUUdzFe@gTBzFe@gTdzF(gTdzFeR4TLϪU Y"ӳ*EgUBzVJoggUԿN@gTdzF(gTdzFe@gTBzFe@gT+*Rҳ*Rҳ*Rҳ*Rҳ*R⫣ϮʀʀLϨ JQHϨ ʀLϨʀLϨ 7bzFe@gTdzF(gTdzFe@gTBzFe@gT+*Rҳ*Rҳ*Rҳ*Rҳ*R⫣{QQQ) Qn''' <<*#"=*KeDYeBYeDYeDYeBYeDYeȁOUy sGUy sG!=_;ʀL\!=t/ 鹣 7?Ϫ'"ӳ*AJYU)2=RdzV%(gULϪ;ʀLϨG2=R3*2=2 3*E!=2 3*t'"ӳ*AJYU)2=RdzV%(gULϪ;2 3*ECe@gTBzFe@gTdzF(gTdzFe J 2=R3*2=2 3*E!=2 3*4*EgURdzVh) Y"ӳ*A!=RdzV7UdzFh JQHϨ ʀLϨʀLϨ 7Ѥ[e@gTʀLϨʀLϨ JQHϨ p{e@gU{e@gU{e@K9WHϪʀrUY_)Q)*2=R3*2=2 3*E!=2 3*TUYUY-\!=+Z˹BzVeW_|uU2 3*E!=2 3*2=R3*2=2|G{QQQ) Qn~|JYCJPHϪU)2=ҳ*EgUz)Q)*2=R3*2=2 3*E!=2 3*5/2"2"2''' <<7Ϸ~UDz>y H"=dz>PUDz| r.\ƫ2@ŝTHA%THAh)2="sP 2="sPw4[e@gULϪ ʀr.ӳ*"=RdzVe@gUWJ9J9-\RDz*ARDz* JYURezVe@rRdzVe@gUh;*"=RdzVe@gUsUУkUY'J9JRez*ErC%THA7ʪ JYURezVe@rVʀ\gUh7*"=RdzVe@gUsUУkUYʀHAeWDz*2T{e@k99J򋯎FTe@gULϪ ʀr.ӳ*zs "ӳ*"=2@^9ʀHAeWsz h-2=^)Z~gWe@gULϪ ʀr.ӳ*zs "ӳ*"=2|G{ YUY"ӳ*"=2G9P)2=2 ҳ*ԟOP)"= sP)"=T\J9Jo2UY"ӳ*"=2ʀ\CʀHϪ 7AԿHϳʈHϳʈHϳʄLϳʈHϳʈ\L<<7?~UDz>y H"=dz>PUDz|G9xULspsR)"= sP)"=T\J9Joj*"=RdzVe@gUUDzVe@rRdzVe@gUΓJ9J9-\R(:TLATzUY"ӳ*"=2H@gU(*EgUDzVe(2 ҳ*EgUDzVe@K9Y=ʹJYUn~|J9J9 "sP)zs*ARDz*WVe@gULϪ ʀr.ӳ*zs[UY;Z·oU)2=2 ҳ*Z~ezVe@rUt/2=2x+"=^9ʀr.sPY\砲+Ez|_2*"=RdzVe@gUUDzVe@rRdzVe@gU+"=^9ʀr.sPY\砲+Ez\;*"=RdzVe@gU ʀHϪUY;SHϪ ʀHϪUYU)2=2 ҳ*Tz T{e@CeWLAeWLAeW^rO!=2 ҳ*"=RdzVe@gUDzVʀHϪ 7AԿHϳʈHϳʈHϳʄLϳʈHϳʈHϳʄLϳʈHϳx5}*2=dz(L; y QHZ˹Bz<鹣 7?y?U Y"ӳ*EK9WHϪU Y"ӳ*?| LϨ JQHϨ ʀLϨʀLϨ 7?c'RdzVJPHϪU)2=ҳ*EgUzUPWQ) QQ;22 3*2=R3*2=2 3*E!=2 3*4VNUJYRdzVh) Y"ӳ*A!=RdzV7\UUdzFe@]e@gTsʀLϨʀLϨ 77 h|QPW-\!=2 3*E!=2 3*͟*EGJPHϪU)ZʹBzVJPHϪUw<ʀ ʀʀLϨ h) Q) Qn~z hJQHϪJQHϪJQHϪJQHϪJ򋯎;ҷʀʀLϨ ʀrQQ;SLϨ ʀʀLϨ h) Q) Qn~z hJQHϪJQHϪJQHϪJQHϪJ򋯎^)gTdzFe@]e@gTsʀLϨʀLϨ 7AԿLϓʈLϓʈ>*#2=O*#ZʹBzTFdzT&2"2|d>r_We@LʀH_2=|| HWeR4THAhJRez*Edz*Eқh߿UԿN@gUUDzVe@K9YU)2=2 ҳ*tIhJP)"=THA%THA7ј]uUPWY-\gUDzVʀHϪ 7ouUPWY-\gUDzVʀHϪ 7?P>AhJP)"=THA%THA7ouUPWY-\gUDzVʀHϪ 77 ʀʀHϪ ʀHϪUYvJP)"=RDz*EK99J9Jo,7 uJYURezVe@gULϪ p{e@CeWLAeWLAeWLAeWLAeW_|uUUDzVe@gULϪ ʀHϪUY;SHϪ ʀHϪUYU)2=2 ҳ*T ^)2=^)2=^)2=^)2=^):T{=ʀHϪ JYUY"ӳ*"=2]S"=*#"=*#"=*2=*#"=*#"=*2=*#"=*GWe@U鹣2=dz(2 sG!=dzh- y @ƫ2@R4TLϪU Y"ӳ*EgUBzVJoiVP:QQQ) Qn~&~R)*EgULϪJY"ӳ*A!=RdzV7ј]uQQQ) QnoV**2=2 3*E!=2 3*2=R3*zs-?R4TLϪU Y"ӳ*EgUBzVYε⫣鯻**2=2 3*E!=2 3*2=R3*zs-hUUdzFe@gTBzFe@gTdzF(gT,+*Rҳ*Rҳ*Rҳ*Rҳ*RkuO1=2 3*2=R3*2=2 3*E!=2g94$JPHϪ*EK9WHϪU Yg9򋯎**2=2 3*E!=2 3*2=R3*zs ;SLϨ ʀLϨʀLϨ JQHϨ YεkIhU)2=ҳ*EgULϪJѳkWG/3*2=2 3*E!=2 3*2=R3*zs-k_IeDIeDIeB!=O*#2=O*#2=O* yRѳkWd | @_"2 @sDz>гk*tPzR)"= sP)*ARDz*Edz*ErC7Ѵ)| JYu"ӳ*"=2 ҳ*EgU,*t^N*Edz*EC%THATLAYu;voU)2=2EgUDzVe@gULϪ Y5ThCǷʀHϪUPW)2=2 ҳ*"=RdzVe@r2@"sP 2=dz*ERDz*AR,:TzMVY"ӳ**EgUDzVe@gULϪ Y5ThUDzVʀJYUY"ӳ*zsGTz T{e@K99ʀr.sPYCeWʀHϪUPW)2=2 ҳ*"=RdzVe@r2@^9ʀHAeWsz h-2=^):T{府*"=RdzVe@Ut~$UZezVe@gUhsO!=2 ҳ*"=RdzVe@gUDzVʀHϪ 7?GRDz*AR4TLATHA%THA7=ʀHϪ JYUY"ӳ*"=2]S"=*#"=*#"=*2=*#"=*#"=*2=*#"=*G& | @Dz| <@\Dzh*t$sR)"=CTLATHA%THA7[e@gU#U)2=2 ҳ*"=RdzVe@gURDz*AJ9J9J9Jo1*"=R4TDzVʀHϪ JYUni;VY2 ҳ*EgUDzVe@gULϪ pTHA%P)"= sP)ʹLAh-2="sPw4[e@gUʀHϪUVezVe@k9YUnoTY2 ҳ*EgUsUZezVe@gU+"=^9ʀr.sPY\砲+E/:)SU)*"=RdzVe@[9Y\gUDzVe2 sPYz h)2=^Zez*R⫣ϮʀHϪ U)2=2ʀr.ӳ*"=2gTY2 ҳ*EgUsUZezVe@gU+"=^9ʀr.sPY\砲+E/:zUYU)2=2ʀr.ӳ*"=2]S"=*#"=*#"=*2=*#ʹLϳʈr.2"2|dz~UdzxUdzQHWe@[9WHZ˹Bz<鹣 7?IJСRdzV%(gUrU)Z˹BzVJo3ɷʀLϨG2=R3*ʹBzFe@k9WHϨ p?(TLϪ*EgUBzVh+ Y+gULϪ;2 3*ECe@gTBzFe@[9WHϨ h- QniV2 3*E!=2+gTsʀLϨ 7?P>AJСRdzV%(gUrU)Z˹BzVJo*2=R4TdzF(gTsʀrQ;FQ)*2=R3*ʹBzFe@k9WHϨ p{e@gU{e@gU{e@K9WHϪʀrUY_)Q)*2=R3*ʹBzFe@k9WHϨ p *EgU"ӳ*A!=RdzVJPHϪUwU2 3*E!=2 3*2=R3*2=2|G{QQQ) Qn~|T)2=40IJRҳ*EgUBzVJo{QQQ) Qn''' <<y HJ@Uy HZ˹Lsp3O*Edz*EC%THATLATzMȾUDzVʀJYUY"ӳ*"=2@O'"sP 2=dz*ERDz*ARDz*|*"=RdzVe@9LϪ ʀHϪUY;> JYu"ӳ*"=2 ҳ*EgUDzVe *Edz*EC%THATLATzMʀHϪUPW)2=2 ҳ*"=RdzVe@gUhUDzVʀJYUY"ӳ*"=2@^9ʀHAeWsz h-2=^)Z~H JYu"ӳ*"=2 ҳ*EgUDzVe2 sPYz h)2=^Zez*R⫣ϮʀHϪUP"ӳ*"=2 ҳ*EgUDzVe6ҳ**EgUULϪ ʀHϪUY'J9 sP)"="sP 2="sPw_YU)2=2/2ʀHϪUY?yVGeBYeDYeDK9yVyVyVyVo?29~U4o_9=)=)=9= h+7zsWhN^5/4^:N*ESz*Asz*ESz*ECh+sT)Z˹U\Jo[e@SzN*EszN*sRPWV52kNIe@r2@_I')=G9=G)=GRs9\sz*ErC79[e@SzN*EszN*sRPWV52kNIe@r2|GӇoM99 hJIe@]e@[9לʀr9='=˹p?QTUUUJV5Rs9=˹|GӚ2)='9='M9 h+sRZ52g9PnMRДJќʀTUs9 h-sRгk 7?PW4稲+sTY ^)sTY9=G^):T{=eJIe@]hNIe@SzN**ʹTs9 Y5T+sTYM9ʀz9Jќz*r̞T4R42)='um\szN*Z˹T,*w{e@SzN*EszN*sRPWV52kNIe@r2@^Дz hJQeW4T{hNQeWU{PYz hJIhNIe@SzN**ʹTs9 Y5T|8TF4gU&4gUF4gUFtUT&4gUFsY=˹#PKn=IM2 cub/truelight.cubUT +MWMUx}n\YtXṞ@Bb$@ 1lCb'ܪ-À˵^7׿{o_|~˿{/}W_xۿo_?可7^@Ƿ_޿~xq{|ŗ?3_}Ƌ误7^|x3?x|oƋnjork}׾޿_7^@??/|ys/oo/So׿-^}yxxW_޿}IxWѿ-^}ysW?>?߾~w-^ER[W_W_~<=ҿm@?Ȁ_noӟO֟?Y8ןqc/0Ws|纽Ϋh]*E[h]*E[1u}s]*AJѷqK%R:g T;@Kh Tzsm>ƹJV8V)*c~{Q)*E[%R)*E[%R)*EqKcR Ts]*AJ7˳@KeRUZ*YUZzsm>ƹJV8V)*c ? TZ*E[e2R)*I=ƹ;>ƹJV8V)*cRUJХRUJХRU\J8ץt}T.n~gg@Kh TZ*E[e2ck 1ε**}*E[el~1 TZ*E[e2R)*-\[eqRU6εU;2V9ߕK|W*2V9ߕK|Ws]*28ץr+?S@Z*E[e2R)*-\[eqRU6εUF]hJѥr+m]hJѥr+ǹ.]sR9ߕ5*-JVh fVh1εU*E[eo\[h/@KeRUZ*-2К4ck 1εU@ƹJVh+m])Twer+m])Twe8ץr+}s]*|WZ*-2Rhm@q28V)*}*E[elz*RBLKe_* 2moVcoV8* 27T2=odz^(FL Ezdz^(F\72=odz^h?wZJPgULϪƹ"=RdzV%(ҳ*EgU=? >O 3*Q)@gT2=RLϨoEhU)2=Y"ӳ*EgU"=RdzV_2R@gT"=2LϨEzFe 3*c L< T2=2HϨ dzFe 3*EQFvm"ӳ*EgU"=RdzVJPgULϪt ?P= T2=2HϨ dzFe 3*EQBcTh dzFe 3*EQ@gT"=2P)*EgULϪEzVJYHϪU\{VeyQJQgT2=2HϨ dzFel~ Uw(ҳ*RY])EzV|Wn}ͮ@Ke 3*Q)@gT2=RLϨ/N1=2LϨEzFe 3*Q)@gT7@[|W"=r+EU9ߕHϪJQgUw_ }N1=2LϨEzFe 3*Q)@gT_Ce"2PY(2P|,P|w֋_ ~*2y#H"=odzz*72=_|8B 7OelUnm"sC%*EP)"=J9THϡͿM^?O@gUsUJYHϪoRDz"sC*EP 2=J9T*-HϪ DzV@gU"=RdzVe ҳ*c [UZ*UJYHϪ DzV@gU7zRUHϡRDz sC*AP)"=J7@Ke ҳ*U)2=2YHϪUBcTh DzVe ҳ*EgU"=2Y"ӳ*Uh+m])Twe s@P9ߕ\P9ߕo|-@"=2Y"ӳ*UJYHϪo4ߕ]*29Twe s@q.sJ7Uh DzVe ҳ*EgU"=2Y"ӳ*U_hLUZ*UJYHϪ DzV@gU7@[|W.]*29Twe89TwR9ߕ߽SHϪ DzVe ҳ*EgU"=2Y"ӳ*UޫOHϧDSe!2T|,dz>U&"=*s \SyT2=odz^(F dz^(F\72=odz^h?^ՋJYKJPgULϪU JYn9MLϨ]LϨEzFe 3*Q)@gT_V)2=tRNƹ"=RdzV%(ҳ*EgUٟU2=RU2=RLϨ dzF(3*Q_ 22HϨ dzFe 3*EQF%^TLϪ]*EgU"=RdzVJPgULϪt ߺU2=RU2=RLϨ dzF(3*Q_h*Q)*Q)@gT2=RLϨo4ߕLϪ@gUwe8WgUwe8WgUw_ ])LϨmLϨEzFe 3*Q)@gT7Z "ӳ*AJYHϪU)2=Y"ӳ*B5*Q)*Q)@gT2=RLϨ/N1=2LϨEzFe 3*Q)@gT7Z_OU TLϪEzVJYHϪUbzFe 3*Q)@gT2=RLϨBտLχDCe"PCe"2PY(2P_T"=_B Rdzz*72=_|8B 7Oel~RDz sm sC*AP)"=J7QU"=RdzVe}@LϪ DzVe ҳ*EgU"=26XC%*E[%*EP)"=J9THϡ/gWe ҳ*EgUzSewR@q.ӳ*U_Ye ҳ*EgUZ*EgU"=2Y"ӳ*U֋J9TLϡRULϡRDz"sC*B2Y"ӳ*-"ӳ*UJYHϪ/?FHϪUhU@gULϪ DzVel~ Dz]*2m*2}*Rtʝ2UJYJYHϪ DzV@gU7@P9ߕHϡr+ƹLϡr+ǹLϡr+EUJY,2=2YHϪUBҳ*UJYHϪ DzV@gU7@P9ߕHϡr+ƹLϡr+ǹLϡr+EBzVe ҳ*U)2=2YHϪU/^|LDz>U&"=* OHϧDSe!2T_y~*/Dz|!H/@L"=_>ezBS7/*EP THϡdz"sC%*EP:ų@gU;HϪU@gULϪ DzVel~זRDzK*AP)"=J9TLϡRDzn~=*U)*U)2=2YHϪU뿞2Y{B DzVe8YHϪUF_ϋJ9T."sC*EP 2=J9T$*U)*U)2=2YHϪUBǓ2Y2Y"ӳ*UJYHϪo4ߕHϡr+C|WsC|WsC|WnN DzVh DzV@gU"=RdzVe ҳ*cwe s@P9ߕn\P9ߕ\P9ߕo|-t_2Y2Y"ӳ*UJYHϪ/S*U)*U)2=2YHϪUF]*29Twe89Twe89Tw_ }NY*U)*U)2=2YHϪU/^DSeU&"=* OHϧDSe!2T_\T2=odz^h?Lz*Oe FqH}~*cZEJХRdzV%(ҳ*EgULϪEzVJ7޳*Q)2=RLϨ dzF(3*Q5@U TLϪEzVJYHϪUڳ22HϨ dzFe 3*EQB{ U2=Rt}OQ)@gT2=RLϨoULϪ[Jm+ҳ*EgU"=RdzV_*Q)*Q)@gT2=RLϨ/t~VJVJQgT2=2HϨ dzFel~ dzV|W2=r+ƹ"=r+ǹ"=r+EZJ dzFh dzF(3*QJQgT2=26|W2=r+U9ߕn\U9ߕ\U9ߕo|-t_22HϨ dzFe 3*EQB3*QJQgT2=2HϨ dzFel~JYKJPgULϪU JYn~+e22HϨ dzFe 3*EQ/^|Ldz>T&2=* Ez>T&2=*"=*~x~*/Dz|!H/@L"=_>ezзq.Fo"sC*Eq.sC%*EP:~A2Y"ӳ*U6ezVe ҳ*EgU"=26o_THϡdz"sƹLϡRDz sC_hϮ@gULϪ DzVe8Y>ƹJYHϪ/tgHϪU@q.ӳ*}sm"ӳ*Uh}=RDz sC6ezqK%*EPڟYHϪU@q.ӳ*}s[MsU_gHϪU@q.ӳ*}sm"ӳ*Uh+C|W"= t2= t2=~k2UJYHϪ t2=28V)2=2Y29Twe s@q.s@q.sJ7UJYHϪ t2=28V)2=2Y)gU"=2Y"ӳ*UckUF "sC*Eq.s}s]*AP)"=J7N DzV@gUsUckU/^|LDz>U&"=* OHϧD\,dz>U&"=*s??H"=odzBLZOe F }sRdzзq.Fo "sC*Eq.s}s]*AP)"=J7[gHϪU@Ke ҳ*}sm"ӳ*UW/*EP 2=J9Tn\P)TLϡRDzn~=*U)2=2Y;HϪ 1εULϪ DzVel~# < DzV@gUsUckUF "sC*E[*E\J9THϡ/?*U)2=2Yn\gU[UB*U)2=2YnLY>ƹ$U6ezVel~3ߕHϡr+C|WsC|WsC|W.]< DzV@gUZ*UckUF]*29Twe89Twe89TwR9ߕ HϪU@@gU"=RdzVe ҳ*c =SHϪ DzVe ҳ*EgU"=2Y"ӳ*Uh+C|W"= Uw*Rdz])Twwҳ*UJYHϪ DzV@gU_Se"2TY|LDz>U&"=* OHϧzB?5=?Ly#B7ZOe B72=oty#BozU JY8WgULϪEzVJ7g dzFe 3*EQ@gT"=2^?RULϪU JY"ӳ*AU)2=/gWe2LϨEzFe 3*Q)@gT:~2R@gT"=2LϨEzFe 3*cSRdzVhU)sEzVJPgULϪt Ye2@gTsEzFe 3*EQBcTh$,2=2R@qHϨ dzF(3*Q}U^iHϪU)sEzVJPgULϪt }YeyQh dzFe8WgT2=RLϨo4ߕEzV|W"=r+EU9ߕHϪJ7~GzVh dzFe2n\QJQgT2=26;@gTZ*Q6LϨEzFe 3*cwer+EU9ߕHϪJQgUw(ҳ*Rt{Q@Ke 3*ƹ"=2HϨ dzFelzez>T&2=*R|Lt|Ldz>T|Ldz>T;ůr@ Dz|T"=odzz*72=_|8B 7Oel~e'TJ9TJ9Tn\P)"=J9THϡ/t*@Ke ҳ*ƹLϪ DzV@gU7zʋJV)"=JV)"=Jm*EP 2=J9T T"=2R@q.ӳ*U)2=2Y_?> T"=2R@q.ӳ*U)2=2Y*E[*E[*Eq.sC%*EP:~Q2R@Ke ҳ*ƹLϪ DzV@gU@Ke ҳ*-HϪ T"=2Y"ӳ*Uh RDzRDz89THϡdz"strSeϓ*EgU"=2m@gULϪ DzVel~ Uw*Rdz])2=C|Wn@Ke ҳ*U)2=2YHϪUBҳ*UJYHϪ DzV@gU7@[|WLϡr+EP9ߕ"sJ9TwR9ߕ߽SHϪ DzVe ҳ*EgU"=2Y"ӳ*UޫOHϧDSe!2T|,dz>U&"=*s \Sh=L EzyH2yH7sEzyT7z/^TJY"ӳ*AU)2=RdzV%(ҳ*EgUYeyQJQgT2=2HϨ dzFel~KEhU)2=Y"ӳ*EgU"=RdzV_hϮ@Ke 3*Q)@gT2=RLϨ/tYe2LϨEzFe 3*Q)@\h}=RULϪU JY"ӳ*AU)BowUZ*QJQgT2=2HϨ 9uǨ2R@gT"=2LϨEzFeqNl~ Uw(ҳ*RY])EzV|WnzQ@gT"=2LϨEzFeqo|>RWU"=RNƹ"=RdzV%(ҳ*E\Z:@Ke 3*Q)@gT2=R>ǹB3*QJQgT2=2HϨ 9u^Km"ӳ*EgU"=RdzVJPgU>ǹnw3*QJQgT2=2HϨ 9u_P|Ldz>T|Ldz>T&2=* Ez>T&zguezB\oCJ9TLϡRULϡRDz"sCsR:.gHϪUhU@gULϪ 9εU7z=^THϡdzdz"sC%*E\J7qS? DzV@kU@gULϪ 9εU:~2Y"ӳ*-"ӳ*UJY>ǹF "sChC*EP 2=J8ץ/tJYe ҳ*EgUZ*EgU"=2Y"ӳ*}smǨ2Y"ӳ*-"ӳ*UJY>ǹ;29Twe s@q.s@q.sJѥr+wTe ҳ*EgUZ*EgU"=2Y"ӳ*}sm29Twe s@q.s@q.sJѥr+﷗*U)2=2ל**EgUsUBҳ*UJYHϪ DzV@gU7zRDz sm sC*AP)"=J7wҳ*UJYHϪ DzV@gU_Se"2TY|LDz>U&"=* OHϧzgM Dzy#H"=odzz*72=_|8B 7Oel~ןd^THϡtC%*EP)"=J9THϡ/tx2YN ҳ*EgU"=2Y"ӳ*Ug"s]*EP 2=J9THϡdz"st UJVJYHϪ DzV@gU:gHϪmHϪU@gULϪ DzVel~J9T."sC1ez89THϡ/tYe ҳ*E[e ҳ*EgUzsU>ezVe ҳ*c Qe ҳ*E[e ҳ*EgUzsU>ezVe ҳ*cwe s@P9ߕn\P9ߕ\P9ߕo|-S*U)*U)2=2c@q.ӳ*Uh+C|W"= t2= t2=~k]HϪmHϪU1ezVe8YHϪͿ*U)*U)2=2c@q.ӳ*Uh+C|W"= t2= t2=~k)gU"=2Y"ӳ*=ƹLϪ t2=2Y_T|LDz>U2=*=ƹLϧDq.2T_i@L 2y#B7ZOe8WLǹ"=odz~*cRdzV%R)2=Y8WgU\U)2=/tL2N 3*EQ1\QF?(U TLϪEzV1Y8WgULϪt UJVJQgTzsEzFe8WgT2=26qR= dzFh dzF(3*=ƹ"=2}+3*Qh}=RdzV%R)2=Y8WgU\U)2=/tYe 3*E[e 3*EQ1\QBcTJVJQgTzsEzFe8WgT2=26|W2=r+U9ߕn\U9ߕ\U9ߕo|-tLT2=RU2=R\Q>LϨo6*EgU."ӳ*AU)2=RdzV%(ҳ*EgUkvU2=RU2=RLϨ dzF(3*Q_bzFe 3*Q)@gT2=RLϨoULϪ6l$RtJYHϪUbzFe 3*Q)@gT2=RLϨBտLχDCe"PCe"2PY(2P_S|!F /JB Dz|!\ }2=oF3_THϡdzdz"sC%*EP:!{VJYJYHϪ DzV@gU7zE*AP)*AP)"=J9TLϡRDzn~GgHϪUh}"ӳ*UJYHϪ/t2Y"ӳ*-"ӳ*UJYHϪoP)"=J9TJ9THϡRDz sC_XU"=RdzVeRdzVe ҳ*U)2=2YǨ2Y"ӳ*-"ӳ*UJYHϪo4ߕHϡr+C|WsC|WsC|WnN DzV@K@gU"=RdzVe ҳ*cwe s@P9ߕn\P9ߕ\P9ߕo|-t_2Y"ӳ*YdzVe ҳ*U)2=2Y)gUZ*EgUZ*EgU"=2Y"ӳ*Uh}=RDz sm sC*AP)"=J7UJY^QHn\gU"=RdzVe ҳ*c{/2/LϧDSe8T|,dz>U&"=*sSHh=3=?#=?#=?3=?Tzs}sRtgmLOh?^#=JЙSHϩRU\gzN8יSsR:= tR):s tRh :s t:s 9εU7z'EHϩtT):sm8יS>uT)TU:sT:s TzsTsT*c ?= tR):s tRh :s t:s 9εU7zEHϩtT):sm8יS>uT)T3Ye#=JљKe#=@Ke8יKe8יKeq26S*T\*TZ*=ƹ\*ǹ\*}sm2БS|W:s@[|W*RtT9ߕK|W~zTZ*Egz.\*-\gz.\gz.>ǹF]Hϩr+9Uwer+EgzN]):sJѥr+f/\*Egz.\*-\gz.\gz.>ǹB tR):s tRh :s t:s 9εU7@GzN]Hϩr+m]):sJљS|W.]}+T\*TZ*=ƹ\*ǹ\*}sm_|qLtgU:ӳ*Y^) Dq3=28 PK q> Acub/UT2 NUxPKn=Eec% 7cub/crosstalk.cubUT*MUxPKn=YN ccub/halfred_tiny_truelight.cubUT+MUxPKn= W7" dcub/halfred_truelight.cubUT+MUxPKn=`Q:" cub/halfred_truelight_log.cubUT+MUxPKn=IM2  cub/truelight.cubUT+MUxPK opencolorio-1.1.0~dfsg0.orig/testdata/spi.zip0000644000175000017500000060565613223553423017440 0ustar mfvmfvPK +o>spi/UT  N NUxPKo>};0spi/diffusemult.spimtxUT  N NUx3г05U03`. .qPKo>HiPspi/lg10.spi1dUT  N NUxeK&˱7*2ci\HBw]O^ފOWj7OkܽGn-|m";:7 Eyt0>EnmˇMg|sjm"֚l8ORuv>t\'˿4ѹ~f(=|k/97t:gUe]w:>-XoWL TGӺkeWި'ͳR_NǬu6:Cgic*^CgGߖԆfі(R>O)WVDe*֟e$n"nCWos7i%#{o貏WĘ.-NK:˓3۽ټ2 I_G.kZ*f*[*Ͻ;& \v]ϥ:C]W!B+]*iȼTjm0,Mvؚgt)'E|SMBz*:$[ļV=zQڇS_EѪ-N mCOd"buuzl!=ǖ3nk]R;:oǻI>*.9ГbgSW KK5lNmO9BFU:br%-9tvBN ƚH5| s.i}4)|)٫XΥClw}K \G o=8.+&ˤu6Bqcu!dJ{/ՆLLЕxw~#_(-]86t1 |/iy;kZZзO:R;E,-h`S6r#-ea8]A}'WDzWPo.r\4ΥAl{\trteeyV˳|"K-;Q[g鄝VrWD>^Lb"7B)gQG[3h!ԛ/S-M=]oRj NӼS,ec&[U\WEፘM'EˮE;?EP8CGZDZxzpXˣ) mV1] fUJMXwF,-e㷱8=Y&&”:uQm:ODX!Ǥ>4NGA7DΑ|$i^dOVI1踤oqQ*[NREsa9ڟI:83gr:g2w0K|{*:>)U;}[B\5b89OA&|Ezj3.RgJH.Y*O㧧+ᷞx롵YfI~?Ӌ `R*2S3Tj<)KZ-HR E}!Ja\ǖB,S>"s(vLo7r?)H!敫#+T:Ū/΁'^Q x|#:-FY+(ҰdѪG'HVmhRT8kY34 ~ ?OVm )Oώ'})RYoOpO*vj|?-R*[y]:z,yZXW3XRMzJ6,̃T)(*/ҷ)F:: O+A&G$?uWh,_S,L=Y_Ŗ^j+WÁų"%;7H7RI-JD+51/҅o%ѿCuJAEvT,+2Z]Z$,Lw@4Eze"ҐBR:A߇(I/ 0pet'{CiS}rU:T^LBV**rwzi?#W Is.w2ZZCt%yb})e?^ 庹)%";':?V\n[2vz)v_=D$&4dV!ȉ)Oy~Ԃ]i2nײRU0G)Qǿ%ɫ CkˊWD~咋V%3oTd@x/Qd =7(s[o+[΄+϶\<>ubW.N4g;QOΦΰ,;`_~L[*S ݊Py *omi >Z*<DpQFUW=ey -O9!^(Pfܣ,5^(A"F\,{CNO,o2; <~WZ9P$B]m=i4isIH5J$$al쿾;NKEȽs3m?:dvПECEe)G6nO5!u82,zY!dd륉b0},1S:@T >;m$s\>Yvu  lDzQQyՖS^n$|86;M H72{$m/t&Á)=; :HyKV|K#UDĔ|T *_IrTf癸rr%NdDXהj>DFXiwtY*Z>QhiBS\24CtT%%G; PjSFXB)'Ǘ.G'/AT _i.oʕo=d]w ]dEi .{Mmu rjpՋӾSЖ JcKB)J}O67oBPmHiu~=!A)\#z{~~mכxg b53!/:MԶ54i\IY=\Ɛ9E_I,{B\P#mC@m B!!gg ZF!ThN׃%{YYm r69V6VGS^!}+ q\RjtϏA_XvwTTKإ(j;_j0Y(GB|f$<`,G,B>?:ge ]A=TE|77HԷ>9/#T=,= /BbFPb+YQ%`Cfay-W'EԱ渱S YNBhW,*&/fXEeTUHY,O$zB~Xzr`&),Ԃ9Hr4y#;Mȟ)NNxr}V⎌[0PD :sb4;J_&齼+]RD$/A3*e+h$6zߝ25y;SihwꝛjxI87cK Xܽ45< bxh<Yn) %e!mW(i:Phh>2DF8`h.<-N\ p#гNB52M*_SƂh~(jc o\";j|U@P|NG{ @lJCpYX?Gt]Dw2fW wzzilȏ'㋬9P^8RDB Ƶvڔ. j@c ]`j@Kq-~MhM"_֝?݅vo(=#; vp(T֩#d1x)!`E(\!;w WNV` Qxٲ8.ƈ:gr3pm>g4lgFKh 1zR> '|MMӅ6:HxФ3 ePtX󔢤_Je"$O 'k7/⎒<roG9xt,]!!@8(BڼsYx(+ [ecHFO/ha|]L;Pw4mExPXhZPƔy 膢䂰Hk@lrʨIgt(7@)\;j#͘Te4tkj6ppB9H!-Lr@S'f,5nj(k>DC"* K{~xCN+n:@㯚xrmP[%elfG^w#/frw|$:YH`RkvRR,CtPDxC߶꜡vSffھ ҢW+%]DW+Un N^>%ǸH97ǘEϘay񮛚O6 }JtNաMFg7 b3ՖOKkط@Zc(>Ѵ בVg-: } EH.G_mhF9us&})?hN/%oc 0ݛpW>[Nv= }\ll}Y־4Be2Qs7/$NG0m# t'uF3m&")z*(phn(*Z/"u~sWlIHӠX!'LW&$_qt(Ix:di_Nr\6dpW"<$A Yu`Q>]d_zU{.Q!NtY>r)ګzkݘ? t9+᛺AiR1mU\yi,% kLz@-9R#RTtxW3( RE޴ݷţ1?e[y |wy)T/~v&Cpԕ|x^g̼oexZ4jed&R&+Bݷ] =>B6FA,<".];<=?> ԦU4vj`g!#\Iјhbr" %'qVء\SO47 Bɏ%~zJ'iԹ~9x8Ć{I(8u2H UR@T߅Φq*UZ}nΝUB݁"tHV/(#Z&%Q o{k*p\O7wc$)S}@D\o }^}IwpUvNi:|E,.K@F+ PcTg]ykAN!oK͏ol"OeECv+8l|j|-/E7lv3.?*id=B_!H+[M!}|sg#l./z2i=w!4-亩>k@ǥ@Z6.>XYpR6S .is5Jd3*W>X*JUXrN1U])õAtvzw_>$BWY ,<:Ix RlRݵ⪃bk1 4]7EGc}uե}V`4dFZfIH( A`{ٻABL 8@Te6X.OG܎u9j 줶J\=([7w~Q󕇯2m]:Z~ZA`gu{D9!YռIu/CZ-Í.!KOc)?I8sg t -I=J 3i B뇊$qͬ'޲ĦXQ|/3i@f41s.uٮFL8-`kdOI)Hߤ}oW* OY& lpFHR'q{.JY `¹"Á2=6\{ P<ʛ|r崆QuPe| vK_V0{(l; 4ɨݢİ8opԤ<.`f QI&]=fن/fHvee li:\r}26g&N;!3 sM9-ScGݍL:Dh¢Ռ>%Ֆ؃ڜqH~%LNVN##h|07z9bT?WTjSP1MeZȁzO>_3hMZF_> t/ŏ2v F&^^ X0=}_*%;GQLz_֡j}kcc'48(v2 TP$̽Yc= IB_2=efhnėv&|>?Tҝ`RHmH wsJ W M/Bgg>M^Fp-L RI;"2 &c)EV@,3ևL:Ý5E ZO:-B1SeMҧ8-{}4Zk ߗ+ȇ2E a_Y*= r+}`skoـSd0_&k>x=Bw`@ gA$m]j+tckdv* [ vcɯwɀ >;POK\ʛ_*Po$ϡӵ݌s7HNv#t6abD]l y9|Q6B[d2m0Vjgd%xeP.ƎVDdBJ2TtJg Vyi+וܯԉh!/ #U +)B| K%($K 륄  <=}$vRpNR~:k[jט.k%L="-4 *0;y߾7KN>&~Z My1_7q2n戢 }O/Y|- ˋIuiiJ 1,2 ƹr2.|>}Ѣ=͚[ NpB td{az HKC fL_f&Xm023a;:;Y8/3 @F\ sIW,z zIKHvBMR)~ur`OY j :!*<,KRIB庵V},D2 ʽ9s|+Z0n D%Yw\: roxR xk=e'-n3 ;>&_xgF@Eי9gn]Z I!& Ժy+ O9``JFCgt=]{-8EHg3tRh>ȁCdN -*lܢPK.,]1 L_T;8s1u{d3K_ 2؇l~eګ(@Ł\솹PC5)GT4J&@Oۖg^q2v2ӌH ʲn??&{9;eށgے%Ҳ>$-^}e(Qm:%oј;~sB%2;1 f 4p?6nߐN{H,h!oWr/|)_u| yϥG쉩ɳ;psK/LP 2pA?Vt}}1T!=Ǟ<.6HB[ Q:UvO$o)Hgpk)PW͌?C &16!M@Z:{ʖv x#%c-([)2Fdw:tcLt[xS& T:[*i_ U銺5~R x^B(̕>)R[I#pE7ܡxS@J2ϡ0ZH>ͿEMjⳌ3ÅdxI>R1%I+ ;KoȬr} ϩOnbp 2D&ϼħKz)D*yAz(8D%\T!I@:zLH(dc|4yl͊}eʒf,ܮQ dDйlzi&=d|d&_p@g¹a9Nk&8 !J[b@oP_~OeC]ב3Ya%yT+3QPIV7h`p'NrF񟝭LC-2ķ:|f$y_6jl{=5')0Jx <@u_&yZA%1K-Of riuphOJiuq,q>)i8Gdgv26n^vD.SRvS0 e)!o e>|w{ǖ,oB|O4gܙ7<Y<m,B4/۔e5 Wik2dΰۨ$B7s1,'o?3s& 46~rixwGWvtɔzv\|}IC5dRB!&^d6]`pG56 85 %!1u % ~x$"B\t#oJ_+&c926v,#̨QFc?eau]~ Զ[:|L@VMSQ|=DžXOJ23,vTN7J s5ʲԂ,F1, -09Ea W/F=?@Dv2tO4prrs= XB>A֑dNͿ:Yܛp2Z'5LOY *3iaEvS9$$"y 1ְ 4M NXtO'F 7XfN/L {ב3i2.*,*a!6~ #/34j2,hӦMXnCF@ZKMN.O u8c7eS(gxRqޏ )pFk=th賔Aj6~e·РB#):m7V`Bz. {'I3.ʼL@ ]|t1nqkN;:dY iK2 3}Ayd>gXclH崧߳+/`FrPSSqi($#hk'qHy^dܸLC.IGj7|Xc8rJJ~N#;r> 92M|1;ȘvΐtOFP<)v]Ǡb'ёr7 >W `8pzvDp{lz7mA-k &8MBIK"'\m&@)PoY1}x)'r`P?(C$ѵԃ"@6Y$bh /$'pvBwsFv&OsoӌFSGhn$AI338HN3_~$R$<줷N `sG;IPpLc ^4?t74+&k@'{aӰIIޏɻ Jg]+wx>] ^ImF$bVdl-mp;F' ;?^\=d*>X8*kL"OhB=rWfA:4+qU"-Y=- `f|yt;>鞮/ԃf:99|tDY{'ZvZ aAS׸mf/Cg:%p_<#fjZLEpGg1 \z-NKqHy,$̬.^h{^<#yQ滀j<'^itk3N%wN 6,ߠUvR|v[;Ejՠ< |`#z%FWv$uXPrEc"֌{lE(^Lx8 өzI4㗚P0#`bA\҉+DžS-9} r(Z(`je4]~;=4" @ŗDx& hD=6o:٪8{ZҲE3~AY8b;b'8Dc~$R{IF)h\tzī( ;mЛ 7K$Ap+D|$M?${H#I{:V7^؛_|-Z/n\c?*Ӂ %4a/fXwsU옿+J- ȼ,ãߎ=@KGfŅ}5ċѣF_ yxP}ZB2 [pOH z&c=K"ұ'EAz@M~OYu{>*πWOcmS[BbSc|!EGy9FkU Ǵfi=r9|\CpT=~lj"$b$) 8]qq?0Dj#;oʁnQ4)M-r#=gNe4"Hy0l("pn}Uhl1ݠ;BT=` 6@wByٍoD#|d!D;#D^q}:SwMϚDVCC-cS?SuT"Hc !,U>AR YQ~6jOɜCqz\(mQ_0Ҕ{K8Kmsv{v .k6C8NA QsFo+B!XKEVej/+J0*k"; 2A%#rË8&"wrf cnG:MdL"D %ʘ ik{h-̬ۛ޸1 M+GS“ W+ibW80|?A#1q;Bc%Q#c駳%4˼1<4j"rzCCIEϝ _|BrTy'DS/t:SclIavcǓc8cO]N],vUԭEg>˵cz0%М9H_wn $j(Qn&&AӌA4)|9>wn W?aJ7n5=0̏6)*)ah-J_Ǵ2Qssb@3HM " 1E2A1zI; 2 {,ȋ4$̏E4:})b5k ;#)(̈Ү<TLcF$ hN~v`44a3"?jF]DDh`rb"~xHLm g«0bLm6`CJG~/; ]7KN؃tZ o1ckَ"HSHV] $u8cF} ;kZk GU ^ rh~/ vߢAW'sxF (VAK{(ɾST =&("3zgjf+ >"";7-b2=Con~''@VĬ>L,m5xIׂmEQC3 6qΓ~ NQdn"*&t$ P< mǓGFM$?`#B(jW`BiR.QE*9o$qJL#*3)FJk6(btzC.I%?Nc;[%!o|Aӓibp4c7@|A+*||hfZQ_P,,GFpzhP~Ԇv&b9ݐI`<.TK^ݩtT'5|&A#yQQ7z$ېh,ͱ'&һp#œ8gEsZAEqg^As_J&#wO(sGܮOxjލ N!DPt'P23vV=Zu ƎtaQq9%#G hwyصcnX"AFAK(4y(n<=͎Ԩ9?@@ՕØEbd#S75XƴGYH 1mMv4:?f͋n̏^qzLU9+Ov7dBuEFs>+1S 6p{!Pއ;';q޼ ׇ2 wA#)c8F pz@`PsK7 JW;b@\Y$<ū ;wLecd"Uv%l `];ߜ//Y]0 ?tpivEp=H]* pz_EHXQJD8 qtDnwА1IEGᡕGP:z$6{C Pfbdۓ*D@M( % fHg4DtAd;em/vJ l%w*xio@G;he0>ݐ: +ɼDP@ ;s*xq Uxaa `(:ϭ v䳑 EZӢkI"~@*`$p.x"D3h4J8|Y$p2~@g0HsX[IKN ń AfP6 /I *9܂`2'%i r;MfC<-ct}hb$7a}=cX ԰;= *nOW 5RNE9=3o^L grrڦ&2\Ajȭ ]tOmPey1@(Z1US-I w͗? P1yx>'+g@x"D qq[QLF Q4E$GIDHHD6 y]EkDp 虈Z.>R'|qmDI3/3 DU5$$.ƍ;gD+)e#LZ8{qqh>AD^K?5a<}IᚴEs^蚗֋ ICYY{}E,G,2O $'@>~DX!p)$DFpO~poLF-4:(pcM. Q<ҥ8U`?A蛈%c ("ʢJBLacaYo F*l9K!ZtcԤ>J)^Nqh`%AET'LsRldg'tx- E?oNwvFd9Z+t`\< 6R_-E|#|Aspi/identity.spi3dUT  N NUxtQ#%(j$@??.1m9SyWF{Lƿoݿw~:o}^u?7w><緾ww[?|<-~op|#Z 3?}=F%NZ- ޿x{# ;v={_{O1~uz=WNu>=ט/Gk;1nWk^v~/]v_||}h/b:BBl'qA}A5ŅmGqqsqYK7=9ŅnυNg\\|==X,H>EiϢX,L:cqڳ8u ԞEJg,T{*bgX}\Ǣ錹X4X4XX4ĢX4XXX΢q'¢uMghEE,b:5EԼOE,b:Y4>hhEY,ZgtY4X΢錑u Y4X΢,h:]Xa%h.ڈEK6btG,G,g,ڈEsqF,NbF,G,ڈEQ,ڈEQ,`8KaXqƢ MghEYܚqvj^ͧ¢ MghEE,w 6X4X,mh:E,g,`tȺE,g,`t6X4鮏u,߇Xܳٳfdzf:bdze:>%;segtv< v< د/z^k9\G,b-X#VKGYGlXRYVGb*X#JGzyM:b8b(BP:}:b8bX'1n`X&إ#vIGJGt2Gg;iX8aglQgD ;ts;Xؠ369`X89c d}Wlߞ9Y89ٝ9Y89ٜ8 q8ɩɴuIl<',ĉ^̾΀9Y焍9٘89Y8}9ٗu9Y8a8}r, r+qr*q[;6ܔWl[iU^*1W GX8b[^-<A+%NXW, '1Nbe^Lk94/ؚ[G͋(pwѩ!5bu8y;qXvb}y?X b^lPB/V#m,ы%#qkb8҅0\YH׳H:b׳H:ϽEEEsGgtt= t=XY$"]Hk9HW,bX$X+IGHW,\HRYHW,bX$X+IGzyMEb8bX$"]H:Eb8bX$1n`X$X+IGHW,t2+HX"c8bX$s߱Hq"c8y;Xw,RHX$NbޱH"Y8Jfs`,GHo)X7Q,қE(.țESCj6 "qfEzH6 "f8EzH"Y8b,G̩0X7G,қE("q =a|_$E"="qğE#sG>H"}bE"qE$"Q6a8EHq"}X$b>,GqA>,RRYHXG,҇EH/oiH)XQ,҇E("a8bN݆"}X8b>,GH#] cˮ&{^~/ _M3t3 -tpR_>l:_>HG ݘ_D/t#MHg HtB:_F.Lj6 HB7_Fڐ m.:LB7tƿЍ!/t#ЙnL#6 H#tD:_F*]XCXysEt"~//Z:#ЙH'8ӢE:8NEt#-Z:b"F:YK7tBg,gZ4 h:֐Npvy5tBg,gZ4 \hiH'tƢNE#LF:3XhiH'tƢN,e>݋D^^H'tG:3NpEtBGqq" GZH'tĢE:#tn6-X4 δh:cH'tƭ!Lj6-X4 δh:K/xhH'8ӢNE#F:tBgYhH'8ӢNE#Yc|-҉hNLstBg#L鄎D:- hNEtBG,g/l"Z4 hiH'tƢN[C:ٙl*Z4 hiH't^nsѢNpE#F:3t3-4ncѢNpE#F:t2k|/Z{y"ЙG>- ʼnB',Zi" X4" _Dhd:c(8ӢRE3ͫTh:cѨ)8ӢS,E#LFQ3Bg,MgZ4 idƢE#LFW3Bg鮏e,! ܋qE^^+tG`3XpEBGqq" GZH-tĢEl#܂n6-ɅX4 δhd:c/tƭ!Lj6-X4 δh$:K/xh08ӢbE#FCgYhH28ӢeE#Yc|7E- iQgLxiѢQ\4t¢E- hhE#,MDF3N3-X4J qkH58;ӼMEF3Z3- m.Z4 δh:cH6tƢlpE#ЙFm,Z4 δht:c7tX2bD۽hnExCg{:gZ7t'hQppECG,Z4:bш88fѢqELFȡ3CgR4fSѢsELFΡw3-EX4h4iш:tu3-]X4>̇X?&z/Z{y"ЙuG-ʼnC',Zi"X4"_Dhd:c<8ӢzEԃ3ͫTh:cѨ=8Ӣ{,E#LF3Cg,gZ4idƢE#LF3Cg鮏e,!"'{/Z{y"ЙG-ʼnD',Z i" X4"_Dhd :c@8ӢE3ͫTh :cѨA8Ӣ,E#LF3$Dg,MgZ4idƢE# LF30Dg鮏e,әc'Ƣm>e(CtOeF֣ sqz!:EQpO GXebѾu_D ,Z_~/V?E@ˢO e'hY d\ d d d dXN3X dXN3>Lt2Q-ʐhQLs2Dgã LeD-hQE2DG,eg/l"Z4h!i(CtƢQ[Cٙl*Z4h!i(Ct^nsѢQpE F323-e4ncѢQpE Ft2W܋eH^^(CtG3QpE2DGqq eGZ(CtĢE#2n6-eX4δh!:c(Ctƭ Lj6-eX4δh!:K/xh(C8ӢQE F™2DgYh(C8ӢQE Yc|(ChQE2Dg{!:egZ(Ct'hQpE2DG,Z!:b(C8fѢQE LF32Dg4fSѢQE LFw23-eX4h!i(Ctu23-eX4>̇X$^(CE3=23-Z!:eNX(C8ҢE#-h!th(CtƢQpE F3n eggWh(CtƢQpE YzEF™2Dg,eX4δh!:ȺEF™2Dg,e]XCDr?hQE2Dg{!:egZ(Ct'hQpE2DG,Z!:b(C8fѢQE LF32Dg4fSѢQE LFw23-eX4h!i(Ctu23-eX4>̇X޳Cjգ U,W=R_B<фGRҫEH)z!% % % % %t d %T D %4 $ %  %YuYuRYuYuڏXu%V%&EW)iQ~LviQܔ(?t>E*QQ~舕,MDKE33+qa(?8;ӼMEE3v3- m.Z/δ_:c(?tƆQ~pЙFm,Z2δe:c(?tX2"ʏ/Z{yѢЙG-ʼnC',ZiѢ凎X4_Dh:c(?8ӢQ~E3ͫTh:c(?8ӢQ~,ELF3Cg,gZ4idƢELF3Cg鮏e,!E-iQ~LxiѢQ\(?t¢E-hQ~E,MDF33-X4qk(?8;ӼMEF33- m.Z4δh:c(?tƢQ~pEЙFm,Z4δh:c(?tX}WbGj;vG:G6sqF:EQ~pĢ(?t6Q,ڠ,ME:+)?8cb 4fSabg,\XͅE\XͅE\XEL#6}%_-XE,mP~,e>]~os;Xw뱾1c}ScuvƸFƸ{-q˛.8-Ɲn,oXXުOI1Jcy{bU35Sag]뗟7\v\ym_D=|"g>3s癏̇rj^ͧ<<0|.R^syVd\Mg>gaٛysyg\4cyiXg>g]>ֱ|bYygiںxgx.b9[9[{hm]ssE??k6[ssL,rE?=?k˰ܮܮ=٢ן՞gb-~^^[4A9_9_{&L ~~E3Qԟ֞eG3q ֞ GB$DRNX{~N؞ 4KaaEC#;K.Rho#.sǶ.@ "T@{~.ٞ "@{~NٖA4?5О[gv"A{~ٞ "TA{~ٖA4?eОsgB4?uО{gB4?ОeM/O%M/O)M/O-m oΒhgx7ssdj]"fhMv=E4&T{~.۞ ь"S=?m QDoR홸ݣߴjq3!QDobmD3hM=E4&W{~۞ ь"ӫ=?n QDco(7sLfdq^<GI3iF/a&scDE2Wb"yH>.^ُHA$ s?.E"H B$ DSDH$D)" |HA$"ɧ$.$SwH>E$ !OI SD" |HA$"ɧ$D)" |H@"D)" |H@B$"-Ffc~h{~,YJZh{~Q cii99[$B*KMm!YzZ~i{~!h\?tyZ~NiScyZ~ni[e<]-?Ǵ12mkmsn6O]=msO A砶9;FAsQ[\-Bil9-~N!hT?72af[4Yb:{:+F,D鬐Ί@4΂H4 A4 A4%s ΊA4%hJ:+єtV 0gz\40bMIga$ΊIEhJ: #єtV )DSYbRh@MIga$ΊA4%vEs3a=sdsd7gY4Ί=0B{:+x: "x:+x:+єt&Ec?ϧ20MIg ΊvtL~mgeMIga$ΊIEc?ϻ1MIg ΊA4%hJ:+F/~>nc$ΊA4%vE??ǀuv[4Yb:{:+F,D鬐Ί@4΂H4 A4 A4%k?&,єtV ),DSY1b%9~LY)DSYb?,єtF)DSY10MIg?,єtF)DSY1iva=o-og,Y1z|F~VH\phE /hA$Oh oh h`Mh H4%hJI+]RZ3.DSbZ1Դ0MiŤ 袁A4%hJQ+єV )M-DSZ1z)\4 d0Mj ֊I;좹-9ʛ,kuV[#[!q=h<h<h<hJn 碱/ m )-DS[1b%9ࢱm ).DS\1h+H[#єW ))DSb\bRhK[|#є(W )Y.rvS67βh<\1zHsa$s@WBDDWFW).L^1adbMta$A4..̙^cMu RH4%.`1g0M)v A4مhJ+F/E1fd0Mv I;k۳$e}bU^ ew/Eh {,$Dӽ  so+e0R RkJ sESbB402XL. t 7Е2X @W`1|])aM/e. t A4bRI;7=_78n4sEe^Cz #x,$." BBM+ &EhZ iE4H4Ѵ"nw+ LѴ"DӊhhJ,&]@ )e0DS`1bM)a$RKA4 hJ,є2XLȧ2-/,`1z 2F2XH\p/E /A$/ / RhJ,є2F)eDS`1RÜuh?,є2X )e0DS`1shJ #є2X )eDS`bRchJ #є2X )ec;^Eepex,Fb^H4^ eDe0DeDeDS`<< )eDS`bM)pK sEhJ,є2F)et]400M) RA4 hJ,F/є2F)eDS`1i]473{h ,/u2X``!q h h h hJ 碁A4 hJ #є2X )enw)a:h`M) RH4 .є2F)eDS`10M)pр RH4 hJ,&fz|MoxgY4^e=0B{,x "x,x,є2&DS`10M) Rv2LC1ebM)a$RIDS`bM) RH4 DS`bM)Ť1χ2X@ tgݫQ{\>{= .=^OtzzɁz˧zˇzigzIGz)'z z zɀ z˧ zˇ zig zIG z)' z  zscԿSĿC3A~$^YVbz+F/l寐^'^H(^ (^ A)s R*VJ+W 0gz,0bpK)a$RI^J #W ) S_)bRc@L)adRA3v=s3a[4^Yb:{+F/D寐^@4^H4^ A4^ A4k?&,єW )/DS_1bݥ9~LY)DS_b?,єF)DS_10M)?,єF)DS_1ivaѷh,/uW__!qhhhhJ 碁A4hJ #єW )nw)a:h`M) RH4.єF)DS_10M)pр RH4hJ+&f;xYW W~0fx+_!/^ /hF)a\40!Q_1HR Q_1!Q_1qG)a:h`B4bB40fWL.(/ A4bRh@B40fWLfWLȧmhm5M%]#߶d{b5mYko!o[m1ŚE E VEe-m[ۖ-nm[vܢ۶,w[-[֭n:u۲m,p[-mʶue[նj[K1ju@ퟙjc gϞ{6ӿg=;=:hޣO ]v,G}>~tK$t<7|"3ȳz'l<<7|(|*3˳u,|}.>gٸysyn\}g>gE#>g晏ٵycyVmuKc!elwįY۟%tj2Cv B4E#E#"D]4 tMw "~E4bB4_!^D#&DӋhE4E4bB4_!^D#FE#&DӋhE4bB4FL+DӋhRhhz B4FLшh_}vhx{")o~!,"/Eo~h,"_Hf5aD3h0E4fd~ь"p2hFY8_sF4,̯9#QDoNל(7 'kΈf؛5fD3h3E4fdc>azz0Qa‹|eI>L10&""r^@ڏ""$r[@Pjf9,B6.So?fV׊VA*KE[1]rR@0FB9\(B'!̿.29\& p !ZԱ9Oߓ;I9]#_b t_9=~9] WM}ELOb?Mqy_1=4QYԱ~$DgғOmEJOb?Sqi_)=LQY~$3EgUғ]EHO`?RdqY_!=HQYT~}$v#>E1/7sTrUr E$ O $D)" |H@B$"ɧ$D)"a.ɧ$D)" |H@.Qrf )g9h41͒(T6KL! hT6KOBf jBls~8ˢtV^gOg!=h<YYY!Y!0yx.DSY10MIg ΊvtLєtV ),DSY1h`MIga$ΊA4%hJ: #єtV^  ),DSY1bhnf>Elex:+FbH4 D,DDDSY<< )DSYbMIgpK: sEhJ:+єtF)鬘t]400MIg ΊA4%hJ:+F/єtF)DSY1i]473fޢt6βh<Y1zHOga$OgtVtDtVtV),L^1abMIga$ΊA4%.,̙^cMIg H4%.`1g0MIg ΊA4%hJ:+F/E1f0MIg ΊI;WH\ptE /tA$Ot ot hJ+єNF)DSJ]1œuh?,єXW ).DSr]1shJ #єbW )ɮDS]DbRchJ #єnW )ᮘc;7qE^Cz #x+$." 'B7BMxa\40dbMxa$A4.)/̙^ )1DSj^bt H4hJ+єF)Q.DS^tbM {Ťv|XO{WqEq^Cz #x+$." 'B7BM|a\40dbM|a$A4./̙^ )DSj_bt H4hJ+єF)ѯ.DS_tbM Ťv|XOWqE^Cz #x+$." 'B7BMaڏ K4%hJ #єX )%nwIa:ShJ ,єF)9t9K4%hJ,є$X )M0DS`1z)1K4% hJ,є0XL+/Y۞o2X s2X`~hB ޽ ^ }BB4`!!^`~碁 RJ/ t  מ2XWz\4~cF4v ch@W`~o+ebR DK,F/o+e0@4bRI;좹1h8nxgY4^e=0B{,x "x,x,є2&EhJ,є2F)eDS`1RÜup RA4 hJ,&]@ )e0DS`1bM)a$RKA4 hJ,є2XLȧ2-n,/u2X``!q h h h h&D]4bMwH4E#tnwwuh?,tD]40M)Ť Y)e0DS`1bM)a$RKY)e0DS`1bz|OqEe^Cz #x,$." BBM)a\40bM)a$RA4 .e0̙^ )eDS`bt RH4 hJ,є2F)e.DS`bM)Ťv|X/iܢ28βh `1zH/a$/2X2D2X2X)e0Lє2X )e0DS`1bݥ 9ࢁA4 hJ #є2XL.DS`bM) RH4 EhJ #є2X )e.e7Eepex,Fb^H4^ eDe0DeDeDS`y=.<.;%.;.:%.:.9%.9.8%.8.7%.7.6%.6.5%.5.4%.4RO#nxgY%^ы=0BF{+x "x+x+&ϝTJ+FZ)R_1\RœupR-\J+&]@ z)/R_1b0L)aRKA2eJ+͔WLȧoxgY4^=0B{+x "x+x+є&DS_10M) RvLC1ebM)a$RIDS_bM) RH4DS_bM)Ť1χGߢ7βh_1zH/a$/WDWW)/LєW )/DS_1bݥ9ࢁA4hJ #єWL.DS_bM) RH4EhJ #єW )寘.>7~}ֶgGz+yx+F?N_D3\寈 /hBB40yx.(~$l)a(寘(寘ݣ0gz\40!Q_1!Q_D3J+&]@ LfьR ьR ьR Q_1z)\4 !Q_D3J+&D3J+&föE46̚U-kpd{b5mYko!o[m1ŚE E VEe-m[ۖ-nm[vܢ۶,նmjl۲׶e-m[Qۖ͵-+k m˻jl[ԪYNVKjZMk=~߳gϟ=;G}O^~ro貣gGo?{{_&'OYyyvoD՛g>g晏YyC95SynXg>g sI/x<+7|.3˳p<<6|.Y<6|,Ϯ3˳jX]XE օYZ.^fx=ںںa!ۺy.Z[3m]Єm]Ԍ¶ua3lq~MEnșnЉa-vfb-xf6[Ĝzگ)?3!fH "h&_sF ĐL Q4EfB̈́LƌH$1P2bi&h~߇.ϒhF swш!twMwр .!!^DE4bB4"1!^D#&nw/9:hĄhzM/A4F.FL ^D#&DӋhĄhz E4bx)\4BB4F;DӋhݾ{9&?C(YjYp2!_!\.~hFHfhhF Jsш ь"1!QDï(E4bv"~uupш ь"1!QDï( E4 ь"1!QD#&D3hE4bx)\4BB4_!QD#&D3hh]4ϯ{h93q4sf"f!A'D?L .9%BB%Dul}E|NFN׈}{g;]"WNsE2Wb"yH>.^ُHA$ s?.E"H B$ DSDH$D)" |HA$"ɧ$.$SwH>E$ !OI SD" |HA$"ɧ$D)" |H@"D)" |H@B$"-FfcYBY,%Mz"KJ36KK(h4!RYj6KN(h4!m&ST1yxDŽy6OT(hT51m&U1gzڏ)+h51mQikb?^by6O_C m&F/E1fmƊQlbElex<+F׳bH4 D-D D DS"Z<< )DS:ZbM)ipKJ sEhJL+єF)9t]400M)j ԊA4hJT+F/єF)]DSZ1i]473#yYb:{`+F-D㑭ي@4ڂH4 A4 A4%s9̏ K4%hJv+єV 0gz\4u7cM pa$IEc_|3?,єW ))DSb\bRh식oǘ%A4%vE_|T߼͍,su:W\\!q=hh<hhJ ~LX)DS:]bM)upK sסDSb]1Ժ0MuŤ Y).DS]1$bMiva$KY).DS]1bz{߄[4Yǻb:{+F.D@4^H4 A4 A4%s A4ㅑhJ+єW 0gz\40ļbMya$IEhJ #єW )IDS^DbRh@Mza$A4%vEs3a=_[4Yǽb:{+Fy/D}@4^H4 A4 A4%s A4hJ+єW 0gz\40ľbM}a$IEhJ #єW )ɯDS_DbRh@M~a$A4%vEs3a=_[4Yǿb:{+F/D@4^H4 A4 A4%k?&,є X )0DSB`1b%9~LY)1DSj`b?,є F)EDS`140M?,є,F)]DS`1iv[ /,b`^!0{,`!e0`!!eM/e0L~]) t 7Е2XL2X _{V`3. t  A4bto+e0bRJ hz)po+e0 7Е2XLa{|OqEe^Cz #x,$." BBM)a\40bM)a$RA4 .e0̙^ )eDS`bt RH4 hJ,є2F)e.DS`bM)Ťv|nz8ˢ2X^g/! h ```!`!0yxDŽ%RA4 hJ,є2X 0gzڏ)K4 hJ #є2XLǜ%RH4 hJ,є2F)eǘ%RH4 hJ,&؎y>n sEe^Cz #x,$." BB( &EhF E4H4ь"n( Lь"D3hhJ,&]@ E4H4ь"D3hhF ^  E4H4є2XLȧ2-/,`1z 2F2XH\p/E /A$/ / Rh`M) RH4 hJ,]`3.DS`10M)Ť 袁A4 hJ,є2X )e0DS`1z)\4 0M) RI;좹^[4^Yb:{,Fe0De^@4^H4^ A4^ A4 k?&,є2X )e0DS`1bݥ 9~LY)eDS`b?,є2F)eDS`10M)?,є2F)eDS`1iva 'ݻYpA*|{>tOG݃^z^r^j^b^Z^R^J^B^:y^2q^*i^"a^Y^Q^ I^A^_A/oA/oA/oA/oA/>bн6qU^3z #x+$n" B0BPJ)a)0HbJ)aR+./̙^7 j)R_ɥbtR/`J+ÔF)$S_YbL)Ťv|X/?qE^Cz #x+$." BBM)aڏ K4hJ #єW )nw)a:ShJ+єF)寘t9K4hJ+єW )/DS_1z)1K4hJ+єWL|X/-/,_1zFWH\p/E /A$/ / Rh`M) RH4hJ+]_3.DS_10M)Ť 袁A4hJ+єW )/DS_1z)\4 0M) RI;좹/Y۞ ^rx/Ws"B4_~hBB4_!!Q_~碁 ьRG–_ Q_1!Q_1qG)ř^ LfWLf_ Q_1h`B4ьR ьR ьRlhF)pрhF)n<̏1#Q_l<v-yǚo]k仾;ֺwy;wYo~#w=XC۱۶cMw7l5[bMag7Q%tI?H_A& EDUOQ|\!"DqQ@(>. E&EDQ|\\}?SDqQ(>. E(@C""DqQ@(>. m؍t k'[kQ2!*h$2!@4Rhk"hT2[k2)B֚N&`kM(hR 3k*ز2![X QeeB,LB4-K1BeI[f&$]-K5(زd3![n&`N! ,LUei,,L I:vÝL$2"3H,WO!z>K?A$K?E]S"B"S"S"$Ϭ*x)x "x)x)'șH<H<H<[OW"D"S"S"D"SÕH<H<H<u;HMEbgeX)DB|~H$~lDb'DbDbD'HYU"S"D"S"SO3 g+x)x "x)$]D'DDD'DͿ+x "x)x)$- w>5EbgeX)DB|~H$~lDb'DbDbD'HYU"S"D"S"SO3 g+x)x "x)$]D'DDD'DͿ+x "x)x)$- w>ErH,?蕵SOOq-HH,HHI yfm?Wp EDrH@"".@4DrH@" D"THn}?]ăPċP!ēP!ěPģP!W",D".T"0THZԱ|NKCryvGY$ +k=% E".[&*X( !X**X,*x. gsH<H<H<H<EtLoJ$ A$H$ I׭+xF "xH*xJ*xL "xN*DJ$H$ A$ I:vÝiiȼY[GY$ +ku= ".[`*Xa !Xb*Xc*xd gsH<3H3H<4H4ELoJ$ A$^H$ I׭+xp "xq*xr*xs "xt*DJ$H$ޝ A$ I:vÝi"4H,>WS!z>OA$OE]U"B"U"U"$Ϭ*x*x "x*x*)*șHv8"xU^YW,_H_wV VVV#V+[A$+[E]U"B"U"U"$Ϭ*x*x "x*x*e+șHlHlHl[OW"D"U"U"D"UÕHlHlHlu;{PHl,+[蕵UVVqlHlHlHlHl3kJ$^ A$^H$^ A$^ "{ rl%/[ /[A$/[ӕHlHlHlHlHlp%/[A$/[ /[E紲-De&V Y "X*"""" $Ϭ*.DrHH "9\$ \EșH "9\$H$$]DrHH "9\$ p".Ϳ+.@$EHlu;x8"U^Y+[lHlwVVVVVj#+\+;\g*"VxrU@dX H"B$U!*HY /W#+\A$U!!媐U3 gHBB$UD2\[O /WArUHdx*$D2\A$U!W?UD2\"^ I:vÝϹۨcIV7PҪo%R]4K]:,5Q:uyt,!X mѱcmNB.o2]k^9֮tysAfXKmα&cmG6.oj]k&9>ty saXm˱cm@[c?7)Z}.oO5\ޘk繼%9fwqdߓ<C'r\ek{r,k=RͿm? 5OֿNd?4OֿJd?4OL[',b_E7'mwDWQn~'x?=\۾?-(* E7QG6'&& $DDל~(ÚOQtTs"njNb?SDM1Ig(?9LE7QG4')& $#EDϜnG(x{v'IcEyK=U>8sm*  \[QU0Q;dOQ ?640Qc؏Q 76D0Q;cQ /6L0QbQ '6L0Q;b؏Q 6H0Qa؍"]6 iX4!X,!:IcqΟ {,qX 98A8VcՁ&ݷD*\p.*8Vʍ Ow"s~4pX<s\%<<>w4!Kڿlb_q3_sΑl`_J};IeLa 20$x/@heʍ Ow-"dZDI"z"<յ\tkC"@!kC*4!"V\@@ZE 絊ԘvZE Dp"@*J};IDp"@*!k\0$"V k@Vnl}*SUA{{O^E"x"UޫWp"x"gSUAggOYE""U>|Vp""&Dvc"|L!@+76)ĒAҒq%K%K% ڒ%๧mI9AҒ P HZ$)<5 LAҚP HZDƬ須3Mm' iM A&"C[Dշ3U"$a"0Ik(BAҚ"&BCۑ*HZD D1Ikc3mż(t1N(tQ^5]G[EbMĵ]E#5](tQXEE0nmHE&GK?.%=HUDdH}+".gm"?H[ȏ""w&cdH.".m"?Hcȏ""w&cdH}I.".m"?Hkv. Ҩ~㢀Q|\A "DqQ@ĝ(85(( BE㢀""DqQ@(>. E( zߏQ|\A "DqQ@hnY?9ZHr QA& QBld"ZS/ښLP ZDlYJ)$Ϭ4 !زR-K-BeeB,rlQG3![d QeifBu*زTS-K6BefB,`R΄h}?\[v QegBB#RτEl&yoXGY$~ +k= ".[)X !X)X)x gsH<H<H<H<ELoJ$~ A$~H$~ I׭+x "x)x)x "x)DJ$~H$~ A$~ I:vÝi}SoXGY$~ +k= ".[)X !X)X)x gsH<H<H<H<ELoJ$~ A$~H$~ I׭+x "x)x)x "x)DJ$~H$~ A$~ I:vÝi} oXGY$~ +k= ".[)X !X)X)x gsH<H<H<H<ELoJ$~ A$~H$~ I׭+x "x)x)x "x)DJ$~H$~ A$~ I:vÝi}nXGY$ +k= ".[*X !X*X*x gsH<HH<HELoJ$ A$^H$ I׭+x "x*x*x "x*DJ$H$ޅ A$ I:vÝii_/;(P!ze-DD"HTDeD  E!$KEE EE EA~'BG gBBȞim?[Q!RR!t%HA$I OI IA$Ih}?\ēRģR!ijR!iQn9--=wvGY$ +ku= ".[`*Xa !Xb*Xc*L$ yfm?We"H^&e"H^&!\䗉LoJ$/D2H$ I׭+xp "xq*xr*xs "xt*DJ$H$ޝ A$ I:vÝi"4H,>WS!z>OA$OE]U"B"U"U"$Ϭ*x*x "x*x*)*șHj bV W:Y*D_Lde+"VxrU@[ oUD[*"Dҽl3k"eAV}BB$V!| g~t/[H {*$]AV}B1/[ b^ eͿot/[HBҢpsZzqEbeV Y "X*""" yfm?WV!VV!V!\d/[A4DeDe+Det~ BB B4De+DeDec7V޳EbekeX*DB|VH$VleDbe+DbeDbeDe+HYU"U"D"U"UV3 g+x*x "x*$]De+DeDeDe+DeͿ+x "x*x*$- w>nXGY$V +ke= ".[*X !X*X*x gsHlHlHlHlELoJ$^ A$^H$^ I׭+x "x*x*x "x*DJ$^H$^ A$^ I:vÝie=[$VQBZ*Dge+DbeV @$VBH$V@$V@$^䙵\%/[ /[A$/[ /[pl9~B BuJ$^H$^ A$^ A$^H$^ ~ BBҢpsZzoXGY$V +ke= ".[*X !X*X*x gsHlHlHlHlELoJ$^ A$^H$^ I׭+x "x*x*x "x*DJ$^H$^ A$^ I:vÝie OQޜdL#<[ZnQݚwKZK߭h-e|{wYK߽f-U|D[wOYK߽d-E|;wXK\ۙշ32^ oˍ)|0/庰 lG*Y\^H oWK=]U߭\6qUaV Y "[X*"."0"P yfm?WIU!XUiU!xU!a/WA4*媐t~҇ 򇗫BB0 RB4$*,4媐c7U$}8"rU^Y+W\H\wUUUUUE&8]&痸"& B$Eȏ""ON\Iw?'cHӟ1[D]$ω.".D~Lts"?H?9E$Ebď""ONpIw?'97Gm{D2L$͸/2~ <0q_A籊^cH$FDEDl*rcU jr8V}4&8L"ua!".a85(8L"Yi& \}?Sq2 0a8L"]  G,8"BBqF}D|m&Nӄ}[:MW~saOSukw NU,rK@&^_nGVQ/I۝$Q\(DZ^(LZEn!kb=VQ!D/Ҩ~2QQ\& ~(.ew2QSo"D!"Dq(L"t~2Q Dq(D(.e2Q`}?RDq(L"BBqF}ķb.D$QMo6Q(& ھM(&Dx(BoEiTm?MDvQ@(. Ex( ξ]AxOQ]!"DvQ@rLEx( BoDQ] G(. Ex( c7#~LOQ|LIDk1Q@hEcxDycQ|L! DqQFDDQ|\!"EĩDE(@.WQ|\A "DqQ@(>. E~Q|\!B8v#=Ț>֚@r5L 5L:5`kM$КJ&`kM&E c5LB~ ,L%BlYj-K.B0d饐3 g`R̄;%BlYt~ ,`˒̈́lY-K8f)gB4-K;(ز3![z&$- w>g3|8"S^YK?,H,wOOOOOSA$SE]@U"BB"DU"FU"H$Ϭ*x*x "x*x**șH+[A$+[E]U"B"U"U"$Ϭ*x*x "x*x*e+șHlHlHl[OW"D"U"U"D"UÕHlHlHlu;{Hl,+[蕵UVVqlHlHlHlHl3kJ$^ A$^H$^ A$^ "{ rl%/[ /[A$/[ӕHlHlHlHlHlp%/[A$/[ /[E紲-+[(V!zel糲D"UDe+[ +[!$+[E +[E /[A~B BB^im?[V!VV!t%/[A$/[ /[ /[A$/[h}?\VV!V!iQn9lp8"U^Y+[lHlwVVVVVj#+\+;\g*"VxrU@dX H"B$U!*HY /W#+\A$U!!媐U3 gHBB$UD2\[O /WArUHdx*$D2\A$U!W?UD2\"^ I:vÝϹۨcIV7PҪo%R]4K]:,5Q:uyt,!X mѱcmNB.o2]k^9֮tysAfXKmα&cmG6.oj]k&9>ty saXm˱cm@[c?7)Z}.oO5\ޘk繼%9f|k=v {4Gz䴓ye/;7{r'ς}Ovrc'zͿ,<9<5lj#óY,g7Q%tI?Hӟ_A Ҩ~0ywq:D93~h0mkf q4DrLQaʀCD0a_ tq.D0)8L0WU ƱOվ߃9H8M_`l4I_=?υ=M~ϯ98MW~?zXw"~3D a lNս-k{'$R8] WN`;Ip֯vt!_;$:Xwo Ny'^&Ϝ&x e.^& lӗ|Bx/3@(J"^.˭Zx /D\ח!So"r7^.])zx/D傀CA+H%x% B/qF}kEN(U"x-U"xkVQxB!kVQQ\((.DUOQ\& !D(.ew2Q@xOQ\& !D(.])L2QQ\& !D(.#EBN2QQ\& ~nb7#M/I۝$QMo6QDyڟ(&uxD/BoE"(. E@oD;vQ/NM'(. E@o.WQ] DvQ@(. E@oC""~(. Em~cwcxN(>& ^ˏG(@sm?& CEcQ|L!"4&( BE㢀Q|\qg?. NM'(>. E( t~Q|\!"DqQ(>. #EE㢀Q|\ƱAOl)dBTЬIdBԁi[k"hT2[k2)B֚N&"ք2[R 3k*ز2![X QeeB,LB4-K1hd QeifBu*زTS-K6BefB,B ~ ,`τlYꙐc7D2/-K?(O!ze-D"SDeK? K?!$K?E K?E O?A~B BBȞ~im?[O!OO!t%O?A$O? O? O?A$O?h}?\OO!O!iQn9-o-K?(O!ze-D"SDeK? K?!$K?E K?E O?A~B BBȞ~im?[O!OO!t%O?A$O? O? O?A$O?h}?\OO!O!iQn9--K?(O!ze-D"SDeK? K?!$K?E K?E O?A~B BBȞ~im?[O!OO!t%O?A$O? O? O?A$O?h}?\OO!O!iQn9--k?(O!zeD"SDe @ +@!$K@E k@E @A~gBw BBȞim?[cP!kPsP!t%BA$/B OB oBA$Bh}?\ijPĻP!P!iQn9OI|;oXGY$V +ke= ".[*X !X*X*x gsHlHlHlHlELoJ$^ A$^H$^ I׭+x "x*x*x "x*DJ$^H$^ A$^ I:vÝie=[$VQBZ*Dge+DbeV @$VBH$V@$V@$^䙵\%/[ /[A$/[ /[pl9~B BuJ$^H$^ A$^ A$^H$^ ~ BBҢpsZzqEbeV Y "X*""" yfm?WV!VV!V!\d/[A4DeDe+Det~ BB B4De+DeDec7VSEbekeX*DB|VH$VleDbe+DbeDbeDe+HYU"U"D"U"UV3 g+x*x "x*$]De+DeDeDe+DeͿ+x "x*x*$- w>繊+"5HlWV!z>+[A$+[E]U"B"U"U"$Ϭ*x*x "x*x*e+șHlHlHl[OW"D"U"U"D"UÕHlHlHlu;VwZk-ky|ݢV54[ZnAk ,{Z1k⻷${Z!k w{Zjk7{ZJk wWK߽^-|xDwOWw+W'MajeUX*D/BxVVk|a*aa*HYUrUrDrUrUwU3 g+ux*wx "yx*$]* *Ϳ+x "x*x*$- w>}8"y"WU!z>+WA$+WE]rU"rB"rU"rU"r$Ϭ*x*x "x*x**șH\H\H&!t%D"yH D"yH@$DÕH&m"H\u;{8"rU^Y+W\H\wUUUUU9E$Eȏ""ONd;s o}(dHʛq_d@xa"7x0q_dH͸/AHߌȏ""7&cdH͸,".3n"?fHߌȏ""7&cdH͸.".3n"?Hތď""7&cdH͸l}cɽ#8I9Ve=VَU"8X"ǪA X" q8LiTm?Mq!La r%FD /DXV-\ ᅗ{"ĩDQnx@/.W=\A"rA@!^n P~HKkB8v#>ⵊޞ)kE$Q\(DZ^(Dh* Dq\kC* DqVQQ\& 4&L"BQ\& !D!"e85(L"BQ\& \}?SDq( eL"BQ\&  G(.L"BBqF}ķiI۝$QMo6Q(& ھM(&Dx(BoEiTm?MDvQ@(. Ex( ξ]AxOQ]!"DvQ@rLEx( BoDQ] G(. Ex(@&v#>DbIDk1Q@h'D1Q,i!b{ D1QG4&( BEQ|\!"E85(( BEQ|\\}?SDqQ/E( BEQ|\ G(>.( BqF:{5}5([k 4ku k)D֚H&"5L֚LP ZD2B~ ,L%BlYj-K.B0d饐3 g`R̄lY)D I׭匿`RM! ,L !زS-K9plY)4K<BegBҢps6ɼ̷H,,K?蕵SOOq-H,H,H,H<3kJ$~ A$~H$~ A$~ "{ rl%O? O?A$O?ӕH<H<H<H<H<p%O?A$O? O?E󾩷H,,K?蕵SOOq-H,H,H,H<3kJ$~ A$~H$~ A$~ "{ rl%O? O?A$O?ӕH<H<H<H<H<p%O?A$O? O?EHkx8"S^YK?,H,wOOOOOWS!z>OA$OE]U"B"U"U"$Ϭ*x*x "x*x*)*șHv䳊$H,^WU!z>WA$WE]U"B"U"U"H@~D"|L$ D"|L$B șH>&!c"H([ H$([EX$([MH$([MH$,[F?WeeeedBgkl5"lbl5mӵHX HXHXHX HXg?\eee([K$([Re,V#~>B,&YFj@"A*"AjB"AjB"a*$g6Z$,[H$,[X$,[H$,[ lrG?[eee8nE²UE²ՈD²ՈD²UE²Ո?Z$,[X$,[H$,[E]pDB~"l]뽏ZyDz'VM뭍HZoiDz+'[?ٳ޺ɜO֬*~2fE-뭉LYoIdz+'C[?ٱzɌOV~2b 뭅LXo)dz+'[?ٯWodz'[?ٮt Dz=e {)UrՈ?U!U\5 _\aa\5!c\5!e\3\- Fd B F FtY 9brՈrUrHO`*`jDajDa* ajp-BlFF⢮ns\/\K)F(WP HPg  媐j\5"\b\5"\5rUl-F$B,F~ U! U# U# U! U#k\b\5"\5uu={^J| !YF|(WX$(WM쳌rՀDrUErՄDrՄDrUHlsHXHX HXHXAf*~ U# U!ɇ"mӵH>F,E"D"P$B$ECg?\Cl"P$B$F⢮nϹPZR(WhgU#P HU߳P"Y(WEH$ 媉-rb*$g6J$,WH$媑-r>ȋ媐#?J$媑-rUDX6J$d\5EX"Y,WH$_YrUDX"Y,WE]p,ud@]UNWTKUt,5_ңW*jy-JzZ^ڜWƦ%誕iyj^Z^|ڕWe%iy͹jBZ^pڎWF檵hyj&Z^dڇWEhymj Z^XڀUr과\5,/&W<+UϿoLFtεϵkߋv.X:ιuΥW]^s鍥뢝K,]^k ^k ^k ^k #^k C9b^S^k c^k s^k1|/ڵ|/ڵ|/ڵ|/ڵ|/ڵ&hhhYX2!LJ]n 絼x\d\dp\`|!G6LBt /(5]Q.l"^`rxDŽ}GBzb' >OFvԋ0~Lԋ0FA2q9[ ! bTA$#Q*d$Q18VcHFI0ʨBIFbU,^χ>=FғY??h ?}'DÏHO#̈́h|~ ͤh!E3)~Jz1?&lL^̏[4cͤhAE3)~Rz1?lL^̏9[4gcͤhaE3)~Zz1?lL^L;aD}hR4 ;C.oN ;WX4 [@$EE(hEwc͢hb~L٢Y ]̏9[41gfQ4|x1?l,o/ǜ-E=E( chEwӎ|Gu/!?2.*Po{B-}xЅ _lxB"d'!BxRə~Ɠ"kF,D"bD"@"@$H>H>FrfEHH$d#ɇ""|(!:d#G H>Cl"P$B~ɇ"وEHH$DDH6b|(!k|(X$DDHE]p(wmtk%h)i0դ4ajZw?ȫE,QS |zARTa3#hCpІD j0ڐ p>~!e AV!6#hC?DІ5mH_qІ )l0smHcڐ l0yW7aDsh"fbΚD:+&Dtֈ8Y Y!!F,F,bF? Y3 Y1!f,f|Ί9rF? Y3 Y1!f~!bB4LgX4LgX4LgńhΚC4LgńhΚhΚ;1_t:_ kE4Hg>#5tVLp&,BB4HgX4HgX4LgŔ~!f,bB4LgX4Lgt3s>~!f,bB4LgC4LgńhΚhΚhΊ 05[11hΊ 05c05wxucu2A:׊hΚ}F:k&鬘 Y#:HgMX4HghhhΊ)C4LgX4LgńhΚhΚf:+}C4LgX4LgńhΚ89hΊ 05c05c0a:k&bc0a:kƢa:k&|=,}Evv 5zL<$Y1!FtКhP 5bѠ5b0S7 hњhъ 05cѰ5͔V̑0)hӚhXӊ 05ps0aQkƢaRkƢaS+&DèLlaV+&Dî֌EðLՍzX֊hך}F`k& "[#:lMX4mhhhۊ)C4LnX4nńhݚhޚfz+}C4oX4 pńh89h 05c05c0ak&bc0akƢak&|=,#"6w 5:L<$\1!Ft蚰hP 5bѠ5b0S7 h隱h 05cѰ5TW̑0)h뚱hX 05ps0akƢakƢa+&DhLla+&Dn׌EpLՍzXI^+Ak&xHbB4w#5aѠAkĢAkĢa+ o05cѰakƢakƧ)#aS05cѰak&a+&Dâ׌Eä׌EæWLQ؊ُ9DìWL]aëH{]m^+Ak&uxHbB4{#5aѠAkĢAkĢa+ o05cѰakƢakƧ#aS05cѰak&a+&D׌E׌EWLѯ؊ُ9DWLݯᯙëH^+Ak&xHbB4#6aѠAlĢAlĢa, o06cѰalƢa lƧ)#aS06cѰal&a,&D"،E$،E&XLQ؊ُ9D,XL]aë+V(K}FV~e0f׫Ph&`#O&$2XE3Qh&`#+h_i~?(h_i~?(X89/б @2،e`1dl&bc_c,Ƣ,X;1_; s_Ѡ kE4(> 62XLep&,BB4(X4(X4,Ŕ~!f,bB4,X4,t s>~!f,bB4,C4,ńhXhXhX Ѱ 6[11hX Ѱ 6cѰ 6wxuce5կhP"fbQD,&D2؈8` `!!F,F,bF? `3 `1!f,f|Y9rF? `3 `1!f~!bB4,X4,X4,ńhXC4,ńhXhX;1_2W4(Z `3(C AlDe e `# `# `1expee `3 `3>,ree `3yg? `1!f,f,bB4,V~!bB4,X4,^ݘE|M+{egf!Q Ѡ 62؄E2XHeee2O8D2،E2XLeenb܇O9D2،E2XLe@肛&*D|` {0?=(_L&{w9d |`s0?9,_L&;s d|`k0?5,_L &w3d{`c0'x_kE%(5ψWLh&BB((((X),Ŕ~!flbB+,+,`s>~ʡfbB.,C/,ń_X`XaX Ű5[11dX ˰5cͰ5wxuc_ ߽VDL3_3(ńhPGk¢A+$D׈E׈EWL'akƢa+&D׌E׌O7_1GakƢa+&DL9DWL寘 _3s寘 _3 _3yW7aQ^_ѠkE4(>5WLp&,BB4(X4(X4,Ŕ~!f,bB4,X4,ts>~!f,bB4,C4,ńhXhXhX Ѱ5[11hX Ѱ5cѰ5wxuc>vwmtk寄}^(_'WEP|5!,B,׈DPh_1exEX_ WEXh_3:݋寘#aSh_3b+Ƣ;-?Esh~٢YQ4bb+f?+ah6cѬ(1bk&|=HьaJ;8D2)u)Y((=(!(都(ͮ'1BtGAsG@rG5w_QzmoG5rv[]3QskG5עvԛ[SQlmhG5j^ĀZN֗n/I[5[X[𷶰umK9[yb{^ui_7o郥;$?D;0}5Ld_s 7\H;0#50}5eߺs sٗp%7|b.ʝk˾q/ܹva.kKlb,k˾kƲy1<뫌|Q.ھRׅy-/(/(0?(1_Q.d"r1:EMDv .71a_Q/r2У^`|G肏zѩs>S'#*`,QELcèbƂUH" cTacq*dǘ-QE2PXFK2qW;a'DwF?f`}?}'DszyE3!׻"LE3)׻'cͤhn_̏[4}{2?lLE3)׻'cͤhn_̏9[4}{2?lL_ȏ1[4}{2?lLɴc>vA4~Y6ڵ͂h/ C.9~ /yE ?hEs{Yx2?&l,d~LآYeE(“1efQ4'c͢hn/ Oǜ-E^̏9[4,<shE×'c͢hn/ Oǘ-E^L;aU4׵b<#k< !v.1"<#qQW79dhVR#4Ÿ#VKH?9-OWX >- }~f$iZ偟>vVAuOqPih'jm~V$ڙZ>vVAeOqP)hgj]EhGjY~B$ڑZU>f#>!?2.*Po{B-}xЅ _lxB"d'!BxRə~Ɠ"k"@$H>}?l"@$"$D"B"P$ə~ɇ""|(X$DDH (1"P$B$EC6Z$d#ɇ""|(!ɇ"وEHxEH6b|(!ɇ"uuýnm5% &z1LMKDV@R4m595A[MOqV@!E5S7 [*ij0ڐ j0ڐ 骙#aSZR`!i5A`~!u5A`!} AX3! &bc il| ,*wsë6"fbΚD:?hG:k¢A:{{ĢA: ᵓW7 h Y!Dt֌Et֌O7Y}C4LgX4Lg Y3yg? Y!Dt֌Et֌EtV05[11h!f,fn"NW4HgZ Y3HgC"A:kD 鬐 Y# Y# Y1exp鬘 Y3 Y3>Lgr鬘 Y3yg? Y1!f,f,bB4LgV~!bB4LgX4Lg^ݘE:{̯h"fbΚD:+&Dtֈ8Y Y!!F,F,bF? Y3 Y1!f,f|Ί9rF? Y3 Y1!f~!bB4LgX4LgX4LgńhΚC4LgńhΚhΚ;1_t:u_ѠkE4g>5|VLp&,BB4HhX4hhX4hŔ~!ff,vbB4 iX4,it3s>~!ƴf,ִbB4iC4 jńhXԚhԚhԊ 05[11hՊ Ѱ5c05wxuciC|nygf!؊ 5քEVH2O8D֌EVL٭nb܇O9D֌EWL Lur s]3yg? ]1!f,&f,6bB4vV~!fbB4vX4 w^ݘE{h"ĻfbQD+&D~׈8^ ^!!$F,4F,FbF? 3^3 ;^1!f,f|9rF? c^3 k^1!f~!bB4,zX4LzX4lzńhC4zńhh;1_h"ĽfbQD+&D׈8_ _!!$F,4F,FbF? 3_3 ;_1!f,f|9rF? c_3 k_1!f~!bB4,~X4L~X4l~ńhC4~ńhh;1_v+{gԿf! Ѡ5؄EXH  2O8D ،EXL!%nb܇O9D،EXL9Qh&`! t(H4ef S7 [4e`1 t,H4e`1GlLf$2XE3Y89/б @2،e`1dl&bc_c,Ƣ,H4eë(E3 Z `3(C AlDe e `# `#͠h6S7 hE#ƢfB4c FOh6s>~!AшhE `3yg? `1!f,f,bB4,V~!bB4,X4,^ݘE|M+{egf!Q Ѡ 62؄E2XHeee2O8D2،E2XLeenb܇O9D2،E2XLe>hL$O&AÃd|`u0?:lLO&K!d|`m0?6lL&O & Cd{`e0?2lLD{=$(ZQ _3(36AkD' 寐 _#6 _#V _1expH[寘 _3 _3>,r寘 _3yg? _1f,flbB1,V~!b2,X3,^ݘE{EwѠ5L<$_1!FtQhP Ѡ5bѠ5bѰS7 hXhX Ѱ5cѰ5W̑0)hXhX Ѱ5psѰakƢakƢa+&DLla+&D׌ELՍzDsGEwѠ5L<$_1!FtQhP Ѡ5bѠ5bѰS7 hXhX Ѱ5cѰ5W̑0)hXhX Ѱ5psѰakƢakƢa+&DLla+&D׌ELՍ|؅wMߵѭBk&:Ib,> fb,F$׈DX)-׌JXb,׌DX^,EXh_1bk&l,b,׌DXh_1bk&bcf5#,fnÖw/x8[Z"_]sWzˋUz w]୯mWIw UvX]ҭgWsUJv ]ĭaWMp Uu趾t;P9X^N_CLd_s w\D;0}5d_s C9b^S\X;0} \r'沯ܹwa.k˾o沯۹&Ʋ/۹va,gcɳX·+u]Q.r~rÍrB&(3 ]Q.h \DtaGzqE"' ={ԋ.<Q/z0G1e_Q/~2"U?l1*`,QD1(0FF0ǨH[1"U$X( %eT$wxc>vB4zomk) ܿ#9!׻|B4wWX4}|~ ͤhn_̏ [4}{2?&lLE3)׻'cͤhn_̏9[4}{2?lLE3)׻'cͤhE3)׻'cͤhn_L;aD㗅k]K,Y??hn/ hn/ WX4 ,C>?fQ4'c͢hn/ ODŽ-E^̏[4,<ShEs{Yx2?l,d~٢YeE(“1gfQ4|Yx"?l,d~٢Yeɴc>QEs]3꙽yT&?eU2BGu}U1dG5 QcB~yT^Ћj< #rnb<#2f1X1Zy@+Fd"Ry@*F~VJb<`#B1"<!:1~2b<#R*1uu=HOOf%5r@#?bDP~nxur@ ?A}gOqPhiuT~^$qZŁ>vAmgOqPIhgjeT~N$ڙZ>vA]ԟ>vAY'OUqPhFz>8c/S !~'d [؇ ]/&,'!Bx"'ji<) !Ɠ؈6OzCl'!Dx<8n>6b<!ȓ"&,D"B"@$"$Ej|(!ɇ"وEHH$D"l-E"D"P$H>8nEH6b|(!ɇ""|(X$D?Z$d#ɇ""|(!qQW7+ՄTk%h)i0դ4ajZj&A8hɩjz )2O86*ڐ j09rF?ڐ Iڐps e y A`!5AR`b+f?fKf 5A`! &|=h|FVDtL3Y3HgńhG:k¢A:+$DtֈEtֈEtVL'a:kƢa:+&Dt֌Et֌O7Y1Ga:kƢa:+&DtL9DtVL鬘 Y3s鬘 Y3 Y3yW7a?|FVDtL3Y3Hg Y#:HgMX4HgY4HgR~OX4Lg06O8Dt֌Et֌O7Y}C4LgX4Lg Y3yg? Y!Dt֌Et֌EtV05[11h!f,fn"NW4HgZ Y3HgC"A:kD 鬐 Y# Y# Y1exp鬘 Y3 Y3>Lgr鬘 Y3yg? Y1!f,f,bB4LgV~!bB4LgX4Lg^ݘE:{h"ijfbQϚD>+&D~ֈ8Z Z!!$F,4F,FbF? 3Z3 ;Z1!f,f|Ҋ9rF? cZ3 kZ1!f~!bB4,jX4LjX4ljńh՚C4jńh՚h֚;1__o>FVDL3[3HlńhGfk¢Ah+$DֈEֈEVL'arkƢat+&D֌E֌O7[1Ga~kƢa+&DL9D WL!)1 s\3sI \3 \3yW7a{qgԹf! Ѡ5@ׄEBWH2O8DL׌ENWLnb܇O9DX׌EZWL>hL$O&AÃd|`u0?:lLO&K!d|`m0?6lL&O & Cd{`e0?2lLC&A׊JPEk&寘 _#:(M'(PPQPRX)C*,*,ńVXWXf+}C-,-,ń\X89^X 5c5cðak&bcɰakƚak&|=,+{寙gf!Q Ѡ5ׄEWH寘2O8D׌EWLnb܇O9D׌EWL寙B_ ׌y5$_1BkdׄDP h_#BkDY,Ŕ~bkFY,X4f5ӽX9rF?ef5#,b,L٢Y,X4f5#,b,Lll,b,׌DX;1_[kU_]ūU"_]sWzˋUz w]୯mWIw UvX]ҭgWsUJv ]ĭaWMp Uu趾t][WlUuհ\]UWMi U*uxD]OWeU;t@|Yzj:Q=_ÿk koQ[:t'V7oU[zc{>X^N_CLd_s w\D;0}5d_s C9b^S\X;0} \r'沯ܹwa.k˾o沯۹&Ʋ/۹va,gcɳX·+u]Q.r~rÍrB&(3 ]Q.h \DtaGzqE"' ={ԋ.<Q/z0G1e_Q/~2"U?l1*`,QD1(0FF0ǨH[1"U$X( %eT$wxc>vB4zomk) ܿc9!׻|B4wWX4}|~ ͤhn_̏ [4}{2?&lLE3)׻'cͤhn_̏9[4}{2?lLE3)׻'cͤhE3)׻'cͤhn_L;aD㗅k]K,Y??hn/ hn/ WX4 ,C>?fQ4'c͢hn/ ODŽ-E^̏[4,<ShEs{Yx2?l,d~٢YeE(“1gfQ4|Yx"?l,d~٢Yeɴc>QEs]3꙽yT&?eU2BGu}U1dG5 QcB~yT^Ћj< #rnb<#2f1X1Zy@+Fd"Ry@*F~VJb<`#B1"<!:1~2b<#R*1uu=HOOf%5r@#?bDP~nxur@ ?A}gOqPhiuT~^$qZŁ>vAmgOqPIhgjeT~N$ڙZ>vA]ԟ>vAY'OUqPhFz>8c/S !~'d [؇ ]/&,'!Bx"'ji<) !Ɠ؈6OzCl'!Dx<8n>6b<!ȓ"&,D"B"@$"$Ej|(!ɇ"وEHH$D"l-E"D"P$H>8nEH6b|(!ɇ""|(X$D?Z$d#ɇ""|(!qQW7+ՄTk%h)i0դ4ajZj&A'&F"hi j6fF?ڐ ke U A`\Q!]5s>~!e AV3!m &ARW3!y FH_qІLmHa#hCk&6$8hC*LՍzќ'+{鬙gf!Ί 5tքEtVH鬘2O8Dt֌EtVLnb܇O9Dt֌EtVL鬙#5tV 5tքEtEtֈEtW^;exp,q3C4LgtV8rF? Y3 Y!DtL9DtV05c05c0B4LgV~!C鬙ëHgS ٽVDxL3Y3gńhG@k¢AA+$DֈEֈEÈVL'aFkƢaG+&DÐ֌EÒ֌O7SZ1GaLkƢaM+&DÜL9DàVLEIM Z3sY Z3 Z3yW7aF|nygf!؊ 5քEVH2O8D֌EVL٭nb܇O9D֌EWL Lur s]3yg? ]1!f,&f,6bB4vV~!fbB4vX4 w^ݘE{h"ĻfbQD+&D~׈8^ ^!!$F,4F,FbF? 3^3 ;^1!f,f|9rF? c^3 k^1!f~!bB4,zX4LzX4lzńhC4zńhh;1_h"ĽfbQD+&D׈8_ _!!$F,4F,FbF? 3_3 ;_1!f,f|9rF? c_3 k_1!f~!bB4,~X4L~X4l~ńhC4~ńhh;1_h"ĿfbQD+&D׈8` `!!$F,4F,FbF? 3`3 ;`1!f,f|9rF? c`3 k`1!f~!bB4,X4LX4lńhC4̂ńhh;1_b2xwmtkPCl&~ ef 6DlB(/С 6"LF$2XL'@2،ef 6#Lfg,E3Yh&`1dl&@2XL`3dlƿ@2XE3YXh&`3:fnâ & VD2L3`3(ńhPGl¢A,$D2؈E2؈E2XL'alƢa,&D2،E2،O7`1GalƢa,&D2L9D2XLeee `3se `3 `3yW7aQ_Se^+Al&exHbB4(耣 6aѠ AlĢAlĢa, oѰ 6cѰ alƢalƧe#aSѰ 6cѰ al&a,&D2،E2،E2XLe؊ُ9D2XLeeë(}E Z `3(C AlDe e `# `#͢h6S7 hE#ƢYfB4c,FOh6s>~!EшhE `3yg?͢h6YfQ4b,El&D(1sfQ4 ,FE2LՍzX4A׊hP}Fl&e `#:(MX4(hPhPhX)C4,X4,ńhXhXf,}C4,X4,ńhX89hX Ѱ 6cѰ 6cѰ al&bcѰ alƢal&|=QEs~E2xѠ 62L<$`1!FtQhP Ѡ 6bѠ 6bѰ S7 hXhX Ѱ 6cѰ 62X̑0)hXhX Ѱ 6psѰ alƢalƢa,&D2Lla,&D2،E2LՍzXD|07LdU냉(D|`" z0Q߿<L&sg5d |`2r0Y߿8 Lv &3kd|`2j0Y߿4 L &g+d{`2O &&A׊JPEk&寘 _#:(M'(PPQPRX)C*,*,ńVXWXf+}C-,-,ń\X89^X 5c5cðak&bcɰakƚak&|=,+{寙gf!Q Ѡ5ׄEWH寘2O8D׌EWLnb܇O9D׌EWL寙B_ ׌y5$_1BkdׄDP h_#BkDY,Ŕ~bk%,_1bkFY,t/b܇O٢Y,H4f5psh_1bkFY,H4f5[11_ WEXh_3yW7aK}ͻJxJ䋗Խu*YoyJ[_֗*n}aj[_ծ֗Vyn}1j[_ɮ֗5 n}j{[_ֶ֗u몙m}Ѻj_[_֗)m}jC[^֗V骹l}qj'[_Ȟ/KψD5[X[𷶰umK9[yb{^ui_7o郥;$?D;0}5Ld_s 7\H;0#50}5eߺs sٗp%7|b.ʝk˾q/ܹva.kKlb,k˾kƲy1<뫌|Q.ھRׅy-/(/(0?(1_Q.d"r1:EMDv .71a_Q/r2У^`|G肏zѩs>S'#*`,QELcèbƂUH" cTacq*dǘ-QE2PXFK2qW;a'DwF?f`}?}'DszyE3!׻"LE3)׻'cͤhn_̏[4}{2?lLE3)׻'cͤhn_̏9[4}{2?lL_ȏ1[4}{2?lLɴc>vA4~Y6ڵ͂h/ C.9~ /yE ?hEs{Yx2?&l,d~LآYeE(“1efQ4'c͢hn/ Oǜ-E^̏9[4,<shE×'c͢hn/ Oǘ-E^L;aU4׵b<#k< !v.1"<#qQW79dhVR#4Ÿ#VKH?9-OWX >- }~f$iZ偟>vVAuOqPih'jm~V$ڙZ>vVAeOqP)hgj]EhGjY~B$ڑZU>f#>!?2.*Po{B-}xЅ _lxB"d'!BxRə~Ɠ"k"@$H>}?l"@$"$D"B"P$ə~ɇ""|(X$DDH (1"P$B$EC6Z$d#ɇ""|(!ɇ"وEHxEH6b|(!ɇ"uuý+A[MHV=QMJf"hi jj8h j ڐ)#hC6$f"hC2 骙#aS )k0ڐ ik0yg?ڐ k0ڐ ڐ[11GІ4LmHdqІT6ë9OW4HgZ Y3HgC"A:kD 鬐 Y# Y# Y1exp鬘 Y3 Y3>Lgr鬘 Y3yg? Y1!f,f,bB4LgV~!bB4LgX4Lg^ݘE:{ޯh"fbΚD:+&Dtֈ8Y Y!!F,F,bF? Y3 Y1!f,f|Ί9rF? Y3 Y1!f~!bB4LgX4LgX4LgńhΚC4LgńhΚhΚ;1_h'ߵѭ 5tL<$Y1!FtΚh 5b 5b0S7 hΚhΊ 05c05tV̑0)hΚhΊ 05ps0a:kƢa:kƢa:+&DtLla:o-f,~3ݘE:]Z Y3ϨgC"B4g#5aѠB4HhX4hhX4F~!ESߋ<(#<(#aS<(1̓05ps0B4,jX4LjX4lj Z3sYaWkƢaXk&|=,ڇ~\Z Z3lC"AdkD  R[# b[# s[1expɭѭ [3 [3>Lor \3yg? 3\1!f,f,ƸbB4qV~!&bB4rX4r^ݘE{h"ĹfbQ皉D+&D>׈8] ]!!$F,4F,FbF? 3]3 ;]1!f,f|9rF? c]3 k]1!f~!bB4,vX4LvX4lvńh횉C4vńh횱h;1_t: _ѠkE4w>5|WLp&,BB4HxX4hxX4xŔ~!ff,vbB4 yX4,yt3s>~!Ƽf,ּbB4yC4 zńhXhh 05[11h Ѱ5c05wxuci_ѠkE4{>5WL}p&,BB4H|X4h|X4|Ŕ~!ff,vbB4 }X4,}t3s>~!ƾf,־bB4}C4 ~ńhXhh 05[11h Ѱ5c05wxuc﵃_ѠkE4>5WLp&,BB4HX4hX4Ŕ~!ff,vbB4 X4,t3s>~!f,bB4́C4 ńhXhh 0 6[11h Ѱ 6c0 6wxuc~ ea/С 6?2Lz`1Dld2؄D3Q _ClD(H4e2O8~e`1 t,H4e`1GlLf$2XE3Y89/б @2،e`1dl&bc_c,Ƣ,X;1_2W4(Z `3(C AlDe e `# `# `1expee `3 `3>,ree `3yg? `1!f,f,bB4,V~!bB4,X4,^ݘE|M+{egf!Q Ѡ 62؄E2XHeee2O8D2،E2XLeenb܇O9D2،E2XLe,ree `3yg? `1!f,f,bB4,V~!bB4,X4,^ݘE|M+D]+y@4bbQD,&D2؈8` `!!F,F,E2O8DhX4f3!E#ƢyP4b|f܇O9DhX4f3!E#&yP4 <(1̓c<(̈́h؊ُ9Dh6yP4b,fnâ IA׊hP}Fl&e `#:(MX4(hPhPhX)C4,X4,ńhXhXf,}C4,X4,ńhX89hX Ѱ 6cѰ 6cѰ al&bcѰ alƢal&|=,a" n>@肛&*D|` {0?=(_L&{w9d |`s0?9,_L&;s d|`k0?5,_L &w3d{`c0'x_kE%(5ψWLh&BB((((X),Ŕ~!flbB+,+,`s>~ʡfbB.,C/,ń_X`XaX Ű5[11dX ˰5cͰ5wxuc_ ߽VDL3_3(ńhPGk¢A+$D׈E׈EWL'akƢa+&D׌E׌O7_1GakƢa+&DL9DWL寘 _3s寘 _3 _3yW7aQ^_ѠkE4(>5WLp&,BB4(X4(X4,Ŕ~!f,bB4,X4,ts>~!f,bB4,C4,ńhXhXhX Ѱ5[11hX Ѱ5cѰ5wxuc>vwmtk寄EkPNf5BkBY(X4 f5",bF?af5f5#,ft_1Gl,f$WEX89[4f5#,f$WEX㯄e+ƢY,H4寙ë]% UZ_]%KU:w]筯pW yU vt]٭jWuKU+zv<]˭dW rUKv]^WnKUku̶h]XW kUZuՔP]-RWgKUt\8]LW dϗ߮׿7ʿk6omam=ھKs-ҾKo,}KwCI聉wa"kȾz&o޹wa(Gk`*ڝk˾u/ݹKn\;0}5e_s s\\u;0Xe;0}5e_c,yWRׅy-/(/(0?(1_Q.d"r1:EMDv .71a_Q/r2У^`|G肏zѩs>S'#*`,QELcèbƂUH" cTacq*dǘ-QE2PXFK2qW;a'DwF?f`}?}'DszyE3!׻"LE3)׻'cͤhn_̏[4}{2?lLE3)׻'cͤhn_̏9[4}{2?lL_ȏ1[4}{2?lLɴc>vA4~Y6ڵ͂h/ C.9~ /yE ?hEs{Yx2?&l,d~LآYeE(“1efQ4'c͢hn/ Oǜ-E^̏9[4,<shE×'c͢hn/ Oǘ-E^L;aU4׵b<#k< !v.1"<#qQW79dhVR#4Ÿ#VKH?9-OWX >- }~f$iZ偟>vVAuOqPih'jm~V$ڙZ>vVAeOqP)hgj]EhGjY~B$ڑZU>f#>!?2.*Po{B-}xЅ _lxB"d'!BxRə~Ɠ"k"@$H>}?l"@$"$D"B"P$ə~ɇ""|(X$DDH (1"P$B$EC6Z$d#ɇ""|(!ɇ"وEHxEH6b|(!ɇ"uuý+A[MHV=QMJf"hi jj8h j ڐ)#hC6$f"hC6$`f܇O968hCj&6#hCj&6$8hC6$f"hC LlAX3! AR`n<_ kE4Hg>#5tVLp&,BB4HgX4HgX4LgŔ~!f,bB4LgX4Lgt3s>~!f,bB4LgC4LgńhΚhΚhΊ 05[11hΊ 05c05wxucuzA:׊hΚ}F:k&鬘 Y#:HgMX4HghhhΊ)C4LgX4LgńhΚhΚf:+}C4LgX4LgńhΚ89hΊ 05c05c0a:k&bc0a:kƢa:k&|=,d~Etv 5tL<$Y1!FtΚh 5b 5b0S7 hΚhΊ 05c05tV̑0)hΚhΊ 05ps0a:kƢa:kƢa:+&DtLla:+&Dt֌EtLՍzX[֊hϚ}F=k& Y#:hMX4(hhhhъ)C4hX4hńhҚhXҚfJ+}C4iX4ińhӚ89hԊ Ѱ5c05cѰaTk&bc0aWkƢaXk&|=,֊hך}F`k&AdkD AjkĢAlkĢ9(/9O8DsP41L?A㰙~!8rF?Aшhf!DL9D W05c05c0B4qV~!&CQYëHsܽVD8L3\3sńhGk¢A+$DD׈EF׈EHWL'akƢa+&DP׌ER׌O7S]1GakƢa+&D\L9D`WLŮɮͮ ]3sٮ ]3 ]3yW7a^'+{gԻf! Ѡ5ׄEWH  2O8DÌ׌EÎWL!%nb܇O9DØ׌EÚWL9Qh&`! t(H4ef S7 /б 6_c,&~ef 6=Y9rF?ef 6#Lb,2L9~e:f t,Xh&`3s`1dlƿ@2LՍzќe^+Al&exHbB4(耣 6aѠ AlĢAlĢa, oѰ 6cѰ alƢalƧe#aSѰ 6cѰ al&a,&D2،E2،E2XLe؊ُ9D2XLeeë(~E2xѠ 62L<$`1!FtQhP Ѡ 6bѠ 6bѰ S7 hXhX Ѱ 6cѰ 62X̑0)hXhX Ѱ 6psѰ alƢalƢa,&D2Lla,&D2،E2LՍzXľA׊hP}Fl&e `#:(MX4(hPhPhX)C4,X4,ńhXhXf,}C4,X4,ńhX89hX Ѱ 6cѰ 6cѰ al&bcѰ alƢal&|=,k_Ѡ kE4(> 62XLep&,BB4(X4(X4,Ŕ~!f,bB4,X4,t s>~!f,bB4,C4,ńhXhXhX Ѱ 6[11hX Ѱ 6cѰ 6wxuceOQE׊h*3(C AlDe e `# `#ш)C4DcƢ9 1!1cs>~!1cј89hFLhX4DcƢ9 1!1[11hFLhX4,^ݘEhf MF,$Up `:h0H`P_^-3\C.-Z Y if vvBlf_C*qtC)l(L1vnn .a+*a+$/j{='&A׊JPEk&寘 _#:(M'(PPQPRX)C*,*,ńVXWXf+}C-,-,ń\X89^X 5c5cðak&bcɰakƚak&|=,+{寙gf!Q Ѡ5ׄEWH寘2O8D׌EWLnb܇O9D׌EWL寙B_ ׌y5$_1BkdׄDP h_#BkDY,Ŕ~bk%,_1bkFY,t/b܇O٢Y,H4f5psh_1bkFY,H4f5[11_ WEXh_3yW7aGf| Sw)%I{GHzGGyGF yGF)xG5EIwGUDmvGuCuGBtGAsG@rG5^x|v;^Q/wmG5:׾v{\Q/p-jG5ֆvZQ/if E (ed}brF| &-G]wouVXW]o鍥[`{:=0}5Ld߽s W\D;0}5 y Le_s cٷ\\;7s ˾roܹ wa.k˾n#˾lƲڹvu%*c9buFp^ˋ7K1L7E r >h\$tAGrQх&; &7~Lyԋ.:_Q/v2^dtjGǔ}GH `T$p0 FD2ŨHFUX#o1fdTc*d$QŒLՎ| ݿѮh&DszY??hn_!d ܾC^=bLH4}{2?&lLE3)׻'cͤhn_̏)[4}{2?lLE3)׻'cͤhn_̏9[4׻'cͤhn_̏1[4}{2χ]_v-E ?f` ,C> ,C^=b,@$E^̏ [4,<hEs{Yx2?Fl,d~L٢YeE(“1gfQ4'c͢hn/ Oǜ-EeE(“1ffQ4'ӎ|Gu/Cl$g6Z$DDH6b|(!ɇ"H6rG?[CH>F,E"$k|(X$DDHH$d#ɇ"~ɇ"وEHH$DH\ bj:m5!Z jJLD5) &bMFML'z4m595A[MOqV@!E5S7 GІ45mHTDІT5ye Y U3GAR`!i5c #hCj&6$8hC6$f"hC LlAX3! AR`n<_ kE4Hg>#5tVLp&,BB4HgX4HgX4LgŔ~!f,bB4LgX4Lgt3s>~!f,bB4LgC4LgńhΚhΚhΊ 05[11hΊ 05c05wxucuzA:׊hΚ}F:k&鬘 Y#:HgMX4HghhhΊ)C4LgX4LgńhΚhΚf:+}C4LgX4LgńhΚ89hΊ 05c05c0a:k&bc0a:kƢa:k&|=,d~Etv 5tL<$Y1!FtΚh 5b 5b0S7 hΚhΊ 05c05tV̑0)hΚhΊ 05ps0a:kƢa:kƢa:+&DtLla:+&Dt֌EtLՍzXש^+ALyr15 s^3yg? ^1!f,&f,6bB4zV~!fbB4zX4 {^ݘE{W4h{Z ^3Ϩ{C"AkD  _# _# #_1exp C_3 K_3>L}r s_3yg? _1!f,&f,6bB4~V~!fbB4~X4 ^ݘT\; ߽VDL3_3ńhGl¢A,$D؈E؈EXL'alƢa,&D،E،O7S`1Ga lƢa ,&DL9D XLEIM `3sY `3 `3yW7WPn`3`(įW cLF(MH4e:F$2؈D3Y)X/б @2،D3YϞ s>~dlF,X4e 62XLep&,BB4(X4(X4,Ŕ~!f,bB4,X4,t s>~!f,bB4,C4,ńhXhXhX Ѱ 6[11hX Ѱ 6cѰ 6wxuce5hP"fbQD,&D2؈8` `!!F,F,bF? `3 `1!f,f|Y9rF? `3 `1!f~!bB4,X4,X4,ńhXC4,ńhXhX;1_2'e^+Al&exHbB4(耣 6aѠ AlĢAlĢa, oѰ 6cѰ alƢalƧe#aSѰ 6cѰ al&a,&D2،E2،E2XLe؊ُ9D2XLeeë( GY*yB3&*D|` {0?=(_L&{w9d |`s0?9,_L&;sNN7Rn'r`>)ۗI>4OpC&O7TdL}Mw5L<#_1aFtQOP 5b5bS7 TXUX 5c5W̑0)ZX[X 5ps~akƂakƆa+&Lla+&,׌5LՍzXW4(Z _3(CAkD 寐 _# _# _1exp寘 _3 _3>,r寘 _3yg? _1!f,f,bB4,V~!bB4,X4,^ݘ@4W4(Z _3(CAkD 寐 _# _# _1exp寘 _3 _3>,r寘 _3yg? _1!f,f,bB4,V~!bB4,X4,^ݘχ](]Z+aQ>/f⯓D+ƢY(Ph_!BkDY(H4寘2OآY,e+ƢY,H4W̑0)[4fc,f~b+ƢY,H4fc,fb+f?+aYh_3bk&|=l)yWI~wvW|Rw]%-/rWy+UBv]%ݭ/lWmvUcvJ]5ϭ/fWr+U2v]5/`WmoUuڶn]5/ZWk+UruբV]5/TWmh˫Uuj>]5/NWd+UeT5' k|Ե}K9XUX޿郥;$?D;0}5Ld_s 7\H;0#50}5eߺs sٗp%7|b.ʝk˾q/ܹva.kKlb,k˾kƲy1<뫌|Q.ھRׅy-/(/(0?(1_Q.d"r1:EMDv .71a_Q/r2У^`|G肏zѩs>S'#*`,QELcèbƂUH" cTacq*dǘ-QE2PXFK2qW;a'DwF?f`}?}'DszyE3!׻"LE3)׻'cͤhn_̏[4}{2?lLE3)׻'cͤhn_̏9[4}{2?lL_ȏ1[4}{2?lLɴc>vA4~Y6ڵ͂h/ C.9~ /yE ?hEs{Yx2?&l,d~LآYeE(“1efQ4'c͢hn/ Oǜ-E^̏9[4,<shE×'c͢hn/ Oǘ-E^L;aU4׵b<#k< !v.1"<#qQW79VF9Mx[Xd~vl` 2| @6 9N8(M%؄q=(/qG;Qk66!kƗ4Jcqf;S+2q0 cA_| .6vAYD+JH6f#>!?2.*Po{B-}xЅ _lxB"d'!BxRə~Ɠ"k"@$H>}?l"@$"$D"B"P$ə~ɇ""|(X$DDH (1"P$B$EC6Z$d#ɇ""|(!ɇ"وEHxEH6b|(!ɇ"uuý+A[MHV=QMJf"hi jj8h j ڐ)#hC6$f"hC6$`f܇OjHYqІLmH[89GІLmH^qІ5mH`DІ6؊ُ96f"hC"6^ݘy¿A:׊hΚ}F:k&鬘 Y#:HgMX4HghhhΊ)C4LgX4LgńhΚhΚf:+}C4LgX4LgńhΚ89hΊ 05c05c0a:k&bc0a:kƢa:k&|=,~Etv 5tL<$Y1!FtΚh 5b 5b0S7 hΚhΊ 05c05tV̑0)hΚhΊ 05ps0a:kƢa:kƢa:+&DtLla:+&Dt֌EtLՍzX^+A:k&鬙xHbB4Hg#5a A:kĢA:kĢa:+ o05c0a:kƢa:kƧ鬘#aS05c0a:k&a:+&Dt֌Et֌EtVL鬙؊ُ9DtVL鬙ëHgS ٽVDxL3Y3gńhG@k¢AA+$DֈEֈEÈVL'aFkƢaG+&DÐ֌EÒ֌O7SZ1GaLkƢaM+&DÜL9DàVLEIM Z3sY Z3 Z3yW7a^'+ĵ{ygf!؊ 5քEVH2O8D֌EVL٭nb܇O9D֌EWL Lur s]3yg? ]1!f,&f,6bB4vV~!fbB4vX4 w^ݘ}A4?|FVDxL3]3w ]#:xMX4(x ^# ^#͋(C4/FEhX4/FEh۴~GyQ4EhB4yC4 z ^3 ^3 ^!DèLla֫?hh;1_h"ĽfbQD+&D׈8_ _!!$F,4F,FbF? 3_3 ;_1!f,f|9rF? c_3 k_1!f~!bB4,~X4L~X4l~ńhC4~ńhh;1_h"ĿfbQD+&D׈8` `!!$F,4F,FbF? 3`3 ;`1!f,f|9rF? c`3 k`1!f~!bB4,X4LX4lńhC4̂ńhh;1_b2xwmtkPCl&~ ef 6DlB(/С 6"LF$2XL'@2،e:f$2،Nd,}-2،D3Yh&`3yg?:bX/б 6_c,Ƣ,V~ t,X4e`3yW7aQ_e^+Al&exHbB4(耣 6aѠ AlĢAlĢa, oѰ 6cѰ alƢalƧe#aSѰ 6cѰ al&a,&D2،E2،E2XLe؊ُ9D2XLeeë(~E2xѠ 62L<$`1!FtQhP Ѡ 6bѠ 6bѰ S7 hXhX Ѱ 6cѰ 62X̑0)hXhX Ѱ 6psѰ alƢalƢa,&D2Lla,&D2،E2LՍzXľA׊hP}Fl&e `#:(MX4(hPhPhX)C4,X4,ńhXhXf,}C4,X4,ńhX89hX Ѱ 6cѰ 6cѰ al&bcѰ alƢal&|=,k_Ѡ kE4(> 62XLep&,BB4(X4(X4,Ŕ~!f,bB4,X4,t s>~!f,bB4,C4,ńhXhXhX Ѱ 6[11hX Ѱ 6cѰ 6wxuceO VD2L3`3(ńhPGl¢A,$D2؈E2؈E2XL'alƢa,&D2،E2،O7`1GalƢa,&D2L9D2XLeee `3se `3 `3yW7aQ_ .͠ ,XH< cF,A ` ` {v!B b0x#G b0HH$(ZQ *L<#_1aFtQOP 5b5bS7 TXUX 5c5W̑0)ZX[X (1yg?ˋzLE`^El&bV~!%̋cͰ5wxuc_ ߽VDL3_3(ńhPGk¢A+$D׈E׈EWL'akƢa+&D׌E׌O7_1GakƢa+&DL9DWL寘 _3s寘 _3 _3yW7aQ^_ѠkE4(>5WLp&,BB4(X4(X4,Ŕ~!f,bB4,X4,ts>~!f,bB4,C4,ńhXhXhX Ѱ5[11hX Ѱ5cѰ5wxuc>vwmtk寄EkPNf5BkBY(X4 f5",bF?af5f5#,ft_1Gl,f$WEX89[4f5#,f$WEX㯄e+ƢY,H4寙ë]% UZ_]%KU:w]筯pW yU vt]٭jWuKU+zv<]˭dW rUKv]^WnKUku̶h]XW kUZuՔP]-RWgKUt\8]LW dϗ moombmoo[{Ե},]o剕 [zե}X޿ٗ\D;0}5Ld߼s #\PT;0}5e_s1+wa.Ɲk˾p۹va.1va,k˾jYX2!FhJ]n 絼x\d\dp\`|!G6LBt /(5]Q.l"^`rxDŽ}GBzb' >OFvԋ0~Lԋ0FA2q9[ ! bTA$#Q*d$Q18VcHFI0ʨBIFbU,^χS_v-E3!3 јCNFE3!#OƄD3!!̈́hH41"LFLoE3)3ͤhX41#LƌNhǔ-Iјh&E#Ƣ8ǜ-Iшh&EcFfR4b,IјVch&E#ƢfR4fv./ FYe~0~^!d^!hDs{Y|~ ͢hn/ ODŽ-E^̏ [4,<#hEs{Yx2?l,d~٢YeE(“1gfQ4'c͢hD~٢YeE(“i|>죊֗g3{)51M~T>d1h?b 0j̣ Ƅ~1!<!9ry@.F"jy@-FdbD9bV*XETqt"Fy(F$bD>y'Btbp-d".y%FTb$.{>쟞[JjFj ?')> @SLD;M<'N8I8?-}DJD;SK4'8 I30 ?%}L?#}H-OHD;R*'ь|'Dq^xߥT|BxOb# _E#?Z$DDH6b|(!qf?]Cl"P$B$E"D"P$H>õH>F,E"D"P$B⢮nWS%h JVS`&D SR34T55 A[MNDV@dQ@!E5S7 GІ45mHTDІT5mHVqEt̑0)GІ5e i5A`~!u5A`!} AX3V@ LlAX3! AR`n<_ kE4Hg>#5tVLp&,BB4HgX4HgX4LgŔ~!f,bB4LgX4Lgt3s>~!f,bB4LgC4LgńhΚhΚhΊ 05[11hΊ 05c05wxucuzA:׊hΚ}F:k&鬘 Y#:HgMX4HghhhΊ)C4LgX4LgńhΚhΚf:+}C4LgX4LgńhΚ89hΊ 05c05c0a:k&bc0a:kƢa:k&|=,d~Etv 5tL<$Y1!FtΚh 5b 5b0S7 hΚhΊ 05c05tV̑0)hΚhΊ 05ps0a:kƢa:kƢa:+&DtLla:+&Dt֌EtLՍzXש^+A,ree `3yg? `1!f,f,bB4,V~!bB4,X4,^ݘE|M+{egf!Q Ѡ 62؄E2XHeee2O8D2،E2XLeenb܇O9D2،E2XLe1(^+*Ak&6寙xFb&(D5aBAkFAkJa+ o5cZak^ak寘#aS5crak&za+&׌׌ WL(寙؊ُ9$WLXk寙ë(hP"wgf!Q Ѡ5ׄEWH寘2O8D׌EWLnb܇O9D׌EWL ј89h1cѼ!3yC4fb+f?yC4f,fnâA׊hP}Fk&寘 _#:(MX4(hPhPhX)C4,X4,ńhXhXf+}C4,X4,ńhX89hX Ѱ5cѰ5cѰak&bcѰakƢak&|>B_ ׌y5$_1BkdׄDP h_#BkDY,Ŕ~bk%,_1bkFY,t/b܇O٢Y,H4f5psh_1bkFY,H4f5[11_ WEXh_3yW7aK}ͻJxJ䋗Խu*YoyJ[_֗*n}aj[_ծ֗Vyn}1j[_ɮ֗5 n}j{[_ֶ֗u몙m}Ѻj_[_֗)m}jC[^֗V骹l}qj'[_Ȟ/KB3M-[[Xkҁ<K/Kuz`"kȾ{&޹wa$kʾvƲoݹKwn8>1}5e߸s s\\};0}5%F61}5eߵs cW<KUr>(m_r἖oc n/(2}FI肎rAE& ;ʅMDwԋLo/9]Q/t0أ^dtGԎzу9bƏ)zF@0"H&1gaT1cA*d$QE108FG2ފcɨ" BU(H,%ëyݿѮh&Dcel@8 H%rTqP;KXձ 96{P_∉vAmlB8h/ai&pvVAe| 16!a&䋃A]lCH-vAWlB8Mm\HG|Be'L]JU< !'\!ď,6b[ ؄0DOC263\-'!Dx6ԆyIo~R9b:Oc#Ǔmӵ>F'!DyR Bd' +Ig?\KIly"B'5"$.{>竊VH^U${)E"1}UHX$*,H H$*ɫĄD"1! !9"yA$F$D""yA$F$DbD9bEHH$/DEHqt-D""yA$F$DbD"yA$B,Dbp-D""yA$F$Db$.{>"9/%7D]J!!7D"H6b!,!"لEHDH$oDDH63\-7E"D"yS$HMA~S$9bEHH$od#ɛ"mӵHF,7E"D"yS$B$7EMg?\Ml"yS$B$7E"$.{>"9%D]J| !D"H6b| , "لEHDH$DDH63\-E"D"P$H>CAP$9bEHH$d#ɇ"mӵH>F,E"D"P$B$ECg?\Cl"P$B$E"$.{E15Wjm5% &z1LMK&&=jj8h j R@j o ij0ڐ j0ڐ 骙#aS )k0ڐ\`~!u5A`!} AX3! &bc i[f AR`n<_ kE4Hg>#5tVLp&,BB4HgX4HgX4LgŔ~!f,bB4LgX4Lgt3s>~!f,bB4LgC4LgńhΚhΚhΊ 05[11hΊ 05c05wxucuzA:׊hΚ}F:k&鬘 Y#:HgMX4HghhhΊ)C4LgX4LgńhΚhΚf:+}C4LgX4LgńhΚ89hΊ 05c05c0a:k&bc0a:kƢa:k&|=쪢NW4HgZ Y3HgC"A:kD 鬐 Y# Y# Y1exp鬘 Y3 Y3>Lgr鬘 Y3yg? Y1!f,f,bB4LgV~!bB4LgX4Lg^ݘE:{h"ijfbQϚD>+&D~ֈ8Z Z!!$F,4F,FbF? 3Z3 ;Z1!f,f|Ҋ9rF? cZ3 kZ1!f~!bB4,jX4LjX4ljńh՚C4jńh՚h֚;1__o>FVDL3[3HlńhGfk¢Ah+$DֈEֈEVL'arkƢat+&D֌E֌O7[1Ga~kƢa+&DL9D WL!)1 s\3sI \3 \3yW7a{qgԹf! Ѡ5@ׄEBWH2O8DL׌ENWLnb܇O9DX׌EZWLߵѭ 5L<$^1!FthP 5bѠ5b0S7 hh 05cѰ5W̑0)hhX 05ps0akƢakƢa+&DLla+&D׌ELՍzXߵѭ 5L<$_!D׈8` `!D؈E؈Eh2O8DhX4F| 31h_7O9Dhp<79D89h!f,&f,6CQ؊ُ9D,XѰ 6c0 6wxuc~ ea/С 6?2Lz`1Dld2؄D3Q _ClD(H4e2O8~e`1 t,H4e`1GlLf$2XE3Y89/б @2،e`1dl&bc_c,Ƣ,X;1_2W4(Z `3(C AlDe e `# `# `1expee `3 `3>,ree `3yg? `1!f,f,bB4,V~!bB4,X4,^ݘE|M+{egf!Q Ѡ 62؄E2XHeee2O8D2،E2XLeenb܇O9D2،E2XLe,ree `3yg? `1!f,f,bB4,V~!bB4,X4,^ݘE|M+{egf!Q Ѡ 62؄E2XHeee2O8D2،E2XLeenb܇O9D2،E2XLe@肛&*D|` {0?=(_L&{w9d |`s0?9,_L&;s d|`k0?5,_L &w3d{`c0'x_kE%(5ψWLh&BB((((X),Ŕ~!flbB+,+,`s>~ʡfbB.,C/,ń_X`XaX Ű5[11dX ˰5cͰ5wxuc ߽VDL3_3(ńhPGk¢A+$D׈E׈EWL'akƢa+&D׌E׌O7_1GakƢa+&DL9DWL寘 _3s寘 _3 _3yW7aQ^_ѠkE4FL3_3(ńhPGk¢A+$D׈E׈EWL'akƢa+&D׌E׌O7_1GakƢa+&DhC4f3!E#ƢP4b,E͇[11h>fB4FELՍ|؅wMߵѭBk&:Ib,> fb,F$׈DX)-׌JXb,׌DX^,EXh_1bk&l,b,׌DXh_1bk&bcf5#,fnÖw/xWi}jw/uW{U"w]%/oW)xkUvf]5֭/iWtUbv.]5ȭ/cW-qkUvz]5/]WmU3uվb]5/WW-jkUSBuՆJ]5/QWfUstN2]5{Yz}1Ft ϵk ksQ׾w\:ts剕KK;>X]'/&|&{&z&yFxrļvut׆c.s^k s޸k s^k s޷k s^k sM{ٮ5{׮5{ծY_e,C| 7ʅZ^Q.^2ޏQ.`2~Q.b0\DAb& : u.(6]Q/n09c¾ȣ^dtGbz'S;E}??OFUX 8ǜ-Q1 (FE2ƨUx+1[$$ eT$#*dvNfZZfB4ŬrB4E3!#OƄD3!ɢfB4F$IO9cͤhH4џ,Iјh&EcF{R40~L٢fR4E3)3q9[4џ,Iјh&EcFdLƌbE3)ɢfR4fv.F/ ϵѮhDs{Yx2\ _|A4|Yx"hD×'H4‹1afQ4|Yx1?&l,/ /Lj-EeE(,shE×c͢hb~٢Y _^̏9[4 1ffQ4|Yx1?l,/ /*Z_yṬjƈ7Q-cbOB|/6aa˯*ɫDE"1!HLH$/DHlsH^H^A~A$Bgk # "b #qf?]H^H^g?\H^HKs |R$oDw !X$oD>oDDH6a!"!)F?WMHF,7E"D"yS$BtFgk)!ɛ"وEHqt-7EMHMl"yS$B<"yS$HMH+q|R$Dw} X$D>DDH6a| "!|(F?WCH>F,E"D"P$Bt?Fgk|(!ɇ"وEHqt-ECH>Cl"P$B<"P$H>C^QLMG&Z+A[MI掚1LMKDV@R4m595A[MOqV@!E5S7 GІ45mHTDІT5ye Y U3GAR`!i5A`~!u5A`!} AX3! &bc iڐ l0yW7aDsh"fbΚD:+&Dtֈ8Y Y!!F,F,bF? Y3 Y1!f,f|Ί9rF? Y3 Y1!f~!bB4LgX4LgX4LgńhΚC4LgńhΚhΚ;1_t:_ kE4Hg>#5tVLp&,BB4HgX4HgX4LgŔ~!f,bB4LgX4Lgt3s>~!f,bB4LgC4LgńhΚhΚhΊ 05[11hΊ 05c05wxucu2A:׊hΚ}F:k&鬘 Y#:HgMX4HghhhΊ)C4LgX4LgńhΚhΚf:+}C4LgX4LgńhΚ89hΊ 05c05c0a:k&bc0a:kƢa:k&|=,}Evv 5zL<$Y1!FtКhP 5bѠ5b0S7 hњhъ 05cѰ5͔V̑0)hӚhXӊ 05ps0aQkƢaRkƢaS+&DèLlaV+&Dî֌EðLՍzX֊hך}F`k& "[#:lMX4mhhhۊ)C4LnX4nńhݚhޚfz+}C4oX4 pńh89h 05c05c0ak&bc0akƢak&|=,|E6w 5:L<$\1!Ft蚰hP 5bѠ5b0S7 h隱h 05cѰ5TW̑0)h뚱hX 05ps0akƢakƢa+&DhLla+&Dn׌EpLՍzXI^+Ak&xHbB4w#5aѠAkĢAkĢa+ o05cѰakƢakƧ)#aS05cѰak&a+&Dâ׌Eä׌EæWLQ؊ُ9DìWL]aëH{]m^+Ak&uxHbB4{#5aѠAkĢAkĢa+ o05cѰakƢakƧ#aS05cѰak&a+&D׌E׌EWLѯ؊ُ9DWLݯᯙëH?wmtkE4>5WLp&,BB4HX4hX4Ŕ~!ff,vbB4 X4,t3s>~!f,bB4́C4 ńhXhh 0 6[11h Ѱ 6c0 6wxuc~ ewmtkP>Of׫PDld2؄D3Q t(H4eoxd~ tQ4b tQ4 tQ4b$?E3h~>~MwDƢ,s_c?/б 6_clƿ@2Xh&`3s`,X;1_; s_Ѡ kE4(> 62XLep&,BB4(X4(X4,Ŕ~!f,bB4,X4,t s>~!f,bB4,C4,ńhXhXhX Ѱ 6[11hX Ѱ 6cѰ 6wxuce5կhP"fbQD,&D2؈8` `!!F,F,bF? `3 `1!f,f|Y9rF? `3 `1!f~!bB4,X4,X4,ńhXC4,ńhXhX;1_2W4(Z `3(C AlDe e `# `# `1expee `3 `3>,ree `3yg? `1!f,f,bB4,V~!bB4,X4,^ݘE|M+{egf!Q Ѡ 62؄E2XHeee2O8D2،E2XLeenb܇O9D2،E2XLe@肛&*D|` {0?=(_L&{w9d |`s0?9,_L&;s d|`k0?5,_L &w3d{`c0'x_kE%(5ψWLh&BB((((X),Ŕ~!flbB+,+,`s>~ʡfbB.,C/,ń_X`XaX Ű5[11dX ˰5cͰ5wxuc ߽VDL3_3(ńhPGk¢A+$D׈E׈EWL'akƢa+&D׌E׌O7_1GakƢa+&DL9DWL寘 _3s寘 _3 _3yW7aQ^_ѠkE4(>5WLp&,BB4(X4(X4,Ŕ~!f,bB4,X4,ts>~!f,bB4,C4,ńhXhXhX Ѱ5[11hX Ѱ5cѰ5wxuc>vwmtk寄}^(_'WEP|5!,B,׈DPh_1exEX_ WEXh_3:݋寘#aSh_3b+Ƣ;-?Esh~٢YQ4bb+f?+ah6cѬ(1bk&|=HьaJ;8D2)u)Y((=(!(都(nR6y]^Zzk;UwF^Zz{\Qq kG֔v+[QjgG11ۋe@jRQ5_ÿk k?oQ[:t'V7oU[zc{>X^N_CLd_s w\D;0}5d_s C9b^S\X;0} \r'沯ܹwa.k˾o沯۹&Ʋ/۹va,gcɳX·+u]Q.r~rÍrB&(3 ]Q.h \DtaGzqE"' ={ԋ.<Q/z0G1e_Q/~2"U?l1*`,QD1(0FF0ǨH[1"U$X( %eT$wxc>vB4_k]KLƌyB4fcL>1!LFE3!#̈́hH4?&lLƌD3)1ͤhH41=)1G1efR4f$Iшh&Ec&1gfR4b,Iјh&EcFfR4fǘ-Ih&E};cyW;aD㗅k]K,Y??hn/ hn/ WX4 ,C>?fQ4'c͢hn/ ODŽ-E^̏[4,<ShEs{Yx2?l,d~٢YeE(“1gfQ4|Yx"?l,d~٢Yeɴc>QEs]3꙽yT&?eU2BGu}U1dG5 QcB~yT^Ћj< #rnb<#2f1X1Zy@+Fd"Ry@*F~VJb<`#B1"<!:1~2b<#R*1uu=HOOf%5r@#?bDP~nxur@ ?A}gOqPhiuT~^$qZŁ>vAmgOqPIhgjeT~N$ڙZ>vA]ԟ>vAY'OUqPhFz>8m/S !~'d [؇ ]/&,'!Bx"'ji<) !Ɠ؈6OzCl'!Dx<8n>6b<!ȓ"&,D"B"@$"$Ej|(!ɇ"وEHH$D"l-E"D"P$H>8nEH6b|(!ɇ""|(X$D?Z$d#ɇ""|(!qQW7+ՄTk%h)i0դ4ajZj&A8hɩjz )2O868hCjZHUqІd5WTHWrmHYqІLmH[89[/ڐ# 0 ڐ[11GІ4LmHdqІT6ë9OW4HgZ Y3HgC"A:kD 鬐 Y# Y# Y1exp鬘 Y3 Y3>Lgr鬘 Y3yg? Y1!f,f,bB4LgV~!bB4LgX4Lg^ݘE:{ޯh"fbΚD:+&Dtֈ8Y Y!!F,F,bF? Y3 Y1!f,f|Ί9rF? Y3 Y1!f~!bB4LgX4LgX4LgńhΚC4LgńhΚhΚ;1_t:_ kE4Hg>#5tVLp&,BB4HgX4HgX4LgŔ~!f,bB4LgX4Lgt3s>~!f,bB4LgC4LgńhΚhΚhΊ 05[11hΊ 05c05wxucu꾢A;׊hϚ}F=k& Y#:hMX4(hhhhъ)C4hX4hńhҚhXҚfJ+}C4iX4ińhӚ89hԊ Ѱ5c05cѰaTk&bc0aWkƢaXk&|=,ڇ~\Z Z3lC"AdkD  R[# b[# s[1expɭѭ [3 [3>Lor \3yg? 3\1!f,f,ƸbB4qV~!&bB4rX4r^ݘE{D?"ĹfbQ皉D+&D>׈8] ]!!$F,4F,FbF? 3]3 ;]1!f,f|9rF? c]3 k]1!f~!bB4,vX4LvX4lvńh횉C4vńh횱h;1_t: _ѠkE4w>5|WLp&,BB4HxX4hxX4xŔ~!ff,vbB4 yX4,yt3s>~!Ƽf,ּbB4yC4 zńhXhh 05[11h Ѱ5c05wxuci_ѠkE4{>5WL}p&,BB4H|X4h|X4|Ŕ~!ff,vbB4 }X4,}t3s>~!ƾf,־bB4}C4 ~ńhXhh 05[11h Ѱ5c05wxucSEsW4hZ _3ϨC"AkD  `# `# #`1exp C`3 K`3>Lr15 s`3yg? `1!f,&f,6bB4V~!fbB4X4 ^ݘ_BX6 t( 6^2XE3Q| 6!LBPh&`#d, o_clƿ@2XE3Yh&`33b܇O٢,H4ef 6psh&`1 t,H4ef cLfb+f?:b,2،eë(k[+Al&exHCep&,CeefP4expfP4b,A?hE#ƢA(>~!A½~!8a?hXhXhX!fb+f? `!D2،E2LՍzXTA׊hP}Fl&e `#:(MX4(hPhPhX)C4,X4,ńhXhXf,}C4,X4,ńhX89hX Ѱ 6cѰ 6cѰ al&bcѰ alƢal&|=,kb_Ѡ kE4(> 62XLep&,BB4(X4(X4,Ŕ~!f,bB4,X4,t s>~!f,bB4,C4,ńhXhXhX Ѱ 6[11hX Ѱ 6cѰ 6wxuce5hP"fbQD,&D2؈8` `!!F,F,bF? `3 `1!f,f|Y9rF? `3 `1!f~!bB4,X4,X4,ńhXC4,ńhXhX;1_2'e^+Al&exHbB4(耣 6aѠ AlĢAlĢa, oѰ 6cѰ alƢalƧe#aSѰ 6cѰ al&a,&D2،E2،E2XLe؊ُ9D2XLeeë( 0a n?Ȃ&Qド&D|`y0?<L&kW1d |`q0?8Lf &+cd|`i0?4oL &W#dL}Mw5L<#_1aFtQOP 5b5bS7 TXUX 5c5W̑0)ZX[X 5ps~akƂakƆa+&Lla+&,׌5LՍzXW4(Z _3(CAkD 寐 _# _# _1exp寘 _3 _3>,r寘 _3yg? _1!f,f,bB4,V~!bB4,X4,^ݘ@4W4(Z _3(CAkD 寐 _# _# _1exp寘 _3 _3>,r寘 _3yg? _1!f,f,bB4,V~!bB4,X4,^ݘχ](]Z+aQ>/f⯓D+ƢY(Ph_!BkDY(H4寘2OآY,e+ƢY,H4W̑0)[4fc,f~b+ƢY,H4fc,fb+f?+aYh_3bk&|=l)yWI~%KU:w]筯pW yU vt]٭jWuKU+zv<]˭dW rUKv]^WnK׿# #01Σ\o <U1\*urWK5%O(8]LW dϗgaF| &-G]wouVXW]o鍥[`{:=0}5Ld߽s W\D;0}5 y Le_s cٷ\\;7s ˾roܹ wa.k˾n#˾lƲڹvu%*c9buFp^ˋ7K1L7E r >h\$tAGrQх&; &7~Lyԋ.:_Q/v2^dtjGǔ}GH `T$p0 FD2ŨHFUX#o1fdTc*d$QŒLՎ| ݿѮh&DszX??hn_!d ܾC^=bLH4}{2?&lLE3)׻'cͤhn_̏)[4}{2?lLE3)׻'cͤhn_̏9[4׻'cͤhn_̏1[4}{2χ]~pv-E 3јC.FE #/ƄD !͂hH4 1",FLoE(3͢hX41#,ƌNhǔ-EјhE#ƢY8ǜ-EшhEcFYfQ4b,EјVchE#ƢYfQ4fv>hk}yQ=R3#G?JF1*ƀ a<`L/z3\-bDny-BbDfy,Ft#?Z+hňUX*HHOJy@)BlbDBy@(F|":y@'F<2y@&B\bD*y@%F⢮ns鿕ѬFh?;G~r8Z` M@?5|Z@8IӴ<?1}4KD;N8'N8 I34J?)}LID;S 0S'Ժ83'ЎԲ8( I#*?}HG|Be'L]JU< !'\!ď,6b[ ؄0DOC263\-'!Dx6ԆyIo~R9b:Oc#Ǔmӵ>F'!DyR Bd' +Ig?\KIly"B'5"$.{>竊VH^U${)E"1}UHX$*,H H$*ɫĄD"1! !9"yA$F$D""yA$F$DbD9bEHH$/DEHqt-D""yA$F$DbD"yA$B,Dbp-D""yA$F$Db$.{>"9/%7D]J!!7D"H6b!,!"لEHDH$oDDH63\-7E"D"yS$HMA~S$9bEHH$od#ɛ"mӵHF,7E"D"yS$B$7EMg?\Ml"yS$B$7E"$.{>"9%D]J| !D"H6b| , "لEHDH$DDH63\-E"D"P$H>CAP$9bEHH$d#ɇ"mӵH>F,E"D"P$B$ECg?\Cl"P$B$E"$.{E15Wjm5% &zg5-5A[MLQHUS Hm5= A[MPqІL'A`!Q5AR`!Y U3GAR`!i5A`~@j~H^qІ5mH`DІ6؊ُ96f"hC"6^ݘy¿A:׊hΚ}F:k&鬘 Y#:HgMX4HghhhΊ)C4LgX4LgńhΚhΚf:+}C4LgX4LgńhΚ89hΊ 05c05c0a:k&bc0a:kƢa:k&|=,~Etv 5tL<$Y1!FtΚh 5b 5b0S7 hΚhΊ 05c05tV̑0)hΚhΊ 05ps0a:kƢa:kƢa:+&DtLla:+&Dt֌EtLՍzX^+A:k&鬙xHbB4Hg#5a A:kĢA:kĢa:+ o05c0a:kƢa:kƧ鬘#aS05c0a:k&a:+&Dt֌Et֌EtVL鬙؊ُ9DtVL鬙ëHgS ٽVDxL3Y3gńhG@k¢AA+$DֈEֈEÈVL'aFkƢaG+&DÐ֌EÒ֌O7SZ1GaLkƢaM+&DÜL9DàVLEIM Z3sY Z3 Z3yW7a>֊hך}F`k& "[#:lMX4mhhhۊ)C4LnX4nńhݚhޚfz+}C4oX4 pńh89h 05c05c0ak&bc0akƢak&|=,#"6w 5:L<$\1!Ft蚰hP 5bѠ5b0S7 h隱h 05cѰ5TW̑0)h뚱hX 05ps0akƢakƢa+&DhLla+&Dn׌EpLՍzDsh"ĻfbQD+&D~׈8^ ^!!$F,4F,FbF? 3^3 ;^1!f,f|9rF? c^3 k^1!f~!bB4,zX4LzX4lzńhC4zńhh;1_h"ĽfbQD+&D׈8_ _!!$F,4F,FbF? 3_3 ;_1!f,f|9rF? c_3 k_1!f~!bB4,~X4L~X4l~ńhC4~ńhh;1_h"ĿfbQD+&D׈8` `!!$F,4F,FbF? 3`3 ;`1!f,f|9rF? c`3 k`1!f~!bB4,X4LX4lńhC4̂ńhh;1_b2xwmtkPCl9Qh&`#O&$2XH`#DlD,Ŕ~ t,X_clF,gX9rF?ef 6#Lb,2L٢,X4e`3:b,2Ll@2XE3Y/б 6wxuce5hP"fbQD,&D2؈8` `!!F,F,bF? `3 `1!f,f|Y9rF? `3 `1!f~!bB4,X4,X4,ńhXC4,ńhXhX;1_2x6"fbQD?hPGl¢A?hPhPh&D?~! јh&D?h&DcƢ GfB4/s.psѰ 69D2hX!fb+f? `!D2،E2LՍzXľA׊hP}Fl&e `#:(MX4(hPhPhX)C4,X4,ńhXhXf,}C4,X4,ńhX89hX Ѱ 6cѰ 6cѰ al&bcѰ alƢal&|=,k_Ѡ kE4(> 62XLep&,BB4(X4(X4,Ŕ~!f,bB4,X4,t s>~!f,bB4,C4,ńhXhXhX Ѱ 6[11hX Ѱ 6cѰ 6wxuceO VD2L3`3(ńhPGl¢A,$D2؈E2؈E2XL'alƢa,&D2،E2،O7`1GalƢa,&D2L9D2XLeee `3se `3 `3yW7aQapD|07LT&Mۃ$D|`"x0߿;́L&cG-d |`2p0߿7̀LV &# [d|`2h0޾3Lֿ &G7>1{Ȳt>$(ZQ _3(36AkD' 寐 _#6 _#V _1expH[寘 _3 _3>,r寘 _3yg? _1f,flbB1,V~!b2,X3,^ݘE{EwѠ5L<$_1!FtQhP Ѡ5bѠ5bѰS7 hXhX Ѱ5cѰ5W̑0)hXhX Ѱ5psѰakƢakƢa+&DLla+&D׌ELՍzX׿W4(Z _3(CAkD 寐 _# _# _1exp寘 _3 _3>,r寘 _3yg? _1!f,f,bB4,V~!bB4,X4,^ݘχ](Ͼ%,߽VJXf ?B+ƢY(Ph_!BkDY(H4寘2OآY,e+ƢY,H4W̑0)[4fc,f~b+ƢY,H4fc,fb+f?+aYh_3bk&|=l)yWI~wvW|Rw]%-/rWy+UBv]%ݭ/lWmvUcvJ]5ϭ/fWr+U2v]5/`WmoUuڶn]5/ZWk+UruբV]5/TWmh˫Uuj>]5/NWd+UeY׿6ʿk6omam=ھKs-ҾKo,}KwCI聉wa"kȾz&o޹wa(Gk`*ڝk˾u/ݹKn\;0}5e_s s\\u;0Xe;0}5e_c,yW\} 7ʅZ^Q.^2ޏQ.`2~Q.b0\DAb& : u.(6]Q/n09c¾ȣ^dtGbz'S;E}??OFUX 8ǜ-Q1 (FE2ƨUx+1[$$ eT$#*dvN_v-E3!׻!'Dsz9~ OfB4wDݓ1afR4wODŽ-Iܾ=#h&Eszd~L٢ݓ1gfR4wOǜ-Iܾ=sh&Eszd~٢ =ch&Eszd~٢ݓi|>homk)_1\er@_efA4",d~LآYeE(“1bfQ4'c͢hn/ Oǜ-E^̏9[4,<shEs{Yx2?l,/ Oǘ-E^̏1[4,hk}yQ=R3#G?JF1*ƀ a<`L/z3\-bDny-BbDfy,Ft#?Z+hňUX*HHOJy@)BlbDBy@(F|":y@'F<2y@&B\bD*y@%F⢮ns鿕ѬFh?;G~r8Z` M@?5|Z@8IӴ<?1}4KD;N8'N8 I34J?)}LID;S 0S'Ժ83'ЎԲ8( I#*?}HG|Be'L]JU< !'\!ď,6b[ ؄0DOC263\-'!Dx6ԆyIo~R9b:Oc#Ǔmӵ>F'!DyR Bd' +Ig?\KIly"B'5"$.{>竊VH^U${)E"1}UHX$*,H H$*ɫĄD"1! !9"yA$F$D""yA$F$DbD9bEHH$/DEHqt-D""yA$F$DbD"yA$B,Dbp-D""yA$F$Db$.{>"9/%7D]J!!7D"H6b!,!"لEHDH$oDDH63\-7E"D"yS$HMA~S$9bEHH$od#ɛ"mӵHF,7E"D"yS$B$7EMg?\Ml"yS$B$7E"$.{>"9%D]J| !D"H6b| , "لEHDH$DDH63\-E"D"P$H>CAP$9bEHH$d#ɇ"mӵH>F,E"D"P$B$ECg?\Cl"P$B$E"$.{E15Wjm5% &z1LMKDV@R4dHm5= A[MPqІL'A`!Q5c 8hC+*f܇O968hCj&6#hCj&6$H0k02@k&6V~!5A`! &|=h ٽVDtL3Y3HgńhG:k¢A:+$DtֈEtֈEtVL'a:kƢa:+&Dt֌Et֌O7Y1Ga:kƢa:+&DtL9DtVL鬘 Y3s鬘 Y3 Y3yW7a^+{鬙gf!Ί 5tքEtVH鬘2O8Dt֌EtVLnb܇O9Dt֌EtVL鬙Lgr鬘 Y3yg? Y1!f,f,bB4LgV~!bB4LgX4Lg^ݘE:{h"ijfbQϚD>+&D~ֈ8Z Z!!$F,4F,FbF? 3Z3 ;Z1!f,f|Ҋ9rF? cZ3 kZ1!f~!bB4,jX4LjX4ljńh՚C4jńh՚h֚;1_{@4smtkE4k>#5VLpd&,BB4HmX4mX4mŔ~!&f,FbB4nX4 ot3s>~!f,bB4LpC4pńh⚱h⚱h 05[11h 05c05wxuci@׊h皉}Fk&y \#:tMX4(thhh)C4tX4tńhꚱhXf+}C4uX4uńh89h Ѱ5c05cѰak&bc0akƢak&|=,$|Evw 5zL<$]1!FthP 5bѠ5b0S7 hh 05cѰ5͔W̑0)hhX 05ps0akƢakƢa+&DèLla+&Dî׌EðLՍzX.Ew 5L<$^1!FthP 5bѠ5b0S7 hh 05cѰ5W̑0)hhX 05ps0akƢakƢa+&DLla+&D׌ELՍzX~Ew 5L<$_1!FthP 6bѠ6b0S7 hh 06cѰ6X̑0)hhX 06ps0alƢalƢa,&D(Lla,&D.،E0LՍ+k[+@2L`3U(X4e}'`D,$~ef 6"LbF?:f t,X4ef 6=c,}-2،D3Yh&`3yg?:bXh&`3d,Ƣ,V~ t,X4e`3yW7aQ_e^+Al&exHbB4(耣 6aѠ AlĢAlĢa, oѰ 6cѰ alƢalƧe#aSѰ 6cѰ al&a,&D2،E2،E2XLe؊ُ9D2XLeeë(wmtkE4(> 62XLep&,BB4(X4(X4,Ŕ~!f,bB4,X4,t s>~!f,bB4,C4,ńhXhXhX Ѱ 6[11hX Ѱ 6cѰ 6wxucewmtkE4(> 62XѠ 62؄E2XѠ 6bѠ 6b,f o,FE(͢hX4ӽ(#aS,FE( `3yg?͢huL?͢hfQ4!EшC4,FE2LՍzX4A׊hP}Fl&e `#:(MX4(hPhPhX)C4,X4,ńhXhXf,}C4,X4,ńhX89hX Ѱ 6cѰ 6cѰ al&bcѰ alƢal&|=QEs~E2xѠ 62L<$`1!FtQhP Ѡ 6bѠ 6bѰ S7 hXhX Ѱ 6cѰ 62X̑0)hXhX Ѱ 6psѰ alƢalƢa,&D2Lla,&D2،E2LՍzXD|07LdU냉(D|`" z0Q߿<L&sg5d |`2r0Y߿8 Lv &3kd|`2j0Y߿4 L &g+d{`2O &&A׊JPEk&寘 _#:(M'(PPQPRX)C*,*,ńVXWXf+}C-,-,ń\X89^X 5c5cðak&bcɰakƚak&|=,?+{寙gf!Q Ѡ5ׄEWH寘2O8D׌EWLnb܇O9D׌EWL寙B_ ׌y5$_1BkdׄDP h_#BkDY,Ŕ~bk%,_1bkFY,t/b܇O٢Y,H4f5psh_1bkFY,H4f5[11_ WEXh_3yW7aK}ͻJxJ䋗Խu*YoyJ[_֗*n}aj[_ծ֗Vyn}1j[_ɮ֗5 n}j{[_ֶ֗u몙m}Ѻj_[_֗)m}jC[^֗V骹l}qj'[_Ȟ/KψDHQ5_ÿubmoG]w;t剕 ^ui_퍥>X^N_CLd_s w\D;0}5d_s C9b^S\X;0} \r'沯ܹwa.k˾o沯۹&Ʋ/۹va,gcɳX·+u]Q.r~rÍrB&(3 ]Q.h \DtaGzqE"' ={ԋ.<Q/z0G1e_Q/~2"U?l1*`,QD1(0FF0ǨH[1"U$X( %eT$wxc>vB4zomk) ܿc9!׻|B4wWX4}|~ ͤhn_̏ [4}{2?&lLE3)׻'cͤhn_̏9[4}{2?lLE3)׻'cͤhE3)׻'cͤhn_L;aD㗅k]K,Y??hn/ hn/ WX4 ,C>?fQ4'c͢hn/ ODŽ-E^̏[4,<ShEs{Yx2?l,d~٢YeE(“1gfQ4|Yx"?l,d~٢Yeɴc>QEs]3꙽yT&?eU2BGu}U1dG5 QcB~yT^Ћj< #rnb<#2f1X1Zy@+Fd"Ry@*F~VJb<`#B1"<!:1~2b<#R*1uu=HOOf%5r@#?bDP~nxur@ ?A}gOqPhiuT~^$qZŁ>vAmgOqPIhgjeT~N$ڙZ>vA]ԟ>vAY'OUqPhFz>8m/S !~'d [؇ ]/&,'!Bx"'ji<) !Ɠ؈6OzCl'!Dx<8n>6b<!ȓ"&,D"B"@$"$Ej|(!ɇ"وEHH$D"l-E"D"P$H>8nEH6b|(!ɇ""|(X$D?Z$d#ɇ""|(!qQW7+ՄTk%h)i0դ4ajZj&A8hɩjz )2O868hCjZHUqІd5WTHWrmHYqІLmH[89GІLmH^``dLmHa#hCk&6$8hC*LՍzќ'+{鬙gf!Ί 5tքEtVH鬘2O8Dt֌EtVLnb܇O9Dt֌EtVL鬙Lgr鬘 Y3yg? Y1!f,f,bB4LgV~!bB4LgX4Lg^ݘE:{̯h"fbΚD:+&Dtֈ8Y Y!!F,F,bF? Y3 Y1!f,f|Ί9rF? Y3 Y1!f~!bB4LgX4LgX4LgńhΚC4LgńhΚhΚ;1_hS 5zL<$Y1!FtКhP 5bѠ5b<(͔~!E#ƢyP4 <(1̓h6s>~!E#ƢyP4 05ps0aQkƢaRkƢaS+&DèLlaV+&Dî֌EðLՍzXz6"fbؚDb+&Dֈ82[ B[!!F,ĶF,bF? [3 [1!ff,f|ފ9rF? [3 \1!&f~!fbB4 qX4LqX4qńh㚉C4Lrńh嚱h;1_4kE4s>5~!ƺf,ֺbB4uC4 vńhX욱h욱h 05[11h Ѱ5c05wxucuA׊h}Fk& ]#:xMX4(xhhh)C4xX4xńhhXf+}C4yX4yńh89h Ѱ5c05cѰak&bc0akƢak&|=,kAۻ׊h}Fk&y ^#:|MX4(|hhh)C4|X4|ńhhXf+}C4}X4}ńh89h Ѱ5c05cѰak&bc0akƢak&|=,kA׊h}Fk& _#:MX4(hhh)C4̀X4ńhhXf ,}C4X4ńh89h Ѱ6c0 6cѰ al&bc0 alƢal&|Rߵѭ_Cl&~ e*b,2>e f @2؈D3Qh&`1exp`3:b,2،D3YϞ s>~dlF,X4e 62XLep&,BB4(X4(X4,Ŕ~!f,bB4,X4,t s>~!f,bB4,C4,ńhXhXhX Ѱ 6[11hX Ѱ 6cѰ 6wxuc|]Z2L<$`!D2؈8` `!D2؈E2؈EhF?̓c<(̓c<(1>f}C4FEhB4FL9Dh~!ES~!E#&bc<(̓cѰ 6wxuceO VD2L3`3(ńhPGl¢A,$D2؈E2؈E2XL'alƢa,&D2،E2،O7`1GalƢa,&D2L9D2XLeee `3se `3 `3yW7aQapD|07LT&Mۃ$D|`"x0߿;́L&cG-d |`2p0߿7̀LV &# [d|`2h0޾3Lֿ &G7>1(^+*Ak&6寙xFb&(D5aBAkFAkJa+ o5cZak^ak寘#aS5crak&za+&׌׌ WL(寙؊ُ9$WLXk寙ë(hP"fbQD+&D׈8_ _!!F,F,bF? _3 _1!f,f|Y9rF? _3 _1!f~!bB4,X4,X4,ńhXC4,ńhXhX;1_^+Ak&寙xHbB4(耣5aѠAkĢAkĢa+ oѰ5cѰakƢakƧ寘#aSѰ5cѰak&a+&D׌E׌EWL寙؊ُ9DWL寙ë k[+%,_3Lu(X4 寑}_B+ĢY(H4 fS7 [4,X4f5ӽX9rF?ef5#,b,L٢Y,X4f5#,b,Ll%,_1bkFY,^ݘ-5*/^*/^R׹dE*=o}J[_ޮR׶n}Uj[_ҮZ׳]n}%j[_ƮZװ&m}jt[_Z׭fE}m}źjX[_Zת myj<[_Zק骝l}ej {,=xkkkk{ ڣ;t`:G+O|oҫ. -}~?tĿȾ|&޹wa"kɾxrļݹ[wa.ҝOe_s s7\\;0}5e_s sMe_s cw\XU;:ƒg}1EWp\8%&" 9ʅLdQ.f\@|QGŽra?&hzomk) ј>OƌrB4b, |B4&$ h&DcDfR4brxDŽ-Iјh&E#ƢfR4ft'E#}?lLƌD3)1ͤh?lLFE3)3ͤhH4cLƌbE3)1ͤhH41wxc>vA4~Y6ڵ͂h/ C.9~ /yE ?hEs{Yx2?&l,d~LآYeE(“1efQ4'c͢hn/ Oǜ-E^̏9[4,<shE×'c͢hn/ Oǘ-E^L;aU4׵b<#k< !v.1"<#qQW79dhVR#4Ÿ#VKH?9-OWX >- }~f$iZ偟>vVAuOqPih'jm~V$ڙZ>vVAeOqP)hgj]EhGjY~B$ڑZU>f#>!2.*Po{B-}xЅ _lxB"d'!BxRə~Ɠ"k"@$H>}?l"@$"$D"B"P$ə~ɇ""|(X$DDH (1"P$B$EC6Z$d#ɇ""|(!ɇ"وEHxEH6b|(!ɇ"uuý+A[MHV5) &b&(ijrj$⠭&8hCj o ij0ڐ j0ڐ 骙#aS )k0r@j&6#hCj&6$8hC6$f6؊ُ96f"hC"6^ݘy¿A:׊hΚ}F:k&鬘 Y#:HgMX4HghhhΊ)C4LgX4LgńhΚhΚf:+}C4LgX4LgńhΚ89hΊ 05c05c0a:k&bc0a:kƢa:k&|=h ٽVDtL3Y3HgńhG:k¢A:+$DtֈEtֈEtVL'a:kƢa:+&Dt֌Et֌O7Y1Ga:kƢa:+&DtL9DtVL鬘 Y3s鬘 Y3 Y3yW7a^'+{鬙gf!Ί 5tքEtVH鬘2O8Dt֌EtVLnb܇O9Dt֌EtVL鬙Lir15 sZ3yg? Z1!f,&f,6bB4jV~!fbB4jX4 k^ݘEZЯ7k[+A^k&xH$bB4l#5a AjkĢAlkĢ9( b h|1C4E_s~!9_L? \3yg? 3\1!f,f,ƸbB4qV~!&bB4rX4r^ݘE{D?"ĹfbQ皉D+&D>׈8] ]!!$F,4F,FbF? 3]3 ;]1!f,f|9rF? c]3 k]1!f~!bB4,vX4LvX4lvńh횉C4vńh횱h;1_t: _ѠkE4w>5|WLp&,BB4HxX4hxX4xŔ~!ff,vbB4 yX4,yt3s>~!Ƽf,ּbB4yC4 zńhXhh 05[11h Ѱ5c05wxuci_ѠkE4{>5WL}p&,BB4H|X4h|X4|Ŕ~!ff,vbB4 }X4,}t3s>~!ƾf,־bB4}C4 ~ńhXhh 05[11h Ѱ5c05wxuc﵃_ѠkE4>5WLp&,BB4HX4hX4Ŕ~!ff,vbB4 X4,t3s>~!f,bB4́C4 ńhXhh 0 6[11h Ѱ 6c0 6wxuc~ e3e^+@2،y 6^2XE3Q| 6!LBPh&`#d, o_clƿ@2XL`3dl?{2X̑0)[4ef cLf~ t,/б 6_clƿ@2XE3YXh&`3:fnâ & VD2L3`3(ńhPGl¢A,$D2؈E2؈E2XL'alƢa,&D2،E2،O7`1GalƢa,&D2L9D2XLeee `3se `3 `3yW7ag5կhP"fbQD,&D2؈8` `!!F,F,bF? `3 `1!f,f|Y9rF? `3 `1!f~!bB4,X4,X4,ńhXC4,ńhXhX;1_2W4(Z `3(C AlDe e `# `# `1expee `3 `3>,ree `3yg? `1!f,f,bB4,V~!bB4,X4,^ݘE|M+{egf!Q Ѡ 62؄E2XHeee2O8D2،E2XLeenb܇O9D2،E2XLe,r寘 _3yg? _1!f,f,bB4,V~!bB4,X4,^ݘE{[EwѠ5L<$_1!FtQhP Ѡ5bѠ5bѰS7 hXhX Ѱ5cѰ5W̑0)hXhX Ѱ5psѰakƢakƢa+&DLla+&D׌ELՍ|؅wMߵѭBk&:Ib,> fb,F$׈DX)-׌JXb,׌DX^,EXh_1bk&l,b,׌DXh_1bk&bcf5#,fnÖw/xWi}jw/uW{U"w]%/oW)xkUvf]5֭/iWtUbv.]5ȭ/cW-qkUvz]5/]WmU3uվb]5/WW-jkUSBuՆJ]5/QWfUstN2]5=_\FKK.-ei_\'oYWoUV[yו[ԕ;Y?guKuKuKuKuKuG iYKv.a+v.i vnoFnؗ\W\\\ؗ\ӈ9:}Υ:}Υ:}]z0xߙBP^ʋ5b%yshpI35% 88"& 9B&9 $g6rQх;MDx (9#?br>EO$?EH  a!b1"D<עEX#cq$uu=sV8D1NxTm5",G8\ac<1LH* ţBu0vţB]0!U<*Lm\HG<(/;-Bj⨚o:XG~o=";f݂8 n]z8v t3| j5@7DK'Z8F tH|$J2@7I 'M:8[z7H +' *8 y>ݳL& U"~g&lg}NUZUdg5) %l"G5iZ OHA6a-<^6qG;Q 5p&,' "lgj=ۑZob!Q! qW3?UٿD(>U"* ~O&,O}l?UZ(>U(>U$OQl"G5iZBD(6aQ| 3(6qG;QQ(>&,D!"lgjQ| MXBD(DHbv؄E(DHBDՌAJ[%R J H4% $:F`$A*dJ2i"N`$A8ت)25V`&F"تe jr饑#?FUS@l$H[5 $lVM5DU@lt3[54VM9vlմH[5 VM=ɋ^9HIM?RIM?H<_M?HjiBg,~ӄERO O!efk駐 O# O#>H?96DӈESH駑5;[S#|5?" Hj*"DRTImPMX$Pv!dF,tBB$QX$(Q #ErG; bT# jT!!Fv!BB$(RX$HRX$hRHv!dBB$RX$SE]pi굯_6u/8HlS([96DՈEUHe(Y6ڵ̈́h1㇜?>!GȫG, >#C>?fR4IODŽ-I>%=h&Esd~آsғ1efR4JOǜ-I>)=sh&Esd~٢ғ1gfR4D~٢ғ1ffR4KO ۾ѮhDsǬrA47~|A4w~ȫG,!D({1afQ47'c͢hnNLj-Ȅ)[4;shEs{x2?l,d~٢Y-E(<chEs{x2?l,.d1G^Jڏ2̣F1!<_LH/EHls\ZPi~@,Bgk<#Vb< #qf?]+Q0 Og?\Kpy@$VF9Zv@"?h}(::9 i>'N8(IӴ:6|8-o D;Qk6K'8( I32*2|L-o D;S./ @;R,'юԪ8 I4#= Q)0w)U*x;p?؈m-D.Ob!cw)EHxg??"وEHDHH$d"!| ɇ"HlsH>Cl"P$B$E"DCl~ɇ""|(X$DHO"P$H>CH>F,E"p-ECH>t_ jBՔ4jRL05-5A[MLQHUS Hm5= A[MPqІL'A`dDLmHUqІd5WTHWrmHYqІLmH[89GІՌ2 k0ڐ )l0%3ƚ l0ڐwxucv@4 ^+A:k&鬙xHbB4Hg#5a A:kĢA:kĢa:+ o05c0a:kƢa:kƧ鬘#aS05c0a:k&a:+&Dt֌Et֌EtVL鬙؊ُ9DtVL鬙ëHg ٽVDtL3Y3HgńhG:k¢A:+$DtֈEtֈEtVL'a:kƢa:+&Dt֌Et֌O7Y1Ga:kƢa:+&DtL9DtVL鬘 Y3s鬘 Y3 Y3yW7a^'+{鬙gf!Ί 5tքEtVH鬘2O8Dt֌EtVLnb܇O9Dt֌EtVL鬙Lir15 sZ3yg? Z1!f,&f,6bB4jV~!fbB4jX4 k^ݘEZwmtkE4k>#5VLpd&,BB4HmX4mX4mŔ~!&f,FbB4nX4 ot3s>~!f,bB4LpC4pńh⚱h⚱h 05[11h 05c05wxuci@׊h皉}Fk&y \#:tMX4(thhh)C4tX4tńhꚱhXf+}C4uX4uńh89h Ѱ5c05cѰak&bc0akƢak&|=,$|EhkE4w>5|WLp&,BB4HxX4hxX4/f3expEшh^fB4/FEht(rEшh^fB4yC4 zńhXhh 05[11h Ѱ5c05wxuc ќ_ѠkE4{>5WL}p&,BB4H|X4h|X4|Ŕ~!ff,vbB4 }X4,}t3s>~!ƾf,־bB4}C4 ~ńhXhh 05[11h Ѱ5c05wxuc﵃_ѠkE4>5WLp&,BB4HX4hX4Ŕ~!ff,vbB4 X4,t3s>~!f,bB4́C4 ńhXhh 0 6[11h Ѱ 6c0 6wxuc~ ea/С 6?2Lz`1Dld2؄D3Q _ClD(H4e2O8~ef @2،D3YϞ s>~dlF,X4e 62XLep&,BB4(X4(X4,Ŕ~!f,bB4,X4,t s>~!f,bB4,C4,ńhXhXhX Ѱ 6[11hX Ѱ 6cѰ 6wxuce5կhP"fbQD,&D2؈8` `!!F,F,bF? `3 `1!f,f|Y9rF? `3 `1!f~!bB4,X4,X4,ńhXC4,ńhXhX;1_2W4(Z `3(C AlDe e `# `# `1expee `3 `3>,ree `3yg? `1!f,f,bB4,V~!bB4,X4,^ݘE|M+{egf!Q Ѡ 62؄E2XHeee2O8D2،E2XLeenb܇O9D2،E2XLe@肛&*D|` {0?=(_L&{w9d |`s0?9,_L&;s d|`k0?5,_L &w3d{`c0'wmtkE%/DLl._3( _#:(M'( _#6 _#V _ o5cB+,+,`܇O9׌W(1yg?ˋz_^ ECa3C1/*ލcɼ(̋cͰ5wxuc]EsEwѠ5L<$_1!FtQhP Ѡ5bѠ5bѰS7 hXhX Ѱ5cѰ5W̑0)hXhX Ѱ5psѰakƢakƢa+&DLla+&D׌ELՍzX׿W4(Z _3(CAkD 寐 _# _# _1exp寘 _3 _3>,r寘 _3yg? _1!f,f,bB4,V~!bB4,X4,^ݘχ](]Z+aQ>/f⯓D+ƢY(Ph_!BkDY(H4寘2OآY,H4f5#,ft_1Gl,f$WEX89[4f5#,f$WEX-WEXh_3yW7aK}ͻJxJ䋗Խu*YoyJ[_֗*n}aj[_ծ֗Vyn}1j[_ɮ֗5 n}j{[_ֶ֗u몙m}Ѻj_[_֗)m}jC[^֗V骹l}qj'[_Ȟ/KM-[[Xkҁ<K/Kuz`"kȾ{&޹wa$kʾvƲoݹKwn8>1}5e߸s s\\};0}5%F61}5eߵs cW<KUr>(m_r἖oc n/(2}FI肎rAE& ;ʅMDwԋLo/9]Q/t0أ^dtGԎzу9bƏ)zF@0"H&1gaT1cA*d$QE108FG2ފcɨ" BU(H,%ë׻k]KL~0~ ܾC>}zĢ?h&Eszd~Lآݓ1afR4wOLj-Iܾ=Sh&Eszd~٢ݓ1gfR4wOǜ-Iܾ=sh&EïwOǘ-Iܾ=ch&Eszd1 ,[ZfA4!Ds{Y?}Ds{YzĢYeH4,<hEs{Yx2?&l,d~آYeE(“1gfQ4'c͢hn/ Oǜ-E^̏9[41ffQ4'c͢hn/ O*Z_yṬjƈ7Q-cb?3}4-OLD;M:'ю8(I6j?+}L-OJD;S+2s'8( I3. #,?!}HGD3o{ S|ROB W=!OB>OB|/6aa˯*ɫDE"1!HLH$/DHlsH^H^A~A$Bgk # "b #qf?]H^H^g?\H^HKs |R$oDw !X$oD>oDDH6a!"!)F?WMHF,7E"D"yS$BtFgk)!ɛ"وEHqt-7EMHMl"yS$B<"yS$HMH+q|R$Dw} X$D>DDH6a| "!|(F?WCH>F,E"D"P$Bt?Fgk|(!ɇ"وEHqt-ECH>Cl"P$B<"P$H>C^QLMGՄTk%h)i0դ4ajZj&A8hɩjz" fF?ڐ ڐ j09rF?ڐ Iڐps ڐ k0ڐ )l0smHc2l0ڐwxucv@4 ^+A:k&鬙xHbB4Hg#5a A:kĢA:kĢa:+ o05c0a:kƢa:kƧ鬘#aS05c0a:k&a:+&Dt֌Et֌EtVL鬙؊ُ9DtVL鬙ëHg ٽVDtL3Y3HgńhG:k¢A:+$DtֈEtֈEtVL'a:kƢa:+&Dt֌Et֌O7Y1Ga:kƢa:+&DtL9DtVL鬘 Y3s鬘 Y3 Y3yW7a^'+{鬙gf!Ί 5tքEtVH鬘2O8Dt֌EtVLnb܇O9Dt֌EtVL鬙Lir15 sZ3yg? Z1!f,&f,6bB4jV~!fbB4jX4 k^ݘEZЯ7k[+A^k&xH$bB4l#5a AjkĢAlkĢan+ o05c0avkƢaxkƧ魘#aS05c0ak&a+&D׌E׌EWL9؊ُ9D$WLQYë*#"6w 5:L<$\1!Ft蚰hP 5bѠ5b0S7 h隱h 05cѰ5TW̑0)h뚱hX 05ps0akƢakƢa+&DhLla+&Dn׌EpLՍzXI^+Ak&xHbB4w#5aѠAkĢAkĢa+ o05cѰakƢakƧ)#aS05cѰak&a+&Dâ׌Eä׌EæWLQ؊ُ9DìWL]aëH{] |׊h}Fk&y ^#:|MX4(|hhhfF?͛cѼ)̈́hMш~S49rF?͛cѼ)̈́h89h Ѱ5c05cѰak&bc0akƢak&|=,kA׊h}Fk& _#:MX4(hhh)C4̀X4ńhhXf ,}C4X4ńh89h Ѱ6c0 6cѰ al&bc0 alƢal&|Rߵѭ_Cl&~ e*b,2>e f @2؈D3Qh&`1exp`3:bXh&`33b܇O٢,H4ef 6ps_c,&~e`3:b,2Ll@2XE3Y/б 6wxuce5hP"fbQD,&D2؈8` `!!F,F,bF? `3 `1!f,f|Y9rF? `3 `1!f~!bB4,X4,X4,ńhXC4,ńhXhX;1_2W4(Z `3(C AlDe e `# `# `1expee `3 `3>,ree `3yg? `1!f,f,bB4,V~!bB4,X4,^ݘE|M+{egf!Q Ѡ 62؄E2XHeee2O8D2،E2XLeenb܇O9D2،E2XLe 62XLep&,BB4(X4(X4,Ŕ~!f,bB4,X4,t s>~!f,bB4,C4,ńhXhXhX Ѱ 6[11hX Ѱ 6cѰ 6wxuc 0a n?Ȃ&Qド&D|`y0?<L&kW1d |`q0?8Lf &+cd|`i0?4oL &W#dL/0n寙\fQ 5ׄ}WH+寘2O8׌WLh{lb܇O9׌WLȅ寙h\$tAGrQх&; &7~Lyԋ.:_Q/v2^dtjGǔ}GH `T$p0 FD2ŨHFUX#o1fdTc*d$QŒLՎ| ݿѮh&DszY??hn_!d ܾC^=bLH4}{2?&lLE3)׻'cͤhn_̏)[4}{2?lLE3)׻'cͤhn_̏9[4׻'cͤhn_̏1[4}{2χ]_v-E ?f` ,C> ,C^=b,@$E^̏ [4,<hEs{Yx2?Fl,d~L٢YeE(“1gfQ4'c͢hn/ Oǜ-EeE(“1ffQ4'ӎ|Gu/vAy'OqPyhiq~Z$ډZ>vAi'OqP9hgja~J$ڙZuQFڑZe>vVAUOOe'L]JU< !'\!ď,6b[ ؄0DOC263\-'!Dx6ԆyIo~R9b:Oc#Ǔmӵ>F'!DyR Bd' +Ig?\KIly"B'5"$.{>竊VH^U${)E"1}UHX$*,H H$*ɫĄD"1! !9"yA$F$D""yA$F$DbD9bEHH$/DEHqt-D""yA$F$DbD"yA$B,Dbp-D""yA$F$Db$.{>"9/%7D]J!!7D"H6b!,!"لEHDH$oDDH63\-7E"D"yS$HMA~S$9bEHH$od#ɛ"mӵHF,7E"D"yS$B$7EMg?\Ml"yS$B$7E"$.{>"9%D]J| !D"H6b| , %ǕogmE2?ؽ[c!YNVp8UK //D/D/,>+E"EE") E"EE"EERÆ?H~Y$H~Y$eH~Y$qR$,P$,YT$,YT$,P$,Y"e"eȢ"ebA]^PLGGm!րx`1#fHQSsOFGNSu,mi S*#Tǀ@UȪy]s>(yic@[8s6-PW<j@_,5m܏ـ@cyT3#PYxnbGy tV4}t-2YyhŢ,&YYhB:ItV6Mx(Dg屢ItE,Nwc?e+DgP4cE,?s?g+Dg屢ItE,&Yyhc[1cItV+DgP4 ݘ:{޻h-Mxlc tV+@g: tV+@gP4bh o'lE,&YyhC$:ӝ=`)d0L2Xf&@d<$$$hfxl+~$hfxT43`< Edpih cd0[dXE<`MX 2 Edh C$,Mxh NJ&`<Mx($屢I2m܏ي&`yh C$3vcdI 2V4A}2-2`yh Ƣd0&`Yh BI2X6Mx($屢I2Ed0Nwc?e+$P4IcEd0?s?g+$屢I2Ed0&`yh c[1cI2X+$P4I ݘlO 7 77̠Ò`@ O䁟ā̤ŌdD$O䀟Ā̤ŌdD$O̤ŌdDﵼI-UIxlsck Wk D> W+ (AbR o'l/Z%_yVC$]xJߐ/+~ׇ?#&rb"w.-&rGb"w.-Frb(kT]ZNݥ\]s 1;rswi1;psvi1;nsKYX6s"unyF {؏7ZC G [ꠍLw(,uE-nQpGy|x&ȣ= 6=QG{tjGyۇ)у``"p9S y( =*ы=* <bcEb eBqebqexm|.vFS[͋fF<==9hrR|Fӻ峷P43&=-XT43&޽<0E3h S43&޽<1E3h)S43&޽<3E3h9S43&޽<3E3h9S43&޽,3E3h1S43&޽<1]Q4ӥEho<hEh_Q48T4+F?Q4+fE`QѬ,0EhhV~hV ʢӽha01efeQѬ,DѬ,+rnyEBZY^,Xt_Q,6-ZVyEBTqR)YhW4 + }" u:~+D]EU*bA]Q$XT$(Y(O ''DÆ?H>Q$XT$(Y(O ;ns?]E" E""D`Q|HdH>Q$X"DB|HH>Q$X,k7s(34W|HnɋE" ;"}HB|H䨳"AE")E"CE"CE")lJ|HdQ|HB|HdQ|HdAfl)o,*oIY(o,v~7,7D7D7,7D?åHY$eHY$HY$XPn:Q$g$"Eܒ/DvE" E"EQgE"ERE"E"ERϕ"eȢ"e"eȢ"eȢ")aR$,YT$,P$,Yt)_IY(_,*_,*_IY(_,KHBHdQHdp/(׀Jk@[GIc:x8( te D E.&!]y~V4hӕNJ&A]<Mx8݉s>hC$+MxhؕNJ&]<M"x(dv屢Ihm܏ي&]yhC$3vcu vV4}z-2]yhŢ/&^YhBËIW6Mbx(x屢IE$/Nwc?e+yP4IcE8/?s?g+z屢IEH/&^yhc[1cIW+zP4 ݘ{]4֊&^hC$ ,MxhNJ&`<M"x(d屢I(m܏ي&`yh C$3vcbdpXNko 2,`<,r,E3 R|CE3 @d0 2ox_O@_ tel@_ tel@_ tel@_ tel@d0?s?gf&,.`<.`<.`y(d0ۊ.`y(d0@d0ڍZl 2V4A}2-2`yh Ƣd0&`Yh BI2X6Mx($屢I2Ed0Nwc?e+$P4IcEd0?s?g+$屢I2Ed0&`yh c[1cI2X+$P4I ݘ^4T 2V4A}2-2`yh Ƣd0&`Yh BI2X6Mx($屢I2Ed0Nwc?e+$P4IcEd0?s?g+$屢I2Ed0&`yh c[1cI2X+$P4I ݘ|M. KkEd0 " NJ&`,:Ah Ŋ&`,MX($i [$I2X+$P4It',0SI2EdKXr^R8/g@T΋q>Ob}:Duϑ'Duϋ@A>/'|^OTX>TXy>Pruӧw"uy;ȁw V:/5IxAW|=o1M{p 9]?Q4Q.8uDF эQ6#Q#hG`(buMTFu&*PD5&2"hn'#QLTFgtdVyJZA烞J ?HNӬ >>YA|i >iĥ >bΆ .qs6q){$!KA|9ŜA\ >)Rw>N1'Dq9!ݍS ĥ Sĥ >`b .qΕ ^rsX<؂םB4Bidug (");H߫'?WM{UWEM{Utt^c.DUF^84UCS^7iUqCcd3B^6idUYCS^54;뫍\QAw^1fwА4$SAzDڧ}*hڧ}*hh:5 5b*SACS>4iSAC 1I#h )h 41c!h 4)h r.[A;oAVФ1oMVAV$VФ(h ZI[A}+hV!h_MUJ#h_MUФ|׈&MA*h&6|\WA+}4i WA}WAf}WA}4ivW˹_X D'-BO Dn|,BO D'~fLȂ(DQ "AzHH =AQD D(cڀz/vDۅBOmH zT A,D4X Az"} =A$BO$Z D'%'݈X D'-BO̘QD D( =hAzhӛ1 D'Q `]+):w =- .zh+(D4BOb',BOӏQ "Az"т( =A( =xFǂ( =hAzG`Ƅ,BO$Z D'QD DތYH =A$BO= ZI'׾A,. |hP Ot @A"EH FAA#P$O?b6Da(QD @D($E1 `D(EQ8  HhAH D1)-Rmz3dA"т(. LA6k%Zqm_lA,<vD[A!*-4D TfA,T FHl~l,BV Da+Q "GIG7b>D+QD D?3&dA"т( eA$Y$Z f Ȃ(EQP "Aւ1Xm@J m9 ŶĂ[mnA"тX| NS.HiB\b1.hQGƂ( shAHE rH<|t#cAHEH wA#0cBD/-"^ D(EQ Moƀ,^$ZŽ D/tЗk R[ ~A](VPD b/h:M "`Y A#DA0ۧ1 0D(FQ "A Q #эQ0 "A #т(я YH A$Bb DA16 hAH z VеBc=XlL]lA,8vD[A1-Ǡ4 DfA,D #FHl~l,d 8D2Q "GIG7b>D2QD pD?3&dA0#т(b A$bf$Z f Ȃ(lFQ "A81Xm@J |ؙ؂X B3g$ZAi* A#͂X A, >X Dq4-i HDPn|,i hD4~fLȂ(FQD "ARHH AQXD D(cڀGxGm]lOYh/YhY# "k4"kYd4{4qY N5ۧ1{]d "OhOATDY#эA"k)F"A"k̘=.F=.'E qA=.F"A"ky]d `]+cAb b5 E hA,M$Xd4 b5h48ۧ1 P%ġ hA D8D xFǂ8Dq(%ZE 1! D5Qd "AY#т(Ѧ7c@D5-"k DjVRd5;E"kmAY#тXd NS5Hi"kb5hQdGƂ( hAYHE rDH<|t#cAYHEH A#0cBD5-"k D(FQd Moƀ,"k$ZE D5tȚ#A,. YhPd "ktA"EH YFA#"k$O?b6D5QdD D($F1 D(FQd  hAYHE D5-"kmz3dAY#т( A6k%E\b5uDۅ"kmEH YTd A,F4Xd AY#} A$"k$ZE D5%5݈XE D5-"k̘QdD D( hAYhӛ1 D5Qd `]+)Z"kb b5 E hA,M$Xd4 b5h4(Fb#fcAYHEH A$"k9J"k$> A$"k$ZE 1! D5Qd "AY#т(Ѧ7c@D5-"k DjVRdn 6m 6ym6ym'6ym'6<)扵M4Om yBmS,͓iBiHI$ڦ@'6E3/Avy|㸿P MɯxW A$"g$ZE 1! D3Q "A9#т(rѦ7c@D3-"g Dj:WwcG^9_ "Awm9# "g4"gU4ASW3h 9#}!K "9# .3 9DH<|t#CDqHD?3&DqATDqHDތ+%ƀחgtdԗq*hƣ7kYb{}(_jz_/`/{j}* 7~ڟ̺ڟaڄNՎ9\ UWn~O߶$꯫qPK +o> Aspi/UT NUxPKo>};0 7spi/diffusemult.spimtxUT NUxPKo>HiP spi/lg10.spi1dUT NUxPK%o>#|A AQspi/identity.spi3dUT NUxPK&r opencolorio-1.1.0~dfsg0.orig/testdata/iridas.zip0000644000175000017500000227174613223553423020121 0ustar mfvmfvPK@.Marcie_Grade01.exrUT 9O9Oux l[ yڶ>m۶mvi۶m۶mf̊ؑH|厊 ddn`kkbbm Ϟ0qvo;@Fv6&NNvo8[۹ڹ3[! eldom{&&?l]LlM ́-l;ЈАшZY;9a[nl 1u cg#-lL1__agN0OOm>D@'''}:'_rϺ l9zxalC1)vb,T{v7@#sLUR5YnC: _[5*On9HCCk8wu X?z+ ]cSkswëu˔ +|]&n?kfȎnNRv1΢˄X䉷 +8ΑAP ͦUQ-i_#nfuԙ33sK2֑A G%% j|-k#:>:Tn5ryLNȕ5Z; te 6LMmCu"BDmɧ)JPɤ3Z_q>Vѯ#rw5p8ǷΞR}]j cu]fy4$}g?Mb'.{珟9`{G]>0<.Yn#V"Jӟ_3oؤ;=K(9̢|;D!NYyN셵8-K ;lև3#=RQIr(ǃYOHc̈z\E`1@7+ɄDdK̍`l ِ3`9 ae gi`l` myc:LncI-K$D.Ħ{(~QPN5:$G9/PP4YB;;a9@zЇ7xNJs=iL"yJ1ь4 8gn.n'su}rE!^ɕª^kKB^Pa4jpt"(5'i>`5 OB/@?6)ID`vxlEBDz>J! RNs%HK'Q9HR3-w#xvnX󌬷c;V 1&c?u>x[ScoFއon惊~.S$U<Hڏ">\[FHy4kpYS/eL[jD8b3(Ŋ'L3a 45TTһLNFڋ# b ʪU!|Zu ThT!aMɩv7|"M!f33]=;ЫE\;q4EkoPP;tX's/k`u<7n-[^zW(ƘY|i#pήK ,+w;MEmO!*%FFmթʵ'm rɂyU#_~"??7?/$륫x&\, 36"N%3j;&KGj98oZq=mByr ~+IН4BMb'%{[OHDU?L8w|CL'wɒH{^t$r`*[?DG6 $WE<*xToZ\Z>$qm[ӑ"-Odt :$ҧh1K+y k+ҳ(v4Ssޟj*BRsWKtҠ>9.-fIhBf S?6"WPխ"C%tv72XYy-htIGHwŖn׍򪬻>͢/qW_Xp{,XDݐ҉pJ;#2Ԍs1rN=L(KS#Ks^R54{U̓BkJpv~5Sv{Uxd5>>FIu (؀jHKy_ˈ&?(Tec`Y$/8Jˉ{g+lbL%Cnh1gas0cx/~b'a+Bs۰J&$IvSKq*p悈#XY*XVkwD!sD^~OS1L-Rjbx) OHPFKR️Ǔ@vHpjcw:IZ[#7`ޗFг`y )onfy0KJIbcm ιaCϛ!ĨPTe퍲ߴX?]|1;e4׆Y;M7g3\uUta+~PpJ4z/knC8|~,w~r=3Vڜ3A<0kL+Pb _m}8y۠ hl_B~0R1/oDDh{"K`D<ߓ[̖W*U@7)c8dيW^G{!*)qYu;`gs9#HDwg_ٝL^IʈjIU%M IAs*źVf8_ұ.8EN1],0Nw?*˞T!nЅ^#o1NԳc,hTYVu)!u lJL>:!bsW/?UVHpHum^Tw4[%c('{=`b`fzLi*@ ~>CxmGg3Y2@Ѽs`xuc KA]jC GG{&GD!%jMx(&R5B00>R;V v/"ȏ%q#Hf*mN},nܣ*nZ8&}GgZ͎UUbV.3M&~>F׿lK!hz-$(Y).ctwV =D)\Ѻӡ.OKf 0֐"[&M5R^V@†>k_U,qz.E?y Ď-i| gI-*FUjOB^9HL"*ٿoLߟб$E͟J=D=tMh&-f Pb)+1KQruudNᓤK6{ѕo;vS"2Wh >%J_k~/YW!RP|D|d6@-ٟa$td[:B&v^ihow<.x:i@_Y{,|䫊k#1x,A X`!Kj6z6 ,:_7 % #·=5Sƴ#*XZq*ro -a,^Ę,$,_fNdWO?{n4$I{=L}ߕ͌\1&h6w$@I ]TH,|1w޾bDQ< Wofe?%̳Uo()8ޥaq~\/m,No_=Oǧ,-"Zy⸺a=, 2ɬLBb>NU vS5 wtԈѡwn>^][Qj@D*;F ⫔Sk 9ج1HܲլaU*TK;$FyjIF3B\-C-t"sZey15˂~ [J7P! MNVPl"L21ruBJN!-r&mݎhWlU_l[9`I- a,ae-)?%JS.Bh Y52GcJ=%~]teobGd.0}W#wbUBp~+Qrz̷X!!Ãмl$ZgE_C;'o2e2{ppMk`ేE}u: `=M?4g־5)VuڅfKogcuN.9UC~;K|Y=n\+9fK [ds$O%m28ey Mfl=F£eK@@§A=<斖), 9G?Yr'zŗK\MW\]@T{.!|AYYq]m#@_Uȯ3 yRbͫ+Ǔi e~G@4" Pgf#"TWfA Ul]诨Imgʦ }\H".O%ߗ7Z$+(+#+X8rCz²58rĢ4D_lG#.&Z=Bʮ:or|0Mw25֒7ؠy;ojsZ7- uOjsT)ǩϳ0g ӥ!"T^KWX_[cmk9 'lʬؚR\B)jbR x6E!aT3.rsFޥQ%>7sH"7#`U<1pV9$|y.եv,kI_|uޫvy%0l6AMx}36OP\DvdWwj;e )TH4P"v5_SywɬZMTkH\i96DQ)ݘiT,1s}RLq&W(<+v,O*ch {r.%TXu8`p>bK]}V⅞ȳĘ Rza %|a}R8}דY42FV@mN̶'8쳶쳵$6&)e><Px8ڔcV%7*ٖ8N)y*~P_Lҋ(ޝ6(&FxJ<-ܜx/Y <b~r̪n\IEqG#t͍i=%G Bj  k椿ٌ =6pʧ\hsJ8LHE~1rZ(qr IjoxH+T|T%YFi ̘߳/~q9enHݭY!ĆbHMb~1VM֦-FJSTU淎 ^ƎʔNSO7FXGYxl-=>p+W,>< &Lx=-GNx)88Sq08GO,5}(Frb&[dkѿTVeƛuw%Mp9(4ڿvGlrL>Rhk}+:>l_Y37NwM\fru-#tJ.#*I"e9_nYC$=m(QW5#Kْ0ĝ!( 1,%/{;8S|eo,<ȉ5䴜leid3=iOw0CCy|/7@G0(iMaDAIaHa:Dp#ӟFu\eS*߸QP)-sI]tϸkXJ|_uVm]J"Os.'ŕõvTZaNv̤e|* > G3(&Y](8SLB[hjGgtֱ2W")`QaKhhyL(2qJksBAM:`S%!;y'4ek^,228(>g8vUPr֏ԛfZ'EL[뾜ZweR8S1lj~Yۣ%jubb8ܬ77<-I *<F e0̦zkH(jvbAǀhɰ 6ᵢg>Fu nćG%Wc;ӓzEơ^NgOjhcsX o/1/t̻qogtz+uf&]*M4]{H5p]9] }Hl.=L`t^#Ր@)8Y[k2z.+gf{B{)4лzQҊ;'~maZzvМn{FHL4K %s 7,wRyl ZJ';CeJ0l4n㥫8 um,75圉_}]1z>ܝ"z A ~~N*5㉴ta N$;1_}ouOAӧ{y2Myz%lسC.dmђ_CH'Nw%gi(5p[\'w= UqZD^^a1b t׶>sĮB PF7 9:Bׁ[ '[?swj돼* }1ڈ -hX!@n@u n m:/M} T=ŕ `B;ugq0FiӈA'TU`U/l'Ǭ^JG;&_J-ߕ<9^H  wң/- =X̥;?&]w$ IlAw@[VK]Hv֟XƵ4$kXIzٻ=+sR'q~rl&;o˃llPvq1vXT AY7yv?'l5g1df } aAmr3XvdW RqбlːE4J61"xlYICk$:KFLU[Kv˫ svЦ_pIɲv䩹T@K\ݳօ6^Kh,ކs`3w_cdU=H˥aH[(:i,F}2yQ'hwZOW?x ]{3hp׆uvw+]5ѷʽ3 S(n6J$DQugs/a9dL.+믤>T!zg /x>1;D)C~>Q_ה]\(Rlhcf@vYo|P76 2PK3/wi? c85P9h1sğU~@K7?A2#QDp‚7v\t$'#[=cepsvm?`2[ɌdC C>96jZol+$ګD)oǬ˔H®>a­(>!>yV/LbSѵ̂gWKW75F]sϠ5B<kp^ob#9φOO:?p8IZhPۃԟgt<'qPp-N_RYHkpl0}73 c%Z%zQ.z_&soݧ$k[#ܥxz6/:O$/>FwK lF!Я~1ߩ^cp[2W~~ؽ8PTzW^[Ҿ8~دUs^@7; #;pG!2&ހ+]jZ߽_ޖ v56iWd#Q¾]ݯo̸ zԤWZ!F{U@D蝂%;e}(9+n ʇayR?MH< pjɤ?R{ 5e>}TLa&0%@z!67, {g|ltTٿU@LhU֯eq{}g: ~( ;;eH!^=/5KtfCW*% =OOv:`pn:: ;r( XhH h[bToyeFMD Iկ +"E p7n[BgԶi~wͅ {>69DI]Hg+ lb“Vi|#AfٟMa'e @hlh3ʌxo]TՕ6Bx/>~gO?s#McWg#٫ M٨ґ* E $| c~<az. ! ~Ab>gwki4% CHlsAz+d5Cp3Jm Px#kIp/yD ᷋=ξD jO]vE6} &Y?e۾˙dv6d}ԇ9HѾI>/۱"PtBmr2p gf^M2v_r{Kj@ ƽn0y@mU~L7q<_8}ȠfW"$tb~>C6P$ĕJH,P˝L"EQ7F^6nnnߗ Kz靫t[Ɲ)lxz0wJ\xOKv~r'0a cQԯU*( )Rj\r _wd=WlrF6(n, I\*O#7k1= ٔrJήyغnm/Q!h_X4+[j=t.o?Ba:RPJIRǘᓑC*K4@4䄲JjIZUCn&?a?rW'WN<ԇʨ2gY@֜UQN!Wo2ٯ9=C]||I(?n_6DL3 ;kO/UBjHuAiIsxvN{)h#8ci=Q煂0)j&]eX^r/fOx*feD҉(#d.m[aWzb2%MEυhk(I9+܅(^,1Oעʈ~ı+ecWa҆]NoOy9k^oAȋLhpF^?WXY<'QHPk]=j|D`ǛCii1\mWyW^ `D4Y},,4`wZJS k}Z#ܰ{W 2VjKбsY~ws)‹`YW"ʞuJ#as}jѲbЮ9,m EG穱L×Hi1=SeIS.;Kh W1҄3eRx nz䱆`^ٔEYkpR<- 6/r3hԚ_uĝHTX ` IV9&69K Ē+]tݗOSܵ>\c0tFo~G1/")m`]"奶^J}Mf5THsKud+&'ㄧyoԺ8ߤfעIn;6b׈1 n% 6IJLIIeN=:rVq f[˜Yŷ+" b I^WVv&8d4z\}10d} %8"4;H:?Bl#8>̕mu#AQzG*OGbۻ%?3j?ÅLYwuETWR)!C*SiL6IP/O#څ!j |,ӹG9mعA|Fm{q<Ƴȯr^χ^]+XFR.mD"XEEׄ%* S[|ߤpsz^ֈx"+wMȅh] _ܒ"q)0nHWLL@Qܿ˺<K&B1_פ_-7?T6亮TȢh0κ"+!3vrʞQG%=>Wձw]~F2b}6h>|v8ݳc#̩|sJG&$WG}Vp7' {aD.O6y; ,rpMt*Yhvq^ ƫs-W`nynKeBF?;aX7yu."'Wl'N!Z#TQLf3B}579ݛy=A T ǹL.ι S琚Qf|o2Qo _d"8 5BόY"̠>TtOu(lCn'RA 0WE{tbwCp qJz0]%!ׁ];;vAhuMt I{ß8HVuZ ?Euꤴb?1E0ohK!7PzQac8'@߷sYS#`f:K#–`7|>'f\]›`ɵd㣬`;!‹=KJGc"\]Gj(NoVE:Ԓd$giW>[Iy1avJ_Gy{@-O<}1H\INto4@[q1 h1S=ȂOBU“čfM!=T2hdkK)G(r)m ]mܱ0drshǢrKu*8H?:?SI}L]I!ǿ1Bz0g,DHE NMuN:5)GH$L4<:^Oy$kәtp73zZ1zb )/^L8Kէd좞,ֱcGRwg{"hGM]uT!!h:H!^LQn= y=oHT|2۬C?}T*\*w ̸Yb0ƓtrA X 4TU [hR~rJ ΐĨ6hEɶYo)~{HLߗq2~_{GCDErD]ҜD\2% (2vkyNǎCH3UUYڂ+ yE&_i95ZN䓕 z۪Q%٨Q(R"XbMRNz~ղNr-0KI9 cJdŶRm?b>q1S仗)q>S;KAB %$7xlaK^aIikq(fd N a%H| I9;l%"7jEy *يrF]K3~C$r\ ` Hi֗z|o3ûP:_S'eϺxQey"nx׫t x2,kwqMN$"U[= qY5ڭuOcډlH(㓤&;yDץ[e!nV='y%CD1ivy!Vv٨Ł26WV3\\7ReV+[ㄏ%[%:+9/Ro5R{7bjVGvh2"ֱ( ReثDG]DNբY|׹brۭ6:뜫[J :MO)hqOQfEI*9ƨ@:)Ci<}e\MR*ÚOT&eX/qRk83Y|GGB] +w1҃R)X, Œ肋zOp.5;sS{!7Tp6=ϗq twAgDpFPR\OŜ@\RǶg ߿8 Y09[7-Ιߟ̖-]%9}6ĠKQź\^>ӧT%),c;!_ ])/ Bu#ս$Gױ}Zlk5Vjܣ1 >oO|Z\E)Q;7nQ_2m#l__=v]Kɫ;鮉3LӣH*%ޝMBZ֋{mh%\'l3-m~y*~?-Rnl6s̕1\o:'bjZn\uuYJ0$W<k RU7;L~eθoq3jWm5~V?o Y OGHEe)R.42Ћ >d$~ı$>{.7oM=yxHx3ĺLu_7!xQj|FB 1%dS{߸ @kgqOλ^G++'" c~J9!/Zyy$Rgv뽻n݅@&ߢDeo֚:M.{W( ؎ο0"rJۥ"OӰ6<'c#)* 0!x5 ޽9)-Rw=x̊D3[&Iy{I߿'AھtMO!gJK0Zm rCqa hqHM7O_D[v8\ $$2,+Nە*0 ?'MTƽXa-3>ۚ>#kFfKy[?*~@1QvKPQkQe uMvX^vu]!]NaCYgj= Zkρ{gCDOg Ƣ>syIC˔p_veGU1\}v ׺WoT<^fICdV] ćm#V9u|м2=YfEm*|.xZT Vlp'0~15!VṛQ]/$\j|e~Gxn~ 5ڥ^sOaP~UZor$JrI!aTɐտͭAGɬgG/q6F: =Um;ȕo. #cd*5-8^96}j3z+>7g9g_v?p^s1p;$or8>?]i"#y OiG'n5efLaTfA:]3؏hĺ 0Lz4*xݩD5+ d bz.:(c(<}Hqߞ&cdH] qDO-ofh |Ï]w:{רd#O]l"X \}B07~S7|!Y)ƥa_]T۽/>.5|6iT!ּ<) ha]`Ph{r)rhaH".cc pHȖ\d~nMߟ@G7: ;56{Pt݁ݗ_f8Pl3i4$}~ނ&3 1'iļZqsG [\Yq0e0؈ {0) h fpq`bRZiNiAd,N)aL5@]"d +A 10*B䌕ʑ+ 7q_'b m. BP~f߅F4f[gؚQ4lᵘmSW >N!~Z5!:eq}4z"Gc*BmhZ(_ග  3ꄚyB5Vc?3YUChiil?2>T}cIۊ1#i>᯳O8)dր5텏Fb}qe_kE/Q/*ˊxqE Hy5hM)k#Dꮑy}#6Cg&묩& B՘H4FСմ̏8Mcb4AUMjUYCP_'kJ_8ó\lk0 ƯDm?4N2W~?;Bq?}H;T,f azf#0qb) eIy r"8  ; M6jR`8!D͏15pҙIo  \6}0bm uwD[  ru qŶ=5aEfƫnܡz|[92asR}Nt`U<#& Y(ThrJ 1Cgge)!Z fza 740ۀhGG{bs\U6?..ňrOo9(6鵿vF?O'L۟` p0RρXFl2s y%t~Zוpš PhA':4fC,0% bͻq%jaЄƎ鸿j(.Z~VuV7@|P NX[-  ~3>~nj${AaPo7fSuP2X3a6Z͞ː ?n Mr\Cg='2 R037x 2g- ·ѐUKwoO&ڎ1:6ǞooZ 1^T .n5]Ok_tsݭHLYZKP"BaAy{a* |o`BOG@G䙣jG3h(\Dt뿞(W`ž7ŽPewMsian-"_Qݽ9h5 bs-z0`8e@Dd!A{@oRMQimFlͩ09eMpMipA4TMg5|$BxbG?{ө2Rz@k ߿Y?1%-]RSe+uNCÀMS^lP$"rݝ6PbFf`2|&=)53VAq(%mOJNi) @{SD0pkb:|VA1^Hᓓ׮ sȍdx۽T[- H(=ӫ r/y/$& "_<3,6-2U4Um{6k.ѢhB'Wkn4Gu?/S/?39puS`39!q{^[_uiV_q! @5OӲr[k {bvX}ni0}ZPTE;ONOW|f5aSCn77FZۣa-@ 2+=SpO B -vNiֻ_:gl0Bu?!B:[~2[M(܍!-zzO|S>VxqXso7'YYævAcdx6)iWTzx}eHlHᘞP;(g}$*fDzރF69qj<=~ks~5(z0iomf6Ba\pi7D K#KKDйn!ڶ鱠$HN@搁ė9Z o w*]05?qU}5Or)%Fdr57d!TSz6b;,K/hOMޗ=T~?ʶy w ]Jh6 4ӄ*E$ſrWqL,tg4{.٦{zs $޼ ӝq~]tq5+%+B[M^YgYJyWSdm1eS"n6.d_sSn;0ㆹM8f^-=v&5(!+ҤM_>KʻЗ/sʑa!>?G lJ.$2 36 d2Sݷ˭щ#Us0~إ] j67W]bx9m\2IQs%~`B 5n?OFӖE<21$tRbcECk}ٟKaZկhf<LF060AN (漫{>k)E@`+LxY, SZݵM~ͽ+c;4XT,Ȑ6UiҘhNg`^1Ƅ ZL֎7|8 >Πˀ%$ӖMg>n|;Z:4z~ CbRT,픯4~Ac[=S@5†?D9;> )Ђ S Q6ZXRZ+oXPz3]eHxSR /9@&C}܍$~̬Z&W_h09JoZhf;apw?7XBw^Ź7M!Ơy=) z=&Ց=ϡΉ2m^g%EIA7ӟ3"z-0R݀(^ў\Ib}jΒ X7ѭ{) qDFV^ <ݲrٽBv7nqپ9L~(q;\T!w> J Ε`섋D$PȢ6~[Ǭ_-PHM[2|r|.bS= Fe^]v}BSL0av3X}%5Qw5j{5S[׬< cMT)v㴥+bmee s BxGT#s.lΡlYwspZe`4!$ůM|Oj: FaiߵɪzqSɏD7/jjp#Hx\"Տ:9H-V.}^kj7a^}nηr yB{   NrPңԼ[Yq5 \>>)^s0n&W6pT-?%^ d~pMQri&څټ.P?5K1-\d` ^o#h|"@om^ߠHy[/E^Z{`XC7$r?ڳ1q:I핷&#bnf׃:'銒.>E-G7-RO>B3S\äC=B`R1TlD]T0ʪV/|^fEN__qJs̯I82?sx2DY:e;,_awƥ{igsn/v+3o!{,w1ox;{Um]v IvwiuyYW4D+ A_S ڀ)y|T:]T[.%;l@EB7Fab*-LاѐwqeA&~*,y2g0iwCfZڙk>>sfȉMu=}R(۹dlw p?.ZyGḓ+ŨYX?˚ (7) ޵byqٜX q[QQt AA[Smf˥v }F$tvl k^}3gNQlıH&O>qu3+h5>1B=X_ֹm?7# q %qp˳<\tiZ!c(0"z C$Øc{,}iSr+;kxJs-0+䒛O*u eA)sQ:P0ހ $/HkD}LS܊]1_U!5J|QC#ק !ҊBa"%O7:kw4z]yz,mc5CVFeN-ح;Rgi0K6;} zZ)4HPDz#;x)-k \;oF (!ֺ\̷ws| 4FB`y]Ӏ2f! GbB"D6Q;fb4N%k[ӓNT,[~ݮ3V~$`#eȾW?}npxE-@qUWx3{['`]aܤɡTrV5RWH-ڵp/Zni{"[LڑzOS!>qo0-\xmxH|~emYU4[YYNl3R^5-WwHuIҸ}{.fiLV)'RyR!+.,̓%$[4'#vޖ?լ^TҐ-h\ u=#5] q6rrޘPsRZW9 ЏCV8:\C ;/dq8&9ߋ:ϿW˚1B0Zg曪\];[Pc59n0Pk9\U -c_.&p[W|8PlkL?^aBe" zzЊ:*{qGsE|-u=95,PhVM8+p()16 @('#1j>:NUJry}4%(+'mC`E[A./U7Sޛ4ȣzX#yVhHڥ6v/񥧔c3"=-du@5dέR#1 njaNyTr 'M 7By daHYS#uj}m|7(%׵P3םʮjH%mvC!&EPF%02SEnF:/f&£&+䀘k0Cg)o/R(XiA$OU&:diΖjQ4xH]'G.FŒse5٘a|a-t7R-j ˎ2s*GZM4w|10cͫZ)+ `/h<0A,P , HiӉfoNfl4.d 8C@W[iNrLyFPg POo᥸>TMh-}k'Aow#Fo-=ƶ/سqЃM86!8+zʡ2> bLr@}`53`淎IrA 1b-G_ڏXuߓ oZ -gŰ `{.\Q1Z>&v|*W3qGDڟV2vlrM&Z4>+Ɩ([I\h {>~`1or,\={  ٟH;E>ˈhviw koD$qv.~,CziNw'ލ&똲=3 X)w}. Qqt>wu$3^r+'k<+jeyqVGHo>Kk1%o \/_ y᤹]L]m⳥ګc9COIÒkZޥv , !mp1^btbm!ϼmM!&lJ4ط]\,=!P#|r6{3ģ bjbQ?\k^ow`b)teLdeS QF۾LM?K˻~|{uf\(tՓ쉌뒓j>[lNЪ&:v(fz}Xz;OXnnIEՖ>(I)7϶"7C_po0}F T jh]qG@#bճOܺ_1K&K8'-gʅ oTlK"ܼmdJf!$]i5ɾ~-o(jd6x~I{PާLY趎j=dUNYny_K 蛚bOOt.ԃ2?\- 8NA :޺lPgfyop[IvNuՂ{Fƫ@+J]i00z&>z Hl&^w-$;U쬎P~nao52nHֳBtF ѧB!Ū$s=1!vdrX7 hZUJ_Z/lA@@e˙RlFoMV^H}yEbDoFiw0l|vйKOۆ%,'ȅl\#Vڔ/TWyEF½Ȉ9bwɊ{䥼Gy|r~?h'O8ގ:5]7O^>A'וT6IjzʉL'h^n9eHy&J@JZe euU1 RUx&Z@4? O&|{ ˥փXm>B+&"n_4=Oߛiޅc[0Q쪛$z [%oNg;=S~~9^TTe`{ %Fg XH+,- ;f @8h 18lo>vdO$~wh|oi|T{Ø']̼7~'F̌>o=M td`t &d |DT?8I m+sL IB +\g!j]qs$.g=u`+j2)۬z?fYb5n~iLl%kY!?qLH] [BL#[>bۺm(WoX&ͬ_HqR`$:VvcÒ Q>%@8ܰAPyz.(,1a3MXu[w> e6SLB0pߧcwd_xԜYCҘVq\" \bk6u;PJ]6fS%k }mFRRz(D"$٪;Ju|J_n_zio0_C]}ue7.#kVSzKS;ou">[DpR2{~a8uDW0v)+i_ ҩtBU_Ubi.5kA&urʑF ' Wm:J/~b3|\:-oc͵{g+S<9>Wet5tLjyD5yۓÚ~Va5,w_zCVUpYNdcOnS(SF@w: a.-8T *``aYj_|J|qRzi˭z~@PAyc[?5o1aM7DSܸ)W>z #Nwy(_\M xݕMmZK$$wZJ= qxjvYk޾OJ> H R~C$ٯs|Bu?,~;_#0{m湘Gaz62׹Yanv=At: }[m QN(ɛO_Ι˛̝ȿ\ YoL癝?`P0Ar O7 D -(y2*xEo?0~x 06YёevqH"'Qtnci6p}Sٍj2i ᪬ބs0?Zn2lIK4c|jbȕhLY;Y<LsםHH-ٔ )jpnpO&Y;yxjp&2w/˶3)`y$ xusSݥ*/dbm= 'ps[|~I~5zZ $.8 `(ɹ6M6qQӬ)7OU+NXS/t^ZUvr9[5ef<$H./kANP^> . R4TD-z׳*n:Hf d\YKhaSr~a 9LX}H`_cP$dܻ X҄Fͺ8{3\ӕ-[SƊn8/0#Y\\Z,x)$vp\j7P,x8NO*>.R8m])sTҊ*_Qm*q_]in2 q8 HܻȖVwv0 9K?of9ey^R[0[փ_Amn~Fz`z+X}r-Yd O#nj㘻HrŖ GOA2sbĖbqJQJQ5KU`J% x|9XzPِ Y)QTp -d%&u\%e٭ϪL;F{[oSIQv7c#"ZW>Vb,V XB:K MͰ:# wuSdai{8Po b{}"~)@ Y,J&iMS`iyr?rBR[M\P}Ġ7bߘ2_^ʟ@I\a]' +2_?s7"_Kbpa}b2ASC1%}{_O{#qkyXi sE Ž(3[1<}zrF_"<8؍ =?tSQdfw,8ixOL~ -FYr;H8{PTRToJY9r>KJo ʪZ! .@? 2RP2Bݸk⯃.Iɾ@\:d``=ҏ-¨ZFK(fr NB "25<|~ 4~iqHlDz?456y}”ErZ68;=jGi!d)x`6 @j"}'1mNM ?2 :RW]h b$dQh_3(Y `A#pmd ۈ($2 ;Ptjmk$ r-{,Vrr>ʡ=SCѸtYn |Xڗ=09)=  ˢA5F0m7&i6&ilml5m۶mf{~{:3safGxw9JdS:ӓq|[|_RI& e_7ܻG3Mͮ^qccIy ,Z,8͍FFbT4kG3kRI,7D]I?Le`yLƸ્½LjqBG<{LeSB: b/cbAw&!r=Ϗ;xiy{>tکlH2/DX.:̫DT($Kw0& 3ɷXjg"a^ѧ\M=Αx*t6z}Yߴx  kt춥R<&$T9Oˠǟmȷ1W0k@#+8hΑ qd>f߶" $re}:jB83)$fZx']]sKw^0. i%_kuQ$G 2VWwb(<)\Q9>,ZQR @%{D+F "$Pq,&DKAy聚 Á#Œ iR|os2cQ-T&I4kbcZ XLդlU'սzȱ da0//ghyL#'^|*F9;NSo:fi.1ggQU[, NIY| `p/7dލdC=D^F/+Y{&$\aOm3m3id|]oTUWwSWO:<~SþK8]]@s4DIpKJV2 1q3!](HTцdMFVH^)drpj!W`? .( Fn,jԮL;JgA~ tpߓ>1$7.G~,>OޫgXOl2HdS^! پ61h<='̞c=%^93Ϧ!gt;͑BX ro1 ߅7VFu.HDJijNi]ἴɷcaLc? ;ǺG|rb2\!WT-FNxPƦ|7/Lךr,{cQs=n -]~>tw̐\b%/ -H eq:$Q NK[S`8 w1a/_/`  ^8V nU&Gt!^6C(Jq{95̗֝On n]p}IӜi0wTdx_>avit~$${1Ogϱr+H{`Xy*1W9NonqPˌd>ft >?޸06}%t[X?q:e)[Toy;X4_f[3%<{8P2bL]m.^t{_-4n_YPz6gY\;׻%T[=q7}WnŃq?>+pҊO= >kշ 58\!Raİ;{W(dΩ' ,1/1,橄k,b"OmT BbY|-t\3 ,'GNrPJaPKYcJV~>g)3Ah!$JNPӨH!8p; |胬JgT9=nꊌ!yG7nc>h@ 4rvD?e(G'tdRB"8U0L=QAo܋C>2 TZ=FY}|asy>K`mj˭i&#W)YfsҥCezs7Ʒ?{=m " 7)=ݱAIZIY,ֵ챹EF.=ǷM3*DTR̿N~@V\UR_jB54H#?B;R=:?%1AhPk D_ǩ?BN%2$o ]*a|dT1V+6 W#DvH?Š}Onz=o7_rD3eq1# yR'*oRSdC ɄN%9s0o@8e'A/bBtڡx{]z'RjYDPݲ\d@,;՞?9*z]J$]Ow)fETNT`V >~͐4I}̰f4&K5Oga^.nî/G /Afb3kEdduà6/ʠQ…G ψr> s {U9@&oi.hiڙ%r3%s7cb$W /H p^$FQ 4K-_kkClG>}悈Gs] t눔F1VpFZnᦖh˟']m%.ܹ}$/>L>zWO-.7+\u+̢I7HO1#^쪃ɍ½)Ĥ'Ǯ7q3rqx ]9_TbљI)'bETX q5#92KCpXnUS¤u>GXw`T1Dz.3 p{]dax`wRtBʅC|[k|NBج& DŦ;d<:>~j2eksySY@rb5ZNxrNVdĩ-SΚ]r2!;ܰp[6YXZ_}:#XOʃ.w-& FbI~vbeUsmo,+]3/}:YW62L%k^1 뫮ޗ13氒zZ[zǝ |T N|H;"p?L*` /ޑz˴QZ`p0*˸t0٫B44);#x]+ܫkL+:dKONy=.7 i ;b$}hŎCje{0I>kA?.tjW+fi>1Bʜy] EK#"L޴[# Mڙ dƱD߃Q 8A#~_%v'zL*+bvdVٓUhxڹ V˰pRFjwۤc O[,tDS)>}4HVwe_fBh}U: 4>y1PdZ3Q !kWsL6>*k- 9[hK-ڨW v4ֱvD<*er<#}@X=Kd6a*U |"Ҭhmwzi{or8uAnW rtVS5L2XC6u.CX^%nFP7zcQ7'g`IE7Tީҡ-RX -%MbgN63v~ Zk4ji}bfnӟm"m7  R]uW ;?: 7$.pM<*V$^$I;e a7C$b`S rQPB@n. PJD\Eb{B>TzkX_I0a;aTrDeԍtu-2. p8la/v>$ؚTЋ꩸ʫnXY0뜿7j^ҵp$Lt譎hSGcx,` (:3M~-N Ya ?{%&MeUȢ0A4ШI%|e.~//Ӿ ubM$Bm"z*uE8cn%fyG`Bq,tV dV?L;\ J\`|T/Tg:5Zj!Qx;`wSz3JO% I_ )Y=/?p` Up3<źO 8cIym»6}YYĉ0 C#uf8ٶ@D.ݾb٪vYĨ[0)='%g٪Gl'XيC\tVUs{f^FacS0M%t;@;:BŋXשlx4ڛ.D<+_χTO !jҋ id y]2<-l3`J<'1R|4 *3ѲC8<@7P3-ߘ͕YN`Li]'Cu\_T=g }iL23z*,KN]aѩv6LiR+ M?vCY/,j`0 WG g$Ry8lUQt#G{9-I,+NzCq2aA#tk-`Y|׍7)S*˦cIBU(IId,Rh6OaN)bi[gcGIϩGݦr,oh6冸4Mq,Ղw_jKy"mC4VH}ڛRzrIogcv{vV{}͜ )+:+e( $F/ŶAn$eU**U'|쳫?߆Lj3dj[$5zmgO]Nsw,wI8t)Ȗa_IE>E&-'ypu(- GAb"R+Rc}5梨6D3֔2]fHWxku?#k.љg%j]^= "K=] F͘]Pqʟ,^-5c[g˝)!6S::^7WU}e2>_۳vM\AQ6 ^̹ѭoh~es"/<1igfR~$̙~0Om9ۙ~7B/!|ve[D1t O4Eυb5j#g)m*Eeei>(.#v ȳwxҼ(ľɂ /j"w[.w(#<&iB䬶650E #Ow_{pEGI:/{tϭpIԑ͡1G( Ru,pY@=R$bVrCA1ez݈SحD8 (SGtCߞLb[<ў1M4ȦD}N۞gVɂ(fS=,˨}98*zY t/,d* #sŞXWAn$KS6ns*:j1:9S8aZ-~D}%z(lc_-EY#Ua/oXEWȶ{H4;D%Ss*DR5E܃Ib "#3"q-I&& LI;Q7i%=Gס -̾*+[EsLe Ch'Y $-)qA'R t/Cc^[-.#4^=ENTFS۷ 8*2 ʻZgvQu&B3lmJzp ]( xn!mE%/b"P1JI˃0.PP΅C7P?߶F\/TC{ ·"4Z XjUW9*@(Ht~oj Z׺_kcނ闐1 hI'{ _n旿 nzїz;B9ՑZ'hR2OXp^bQPGgys74`TG%N sád~0{IDcׄq߱pw[6"U@i.cwɯnVE6+%F J*%hvZ"]5pcQP4dqMfYci^gM շ2V 4ڼ^ߞteɸq D.~_v`+'_/WDBثx&!|տOR`EmҘvrOxcH.,zÌVB b(bԨotw~u6\gR߫#2JDűA.Ů-Rds)w!kF=d<7n.o@G72Jә~_UvFDzI4_2ɘlb?ƈ>/ E-[ dCx؈o{!g(3>N9C)5[#m|*X!>8FX5Yk-Qn;{yMSHX _pVm~CyK]Rx2ܼHNܰIړ53n42>u`=|F;t_KeI!0-'XгۮpL]yUEc\Яhh82G#-6WWMaj&gBtF yo .=X3)܇i'&Z$9i8M 1 VjK{X'sx ) +CMXrc١/#F3 AgiKʘiE-n!a"&8a>2INTj 1Hk9_O*pn|~ƫ+s"'qޥW[(4(+U {N-:?6\hҝgTPP\؎[_lsp&A`CCk{y-n'20nT"Ȋ>#KOk6!qS"P s@~s*k- qYfRBg~%*2ålXjYZ$q$ 7ZEN,9]W";p Ĉ"6fM5M;zxUsU8c $Gd 2`Cêo䐅l: D&Ё r X1"ۧY伥T}x `vF&nPPv!߱ ;ք*,Vm4?"qaWCt0Ţ^OoxƾuTpy )k䫚2Л/k>|a R(&2MJC tɾ)Iy(q¤H |?>Vl.u(M]0`0ժ8,M\F0v+4$ԨԯZ5Cy4Fc 2XE~]EDP@FM>mx_uxc4j8( @MMW.t Fae>ێ!~]feJE)~"c:ߒq![ԋD0;ZQŢK&l6 $dP.=Daix*cݎ?~,4Pտ?r yYe.D{bo"bs:$625,hߧؽ&{~a;`Ln%z [fZW_%uтЙ mr9[9rb|y#4Rr*m <#g'/ehrӯ_܈vJ $$(KH0bB5l] C'q)X*!=yZKJ !)Tz0}(|T 9J)/y4*uo0or_*gҘ/*R }0e_R%- Fg%f9 4* O " y0ܙ<"~GP"r6xݳPR5NieZs"WM=G \ۆUhZtv,aqܿ_(n ͒$% " INAuAشBv{RAQ=j+㬌Y>mU` ~~od{%a>"H2鯶 X,,8\X?Ul@%I5OM.>L%v|4R =Ut§"(w8 KM]c1؋SoyqI*4I3OPny#&x÷\6D{R+.AEZE~ÒE鵃 7-$vƔ-zQEnme0rA gԷ~u"h~cDϛ+AT5/`0,A=(iXڧ- `"Cc:H 6w_p%c,J=E󩡗Lb1//(Q,"@ҨZ wGF>bCўۇhӿAw d " L߇桄)~'Bv CrJ#I9/"]neGma B%=O@(c:-M$y5kڭi:['ߤ6_ e#|bXaTE %h$ClY|H_FSJg>fj\lE 5%&,_"as?f6g2Lv1~'˻]Bsqto vFr];3_]mؽa "]@b-Pי XQF\[;0xU%CU%6]Wwf3F#mWmePu"$G3etoL)T[@kp94c ;(t-CGݒ\+ ZImmnhy`^Diy3ǷsB):GwPzVٱ"vb#BE2|%t K<^6~[j{Lp@=Dl4eC#*q˒(A+uې"@nN K/t %pecDyGSُcp$E4|-Ku)}N> W3R|ba#ɪ(X97)-%t~o.fvte)ǂ}9nULiA,l x4*kC]f~!AӔOO,޽Cq IBoʷh ~5mLDhz|ȊZuC? *0 /"2ɖp7`^YV;P.x-?gp$dw Wx`SjtCl x)ev1+aIHЍtc7t g1r<\dmW~7J;>j1[XT =ycY f20pS~z`~o "$R~ƲY*ՇM=ghg]Lv,d Tg*ðC[Asû Km=wND4/'7M6Bu{cJehD'g6~kF5i*){=\cMd'Z鳳iJ|1S;~A %]8kp h¨]԰ͯh'<2n9G"8=eUAFm6x>RmdJn\ffE`޸:DJkUOg?0| f `WleBN懝87E€1<x۞{d}LhydCG$3M^E}#ϋ8۶OV>,> ?wkPai 6 _&J߻3pխ:Y1$iY$ eqq -ۍQƀ;fOAG$e%%1h|BShy3)5|:( p>PVqT^drև'pSR=PQ?ת䂢:gG'yW+`zgMZ-V /XK|Ft9 v~Z{Lz57i(:gdq5ptuī yK}}(}8*s&Zi93"νn`G~ǔTmoD̢ReV.(iur 2AaX2rۗ[j} &C~\%//0ļpujED=/7C I6Gy8TN7*XX2x*[(%d S&5iގ$j@:ci)i'lw+Szh *ᆬڨSm洑2w s]2]ow]f28@Ԝ$#:/âW.R.bo'MO?JA{{{e&5MnxQ +Q S-zoQ:o kQix?ȒKEt{3%g;US%5 [nޙQoү&?C_/V7SXVH-/DG /sA('; 0X^z{#Y)@\{3OK ؑ-K2JOH ~6B;ZNHڠРb DSCmˉgs 33{?udV 8F[-z֧w[MV|=oA)]Q{ MJe*ktl qƸXxa(M3+2I`Thy|]Ō6ϓU %`'dq `s'bgF}\,Iktba[g>RO >F{fu m䜮ʮץkF wRM~c8LJپ$"x0H $Hn\*>Keז> +Q7m "U7yh[aWR  r:[<eNǩ0o䵁^h/ _?|+Tsv`= CwG5S&ۗvLU,JۇNҘۙO^{^Guyz|Ky1NXpkǐ 5 ucS*eӳhf+%Ҿz8mX\ tGޞLN|Y4B{zhd?iB^T _IgRbSz\Ʊ\R#}- g '`, a2/A L & Q2QV@>R Qrr!ɏϻOo$wtFEګwKs35zY"5n ~J́ M<|qAӞ*72u(ZtQ7Ю.8D]d'==tӈQX?_L*/oAB?ڊ:߇6)fi:\hr;hj2-[<\[OH*|  y+xz)܋>XBF [ [NnJC@Nzv{~zu.orʖ&=پoyR`K CJ^5P20) Êkj+z$ LGh.=EMm= Od۩t^4֜6|;P>;ˇ2|5&#MA_ENz5)0$w1)imf {[+ $ŏ3muEN @R6p-ET1|}˯4tAj[_-oM!ka6~eAZ/-R iC⩅7:=6ApQ%Q33k>tUTIVԟj_\E uHn6 㣈O+=s &%a~>0h. g6i6=R:`Gh+/B ٝ5=¯IWp,  NٕRcf5~}9}ݞ,8V&p1A%a:eRt̃)jVʄ}w9U}FSzovB8/ X𝃍^-dz2H9PH\}EX؏sk "19'O&PV[/%q|cwPKjzJ 22TERGjq 8ZUOY,J%yREBQrA ;{ƝlvV^OB͠S!BEu 9\j_ko^,V;j35?7FFu6Olٗ(?^([GOF0 Ф>7a7|SN(>]9s kȜ+SYc49E6?!P\>a85ͯ_)TdM͏X"b=ﵰEy%>ݷ5'{;wC9#M–-CbMV.`־^)  ?4'iyv˕d#w:U6n1վx&vvB zaN}'V! 1qS %gEb?m)vb) |J߃5ӄ/ēgl.pV[*5!`>{b7 XΩ˭֤R^@c$E9yV n#n?BMNrdG_5裡ƛNj%n3cvmDeǮ.q"w#(> 씮~=z;dzcAeU$TH?P-g@:y؟*0`¦W,m]{f-΄DrÏy^JdDsMVw8t[=CNx VH'B>d*)OkxEV|K; Si@Dwbl*c|%=%yj(Pb# w!bVL{ʶAly у,WdXùe7ŀiK}A'Ÿun#,|B=wK@Ul e (?t4`%B;@պ7U_oZo/6QOЮ8:\O}KodЬ3okkvQz2ZtP0\\[h jI G4諀Zpsd6?m݆nE_1 0_*rLEqVV҈0C+]ܑ]J\n-JTp,]p3b4^kYx/xF^r*# ύA~\cq@&[g7a$xa.kn:+C&@ÇJ)S"yry]T';)MNee-˾]#sANey$fvF"}Hi)mJvIPwqT˗r0˧M*֋Z_esMw f1']z BcZνmQ[@ oJܪBPl_NQ*+&;=tQ40herwÌΘ7w?w;#}+(XwdO*5ڋ:r;LJӪS#jvbBaDŸ{D] q . ?8c`$)2].ux1u,l3(#]z 58?tĪF`r^BRY^aXrȮş( a`Z + zJ41ˈ) y$.1v yrP ^<mڈ(SI]%΄WױM5U@?G^)$=j~u$u?zbۓTP(]}x VЃ2/!{<_I̯ 1`<bxɵ:r#wq:7ΫD19#j[h-aFM$T,Ts(~(>qve:*]=7`G7ߡ\_G4>.{K ~zvDB}JnMxxNT68Jh/~^t}hiVp: 酯8ʝg+*g:}wp٘T+Ya8:fHl法jib s/걓%1gl>p_CD-]EͽYlӧ\e&CA[*H g4o&y̆}*kˏ#G\,W\I?\HF:w81Y+8:͸vC/7KDx4X9'/x#h2WٱUk;A!H<%cZK ?=- vD( 0=i=x7 Q(7DzB6Xn}WdThn}4`3F擿4 rRWxaSrjzw+Wضb/dBu/pjIn@awLJKe dN}5l1M/YbۤȬ3 Y+ߠٳUQ9Cm49*Yo؏&Slòs^qh?W~,DVJ~rWS?:PGGiL3z =NMHWh-%3HX}g )rp iw\<3ї{,%60*c4JqБhު5^D$&J^JBAФ'F)qj-޻)0OGA".VPs7(#hȦܽi3lvE`&6 ų c4^RT"+2 eE7Rv(s*4#MWf6LXXWvkKD,'(4G&2&WyEe4_,>n,Z)HB`̙8]KKb(#+WXF>MqcCc t0;]%aAA1.*_±f-Fa*B ;{*0-H1 Ix [bdP;^DW$'o$ɶIW'a]Iғև&4hǮgh9Z, .x[؇V7ew|Tc.n35|W8sp0|@s]%XdcǙI4Ek;p~~΄ƝG!{h% kixGP6}Ox+9q&2(zfd)#E@Ix>¿ߗPsQu%Zʑ2eM]VpJҪp}e}aaƋ/&n׏"L mpC1tH(~ YcWqf{{_ D﷿IDt&v5gԪnb+~ Kr/i VҦNz(1ְ~:F2`o7!$ 0:d,\76'kR,93->Z7AB~S|ꚮ&nA8mL.IK{0S%A" X,eTFgJ[rgo})b1h¥ ψ៯~' /Әkuo~CnRǹ||_޶P/W3XeFn)xyUDw_%(55m.v*ȭLKҥZ0g Md7Y3ɚ'DƟ]gGraQQ[Ge:mv)d! 팥uH@Aqh@z옸 VFHZ'/{wPeq7J1]YC|̾['nB)P*?k6 ,KݘmCO/XeDnKkI2(I&[h*̀f:@~[~C=HG?;!|!]}yPL\~,~K$g[r%zpɛ_{|$ZM󠴃?Vz<0TyzntcxQT~꤇]*nD&ۇ_BCsYdvt24} 04D%K+" ',(8#' mM`B7@Wo:;td|*= IA&k:=606 3 4~צ~_J)HWnJߤb8~ ZGXKz+/D+t5ha/Z- (H>8!7G\7UІΕ>g7 v7мӉ؅F4>ޔO}=h %8H"\au="4g/ @theD"%6C0ؐhT{Fxvѧ*XWEXf-]m|;"#4O8өsIUZsI1,s!)ՑVSm.toL m[_O`5C{>cQZvvPV`k{z@BXUzUn:28Mpe\*Exo?5eDNnrHY6`l_Ǵ @03fCԌlOAo')97?O{D9 StϤl 4\Gײ5<onV0)&#]QNNJ{;YwkuRٻӈ\nV3r32Rd;})J`Ƴl<3B9'Ϻ‰%I/yVdvq{EokJk/WuDA߶fHsED\ڶy/aG!{ȦxflELĂMH4Sh}~i`s@!ٲ5Nš/LX(Lq4}`bw~*M֏vM$>pC}mޖH m@r-9Lzoom9(ezAIΐ06~wr5缸isW,F !#^VȎ|:Fyj3^tANJE_EqV[$mm"Igwr ׹gKq!iFDX?Vz؊$u0#T_Knq;aY5M" 13*7m;3 ϛ kL'op cLz}:?rŊ7:o 1{Fq'dlQr1 -@ՎNz^Xh+E Ӹ`&Fo6=JzٽuFKRl;zV]]kx0,_M\,qs-m#!l ~ʲ~Q:6&s;' A0@t\#w7*Nw-AZ5qsBLy@dw$ߜyM+_ y6Pǯg;˝,v~_sN7bvm+e  n+ >|Ob}]8 t}ϋ8x`K(0c2`ot61Ydy.-˷1@'';3GOש9s'LFPba}i:IYU/لh5^T~ˈhѪ9x9^ӛƘ<ۨp޴v|Bspduʃ aO*qn2y}d$J59Y5lcNKx<2O|J] k+,dxMX\"j`pOf.Crw[W #@waN>Ql;Ų篎+18̋2(iwؼHƔ h(@y4rIݎ6bdr,!sdnT|AmHuS'sAI,KY mQտQ?iJjhGo!j'YG Ƞ(0'-3%3_%vg˅6)cjܦ0낸™΀uUF<1-$$5M x$QD9%hlÖQ.*j9jN{yC+ ǵEg|O|BW/+4uwwD\"TKX_,ko1 C{+bpW+'ՙ8x$WdD2<#2PuQm5-ǫC ߜ𤲙?Ag7/$z/ĨVș"'qDAl@I-o:A{{^a[#7MGlZ'-y9W\BDg}'x֠w٩N"!*1=. U^)7s*^_&QA(J(A@ÿ^{mgRM~VW0\y84|i:vAmv1ϙ.GH!# 5 k)QZ/>IsY`6K2+CcԦ൱NzKt,Rwx?ڼgI|E%u5UgXP{BSGQEcHrݭ z,/7{FqN%sN''y؅&Y/t;EZPf[nau#+X^l" 7OeK 8 kTVyǎiN >8zfJfixI}qI\ EԷF2`JOس,\n<\1((7t`*<$n2b,lU Ft="LĊj!-YZtf:QV1Hݩ9pm9<޿!bj~o(`%:\x5lLNǮ}JY̿`+҄ÎUF:9k|;BY[2$5% VZ.cu{FGEY Z" &Ʀt |CʨkY}R촓&{Ƙw2&H{L槪==[wIvOO\V_<|wydZ^_nAQd0"F~QDw,O L0G{4UNvEgLGCQ81yW(s~"'\PXF{J N`T=a9yS]D6z& L1C;A?k4EF^#Y,v=/5`дIK EU;w9Dw,׿{%#h}f{r-T lhIw'ޅKXtj~ abҴT&(hoIkyfg۲DgY˼);8cJ&S h8ۉp)BaˆM>K̊!#Q߅?+I;?, ܐ4пpd䫷L,F:k{LN{ !]F%TqZٝ |MG5"qLIX#p59 FFRaXUŶOEj??q+R#hS}\$t轱 (ΚДCؗ*t[l}%w.9*KKT~íz4(*k@g 0*>a! XƊrd\Sk+LAgEq ᜒlT?%?> x8t y+:%AܫӶ'ü"9lUt$;"4MqT%pwe,_.͜8 CbO$1u} YR״=&D|ã?:/A=F_t7cNɰrGW˽c];nu#D"_b4 f7y*vl}H.lti'$I&ä.-Ӣ7#|;ຉNVIuo$ݿlM o9NN^z?ֽh OZO+EGBoΰig4Y9CN^\5ȅ&%Ѷ1nM:" ?h@~>s̭֚R_iZ {d[fd;JT ` G@f. uˮuY f i!1󺸒Ve^ ^ts~T3!|D8:ob2թθ U{Ma"3ɕ@fqQ;|! לKvQa=sc n. ݔ[ 7:{x rnvǝ4M!u_йF}n>H̶RV?`. l}4#L!5mED.0Aeń3n"l2BR2tߘ0W&1~dw f^, an`2 .Ӡ^qOW=no,R ޹o,B$h մ_+x9{i敧4?D *u}Ε?[<)V4 g8 Zˮ=o֐b %KrIgwonaj%D7q?:BT>[~/)x_@nBdߠ[:UFG<Twnͯ ;e ˖I kiiu-ZӽWv;_b-h^דS,Sa2¬w| pNBPYz4-}YŤ > 1ԺC1 +;J\h۟PB"\gN~HJc2_S!zQw3ZPx{9oy6Q 藫}rnt>PK2Ŷ/*kމ$F_ Z s^L$OkV3 M`RUF:} # clh)=]ͭTe}x5՘ɛmK %*Fj8m$F~d^ p n0=J밻ιq]iUvkx%zO&ڈқ&&#,R䠁d•$~fJDt,瘲߱HwyO 9}zƻ UmKp*9ʵ<#tkiPh/F~]o k{>[d+9t"beb< A7L?Ru $8;`ܷLEoAXNK>c~<|_=OGN3R,}EKX8m퀏wC,&c%E~eSQۊhzC캗g DT13G$s3{驔7ѯCe*5d܍*3 ¹cmⲁYyJo;pY9ܜЏ[9fYvuSzwEߘpeOeg]Z DLͳ*ܪ "=>QӸh5]JH/"A2LfC:L'9^]IBa x瘡Y2pt,oaL q)? As.pD81ramWq)boD6huƖ;2.#t hTHk!k]>9rQ )e; JZyGa|1ij;l;STԐ]ϼ;UWgowr;{Nx.Kr4N.0>y 'N}y :*۵_"vvnH[ꕴ%o׆+/^py w?Wf|:|\Mw' xP}!TqUXhej7>(ۿG{"JtO#&t|N'3OM['(B mSq-6n`A] =sΟPu6 rfdШG<2ðH+Jқns3R {м4fג\R>|_]744>n9*y֝Jm\ړnGdI!}6Tǿ521 ” ,^TQa} \ŒF: cυwt\3D^^N@(H4Jخg۶ mcl{g۶lɶ9ٵ ֹpJ FATgK{zl 3AS[^~ߪ| }-h'd|5Vc)QW-Ry6˱3tEtxž ?e|evݞ$M*XU L斔fһlak3][xeЌC&AjUlCd#.I%-ƃQ|3Wtg.twH;.K65͘౱:v.Gdd1bL}n+Qfy(7Gx_vlrxI"U~{ 8,(7|)s?<:p)GC4ۑ(- ^q&[I3G'3 e #zz3/C^v$U R/ϋB-b~`d * -~u=F]T#G3&*DE pAͮVG-4Ja]&nYŞfc8:EA ]({zW!M9ꯉTa4BXݗT^]'C UKz;+7-xdo-DyLMhS};\ZFR,>@M-.c1!(6L0%ķ}8@|Uvpﱫ9kp>@,[ z/ YR0Τt[I5gG_ p6ւ! -6'NXI͝_?8-h&D2Q&Fa:πU29:a^U@bQ69_ 蔣kev)uCoGWFP38FnM& ֗=z}`VdpkyJuGI*RIJ#%Oj6kkp٪=;IfJқe"[R4@;-f6t_=` -^mF)7GYKTʉO N}t+ yYf6\Ƨ0ΖCDaSFЈ1"KѺ:c{1Dn{DE@ߥj⸽uGIr( Y+/ԎIxF%q;Y+M9; ~% {i=egh}* gPr*C(kb_5jTFiCV6euЊIcH\EGEvqiC1'װH\h*Y~ @,8͟WvvxG9:{8>chĥ v-0mx%*Vrm~p.c?lw|?֤ U;HKKEOS/T `yxL6$hApA3wWlT)$/7c=Cpt}p7M0YcGs?N ɓDʌ۴m D!Á T}M[~ܻfk-=m7"ϗr]sFim_cA\,C]qLcTeG{pOʥȱEBtz{S8FoYa0z|UgS+gi`-Dw9&& yv0I,ˍ{*gE> SPU*R9dsnrGW+&1jEOΤ]@H<nGǩPSN&Z|3{KGT>(}% RU׼^Hc#l|8!xzT_ |k!j-6!w>ȴZe8Oޫuۍ焉 9a_I/&1YPmoLZѵ7򧕑 G_Åo Vڭ޲L~Z?IA {tvl.k$W@lt/q\cW8%dp½!pE=M tjh_"D8+`I,70"=nbcM-d\8X,RDK (l/pOpBz9`?ᬺF7|I{ch>H(?\\>'tJXѶdx!_'mȀIm;G:㗢觝Xd9=lrzR 썩 d=Pn:aG G"_cTɀ'!8Yю֔1SVE({LBr.չ``A*hA) ׶AqE5 e#m/lO3cHQ8[A8@8h}(6i˂M"_~n0jQIlv8yš"Y' %P7H7S$ %ת/% v1IcW7w| /b)> td1=VOEٷcd'~{tWŧ'n<{mq*qR;JDߑGL'_a!|Vjr%@[+>0?Jk~ IL3a-m/$YFQi) S0QMlubON"/j0ŒY9*݁Nnt,RG. Lk"cO:|gG8p} Z/C--/чlC͸ Hlͷůj '>Rݓ6Fטo4jN])n!>$sC|4xl2ĥjo fw6lZG!YT`'6Ǔo$ |$LNFvCZ1'{gBz,ӇHVpO'5_КZyvBj?PUkJH7{Z<׬풽qEN]闿ſuB#b#NCd W&9R.P !x~a2;0_T-'٘e{Mw#P &- &qFteY9C(?io2\ŎB/S r7`a`p0v>KE1[%#{sGׯv!AzC6#BTMgcZw%ntZlJĬ9n{B{2/'t6 ![J=!a&`nwgk7I[L3QMnw7me VrV1Ib_#g 0s?9I*-I>NŵՖC`]NKq 57rΚ^mЙ)ζ$K)cu߸gk R&v$ܿ>ۉ#=-|eOӇȎ%F :ݒ |nSWԥ<2JY?1x_2>LZY Mj_xBJWɯLݯ:IQdOFf^ɜ_|-a8T үՙ'H f R#H<2C^AV&#/&] ׻WWJwώcqAyWF(h8tyCY !'K3Pܾ{{0}6 '(ܑZ7sˆ=2xٞ3!CR{LuNx"V$j⁊W`QGQ(@ Ո0F<_]a&:#_zQ3b eMm$pJ59rr4Lxë)9mc:ՙlVΧeJK8s5M<'^je%qgiH,οwe9 _>Drc(AA(.]'9w ܁LJffS >cnBÍeJ&w;6=z;fhCXɿ;$_@܋c$?}@ z2(`&>`e#5:ybM Xфޱmӎv|').y2]N\6Bj>Ǚ(D~^T?/V⢀xicaЁZ\˂*uy{yN!2[QK;Ue؎cUQHױW1]FC)_,,)-ezGx@L "ΝY:m["z`w$v3WpPL'>"6CSWm[)^x0R+PRCuZ'ɓ~\~4LM_ՂnXK߽ QLŲZ*] E֮ O| Ky[?/~2%gc()"c@ɏqPKg.^<3{#"m|%=B<|x$x'?Ry7cTJ'>UGFkSC\9|zToGXɢ62zw) ޫS'4H1»"1ho%f"1f`Νf@qdIav* Q90>GʹrY}p/v;w8>Nn{&} Js S%xf"Mvk镽Y&u:? ɟ[{ltS=aN9GlHsm)VT~HKqKZ..P[C!f>"%Kw3L |m*J6Z?QNJ W㙗n@2} : hz~oi׺%>kTV'_v|GW}"WS0~l&Z-O\I-K鲁|$:"\ HUKJ1 BV4~`/XDFAWUN hA#ꚤ̚ww(?F_zCh7u&h^a}.P8jS ѺKb :f.wI?Gw:GV ytur*gB3 ),412Iz=S1ܟR|>R ܰu'̷n]\C#|уpn1a[|+a P#'ZY(_d'APU?]dڱ9u=ŗ^EctV@ dGfqиƥC?ᓬi8jauKƿ,dB=PモA.?!cG;Yr>y~5U{4Yma}>O]\S'8Ȏtߧ~li׺)<UtԠ%K֪xks_Ba@=Zzflbiw y,j%V%SV>a15afCUukM߲2aJqƏ)/@!dwUB$\*%ٮ>W,2-#z[:XYza?I9W E@g}wA/J61~Y[-2|`RadtK4s L 9ܥ-ȗEٶƗ@}a\:L{7ʌ0WO}$q1sl_l q6G.{ O(`{oj>lP puK;h{>\A?Pg8vYCNIx>~r5]VPk7SXNq@ gX76$jNIkx)xJ:v2!7DV~<ԗ 2nͦeT?3x3YH Uzy=`L,b_WYleJ6=ד~9шdqꄳjy [4HۓU;S[4By&Sݎj)~z l-Ӭ9<[ǙbXG[4 lHN^(nF7fX]܏.&]jtO(Z~iߘɳb섹0WKVsL Dwvfką4WoA 7Gp=-o0L9[^4i J1uRJpoөfK/l z܋);乣twQUO:.ΚM#0yLc9m8*_8Ku:ՍۧjY\^ C5c Uз 7tiKz-- 8<6b ,}Z 7oHHJqÐBh|* O1-O3 ?RDIs%*Q~.ܹ]vrVnhiz7DT+\r^ۣ8\ 0?S9Έv u=4 laןvq._KfomP vN4)6e'`)ǞGg B&+RNK㌕:U՛ܸ4pȡM^r'q3w?&ۭ7_)z+u܆W=n,h;<ɕ(tf2BC9н֙GCzh@Via<;..oM]9cg-܏hKKל :, uRSw5=w ,\oR|D jX̊#Y`Zu9As% =`+HߣZ37dMk~醙I_$\ *()Ɂ0?t-0`>5rXQG&^l!s Ye(ȍtѴ/|4en^*XE%#@[5-[QBgq|[=qΫ=0Bk\4x!?$y,1w/wȑZOa-zjZ*hid"d3~;u'Gq_+Mk$UP{U vCkEa?Х'Eq}[%sD+cB\NtaEZ2$s]! 罗5hCǎzՍ7ִȴE~:/c 5g{k:^΢ϻ3ѳ9H/ (x|ٸ/* g,S|M`ںϚ25|ܢ24/L M4Ne?"fWe(d8>t6oM`4-k708WP%J]ģ10m Dzx#!c}r™]y3,l(| gwA$QA/wVE^y;}'y̮514'bݭw uG<녱JSt򫵿؀0BFf쬓g Y!BwV)iJ|DlUd"I>=mu KjxGChn1Qxm w Fn4Ue0> FT }<[._WHyۯP8_U",f/q7ZmɋD( l1aDXֱB%%9'}ظU^!6f(dM̉8dm̃OjC F?L&~xȟ^ ,"jPhy@سc%U"p:nP" $Upza:^F/DؽI`nP[5Si7&,%=Dd֝WNϠ~#wMdDiz?^q׼~5'H&<+<>du?|mR+x+.(DC'/Fm/%H~g7Ausur>'TBSz{S?sQIbZdCl'&) dq'yDf\=G1lu#U0U{ࡒIıȞ) :Gd8i[)y a3,TNSq!P_eL%~ru"eV?WvNDu>d9+dfj-M Q3T\6ʷvrCHc[bX6>F~VIOu&wt}9h8գPaӢs>\b`6?S?k@ X]d9Ϳ=rh.eGZ龐Q/\%n.1+[5(9o;?goB*-wcyͲ7(|pӫdf3b#vycI"jie]}^5`j 񶇟8%2uv|pC-AOFk[zX;;R ?,z85*+ `<9uԝhwTYx59t@- DIT 쯈 4|KIq :wVEbYAt;='uR*{~W WĵRm>L-Z&1$Ir]t}1ѵچzlz]`6KXo_K.ڇѱ9n+˖Woh]wmuC^nc%W6T&=B0Tx=//Y ļViSX?݀>Pf,ܷe0S}k!G#)2q[QE/҄pj/^-J#ч\6.h$KX>īx&et^o ˺vа^XJP#(Q|D?קKr~mY20yx%E0%g;Zcs<~\\)JOOh85R#?e.3ֶK*ӊ4=S$5XkD/%"[HbˋV9%r@EN8GFq-ҳh{s p)aӁ '>M vBOUnY"~}n2<2ik1KVyxjL4lc{ܳOC$ M7/v/&`c5\ u4JMD9T"B}Bc0Zeg1vGU!9 xZyNqr?0k+/A H~+4ɕXڹ݈~xJGU&1W#F譊0Q0zEŚ0F34DW\MV4gB p:ES('FQ{w+5)'| [[-% &otku @ hG(i{ƬK Sw݀'_^$uڔ4GBA'MLJp^Q=c=L""oF؀G"i ^"T;F^#QֆjLJ&*֞^ W[bƆ% q4?GY]M3f ]@ڝڠ0Xi ֭ `mپQGZr(G4Hٮ3][CpԷ'4MјFǂE{8 {XkI=ݒJ`:sW~tO`_ښW~嚂6ۙRvھ2ʖ9Hk*v\n_="pЏDW m0B #y.gHG'(<d򖒫o d/IX9)cdkcXq.9Ǻ4G3)cƞ7q fs/ZJY'0y`8,{Po/+IdZM>m%g6\6+{jWW+F$e;JpzZ!3˻ɛZE?0eWDq-hZJZUHhw a;% no\z&*Re59@A3 ,R1? 6ˑ.gWQJHNwMCe?G…8](X=m)^2aAt#tLz!Rhb!"` wj|sR2:%NA&xsgHpջ'dRF(2B5M% ?x`!ui4"!D!VɿL yKR" [fߑu>wвg{D>LbW>,{)v.g+-5U ZdIB0=dUalyX KR~ oLϛ$w94bdgyhfƏE haڅNIV㴿Edux~]c$9a?TCQWHX*_&bhÊ]Ք4nc1kaC%}Ux}XDq]hP1}ܹ%e-6ӷwu}u~ݴ/ $\ڗ!i{Fya#BDSo 1>F~unwjm͹|콫X1%s4Taۙ2r^" gii3CG}}޵۞a"قF"\ou^bЫ՟ЫU-^KqgXMj] 僚XH mZ3"=F^{7x E8LE@6l((ҼlSs+ *Jـ"}>1VK &_nGgHxII=˷Fz:$YOKTi -6ެ{$Bak,SLu}(VϤU[PF-P^`15$znNoa'pFA |y`Dy#KpWzѧK?㺡AI (K=eƎ< lq]@Q=u緲@"C5T%̒\Vȿ!ǥj\рZvB=#ӅZev:)$)S&x[R* ZV#kԳ{.n{QJ\֭b- hteB4YU[5PFHy5p,+c(*'eC^pK*1=}9]SX]=3=8 "QHvو1P_$m;7f#<:H*gZXGkj(tu6q7XdЬNxT#*?FZb`B`5Uɜd+VGzI<_V4sa䤆x\v#__+[6;`:KFm0\Vմ Z@iq3/}]CŠȦk&,|aP,~ck)=SfGB`djQB79w~D7DZJz1Jz[6!iuSg3 "}f/qҠ߱VcrzTx :&=RaE=7ˑI};{ʁrt:wiybV',0? <D<]z3hw6~qm{N,fV owgQ$<P֒Vv[./g,Ȳ䶊F9KtDA3ow Ϥ/ѷ Oz! n<4Ne(NCoKQOVޭ&)p=&® 1` J&%d X\ԭd$0_lo˗9}vN)+!P| 6 8r0[u.%12ڂ ? ȐFNhE,6ACtgIJQ[VOj6[t',;/M~p UƳ5+Wyg6|= TnKbExהD_fke7ku{ҙ &_Y&i!TnJNCP٘d6qh\Ӄ(R 63al5 f%ڽ8!M?@G Mr%L;IVޔMEN?@9wC_;{d;-~n#*>$0N̍>'4|/Q-*zjל-;r+VzfDwSR(Jb ޣx&N;+A.>y;}HdqLUIa['IފgRh¢H%wd#Hq\-=ϟхRtp6OVz5Zv1K0gS$A︻Uov|Ym10ۙ/iBfeދUI{=z Lgt? +z]:K̐}/z¢1MBZ6bShT7|IJv[!%ïH^@_ߺXg-.Mzrǻ7  t )kg7nxU.ɣ򀍝? >pwu/"Y@D͇+s~_'([J\wϰOg|;P5IZDc3 ch㧂GBƺřr~j:_:yG ]nވ[oQB\l0 BZnjTVD jK32Ʌ<HϻkGݹW{GZ^b +Ra(%_k2o:rf#'q˫`^O[=|ل}TY|}Ml-QWsS`uwb-hp_ T_KueRD,X,z`y"TOu]58Kn3*(#X/B\O*= sT "*eټqH:3Fs3ǖvfVbR vZngisa j}U((R< _Ѧ~OVxnV/9: R'1EW'0f5:?oO|[D`BN%\ߴOsSYF}t b%>Eb9OYc`w{J\^TGewj)fVY9UO0'_).MX9bY@4!}Ĺ=X#?%>)+ck{ {$ֿFYxPPHbԢV\ >x(׹lZbkOC@|Nͧ",+\7q36^׿  ʋ=f6aJ.Őt3"9y,IjCGu.Iy/A\Y5T]W.pr+ !'mj[V?0B+MiWsTfF?ߊ9%=|f㮜hղ _u]}9 3=ED[$2JO/Lomy T] NJHA4X?<贁V/^:>Jlj(¼ʬpŒG{2=,5'ң7?5}~ X?Sim3;ݢ>K7Hg 녏ȤB!,*Fڵ$j4v,JSĨh7qW.~?|d:I=Tj4#>rSË>O!#I tѱ$fȱܝ*#r{]fW z@wyE|fS'C"rb 9- pf+f֙_MrP5`\BG:6yFmxL88+/qޓmHvCZL"6u/f1 4m%5t6n`lj~f##XRv$iL}(uq֓A0K% Fͺ?Ϳ<'m F,ةs/;i(o|'ňփS͌8AR*B Jt/iad3IHq#%X0ąsH;M!&yՕȤ:AdK5|~ ŴTpN8FrAՃe| k*LYv ٻBhHp#ė;r~^ߢ>{R- |^WzEc[qzKv5_oL;nu%3(0',~5ј4 #4f$avɺwGfI D~0)bjK nO"6#>H -"xpW!zI&gwQT"- ص|F탉ϼׅ?leZכW q"ZB? Q k#*|+Dri&8sW-SB!.` D6pT%mMBx9)A`+^8,_RK~+Bt/:F.6QoX]<{Y3E]ۍU l!˨ԜFvT:׸6RKq5>W~T'$ϖ !YR & x E3]M#1 O3F-T]j0sh *Ck$̯~x ODG UK&塵NjFͺh#!-b(!48LAGCGS(wz'i!)4.ˬl}M< K|x-1['KhCI)Rr[ mgC>/8}`SG Mc59 Dr|h0r1]07H52}r_d~xT=/)+uq; l]-pV!Ӻy*jmp`$OZK=qii_޹.*=pAhe"ӤOPF3e0M)tݞ(xjnҎ/` >ϞkeE* ;1a؝@3qpx%D{rA%SdfVPlUWJFj.1H!ea{k_l{o-.Wq z$lZ,etIԨ4A🈱'B8MLHɴGTVDɧ \_A5.̸ \\E"aUgşJiW"G"QCC%{eҍ"<0ٔ[wL+j.;=7F$t |Lf>ou\X8E3Yfkqr1rr{SImO7=a̚?4{geYB\^e+YBYoD3f 0E]^R{vJW skY]׷/[!l &5M[q IRⰷfZ7W 퓅јjscϷ;-}~cXga19>.G`P3ƂyWo |պIv*.W+6?1L7s̹=/F(*LETfi'Zų^M'ݧ]s90) oœ[S\ͷRBfNO,󺈿CQ%q>QPx{YbFNF{gKeb̏ p j jl]ZE _XTo;ʁ“! PשB/1MU Hc573ک2*t—Mc7=/asHCb6&HY ,!Mf59^C.ZdNr}3%ɞ^2HwdO6ٝzOrUͦvTzNY*YkM3M\QyX:B|o@Bwc 1 #) w&3k-!_`[pMk6.ٝL@yt.Ҡ/E1?I-&=3h}~EZ a|5#p3g״{;wC3cLn4Ep%h5ea<";mzOl5Ra\""MVŢ sqܗhd;AmWIEW2 n\8z,8oni1bQ֨Gnm槁~5 ?w؎G%d^g |-7Īη85v%dQ%QKe7 ^vj~2>XsP g0P~.G̃3`T <;=1sb^ `D3q`11ɡ_O<0U*E=eComRQx96h~H`,ٿf3F jxw]; hi$ ߘM$28@ 9x(Q!0U Т?gޘY+@+\(ղjebO*yI;fnxo*$GW#GtvOF+BHLsӌ\r <,E8t%{sʕgh)v ̉. qC%%bQmgp_FGjhjviXB=,H0 +#[iw:QvvU(B1f/[?ՇG5y#) efOŽKj- 9A!)ə&ph[~F1,][]zFm^#FJꌴ]x4s0t$"mt9Q Wk^^:\v 5Fj@-韱; XJρDdh՟&CvCa}׎u Q $)?a[籱&A2$ݾ4.Տzef9P' 1&㛶%W&G1Mo(BaM;>ƘES1mńyo)g:-d05[$'7g@g_EV0=6Z$$rʂz gB2\{/ͭm75-r9-p7Q*JЀZ7y3E%g=+33iAhY2^WؕQW\Lӄ|9Q`EBNT\7oϩ=)Qude`77pY(G<͘LBRm,O55߆ dfI xW^dPtK'Lll.SaY6l:4O/OtCafE G,m-=@2Gǩ}2(8A3 *s>U; LnY%uBq4 0!G4@CD  k0*}bpEY#v$U HY3HnZ0XZbjZ(q?d''L!<&兴sB(% ^Pv}K3: ȿ,0>g N䂔>d\eE= . N-EEh5c%o'<nR7i/heL W̸%Z/hsT3+{TxNK$ Li(B}=yUc8K]&;1G}ZwUW(˳ډ9- Уw`DIݠ*}Qv?Vaj$N?sʄ?9t੭ۋ{洎[cuWs'4GR+4QtzwAr֥pQ)vVUH_WBIŃsHpjh.4,3w00/ZrxBeܳ$z ^zy$Qp l? `K s贌@?`E s#{V.J]y'ٞ+Zdu ظ^Oq&Xgy|qc Q8XOcyh[vQQ?t@jw@E"5OeM e~2?kddq-MATK5KIET]#UYA073yÏ oFMjet5N-p69"ȲŊběIs &WBCRْ7ȸ /wGBD}y&Q?~FM"{0y%|к6<plh.bj/mC݁#[,P\^H^(,>,8zmea_W`*SX)@ឨ vVI'T !2ɮEEJK⿲r[*R97 dR-{\'ͽ|3ё:Q+ 21%nNr) 0:oH>v1s`P\4$2OψizT{<:ǔhPDR [,y6(C&BCI&:zU<\aOxI8b z Eep:K0*JPҵ&4ڻ7ٳS6m[`Ozr~y DN:aZ ۆg徎(i ]Xr^!smO/AxOP$=3!$^@OpR 0DT&Zq)@)߃(Z8NaD`ţzA]̲4X\<lb44=JK[+F0_%/<QtE[y9{\VNS'>64JWUD5=|NqwYDNWϰihȺbsFH`GeyٽIٚ*ɠu0M,MÏAtsҤ**.,D85ӝ@&:Sſ #6Rim`|[OT. 6ćE%/λ@u j>w/.la.ݿ9):j"ڲVC!E4,j=]&v}XrXFLzzq7Oa"_K/L?7mKˎkh9@iaW#j@^^bH¾8t:t tIr rAk"¦Oijf^} ({} ̕?Wpyٿ,JA$G=eĜ}—(n)$to:(6g:|Kg='ա*M9EHTL$9^cjzm KD/D`y~WW ';xaI,c'QwxD@= Ngc_K)T5O_Twd0g@1,.b-m-7P/\#`>|8ؖLXfE*)A4JGS(zػ:&f!V7>ߕŁ*՜n3YK棏1s3X t??J.*^߾&M/+Z!N- 4'ݓ鰨oŰnϨ6#Zlb {xH.'EHrH|/y;^Ղɀ3FɅJCG,Dd(zKi[);@Yvqm fyTױ ,>o41&x_mcteXvw*6lQ[n5U!hI J`v @BeaI@B r.ɼ+u+WT I|bwZ#/6ƳaW:5E=mPܢ%6R73*WV9ؤC*4#[j0ۢ/]>i~R_]քA5ZȐO;+Ҡ=$ݡ||g+`X/ou7s[A#yJ&F$!'m\^]ޘ s 2S3B Cc4+ wF,R/ "!c]$Ptnn89;abd[@{#HS趾8E˔7ZtJ裁)2JdC!p 0d3LS/q_G 7ֱ+ S Ǹ9ETYbHM&9J،9-*W$Z*Pz>"$UIFپ]UMA6mp Q_b% l0>΢6|ҦcR({c&PlVm?(`O[E *n47${dZNd!nJ?vǍb[$PFi#~> 3T Q 0NGN{w"%HGCuf57r |qvaYBE`| Xq62m=ndjd1栈@C{M]"y%c-(8F>GSq7pS< fմopj𐈇-4hإ!ŰJU{ XE{E*<;a_Akvyc{Kt)6Iư/TΨz8,lⱥ]Z_padԤ h=YQ۽=|C)ƨ壓RmtหT eWq| e9dF@z?鰙l#isot1ux&.fߔU|Xc1i]vn+K}>@(ס֪_b&MָH-4D'?UN>8?R;eP'/@[j.3Cufe"xለSg]،z!hTb~Ǐ3}βoٞowq-H"[J,x2h00mQuİ sI$.{uuRIamàIb !UyȠ$'0 "bIS)%Q߿ ?]8^ۉNp\_R$Ռub.vxLuVkW+JzkOx#Cմm]esvQNPnL_TVlOG#sSbT CJIt9;}E*}`ԏag LBioW#A׍OPOGM1X@I_s (B37/Rʙ Xn|ZE?NQMR+ ILP\i=gq4 ǴVЍ:)e8vo5tΉɟّvhDXرO"@G3q U$j'g& O0c7Ifg"^[w ;r;M'vS%)`B3z?;{NRu?M^ ܈=!"Sw=7:lHpb~h3%``+{Wy:- cz^uhLX , 4q=h`o5?euLETMZ&=2q]!P2<~!,S\So# Jx$'&j=g9aȾ26bp2Y\:Q+ҭ Ts Rv6:}(e@+{i\`ʜm݇q ۽q6gtš?zHFd Z DCߕ3ߩ˥k4}NG @{pS_vKq\_~ 1 U.d7l3_ ]i/ qfD}@b<-3W5q¥!§CZM f  R|Bf㕉.&G e?WSv]LE,-/}"?Cɑ 7u(Tu{'$ thm:U[3 0A5L-T(JLHtz/Dv:whlMlCJAEb:{{,VoqN}ƇA{G'|fqu잲*pPH{Twܷ3 63Eo.w7/-ogO7Z1 ׸_J # ӄth*2RPwlbq)j"tCəNs  "#'a 7B]5\$!t;=O$b2^Pe@U8&#F`>LU1inɣލlۂg,YPՑS ~r:Ox&z Tw8O%'LW9KnD?{ z")#LPIR<+2XM|\\ x5&:èK:5tj16LlC3 9qXᭃ+/M$gJLT5DFBw d*%J^c>'GwΟ_G~asE"1qrV0S8OJ`p*K;LҨh )=hTlaƑ1px~٥ *FFVbaBQBI,dCnf8ځ֥׆ЗX v1{'Բ|)mvN~kX287/h=0ߋi|7IH+e͸pwd*b<DD@%[^RgnC_&GUsϣ} .z5^ U2AcoGq(鴻RQŨ#p $h%Q–?mLjN3"O' brVfZϣYSfsYݙڃeR[D:z:NrJQv]q@aQ|^_#;ƪ#%i"N73AgE3G P-8X 9(nGiIGB ;Ŝxe# \0!d}ͦP $wÌ_8veTqXvcr((/*S;ep+IJw =üVmn؋Tr+)DZ0be;1f o&EV  Ȩ TOA(bچX3 f?hr|*/tRy1L#{Phf$A yfC!|IH#x>cT˝ =*0Sl#NߛC.VҾo'X)>5.n3ی.@8Ju'Ld,{q_2pcQn)(F%;I '7'o{zlBUln3ܧb-D3  ם8 5S]jM*7)ǍJ"T*LBӆ̙z=8v˔gӖ8Z( N :51H{uLGp Z>2|H4d*H*Ku.tu6wx|I::zYLȅ1Vll8Q1ewt;&Ǿ?ȣ=4l]}I&Ww[&ޫ}*p7 HEu~ }"ihsB N9 5FA+s\x(}l6Qo,0Gv!.RF?eVui}3*Ξk)RR]X)^܋;wwX{?Odʴ$O0YcR>a\1J舍=f @,{~~ȤI<L^ ICuIoLvR3͇6j$Uن`O+b+d|N.,=%wpAw$n^`x*Hߛ ^L&EjhN{>AO9K Fl~ ߿~1uhoEq:[>7k$ԏGMBUhg>ak=_<45{ZL2s^&ATtpx|*t *w{N9K9̈́aMvąRCOѡLc(sĀjo%b&c0.xKe(n8 ̼ǽ&)wg$k㑟lsv>~"\K`9xEKWt wT6>ldyqoP5%Uodd-caLyfa?":J_#z%e+LF( x5Lsm)nSe'Y !|/%=ޮKk!9ܾڜUL5.?.#7ib@ ow>A;K/@eK9磻e]4>ߋt(gEA!t5ܾqi z'CTl\&L*e"E9%Fh{0 s_H0B͒8 ;/S~#|6!*1s[oMgܓ&2;o׹b= N&$Bq$E:vOWָj5/Vivx5hïc[׹jʇ,ƺONu񓴤|ƏS(v"Ք&:뒏N05ϡר&D[clqKYKPeiˠmÇ9mq^+pXr-託Ьd9}li6o}yzs-rZ.4 ';FilA>\q;M8ȸ,Eiט5p`:gq [S]uo>Y@S~mcsݮMִ1jh&\:OήX aՇ^,Zw$H|tB>y`MZyŽ- r;(N6zx۾Bo qk*z,#)ӆpn^=ڪ>?n+tO޲bG^xk˰1Ȍ`) I!㞂z~gnL%#WcDaG!Y"/Ӫ \i2 ߊꕔhxGh)3U`}Z~32L%.=*A-803!fIVܨʪI(9 LLRn7dmH  ^$4Ki*_rBq_e˷8\޾y|9O U,l,Y[JQaTAe#u=pP!\dKR`:25kK9FGJEЇO Lj[B&q 'Zb}=' 4\91?M@QP%Ix` %26{cRT 9FIzt;]*X. qW.(Yu4Xnf!9%áS5d:8l&ԆL\8]wH%z;6g, rr+aQ[fʲ7+w=FfË/D h~>1%ߘ"K)iAAIm3^tєAh}F5'w&0* dlќ/L@C{UGx;5}Ff;V@1 _sc<YᒭY58.thdD ! N>@'O!PޞxŲqR}֐c`̪GMDde?(!?qRmܣ"xT~_Qz7OۈEΧT:8 7UdLӱԂ ED4|]OQ(7I}d$ZZBsXB" 2Vq+bԌ=>^uڥFnVaZ/R)lTL#,R!=|*a^^TB ZJ,. BJ8X$E>Ct @%BIy I[(/[>wp:pEL{hq0N=\Bc>\{y;h я΃5-O9S\Td"n⽩]k2#gy'2 k*/vs0xw?8, <ӿu@ǎ)5Ȼs aTlmP }+ BLs6pe^d9S G\e .AʬVgۯei ]1YW{lg֊cTTyn6J&z,;]S4ޢ-.pU3qhS/wA ƮhTa=Q7Ua5?ʣij~Gqwݓ>]d1^+g :!7 ZUenCzFR GR5eTN H$(Ei\@"EuX(iaũr# ":M 2xT~3 yX!O%ŭ,2I VraߐAwʁ+dQD'Qu<{cYc(K'c qKdYc?3Gߨc׉- 1-y'  G$1pi剓p3ᇴFG:?Hu?y%6Ppi&_=Np=fӗ?_lEԽ7k zz5fF!W.Ztn@VWz<0Uo4LFرEݽH8GujUa؋>t0tV)r@\:ͨ6`%ZkBWlֻuH1̢KzE;O, K!paי`1i ,F%p[rJUL05r. ΈLoM&*0Y7%,drd녳j[6봟S S[JsdMrm_;a3Y.>LninV)|#4_erm # 5(8#\8z`⨏qB)W8,W3UѳM:zgfjc&+r3~o:MH\Ń!Nw. *̴G!%S&1%6otM.Ll{ L1L;*~X˼;DnSD߆U3d^zI&'J"񁂚_+O^4a[%exyA3sȞ35Rl֚7>7-K@䜭Z{"Oub喞ҡijX_>Lon v7Rk尮gobk ƇdZ}sV47]=gu#<+xnp]VW}cZ~N?)Dp>`i}}U ]RNA>=o1`ՐX nԧ<d^^_ Mh"r"%bܠՉ}J L'mЛPNW9=!Mv іE@9%S ~ie8P87܀3|7 iVM3k\!u AkXT}5^e*q?w-3 ^h1#s M߈%"pڕ@U.b/Բުv;гk*_ `[#[ό3EQucqF1Y}S5ȃ9 ou< 0Dr9\Q!TeĎ$pvGsWgJO l%^i)jko3Qޝ!T,4֝-[9OAjL"iM;S&1"3ϖZ5ߥ=d@ER5x ϛt~DN6e̢=t"vB/s}([-X>4>60U|6#a*vp[D++,kn gAk@.i Ix{óߗJHCeEup+N!EZ+*7C%5\2a7a?\tV_Ðwϭ#'GW͊TT{Ἂ3z_*F3?dʃ&ͧ &<'įϷP+^zZ9sE4+v?H \IIeBDq۱eif r^S39%Og ͎S )\m>;&NG6` x%ܔ]v֮_k=0l&{VƐH6z]'rpC4=%2I!iM]i57_dr]E^Sit7a o[3 w;Wm7س&瓆h=`eBq@J%4a^q >bmUU|%%&H7r=i%yR zkT}&79O|猓@têJOD\C@xMkELMv s+Ps1,z6j!1%\1TV2kI}%::9>[̟ʫ{CMuG lX}[FU ^f)JM4ߝx앤æLˤ<ꇮ9=c/emQ>BbbϴBW/{Y^R!a+/v% ~(t|ӵJAML |E,ب,S&d~#7C0w}gFxrk_'Vm28կ; QlơGf&Sq{f9;JAEŔo }TVc힘oc*熯F/Ga_#}M32Ob Y{F9U/jiv]HiiqURxCHn-rN^,H߸{x40%,A^2:Hu'}`VaK׍[ վwd6*¿foR{fvg{. &+rLHpoGs6V7yR&(e PO־>-""G 9ou#7͵W[ N0#OjXdVB6|DrRm Zfd~N5:=ƀx`R_u{`a#mYGwFk̾m5l[\ڭ>NڲŻr{,T‰f#*h~ǡGZL5\tC_f eKfYPϽ`G0~Wc:к}caF?&rq,=8*LO {kArvz-Mw0r"!ꡕ߭]y}$ѹwZrżK ӆT/eӪ@ (nʿ~4SNeYGg/ Їl7^mF5i)$ mT@hosm" +֡>]T_cԶuI8 v:!()"'\EG8ʩVg%$8թID3@5!Nr=>[dʐDJufmIUl~+mηg>ӄۖb&9u/r5}C[/b!c&?.KڽDڢŊMėĦ*nY ߌ]UǏ[2RFhPDJ#_l~|…4LR8ѰSw v|8r 0bi([P!^8Vxv@X>lM8J#g"wV}6H3/92gZۻai])RZtD{)w{S*u-gӁB:`\y6,ti RU%f{ T;8#RA6vg/) noJ2YIhHۥ*dDM/(PG^\e9" >mg4s:t&Z m;S0At4Vs圼׺EN%w)H~'~-Ȝ!\2mD mGv>?୩|M$QrQCOȖ 0> pzB z/2iF}S5rm7wUWErzIE09w7:E^a,_p~~+ lpy`JbpD?V5o7[oxo63 2s^vxy.(цj/R_3f 5pv}>n='MA ؘQߕڨ6}X5H_Ffo-Tٚ//[EZo#z&?x]G>wܽ p3Ӝ=y1Y=*(H9%Bd}'rS}5)L"gA|~レ*PTcY >WKo/t!xp@Jh81yZ)<޼5M1VVPO亵 ]9p[,Yʟy=Kha7_ >o#R?GR2R?ZT+OF![9`BfGu;Lֻsbji oO-pr Rhunx'e{qqeVqvL-. 7cc־ZT iI,N֘q$0 W{Ivǜ?o؃BWy L.zjY4si_:1v^Y#AӟbI]Է_ZSd J A7?_cNn]Rin&~ˍ* ӼOҗ?)#BLF8XZ\ RbmVs,ؚm輝Hs3 ]Qv:2+Qy7 c[fP`t=DOwȴ'i]؋cӮBX.8Qd:/=tE!`ᩉ=X 9eG;$>tm5}]AtGWy50>kf]@S_Xk:yuhw=AAq^ L5: b>ZݓH}6g.nzg^G ޽J hXMm_}&i|$_=UfV]F+o'VyWnX.}?p [~ukJcO ӓy2scz>^6kΙstTT$ѐ)w+D6:YA͈;mOϨtXv[rm5q]g` 5t1Yfo61~ϊ {ΐ 5**en6,iYGz#K#yBCiPւ Hx1 :wyTPw5#Z/orHr [9J_&1"zYv~|Iẖi>-r1}~v"e;.g`JשO/29S}P⩻1zu[ltn*b;HРOUv,~qqv02v根 q,mF-[p]q.Aӎ8BL{; "4^Y 6)CUV 0~-[*j\)=(+/VLe(P~4#5KTn&pHIl9]Sէgc|5 Qqcm|od"Ni WDC(%9~LL륏QP̗bwa/ _65sT89M{D裧0cIWI[.6 ~eS𧱫%q1G1k}HK4pUzL)!iˡh7TOelj_ 7m襛 HtfcN~bn.gṗ>oG|N߃!WlK0Mt:t^A~/e ks| _01ga_4 *pWz Kag+\7|O*j5|H Ѐ5,A)LQ݁dө2@bSF= =A[8A?I!Z/;Q CX:c%ǀd!ekÉ^Iҳ$qQ {?/}r!r-/V;]Ma(JȚd|>]a Eޭ),jFζP_Z% ddx _umCF+h?>C2 Z 4p=L$`ϼ{?hnY'ܵq?K jﲠlTV^?3^ړC/)m[O]A'(eMc׌ qa}@/0)kiR %*mr0.OIf <7ૼ:6ܯc\ϒfM?'pX@yRxW*!W͹NuAj::.Q'HvV'drgO4 ͇ !|\QQf6=@* _ -"!Ѕ XQjv-/,Ň14}D( xU|WeW+MF,pu> K,?В]ۏT ?#TNCpc@kv/ @.;2ݸXV %s)u:p&zO ZZ&蹚ρf dXiWU?n@(h:j=萃cr[uVVԐ&֚_G-RP,wA#iыnnjv BА=2QCcs~'w@rv1p  |#ڨͥФ-pIm{DD-ϲ`<>QFּ h=NP V9~gxVR eN|C}, B4 cM=?k2;@buU{Y:LwPNke?9diYZ`<0-' 誩?N*ܧ"M6.g'){t}FAm]g),;D +NJfo_E%]cp yۼzf:Za_WWbv) h$h˜ѿG2 d)H}6l L7n|4a=MhD bSZ*Ebs*ye{B^zJ>(X$j\܎)SaG {3V\tؼch}&* FA|l!hI/0"|?ph4=ѓ1;Hp vj97vs΅~+g~y{H?RA`¬ʡl#daX }^AK+3PoGږz}]Wz9G1:AR> :E]Z\(! X32l4җ;? A:}VT 0O,IV":1^̍9q]>aLځٻ)PА-)=?VIKE9I{(Gb&{aRf<>ݟf[ZS`s孽3A*¡&2ˇG\#o׿9C8E=~~hǓllobas64"q2ں^oN]]ӗV[ =1(95[A(+D?pxM=dAFt?Q/4nc\ӣ΋_cmbu.)`lXe[MhP"# oV>۽wn1R܎%|>ZBbDdS3!fsg(Z_[j>uԑX%5E70<ŕD;- ycFI*y8; G6y'na.PFcl#mݙSNj9~ M 6^kcdX8 fSרBo:JiOq6hQjg èHl9 cR~Q| 2߰&;?I ۚU)BU5.16i ƙFVb&'l cR]na-yե[f!ia~ zr&w'hʧ6;FZOݻ]2aifNvK7pv931Kjl !7CT _ Lld͍ Jì"Za<F'}p({Jbg *֥lm= Ũ,䓇QBG~\%C(!B>Dy2#܄;!&)>Z$&n#iw1ϊ3u"]`te/®~IWGHb3ي!oIٚ0uΫA%妴\ ڀko>]ג/LJ<"_2j&0}θs1ML9z[9U#I\6$Oje'%Z^?!`KE烶ṀY o,$€O1T}4O$F3dםV3aÄ7,ݰ92ayn]6/>\|Do㘑`shd=B?kh/rSm'}Ƹ|nAޱ"Ao]wRCZԬ;g0Wkp6*ICXr'e(rnxPR (D읡.!Pf*:s5sȴėY.ӓ♘%&LёGY͍qkY+ƞ[vgY$21 n2 htڶ!Qhi-WZo|\b$˶=P-ZpY(HOsYf1Sepڰnf]9Oku1DovP&ƃ ~J\1_;D=5DB Q(fj6\T8侨΢_ɩR4jUk)g65҉a`FzIM*ՕVWh64pOɍO 3I3Y-s&ޮTZnTŠ@^g%)^#98^}|W/ٴQpnQ+Mݯl”H8΢#|M-H‚M8H9˙4'Eg^?BQ^#y%6;r;yhbr Di[Uvgp\(~^(K8i[^9.spF)>7K}GRRdkVOM'9KZbd 6,fq/$ Sx`"ari"͖+OG[`꧲.b6xqC%nJ__)^C^t2ek[SS*ѭ)2G71`WQ;O AJNK R8Z22>0C ̔m4G.??կbNd20YbH7~ 5e%W:GLңNnجu sӵE-^Dqr(#0Yk@…WVɆ*C]>= 4~Zބ_\ōD$IQΦSlSVY5 [$l!C ^atWBjqG^e/s-j9l Vj}ed5ܦVW\gL zc.5 λ:h'}:R pVn..tGt0rʽS )hrz,y ?ȸF\9vḫ>> /QmyU$o$]}/2Y͌>__Wj͹[OBAMG._%:hB2q]?<*DXI[K'KxTTr$2]7"862zds##-D ~D Qmr7&Bݐa=9(у”:1TIy ~4.!"4":*>'v1*fSc`4-Cs!(ޯˍ-3LdJTM@4BXvR6RD-buN;Fh03BB+#)) f*!vWD?.*g,Ul&Sy$` mπ a@$ ѱ,e9 hbHH3fNRK^p r"D6VܕN:a}@+9! Q'yb|<YE7/w;oUBQ?ȧ9ɓqZof45'NH;MXgQh`()n^&(T5bJ znki.J+:׸oߤWw١WPM9)ߞ[Hg8؊A%! chO{n]ٟEY`?&PѴ'֘Ep~7 q,{lGC.,OS^+/L@}8βH)7;O rb$EGu[ H 4Q9ei`ZNPp۠྅C %5fCFSuT HQ ~ hɓ Em^yO&8q eR1I\aP "K:nN#̀Cn#@Jr&A 6t|!4tT$K#.9Fz^X 0slY(W]wtP8;T:;˧%BEE,5i"|u}]Z5xt=|]Y G8xzR]c hb`%& _AK5Fp'N&ʰHqDqQ.ס?\=:y-YaxI_B n)H(׻q$&$fpyz6릐nSz3F7w(~t~:,~$e<>$/?4 _ J|0PP_oPK@Marcie_Grade02.exrUT 9O9Oux .K muڶm۶m>m۶}ڶm߻of̋x;e^UF dlahggjOsB@@k!;;dlodlioGPCCuK;{w #{&K $Os sX:;zT;WkSz;{S} Cg g'K;db`65c6dg1fet0tv05vQ2t27to~gc'SS9"ljnLf@Pg[X bik*+@v@Vvx1gggg;g1NgPwc,All{* i LG Tu1R:3hTRF)7LM3RV(J(ݠ謽Hp SR T3aЈDނDn nxOotDCB9rB.-M5u|H;bܠ"W؄ E5{䄎?+8\|p‚1PVS:9|MRŽ3ihd>XzԵux8[11'H8%>JTׄ#yf{[U~Cg6bnds;Od%UA8g~ ސ]Ȧ Aר4cq\gÐ8ɴm7tY(1h)3(WDΏ. h6dkob43+1dڻ, ס-زxZC7YK66f>C^Y;o\ӣ83(u5' =+ϟW樁i5[yZ)rA}Ӌ?ڝq_/[Y1_`[iLd/2`I u6R.5 ]+h=66n^?! `?鸎nꓷg33G5Y]-ܢ_:f&vz-i' ilbݒs-}}jىS\$#uoS7aaUͬ$ƾ} ;~֊v~}{%ZODTAVs:Ih"J$ H*pyq8Zcj֡8Qw5ލMv9 |%t's|M!6>/$C<m^!AZ׵0}ÓQ]q\PݏKh"LW-6H הMp+3O@TbJ ]ϫ7bM JYў~Ȏ)"Sa# qaY, ZMeY[~a#ܔ.ZgB3E2\`$mzT7!0#D_NkS4fxhR䴉uiDjAX&l7L6q~ѷX:CJկ+S]'>6|DCv'5cEf_h6ΩQ]'ޝ&ՊRI|T?0EJ%L*^X*#:((=f mQ 1c}S޹`?Gɼc&b$$wEsOAo_R*wP3u)'eb&PI)|<%9 M*0!.RFC%n> )s(GWWMQ F#]xd 3Voy?s Ī]8m?!JKjٽ`dχ,^}# JaNX'$W򳉎R$0ĩ ^ed$LQ "&lKe$ߔ}3}ּ6w,87[jD-ȝ?|\x|us%'0!v}){=F] ~r|i'z"E@w9@Η :>Cݽf$[gl5J>  :ll-bY10{Rϒ<ڢ+AB >2%n0T\F$t*S]GlK䠾䡢KUDY<#BnD7'?YL7uU&@43t+#b)\%OLH-)`e> P&TU'$剕^SRNxEdhBE'`Ѽb};'} g$hdv ^;{=ANny)r1zLf^Ϣ|-s^{I*_ix1i\\رxS(tERo!`L a15: _Ø:6૯"Z3>,1y_Ou@8uբo+!KCf7V`Rh1>˄+&/ѻVobyO/BFFDԪd%TÛpLwTNC kǹmC up&L:ךS}!+R )b QskԎS|jLɗ5@ >LcA&u^j{;!IBNz;2{Q'Ou4 ۗ **!c!ۨO7 h_q*yd%E؟Dui閁 Ypdsa@%lGǟVLW ηKc1 ING/o`%iL|#o.>X?xA o.6r״>>:pxeigF Kk3avwc +}Y7Bfs52WOr #۪-;{W,BaI|XQ&ӳ!s03 թG2\u<վOID'gh>9^ƅ r@>y{ }8P>@Sc(ˑoEꏡw*؂FeAXJʚ?jP9^`hٹBoAR/[SkO.\hN(Yz|űFvՒ0(81ұw09WExsJkpR)h'IQ 1],8TD%ox$c:DhDe;&`νu"-@%=XèqݵOȒ.A5٠ DtТ!ggMu\cO62"5X l/PGe /@ [rD_2R{EÃ\|me^v8ϗ󻘀U_?@,\H(my%Ӭ>;XO|M@rgG5 <4[U n=ݶ^ۓg}UDgq4!^k_ٵ,Sr+DW{Wi%_\ag'羏y] kow`5TsWv8xo* =48:f; mlqCp;j_BS/p 忱Xϼ׆ţ9;(ÿmzZ:e0>oh ;0io%^~G|vtսxvDaANH[_W}]Gʗa /9R3Kw&0J> BGcO9?L}4U7-Πp *@ΖDG|,gȫߘ5J}2y40PtU}/}jh﬍>JvDv=x8d'`S`+<1*>䗼NS*a%"#SxƘ"ES~zWq{_tQtQXcU WOB]ِ4OkJocP;-αf{\?:b5-ϋW8 "Ou|3ŕ3b9=tJ, sI!~Y=dwEٿUcG֖r.ɵ *j紵E^x(Y:_ ctQ#(ߔ4x X>~^XdRec ȝ)p?6 !8E2yLn5A.juTbDP#z6L\vRKUQ*6X%n\l5gKLMJ{7dU:;K(x'6 j> I.OvЅy1BBJu@ۢB_+wx77di]8Y=:hy%$jR.(s7ԙ΄a%%AF[#V _|ky V$>Uz[\]k5忰O>,N~GQA$Q%5,8џ a a2uFW{-0[W\͠¿#6Vɡ8Kp^`AJ ``\ph*IB1I`.֨RM1"\lZA0P{h5@*bSK A%#b(0F6%\({a_ { Ss$8A_|s-m8rF\<( mΏ^ \íwlA Ms\OCY-PWGk.IKX\6qo7q 譗c9R`z#!/k0Uy<7|y@RLs%aO+f`C9XfXκ$KXޢ姂!'Ex^YGHP (wBL,9/+?13+E-7ä>49\1W|3\Ct8WS2A


EOמkTx% k_F E^e 13F)NŴ [PD3v }sĘ6q٭ZKoJ~qd_Ea0 nK:8Ʒ?]F0o}`rTjThJ8FWĝ)I%.q#Y/f_R"/zZʪuxWSNw0}aBjYij]}uѢSU i3UQw2Kc~O}h*)K԰u538|}Jr僼]B# eRprsӰ F\ S*Ǭi'ÒM)^V˖,LKu0(,%տG5c"ɔO&K)p|*CfW͂"s{fC|Z!6W}#TυaO,^O#~fkTjkC$U/(<W. L.h a6j!B?J :I-7dlĴlL ~ %i1x7d Y 6O{3s;0yvQP, ; ǽDU{?!ߴ}^i,8MvI{NGT/oW~{/-@Yjfɨt͓aɷZU_Uj_[]`!3+-$im,~NUiE 7< w fDЉ秫Smh $YD7M"&vx{?TɇL>~+OPʅJ$}*%Rєĺu".>M|>NOdy *Zb H\EevP`bs_mU/VBÖ@d:>$N&D"]&e?*{Wfa;~{Q&8K愡m-B ?HIE\*Kn}>;2#8Kͺ2$VN*Vt sa.1@|9QÑ#Aȏ:=dYbZͿFÕ _p:ξR bq^'E`~W7_Qkd7mM1OpʀLH wm;v6x;Jζ;o5"qgB!yGOGBrq2[aWmHۍ7_MOd#τ^O$LZl$:np6zC][WÛr?7Gt~ 9/\wxCfLE89=&; nvae_UM<߫7[JS?qƄ\ې)i-7|A#{McO^*o rUߍc(nff䠂)#qmHykPE&9F|.՟N @¶%rdw mY;D، %$ =Ȝ;+|Ao'?jb{M)IncPDӻ%M=wkG؈Ț۞$<sNU}t+%&xLKڄJ1m7<+\F َ.³@p9jr~_ц#[q s0I|| !} !8|΁}|}'pW ժqOڈ;4TO8vPfrr.ywgErb zB߹ǰKku*Cj PktU5Ndbuę C;bC\li:e33-ͅ]_UDXvw{YwqKNa>C2X=+oQ: R\݅9]_TM]3SGwV'zZO ߇o7w{XqvvT+.N6<#la{D}L͓azz&w|:\%bù #穋؝8Z DI;níJaa+U>Br$OîuCb];73ȸd]zF,̵+`1Gp&|kBg0&pDSd"ѫ-`b;y=]7 %6Tϥ8ZgN8sRnl2AFTMq*mX9S̀ PN7!ק?;z-.Uq.Ahjy ۥj҅JLi,~8id'睊x9ܕ9oYp%b.;cȆn7yJ8_ëMzNVom?7/4VbeFaiwl_:F1S`]=)@Z2dcNCeTOr*qjm{[!?7 :d6 g\%f4W>{ySIrRūyN+D'udc{h{Ct4Qu2dg[E)qzgً3 ~ϴu²wk\E~[w~͂ߚ@nJvqWϬ5.mAվsٰT$L8lŨ}zR4{'7epBZ^GtJt{?p ڿq4[Ucw\;BCгs1~n8^rc=s=h"1߫K rkm,w 5ktj J%[ga#rgqks˸d{мFԶnYr~sKZNl[?YP,v YIyyڳ9R=IPN\re@ydm_ggl0yöNdj^Yiz͒{ܠk#sM= d]jlf_^dj/5v-=b( > bR W-m/wv:ԯ;=A"qoy4I~N,KU%&f_{B)l=tJͣi]KIڒou-`Ic0-z4Jš?ՎC<@6b?A_WVr }ן9띡7 f2y!qZ}kܛ61o `W~}MvPM/]gSWOu19B=VzL1r^8_oXurdE520k:IJwKy߭#cM/lyFּ K\[؂|@ҿyk]yV1xxU+uJb {ͯvB2`h8B?"J'[+k [ o##m4ac8Z"BF%%-ff.̘D8JMaKaT#r4AY"D@+}k͏PXeY==|C sAȹ W%.;&Ra:Y$ lKV2gɤty;@&rD\6CvūN7&O!ZD\jY)[oʦ*[|6jju*rN#^A+?DMXLg+ЫOq;<0@L/JW徖tpF /P ث}6lԺMS[d'4W2w,WV[N8 }̤MmdtMbe,L5/GSEW¨B^6^fm12-*Xc3i!jmDPK[#H"xFTNu2xHet1D5B*99K͟6N{b&q .J'Q5_?ReOC}5J.ŭ ʧu~O}uP-?pAϱB쇵DnP騾C_ur [ģigiö#{ðNnvBptǕw[%TSF ,z'zٍⳠS i he"edkQ&Arݢd2+?&r?9NJUvՇA@kO+*f%:Fr,,2vc.E@gδ,,bT$w'_Yuw]U^8zcARbShA|9f }-zVr!v"a&j7}s<[WT]bե\ov;x=ot*{;B9, Cf~ѽ`qeEWAs#4ݲ"u478ަ\O$<:*OF)p prAezʖ|{Xܪ9Q-c+$XXP:'^9)fA%őw# zq؀vȊI{`'b )Č?j-ƵE"Zabn*ۡh*(`\ÛFU|S=e{s̰9iPy*clFoժI6lRZ4л?H٧nJZ&؍L9Xrq%'dFT)k `Mɛ-vE7Fٵ< ?WČ}BR5=_H)H_ f:Lݖ%ivR{c䏽Gh-|eaCqiۉ؎yn~EEGIů) )fL"!f_ |QXdl|e2I*(>5,\uUu9r$X²^J *ohQȌn?lHOzIMwTC/ɕ)Idw~W09{-Lۥd56~~9|$ULQbgHN2. 4Y|s8sUΡ.au2*wT$n#Y\gڛ U0,ۑiBNMÎ Ƌm.r̬"'Nݟ\\+bUpVW|6qLӕ{m99S@}[u"3-IV[t\DΤ-oA ~Ⱦڇû aX{O_胨{XM1Y{0G|՚m5p*쒒IS]')6Agq´Rn#|K7GѰuM V;֭v* SƉę >P|r}ᝑS.1Xu&শ7^zVuV {I.5u}p Jdᛯ+~VmlxfcLSb;vrs},cWN/tc:LbE8F4~UhbZzm+(j͕UOzZoۨR}S5Y :s뿞 X(ʥ;qqMgmA!HoBF񭲲gn㧮b&S5)ߣ~Xnvs:7l%/L=F{qC|yO<.m.¾_Pp◭]͹XiS@o1nzj#2|Z#Npwt>=#r9Juݘ.)qŻq(ߺfFA] f,OQˉAΞGiq)$`_qt/%:L pihq`P#AV$T-0ts^_omS}+w߸6ܨoҫI%-S:u;/ QkGT*ɬ;NtYrv(ʢ ^竣%eR?/99ky;ѭr;r/6/b.3ÝdžxWvq6ԔBN42nݯVu~{xD;֗C[GĤ_ G%]@(zlH ۟.=Y(PON`,_˶eof?_}/y=UID}eUAah\`6˖WHY$pCYN61V-F=WW6 RHX - IgPE.gFI)![-5%R_褀!ORROaF'oH>tl_NrWuCHŏ=' 38h=JަU/n1 ڢ8M)ŌoْWC䪆Us;'{Nue]j"+!)28RoYjbe%k#} #%DGӦ ͕Gz_cEZ=~Zs>]޷Y֑OwŪR?gFً?5T[Q0\,I⴨v(Bڊ1DM7?z3gӏݭ9u ?86" .l7ئ$vz:@F9KXڴ+1#AtjbF9ym!]RZ~X̔D~~69?GXlɾ&UeocQgHU7g= S "=¢q.EX;|߿˖_:}^ wO'?a% XLϕ&;/w՗Vbj9Wj(5YiiÕ'%*^zy:-iDsiE֕|+ voгs񹮷H,XnN@O71* řmu5LIBo߆q2LT_lYyn :O^Z7K_z uF(:^cʽij/B'WUtyG􈾽_u -MN7G(L:pzT!q<,ڤOxt6} n[eEPT BNEA3orO%).E#ˡʍ^RwV6}U&IP-,T!'X#lYe,]寵s.t"eӝ,*_ Ε*/S_Շg}/뾡kG^[il.UMuemq3e邖5j`}Tu/4xUҖ^Fh NQ ߝ 5ĕK3l䞡[9ϯq+>&`)BnHNq`[(2oo蝝υ+(]R5rHsK(>ѦW7g5h#I,a@ED2Kށr5]%KG#mOPw<:obC޾/eۮ$I#Q3Tw};vz^wwB6csxIjlN={Dz|xtF >X6MBX˸RM=qg֣ >Eg˷7jh;osT(ΥzݿNE)ʡulaU A;Y.ɵ`z]ؾx>^l:[~G[(bmEZN%pMV,gA]bqdn"t hyRV瓑s9(PN g$^6ޭEPF Vh^=ڙ} __S;51L%2{i=1ņ QAK*ofRc.;x0pm}Wk.-$eyҨt":GwqQ}J܃GX &@fѻ-՚ښٷFm׊B+ω45@OߊgͤX_IURLmXh,/3xVɨ›vx?4?ިw4'&ԉglv9<9:zaRl>5(xk\-X?[VO_k3v JLD%lu|lڗ]-19sdaYk(8f} ?fE|-@J;ut9g}ZhRIӞ;Z{} DLjgD,R kwP37WvR)<5dk*,DR@rq*u)He\ru9GJ;y?LZ3~nnnnpi+?ʯ0avŪ7Z~QEsgh%M=&c!L&F<՝R^Riz%[X? .t^\Q!:#WSaeLXpnIɰnv$u<Γ|}ҽEBtN]fTqo&+7K!E3|VU9=Y\$K?o~k_]+5(kF_VUޥhu% Yл[,4Y]'e}N~EGWdY8g^^ d'_ )gt1cPOR3 ,`([<˝ʝ79҂F7qsYzYfZ}EچQʠ!J]7TyJjxT5N%^ 8b'z*Q߅3F98Ј*>պ?W.%~WV1;cP۝Q罭?c}=* ܠCY]Xph\@fN_cfwPlN*޼-?g?~vCnQ'rJMwހ-eqQ(~jïJb7m Oyf@3njϘqyOɻdmR2^ݦ7nbNSK*:>' uÉ( {0 /PD&O̳^(Zs%yL*$S%TG܄#/d+D#ࡗN-kVM5wJKSOOaGbߪWt>n$wUǘs~OR -Lѧ{Z0"dl%m*L\R#Y4M4~]{_BA@ 9B~=W@Atdt-7HUewow %/jQ>$-ThH]5-N_Yo4:ѵn{p7WS!xէ6E .L<9I3[E*֗_/=J"0?1r QswG)nf|%]? g$Tm|?9C?PLo"~xuɪ0y-k_m{zhۙl8|>!5$Z ,dxH{<ݳ56~qP <4k (bYf뵦;8Ǘ!AMKcb8ݠ"b,@r@}<[5w  [8^GvK(nv` *'Y9 0P*>ԗ^6b;96ǥ$M}rH`x/ (l}?ύ Q XJ54VR> r~%T-$- 5!]f>%'2/ZJzcf=˼\mȘ{5}; *y/1" Ҋ h-/כtB>h8D Zc9`9r. z>!S+N@n@F;۲O C]!xn‰|\c";ɜwL$u߰PF%9Oe7op!VclURVpPZ/jpF-ݾ^) k"-8A  ¨)7;&u9ҚT#THpl0Zx^7  ȩ)WT]9&)触z6l&ĚQ+PLXr8.c8)B]Kz1J1RFfTpӣ`?E @m.sg{B&FW2 #_֑,V]tACuŇUlcgsduBЬWExkxZU8i #H>kI7Z*'3,r3X?IBjdbdƆgzũ4 &@ur+80>wȽvf 5PwoU tK.jVح緁seT%8 ZGV>7Yl]nd;VeYCJWڄ6BJևWMd`ނ1DLBɒo=9rx}7=q-鑻*dY4Ջ͵-lA8@k>EjW Z/U~f5@w }稍Rn]`6 9oOB9W46YxGH6Wu0Ćʭ{m.sJ3pM T']RWJ}13}?&(ɚs6axs„ʺWմS>P0DPf'šot=ka(Pf^_CW6y1B?)3CȺ>p;sDP"8S,CB5yڏsvY(47?mlW} "^޾v8bC RM ږ պ8; v|TT^O837@ߜE# ̂W4&*~k 3:70[J@M(, (,Sa$pb !}CpHFA^shlWM}7! Ĭ$An`'GɻW(6!2D,PXm3̼y( Î@4'BFq-`&K1LP,3?`ѭ Ze䤟6lQ. -FuX\pEKWȜ0#g\p8T?@ž-C`8Ws0oټ97 Kvd&6}Bc<1^p]_^۠ᘦEڝ.8-zfwj<ψY+Isb&}߀vf*P8 k_k>V 'IhVsLϩn0! +-jG8 ֱZ#Au @-Ls`s"3џ{0=kcljPaqبV`-G2~2? GoCDz$4^8g3T ,1.j̲u[hˆ[؅jN~fՇ3@nu6(2v?#R0A稀Gi1fjfP, }XLl?1ײs>saaw8\pS4xTdwpY@x.!=G"M.o×Y4uYΝ1\["HZ(b.#( e:}Du|7*CkԿ꯱f:-JJ+'okؿ<=3*4D)G@GJT\[593! & ׭=bZ>曈lk\FEbsQk04USrX䜯ٞLOSVJAv\Aq Y YĬX2FWmu~KWZ聃/Cw;\M5jz%5QDlnƺ^W2zNuʬV6_YCWuՅ'Ae .]t}q,Ua D 9oZJzuE.۸N P<8WM{xŪ]KPܷ9?.5r?i_$R55\-I$ZUߘ#c5~a__7W}ix\*F^m77?yӚ͎6L qN\ %i}#M9_6pFiQbT?E*q5|bFrK"2Az$ `* {9/E[@4M#o_N9@bzJ/lש|ߓ!);%~U RZeZa2i3ؾwrF:Ố .:@f3F:n1VU^XF-M&M5ui qXaźlVo6z޸ڨۉ Xq C[Q$ZH|&`y}rWC`d_X&.ƞFMqQrK^ V~\XVmdoO7@esWx6.%_c{ Q҇s6,RX;M/W5{8QM`@]:nq&4DxDL6r_%XusbېZbJѸ6$Ƿ[]hr.V_PY ɠ̊Xxְ|J8$~qh^mW[Ә&?A BqVfpro?LBhsAX-?ico K<ۂ3ӞۖT9ۗU c2ůCJB_-xВf@ *I ]_QQq W5=$Om&w.?.gl=owmaxQ6D uٝgЮc%KDʐqYd\I1ja{%ܥi?1)uYU2_$J֦?|kGy~co.AtH(2'? G#/[%+W4~GתxrW sC]`*'gk_#CDb N U_ D|'; ~-/c5;BKYݴS;_<6hYzqrU[Yv7}MH5Qx+vߨAח]&v 8F?BCqB2HhQWus(PiasR<o1qV/>%ˆ9 /*c7AqTD >vKkA'+$AbQvkb̴}'|n룣n^U3́,Ns%IW߱h7nq`mH3;ֹ2[5.!+ # ,AoED0(v'QdLS"w *D  :߱|O=‡ $ 4M4nS]f8wUuԦnsؐX^hTBBY/.p񕹺^0?wvSc+l `M%+:R' o7O9Q60bKsE-~D/y2_>crؤ *m2)dw}]إ%pn4|`7 &/K~+m37tua !AUhq/8;g2uCpL30qiU5/5eZEy|5?wc:ӆp@E{5i-/cA7ܖ%H#yDR@X3o󑩫O[ *p夁2%.Ź`꿥K &2s,S`Rkλcs%Ͷ -l8FԤOx9W Oq'ѵlw^J\Xah4\%ΗŶ=XWF2&i3;`1S?Y$ZAY'ڧyOñPX?s eUٺ*e~^GyuFݦ&8~ =#YZ,f]Y~B7GUߜiAeW>+JBOv,?H!bZ g&|Z%fPs 0߈IR QQcXd?U|Q J=g gfZ{WP(pFd2qRiٹ} WUh&Uz_#p0ygh:5N'\ {[w+*UR^eT8eٺ>eCxZc,3\;{@8dI!p^}XNew]4jB-jN sn). -tX%F3bhƇ, AފO 1.›/RM< $2Kl8(MvV|AAp~B$V9ϻnoxW\e$^Wrg,bjۦj, ,̯Dz+_%/}DiHK"k,iKAFP~*\).`|vp9js 0j&DC? ъY2+<,s G.WO]&B7̷}{5޴挽-}ɧ XIj Rkm@D³G qo0UK7.[k[ wp5ˏZ~`^u(Mzb$HEBf>d?s 6!8"#^s^0鸚;tQLƔ,9xT59.$8݉1Rk4BfPwępMYdƽׁrsumS ppT1OpLZ֕jݧ dP"sKL8+ٟΓE>>aǚ__b4WϹrnܟm.:';]ȇ8pXGy6ya E=HD}si{c7 ۅÆhzJ4}"J_Xﺹ O!.1pouʰdd[N?C}*a9Sgj/gnϓrWTi}'~ݛWT-=~bD*RQݸhk$cM> ./زYq2Z_{#zFoNt[ВM = okqHg׼ّ׋/f;>0rlCmgӀ!nERH-jIZU s Vu,i]2,z yqn1ό(Cd9{7<+U*GnUY8i\ߡaX H폃>`37襺 0u>/8YucgeoЇ㜲?Wki]WoCλjms@GR n?ietR"Hؤg qvc)LPQ%4/6LDdF){ ɨM#Yc3#b~ GM"8%Y>FGܜ>YRldfUͤ=y:/=gWLl ĻNV؞UBbi'rc)kN+Ă)aYknaW+:ʹ QbK^ M50,fl|t,<$ H}mQh0Òg8@wL+SJx}xs,&gl{\NO 9Q&cE7B8:m1O˷t>=&dtnw&J_^|(}1AL4:Ivci"pm=F^2t.V~ѴC,:]:><|S6{sNLT<[o2s_۞oW+1A-vů] 7/,R yκwLg_Ato͝1y8II%RU 0/qʶ8fW YM]x{2bs .]YkVVwtMML(wI!~7bytfC5}Y㊱;nDSES =pi}q͉U __ z^>7b[Ä/ι\$Q* E Dp<0|&YTx^'q/ ob/dd'YR'E6m7~{cÑltLCz`ۗ3ϲ3t>9yU$[DIa! p]2vR4a9,<%M_f]YWL~DQA2ݣE|xjWV<;Ȩ2_k>𷟞9鉸(+<(W  tDj_"?%r-'yO&=3%%9OmETz޹!"S-p>7+ )i5/ifDI:ߚ:Ȝ]NDߥ}]d-+<Bts$sC {v`YQ޿OviK :oB__J+,wJ9[ȽMjIÊ@C,~z\e{H}?S,dʷCh9elZ`|Kay?xiP`uSDޯtMˈ]'}AE`VI+sš|WjÎ ZΔ I!iaN>oo}oӊ&>J.vDbQ5`};}yt˗;%#)Y/6=&6D?JƟr5熟I¥v_[lI%4;Q6:mૼYA;H4HMS:,Rd>6<EQ|E2ʏCߤTިe?ٽrc%(Ū韏[Z< f7}=Guv=kERlgR.Dr}QNk*.OϾ!3M[]gâݜ_j[zWWzj|F{E:\6LMNdx SilӬ|c LC+i=JJٵUv'H>zd*nR^GS/&& /=J,6~J{; m߈TݝUVޱ„WK zWS-jU9fx,g3X ӊ~v(w@E˻Mkt/[yr#z1)pC).NP/ln3#M)}HoQ#M>OxМ{ح)^;l¯u葊Ugֵn:R󜎍ule=VA`bj䒷A/#T \| =4ZY7wla+}%~QRh*y 4wGU;ώXxȟM_i]54?NG3hْ]YEJZI^I?XWnҳ^zѝ~l^|ȫm~\j6=0qM軕7(*/Йmvy3~G#z'yYڧO]۴[vY:7 \'qeLFj{FV{KfT9 8o @ k)a%a쵮.zxſ] `v/t5M (8=؄Ԃt=8-[ \c"bȂ_vQњGCrR,Uҫ5.v /:le0j1Apo!Ξ1@w 92 '_-`e;Ton 4^+&q58p44Ifl#fgp>BePM_mO 4&"Шذ%8XXm{B QruwMs@`fJCRQџ(`o5$}59聲fht;B4m2s#\deH} Fk`1WӀ.Kc=a[䉁H)8Үfb'Ķm{2mtlۙضm۶m9U}^tzv-AѪ sK!. ~_[L]֡ܠ_$'8wv$A#'ΨCH,'nL%{9ȲD}F=Mg,*jf65q1YIU ?h?[R!}@G'}F\R襬wDӂ73eNj}FhE,?%%gO aml㒒AE1tgGvGFl<uv㊲<|Tf~师$Q}ʦ\\lC`D1gU”{@Xir'kdg΀hR zh~by^6n+gd\4!tD {?'ګ IAلO@`Fqng岴Vj}C:61}d3D^!:\X O,9~̰LIg2|Z'&Ο:@2o3h`R9ݾ˯Kap{Mʼ7 ?;8;A{8`~O]kl+~ di#0% R )mLqG=B(vgYB|h#`M7M3 6/£ 6G,056bL>^3R-j?({$#7.bEFfbs p ]d 2*Nly 3ֵ&¼2yw*1)R339]Nodo @a`S3dn̨)+x3+$7ڐ `EE:+ =ڣIs~i 1M#tG_;w;}Mk7O(IUqZ _dqEݓ^~amҔD[}SF.'he^jC)ڰ"˭R| {=J0~3v-ps-zmjJxnh]-CC3TYd^GDQk5?YtNfɊÓՊjoZEJ53"`g[8D!nڤ' R=zwddGf)zc5?y .mș8G ,MXE7- v.2,( 6eNBW@]ܢ\M{V}Bf+4V7 &:EYakgPY͊ϊB">4 NKW+b'#Zb~#iZ蝈^>8dA;XadtuIт7H&0"ڙJu7V%inJqw)d.AzӚNKRqV)X~-vUՋu(yj 0X\A<\>7Y> ;Es譑H}nJVhn&s; n56( Ⓚʏ<2-a:`P n;Nje; ]ndȗTR?bЫ##? ր;GN\~*t_%z_8:\-&r#A0 kr?ήt fs UÚ z6GaD`|}̉E=^I "K~-%RSDaYMy -Ӎ/A}!O#pөgtG. ib@lGR`N"5Hn3~CȒ]#עG˒Si`+d* 1)a3Ag y2nPTдGcҏ1Ym-kRhǠUAyЏ.V Z1VtuMm+=Y SR7> 1,b.K_#=([>|gԚm}"{xY( .W=z*\@ " `djţ{6F=rџ%U@9TQOLh]L6Xir|:K? ֟)*c|= 2ŹLs DL{6Ub2)'28o=01U…h?,'5l7O֎ܪ#.c|٩RZ@N]v;/66hVBSaKoٿ}|LHq5n X/0qhƀq?`4M''({=x'Xw+@ " ̬y˲3lI™dEjˁ ϶^,iw}{ #oHOV(Rt1g㯝>u V4Hu~>-b%d7וwdȴ8.AX7kr6=s*Ϡ |j߸G801b]aiJ?jşA;l/_- YY*_ &Z2FEB+m\{7(sŜ/E|8Qvo\D#e'OC}&zt4<,W`'j9QBU`~<#MγZpnW:jX"]t'u8d0ͅ|| Y:*~Ώ|쏄]$x 8v@rj=٢.>Zxwz4Y;1A-a|.Oe/}i 4B;=slr[Ba ɯu}g4igd~ޗ)ϸUPtցK*SlC^B.ѪG"P%\3i ޕ$huNYP;1rp}qvz^ HNu>ϧWLGS ":VD5(7< g_xY\pRߐlFwhtڋ(G©lj!v.HZi*cOr 쪻]vo Sr͜vݏHH>6Xk҄0s C|WB1H;LI V!0\;­ &F[cWf?oӳ~K5-U>Sx$n^z|WteODymh=/ޱ4=av/{k*aQ[6N9ޗJRv?Z`է×GS=xh{z[\?݂ gmZ<[3B%nGAd!M@uwl92cj[O/y|x!o륳7)S4q$):s=t%2gBuuɉWcSք#s*%\t;țd@Rтa(]F̑?Z&VBY|{4џxkUK"k\ۊGԫF+;*6y} tAK5)iJ V 6&S} F.ΎJaϕN9C!κB vhAfN=61gH{a"7Ӫ6.fI~c-G{h'cvԖH+nkr ?pmp1G %3)<Yc!GjIN$5z>t] e S9#jDk[}1^˄\Ը]qQk]9tV[jf$ƫ3;B Jdpz>7lg%(.9i׀w)(23о4h؆*s0LGh!y=L\zô|[#׹ <+.;r>OhBDDP]) ?X6r7+3=[ƍeHYu΋a62ONp?ǜ{:Gbo;LǼ3Tg-|M3|S3љXTWiezQ|]|$C}ɢ3[ocdNw |@>b a5&flql:GJc_{sYwN\m,0q9ܾn 3<(OU#iyYvW {zr6U[/`pHZYv3vatwHQԆ ޫj˝HQR寴 WW[کB=:lֻK8mljez#fҩ9ԇgf [ kh#I[rEQjN{l`Ҷ->Lŭt33Gnˠ4gi(ƗP&MmB ϱKrk]g޽׶H͇7BFhٵ26S-x,52+וsUc)*Q "y3[ݫ FfV N ``kIof;>}XD սh7uN!7slۆf/m mmu5AӲVmWϠzgtǙET_#D^O3(4`md=kй:i& Wv"!ݙ}e)ќpqi'Sgxy95rsi]=#V'ۍka/JYO'ȃ&qvMސ'Ph=~50[+%u!} \ ^fUMF쨄1Wn]w^TA4lH &3.l7[$tZuDlK9{{";5Q%O%}{y;CbgGoTdw|Xle/IDrNނnϓȻ(ZZ sߌihzJwht]|Qj7|Q Ah]0dug0қc-䙜m5 ]NyDžnTAnK;/nx#x|偫5=ƹ!xQ =:{C7<#Kqnyn󽠮"j3gxDžF~7sTW<6 hi 3"m /zZG̗:<o~ }wyD2pi.cXwrrS1ZG9tYvqO ;0.B|^~.M)8*`2SŽoKZnܻ#67(\J!7' WJS8z Hp©67>;g-9S)R):P%d5aԦ_ ɬ:E1,4cT4m*E6L"?cp='\3^FFlW/)zNV>d+A8Ռ`/]fGرͷ:t>^GQC~-{01гۭ=P<$CFo?vɒ)6_yG9]{yĨCqvo24F`HWtHO{T xueO+Gx0KrnmyTdgm9!Jp'v;I+6w%f!Զ-44v^W_(Z̎k;E|jiDz=J8|֖Vjf,Q0{y>־&rÄʌu=̤IVWIQyܵ)tТ+[v a;i>tLFk 6+؇(gQ{6 mČ:Q_jDذf)NETPU4*2?i63V|+ܔiZ%TWEYX1cğTv;l+FIYU| 2O׭dz+!J׶F=f.窼(ƺ1.mk.\?{wҲ xR.TedFr7翞\9/R#V}E1 m8ژġހ5c'"ɪK%t5gX)I*W(?Sa^rdcޜ }:"9U٤cu3ͺK 1/f|BApT=T3C47ရ!._Y.:%-QN+VptTuD2ald BdfKWx2}8OD*L? YN򢙮W;5];>Vg6C Ӵ8)^IxT> p3SwkY޶o2Kҏ9@-JNAAz&<%|\LzNyH+)M3J;zvonjåaДVfYId/ 좻5*sⷄe?yz4F:gU2w(pf:֐]]9h X ޤ -S]٠W~@8L&cрdbFhਸu_C"k/1:iCZhµc|#kL-ā. 5R%6U$h·ͅ \2rr^:dZ5D@|쪙o]ϯo_lꦐ7C8Xxi?TZXOK0#cyb_Fa]YR/.lP_գ]h(0Zfm%긲AN Gk% ]%Ý:X6_T|Uv)6_^wQ,.;H T~ U1L؆ee ӅE܀^&ƈ~",v['d%!;[RbD"!f5+Hw~k kS5x a]אrN?m!f~a B k, #1"C F! Nz ^D"K * fJS  Gtsf9~q M?kր=_ࠤ _Cr\H҂6[ ϡ!Hmi`*N*(?ݪoDcxAr;j XPdRTcNsg30DI$U,XADJxߠ!]|x8_vTJ(mQg ̾!:k*p3` IFC "x*en0 /T!V]EQPey(G_d@@Ij~ R%\͖N绅} 3OwN-ުEwDȖv;`ȵv,_@E$lb|IJx̣>&BW! "a9}zkx[ť4AR@T9`D/VKg1 wX4QYyE$2)`;.68ۄr+EDXaw@ { 6 ˅%HJJ+ƍKIOK27ddJ [9"[V%ʸq&DiT$ ch G- 8Y7 9|ψDH$܈J1$|ԗGo)FƈsI+>~T_'@5F jp,tF݅T~&F&Nb ,M %eF%qWF52I >-HD=U~5)R"zR<0OV(.rz_x޵b1܏̻ߒϑ#w7cAq-4^j9cRPBڧqGpz\KcED$:3I)U)Deߵ[CMeRڎI$12v[T'lɅ0 grhz(}p L$Z5@6V%?0FKe" J?A%> -d%4U>CRQ 9`lp_)YHd .B$%8eBq?7@IdfJo3vNp؄Dp1DbKNz}5trƤK}C0DFcp-ڸD}vC2o`10<+5Hə9kY‰}xx ;ҢE.+P4&CF`Yٜ6V@ISq ŏw4-RMG% S쀸4̈́)H Nf*Y:)w1! R(Z'|/C).w@Ή(R|'"IĢ{(<|nolaLAލJzh"G e^=gZ*JzKXݦNQ~ac ZHT\{4P$ iTv퓤$l('0e} S2g\rfj~ 9sALr ೤_@L O~d"wĉ /Ip5o[8b11:@p4~c,p)J!-I: +kZٌQ#4>Y lę$R<<ș+wvJƯ}qmǪ4-0ShSqQG^1?V<[J,鏌*bn/ 'dkV?zNPp?Gx ,T;*/>UJ[ L01jcv9x#qBr1@کgAZ!V AW1L">3z )j_CȅId0t5bpCF%IXk]?ΊѢy+Dzi ߘvSfw( nW~hsٕVBWdEsp:hS}= pm]y9ZIQWOZ OIIߤ]xt;?{ăKp^DiPaNjșa+hM~ Ξnc D"zH%{м- lK<$j25 vƼ6*[R{Uyvѷ.C)0*֒`q5+P37=I:=!{]BA6nJ !"SIRgxLl'%JG_7J!j6HȸDT ՗H/:@dm[Tϭ9%!{"qHqq&|L%ەlI\+Ɵb%Nrְy-BP= CX" 'R(+{"5AN0H% %: $Nh2fpa.Rrcxx8K }eh$G?V[7=IBaקkD)-c._{a!k0cr`O,` ۬17Yy24s+FKL%O;9.|LKyq i[d jɿ"w'R:rF~Hnځ4-ŒynCpZ #%XiO:vq:!h8]y4/ҌahU޻:AbY8|<;q{q7o |Mg ^"n[4,ϗ(>ւnDQe 'AO7 /$EɧwSa{l?;l?k}O'55(S;ҷ {x4Zx_t)2<*V|mӢ-wPbK ǝ9cam_|4潁EfQҳ>hm6n"Ev,h"RRK$Fp윈Uϖz)_(ۂ|EvǑn:ݿ{>"n|V ދхYPj]d]Q5S0Ks*d4*TцǁDs؝;>ѩh "Thg==+SDtEE!o蜥 Rޕ^֗YrPGiPa[ D Y# i5úwt /HndW|WB1YPH"?(ķ `q@f(l0?YgUrh2ٰ;QGAGnC ?L^~i4]B~[Uuy}zvch?JHX1]|r@bEmЪ䍼iӋZj<nFݵVS\ul1.ٴ*RϢChT '[/_$'7<%`6iJfV}J_`7Wl C4? ^S~O)Z[iZ&h 䁃4rϛ<TڋV'9[36:W՗Y/[ڸ{ cMvLLSW ͷJgtCBNHbO$0|~ޗt}yA-ʼnoO\I@,Rޫ!/[ڌP l3Dh\V܋Vn_qߟ6 a+3*dwp1SHh6EMa>u,%:rak H%X[JP3$es-)q^ 29FFq/aVrɺ-e..O1`D8rA f9 =<jW(6s.˹o-DLBfܐĿ23/|[@[P-!4mYjq %D~I9W $X`Sg1Yck'8nkl,&~RH>ILk>ۿE*+?Irsچ&r`q=q Qὶm2LZԟ@QcȊB^Vv&UPA"ӡtaDVGw.\ K*5]"(Pg쯓Bn+BQPz B'֓{7Z,jtJIoMo37@'0Æeya[|Cy4_Jf qj% mɳ-HW˴'@;.q1P)Bg)bP UKY-AN%33H̶nV%.Np; ̸%W]gIԻ ̕RՂQMIfRر|)u=gv}_=f>Cxiyc[*c!KG(S /85zyJt\ G.F,0' 񒝜Dt|qÒSl24kDQzsϵSjCIƼG)\lֲ/SU7JL8h&,G:pp;B#vd !B`ZrI#4k0E]YuD6r ҫ$-iLfD% ,Zl[UvܨJsN W~&̐%7Aŗ/Ѳ*ב%g^FL5ev wYxuq׍}Ѽb5%j"L9f-]gd`z6 n3$F~%/J4(\u8UBJÛ0K!J,eggakS`Fr)NQTȟƥeqL-A%儾tĤ(u&>b=W[EY⌞K^Kx|o&>ԋa"VSMЇ[%ͯq K*c 9 KWsQ 򘙭.QHLnfԒb5 zݦ)yڗ^N@wP Ý (8AV'>w^`GjFqyD?=IKQns[*;uh#1ugOsA_\tמoxMڿaC~] l8 7>ᤗAgm&{; ([݋7=.Uhr3< 0MM 틈= Ę6 TcNu 6ȅ~@;0V楞u.b{xpC :YB4{ywm vJFc~؉?PCwqjnYAa.L|^t9jjDҒ^_ƭkn^zť^U_~Δ[6ZRgzsVVj𳗏Ѳp yJSyK1ר85jյIa(ImCx25SY6M)eh=UhBP{7`eIDx"NU^/PDSGPX;TJpy n1vI]befܣ7'+) PABK>QƑ6 ;Nffm n1=w`m6^>V2i|I0fhP6ڠXB(F> ;rGQz(Cj1׬Ĭ1RǵO,en[ ZS>gL`S{yR`_KF!g3H [{>PH.i$&JUG$T&XKXV%iJ%?H wAHݦk9xX?Ⱦc^sF8pD/K ĐйB4غZo F=CArhᚭ:wյOQV "=~ 0-j-Chf]sQZl*5wnn5j&l9Eޯ,7rN/9"ʠ>\(4(w"Сsé?;S??<*XHP9'M SSdoP * ίϩk%&9}rNdGT%y|paE vf)pv" lј_0D S5|X4y BN׏BEһ?oYIh1Ocr-OD']Q-7MAUnR5-8lˏw5SFN;s) ^W=yԐ;8(8XwY7sayIZns3lEGa(=B (%?RZ3ğ_`R4^dYQ]d`p3Uh zZ`'-w1fl ( &J|L?1e9Ay";c6 HBe_Q0|["ա=dL|z4~jEQ,+:A/5h*uDO\Š&JLV*x^`\]3nxmaNQ0%9ZaGcq)@j-x7$48[ HbK7OzC>⌠$w\`gu5ļX||H36@b zhZ\JuP:r/otv C̠k+l!FEabn27Geϩo n7gkߛP|m MjKKwW&ԫ5Ijpx?Ep~_@S~OAaGu%!L'0/ts0dE5c0~,FD/ :ٖOGw5ٸb7d3>>XeHs-l ?wEo).cNRM2ӏ \XKn!QZ q lj2b? k N| د`jB=ĥtJBjmG2 BqrM/c;=_W>i)2'3V+vzwhçsO «TF/d@N &XS hlEO-i餤y$elX;?|qmTlCR>88`N ‚>43 „lO|Tl`)pU%;E'[& f1{έȜvIwXzW;SKe@^87)-٥ya[ohn~2_^Lt2bh^%_i|>B:95aͼDgNkb2V6A~yqVZR~]5Y`ץ={W}Kؗs'%hAXT=AMOJ3.~?3מXq0ͰNW6Azǖ|Kc rg6CI2N'ޅ<%j?!h^(>X-<W'Bo8_ktEb91mL9:0#?nt<̩!wTNx~VNI| 0!L%:ܮ)ҟxHF.d0<dhqǟ%ܶ01XơB s@W2/%=@,GG:Gb]ZKt=>ߘ>%$=a=F!u=t_Vf~m*ɢU]ZPڭ"ÿԾUEu&o > -oX:¯7W; Q^N HUK ){z@5<U@~o1%IqXu>DkR ݟ̫^$!X$zL$K h M92_g(/)q33"ðphd>ԿU:qtp.ǟІ.Mػa.P l#J ntSQDrvtwy|ds jOJY%!&u"_ش5sGņn{0%ߦ)ÄEOaݽҚDG` Ӑ tnZ}?~f~S$̐6̓yڕMOcd7j=W^N͜-/w&^[Yi%oЂATb$5k)u{;qEt/Ո@N!90.Ms-ZuT!Kqg9glႧ7nCDxiVk?$^Z;_hZ2ruKkʿ#lپO!;|P4r ;[/?7ޞ _ps^ o0[.zs8߲FAhZ DkpDAM2]~|>`}H fnD @qB6 sVq5=㰿\+Ѡ~ Lqzer Xš>F^F0q@ #)XB `Ǎ>$Ⰷ2{<|ZU5› A:^[.~ fUk(ҜW27VBp :Q80j`6wȠP/y%0W/WA`ɟl 6(S]b:DSҐfIUX.@% u<@Y()AQcR̉3ϧ5盺`lSLB[ڵUhILn ڒ6t"~#RP(KVZ> l߸ >LO\ibaiRl0Jw0Uݮ^;"0o^{B58Ǚź-˲t$߹|݁%f׻'sX6l)Ar>bBeb 4\L-NB1u.hQ9=4}u]~+jaKyT/FOV`* JkFa=xɷF)ěh"Roψn\9T`1GdޯO1߷6Oްz[/:㯺UQ?2vg'BD'(8h/pBFA#8w͗x6FZ7kNk>0.ԙ0pU˼D@7/ݟ ~k!"f7єJ^YS%[G x)DO4[,ŶzjK h 6x}Zl. N^7w˼޻Ѧd0.: a]#UIOoWoePަ vgL= YjM)u5,9iG-?S 7_q~td&{h^#/w5;x?(=dRt!wVWimWjB_Bh`_&^cp7 ԧ;Yd]8 < *UVM2{89j^o#or$MѓCܨ!/ ]>Utg{y}ȑk}_ 5p2[7rF>IdEOzb@BFs|Xk疊]$Yg#zH7=2@wp죛e1gR|Һa*XCh 2F3#9]U!6(/<%A8AM< U;$$#2MK}ӋRahS9пiz䅯dlX -aoڿ@R)1P:+}p1 K suw[F'^͂;o'D5-LB3PL@34l:unӲkߪ:@biuW&?u(ۑgW:Ձԑ$F'j٫R a \]!ȫ\v< ѽ*Rӭ^$"ntljS*#ZC̱]uGts Vs #p1`{%Pb"4jj&Kia]聻e*V Nk]9mcָB1*֨Axc轲Aw->8S[)417ÿi9JU)mhO ͍+ӫN{ H'Q sȐ&큈:<0l@!#6}{ |ar G32m;6xO-FXżE>UjkML=L6?m+%=H \g_oP.ZsrU%=hzn֮ao2oUte^/ohuf6 0^Qg"0uRHY52@)s?S ԰]3. ttw kWѝ;<]ՁE{u)nqcƉ#qJ.ۄ9I6=X@lqM*^]vX݂d}=r3y]bf? 1g=~{IԆhRCgB-sO7r* Vix8 (OqI0,PԈXQ(~ y!8&8y.y['coR7S>iP=7|7/NحDd O~8V)cl/~.䘅v?I#q ora/(zE7ocWLҠ_YכhC:_Q9sJ b/7la<ܰ-u.ҙEh^1Li&SqMZ[~N͟`o =/uZSpy%>>n1h r#g˟t̏|[Edr,=kV`a[Dumzmn}U㹈Y`:m_I*H&V]YxA,m՚ ޕa+ɓb8V_VeIS;@RC: 9IO:eJg6x>=>&֓237@1Y][ { 2͸ʋ|ShKvȞfr.A#8=蓩]{饂~ڙs(xX4°Nݦb|)/Y- X8Bҧ8kn@SℋZk](-r؞MlW;4g^ r}]YqtINqpEer:DL9:S /Os$[0lނjjm1}٢, fD.|,cj.gJL'-ÕA@,Wn#:tGu{GNtlN /ʩ[eW8ɠGrk35h@ DC;*5:>1ZR|Z^Hevs*.rͶ1 s's!?BmT L/{[Xo]Xn"l |0b=w˂ wcRQDv^ |aholԋuC^tl$$N-Wcj"\#.eMVڔX;EF5ㄕy@')F:1{ff04s BSI@9gtK1ʔoWAc_u-w\* 35<_f[_Cw$`k_ک>Ԭv/K䎐xҍ[ ")xt@țQtGwR)/cb,֢j,[u 7;uF {РU@tod 35[?05{nT'戩&a?B.Sp1@㏌m&&fI`Yˢ~Z>LnVJd)[t^ɴ`| e1>+JtȤdž m[P}!FP.|&A+,,2 6 O?HXv,𭅲 S ^敁iŎl [QX'0AԞ-l{f\{(lXhhERX8/[&jWYzl햄4ij 4p)#x-d^oO,l}|4g^J|;5Ĭ%vM|6OGжKܳI_I|t? 1Ms v˧]MaVg%\o\U δr#Q9.FӇ Y1֘z6>A£ Ē>&(T8.杽ٵvk3Z< o4Ƕ<@vktضކp89}!)_?puػEy U+ 8heǪ i|6K."0X(oV| SldaME@ɉ*g Z*}]~g?b HVy??6vӿ;_ z8 0|-w5|U'Ί5~9T1ӥĿӍs;UuIffx;\di;{-E~4 ;4(?-sƪ?G|Zc~v &N.6nd[y% 96!JwIq˫_9`1`z I{m8BF+@V ܮK".@[ íd7VcF!bP#S%{t.k NNoeCc}Oh:CS7we@]~eȺ]-~ QԛË| JHˈn!QrƑ8tiU?bB+ah!Yj[΂i2xYPgϒtr)ܞ3ϒ2OlOJVBdn45ϗcMӱTP<;X ֭}lS>9D][NsԿ-xH!ّUИU7a>S9,}.R;e Zq-FKn3^/ ǽ?.Ļ9.٘c]jЊ@,6X2)T}tyV4~}ݽ|?m~XN*3 էqfM!{6˅L!SF۹78F/.- eW}^#_xn!vMe*J w|]h{ԛ N:nYV+]+,8( A;Cc$^تaB !鈱FFt 7kKO<܅YW]Qd$-ڢc3S9s{GoScd &b 0ߢy'審lziR72B\ʻ\bNtRKCa`[6xQԅ@j}6iƴZl4Yrs+\B:3g31=׮1 RD3<iH?<#^;w)!n(TSKq|í_Ncb݊:07I;hPj\CqjNXW$30\ )"Apb9rf[(gz 謡 y/4vBBL2࿩ZPNr-Hfx, L+f `Ƿzv/j jfQkc]$˟F6c~Z5,qkuF.86 SqL?]K*ȅrm* ifl䵟} ΣG⡡ٺ hQgڹ&7JE@F'iN >xM@w@Ki?x'&뽭Եf+}rU1r<>_>6T"-j}Uk4n4.΀TGlI_ucm"4/@赛|uwAC➹DsA(s# 7fBHAATQvV|58PtL7 n^CV#WZ `MtSG4/q݃0zqK+5[#7GJn&iЬ?=WJǝ5wdWR?+m4du Hsn[ޝ^#v:ݫe@BaA(wхxp̅ @as@J'wubǎ%̡ȟpi7du L+Qwk*2=KfbQ !??y5)kXNT>%Q|*z p@v _FU!f5~C"ea (PVN2x p u]WnE2N6U ˖u5W~*CHB+Goa_ 3\RCOH7_̦I5񬨪>ȃ( <萊NtNn7|Az_w4M%{6/7v-Ni^}B4dAbgn\Rz \4q2x\yË-geyZI$MW@ʯd57K}Yrކ~oqFldZ^.G`t+viaLStԕ;^230=ڞt?5`t)UYW +z=dkH' xQO'H6`fZ Zӽ@ FfYSGԗBY[3bZ2;u0Nr :d E\F U!SgVᾴ-Ԣ;g  ch:acz͸Q 8X\rHco֛UZwTVn wPreji{ QI Ɨ\#o=w"' g$8E~”w]s7 &1O4Duc;T܏-z$Zgal;|KtB 7b(o o$ircTqY/26_Ml,+:ԇ_Qʎ֚el*Jd2_a2h^UR1o4;#0hLjತ֧'2?U .'ͳ|,BC!fd )ƿZFh2 kf9q}DB.+f@/!T5wwzmͰsս?>/v8] & h*.[ҧ7,2.5eL މs H=Ӣ jA C`N sULUO*LyexhߏuTa yra&%=2.K<+gE|[͏3{{ԱeS+n q(-N㋞ o Ʌ<扩)>9AA6,XuΦ_ΊWܙss(8=|ʾypY āSVMݎ}~Hi%(@8BK{|JgI Uq{~x0o5,+gz ̚1WV֐ZJǯrA:=԰S9u"i2u*àx.(1- 3cZN9u1(ٓc9,y0t!\ c|vY_CHYlis k"^f+nVKo%߸m_kjo %Oy3O6Mz-wMJFlQ*tlY4T*xVVS`OrΜ)N0q epsM*~޾vŒG3FiiVl!1.ʚV.,ᘘk??w+"hI/T`T~CW}ttUIl?𔻥t!]X"׌{N%JԊ93Cvev(8/%?{71iw2Gxюol_]RJU2g+RZ}\@59,GwcӠqc۶ƶyc;iM۶m6n8㬽s>,k꺧$bЬݧNfVEঌ<}uA8G|[Y>i)Sh]1'6s^Kg{3o  SO!7dr1wH`\Ċ q~Ea-QB 7bg.5'I4{LwvcF;乽1k[bh< xJ03i;96EDDOb"ʮUULzrßFRӒfk VbfM5%]O%;Ɍo,̇{Y>mWPP<nB[:W QUXeOKmЇ/-xWq`r OBoBb3ͧ 7O%\T(ݵ"%<;41@EQі?}c[N:ͰVXY̝6"Qb#v} g6Q@l;2 6!r5ZI,$)]51:o*9r3lk|Téf!gËRZOYbK$5U}S'g|̔z`>p D^|ԯ|/=*">J,ޕGiv?Qw%UV2⦓9Vaޑ+k1c fpqal8Ltg}ʗ}}*}(mwhem{"4JZX]{݂R!j80! @6i)k?yv\]u6ZmΚQ4Q ۼ3<>\S|syؘfF8W/I=$!2!٭@7'ʝǰ>H2 a2v Z}[LA-gP&G)?:r pty0?@UeDӶńsclA8\ 89!YZtJ =yeFF &8 8z|4WQ8@b n8Պ'G^M‚3 (a)3G$:qCFqcEw¸އv3 Vhm(΀Zcy좐b0,QnsQ6]̧:8 Ub>o҆. E uQQZ*=eAԂ|J\ߘ}IѼh%E[?w2};K4/1gʢ,1X3>]OE5Hl |Rr%Z"h_l)$ֻxKTF^ixܘdf`4b\!>\aJlty]*‘u{~Paa>h8bGzhMHX֎{> {`&5Yk[=9UW;beV.Zzi_o:})7]$kR$^BgG{3̶NCSX /Ð Rj`'ŵ]~I8W`RM-ڟIϗFDBTR#ɽkhC0!iNtg=Ц,.I1yz< ۰B 'LvsHY()c'd3%NދiG&SڕKrG5#7F(H 1zC0x ='j;_SBL-`t=< ju Oˣb'"1^nAJFVu%RBr)1󎃬Ol.m];%)5 [#hۀ$´}{sDcǬȽGZT,),(| =i=$İ_6wl\k&,-6? p Rtx;\S]2^4ӽ>PH`k3 o݅x24$_NI6]NBe;mҸpၙח9h4 svxD'B*1m1.27Q50 ?3;ׇM䙸7QRw4凱Th7ZsuvQH^`G%3|1| &dF>a9-+g#,B]Np0|;猩Ħ5I4?G5*>SGB /~Yn8* ?ҌC\*%%&/L+@= ''BwLtA l:7y̥\K~5̛4 [l wnDlaYlyQ}7DҴvKPu%fQ7#5[/Y48XD$S|,%I+e0\Z|.UW~m?4qwcDlNxGVV~< i]G)lJ̬ w 1X67E#IjXPpw{ mBI{p8(,lې54:~Jyfx*3yQf~?ؼ WYM+z 1 "U6\_ۑ?zĵYj c v;tw];'Ncz-ۏ^J+X)4NX, %m]?~|6ikW,btw+M2" SH9K%w7stN3z F<7q5܉b3N&o>qvlD2BfgKC5 MMm` |?LzҬ7Kᬔ Lo T.q%- -k0jh/w27KD ;nn%64_CAջ .)=$8qTT؆xYKZրKnd3fA`ğ9]5pAq)+(Qgn2(ܫmwWCIIT*yfİM3?'_z6TG^7MS  fed5 `3$ɩG(Ɗv aƵ`+eLTZyew@v9H`jĘdd^0ezMCY)l3cD0"I#:fdV=FIYH(! nM6 ÛGU0jd|ݴN F 3ET+2( P#7x^`6?)EC8$"Z%o7 MzX[>n{a)hk jg;L0{c$+2=3&l 7&ΆH,̼ă,er9f󀐪<jӯDmJ)%R " *?_6lB*2McޘM M3k_\Ճ$n1@'\SX4;wq2)q`zUwӰ,* @ӕ\M3_^f@\# qe?I{ oX(p: ,1ƿM6 *F-BrH!dzv1Ƭ WqM |cD(oX,bR.kdGi@m"BU]"O'y\Ntayec*,Jx^!  yFlkyF*EgYj: 5UteQM9or|ѰaecobخyWMm -_#$g9  Vq]d-+z(Hɤ>j>s#ؠJYjqӀ_@y;o~MHr|g|:fmI/;bsl4Eu +F?׺B4ө+eR +4qNoNG;;vFYs=GOv6++q{-"5 DFa#=Bcaxy}.V>.i xNo:̳j, CD~Tn ||_ 7d/ c/c-evf!q{`',^w,%eBע`1{sē\ֻɏjjGl!ZUF1 *F>3e^p|bdts]'TsiP=yg-ݔĶFcmu3ztؼ};i\w.k{H=Qj/pdb4,M}QN%p8i@x:39D[/ɓv}oiQrhf)ǏuTTH[I-hܐ(B̪˱k;!=[cGg CN4?*гg˓ރ\;6@J[ !?X0[.4° 9xv-?8͓H4 䧫=ֶd1 O[1nYeɓAXW5!|:ey%HVA ~+~ӿV7l osؼ e7v=6 _A&ZCKa٪jwlU7tʱ8ߨ͔ENz׾5M i?u?얽zkNm'|R_G6jZڌ3VA&Lv䏲A荖oND? ?̀kbhK¥ӬVd7eKRa+8ϗ%÷Qb[;«bR#\-Ü_lԵO)^1o:mȝֱbbj>sJE݊PXmR~ъupbW'=I۷1%•'2K:N09}6Y bܢ/m!p\gdg;=Rۡ׿"4VwrP_`ǘ[5ymAcfHLo+TCw1$@[39Kmh HTFZ3؀g?Hȼ)4mywaѠ }b/r-]s,}q#=s4RqlMXubJ6{=:l3t[I\p" ͷ#pt.-w?([i|CNMw9BG"xl@9~dµӨ[*;WvƶJH[ pz98[~_9<'S(۵ vBa+ՇkݶYLXEw 5p[jwb CeA2T-m7pþ |N*ENl61 '?>pB*iIO?uYL)#ҝP}k<)S4g7ۡG3S"t72wU[&Blt7AagIS.9E,* #mD/#$ 8wCK׷Aq) Q|eC)sʗ,Jy~=0T? psq-EEq w9cpLj '|G7Ѽgw巀d5~Sq)<<Xo[ji5" x ;wqqRbS/_7CVλRtY<4je3yB;X?h,WND+D+7OUЭu3AuoI&Jy-" "2O–MITl 7sZHrs+aX)Zph6ׁw)--g=UK>X1];wgbg6h5DY8'f0kdRL+E?#Jff&K~Wg}EȻ׳uH[nH~p߄˾6v9zp9yPJRD0Sf9߼JH =`GsX̓Ej\RsK-N2 =A,:.F7*Z;*de“^ŝb/L''N.@Z>]a*C?K^^]\2 ?oBlv:n'FV}]տ=ZG`4F ڨ"\%L._]7EF,4oE8BBk6{>DZ<!6TV!+^K1gͦh-,ںҮOTbNamRM+?f4P> Eqef|Vdv^(#EJ0]i eYQ"'I˺xF r֚ rܪ"Aje6{p Fqz|b;1b?T7d/v0Fi ͋|ͥ~/}'SYX53xe3]Sl:#!s`KEJN ~&w5X,XX݉z'<2?Rk>GG>oq,!;)6dSj7V<-vopȓR׿7-2V@TprztYq`um&[Urte()u)kSK[_GU,?-hes9zfTVƒHzgs1yqveZEM&KcŠ&{~e3''Y"ORj 73YgΧR!KI #2w.ݣ;AVa QGlg/ϑŭ'WT56܁;èO7te߭k5$ nY!>빼2}on»|fܧ/R z>΍rFӒ?yI=yLiT#-TqTV5hL_j0yJ;PxLeId* \vT.f%O,~WXd߬fG}86U"_jeJUyR)N[U(8M^J|SX] WϔU16F}5 x0$⥣")C?qyqIQN\n/Rx6hb%%T) v]㾗(A},/[_-49x?Nq%9g–F"BzL.lwӧ엜XoDac8KLzxqIѿ\Q\gzO0 9@G'mJz-VsQUy-^0yz]c/X'bg] `fJdcʉ|rUl I+&~}C 8w1\{{,Bڗ($6A|[s \Ůh`W~>9 IG UlV[_*qIl_ $O8m[TN .fۨӎV}KXm]WH4/&m;Yj`Laj<. y]ݗ$4zWQ.!tsp+ ܪtf-m06Ϥ( J}_7{mv ovvexI E,-9[IKL Ru44CTMe<CHa>2}]{I/?^d%n==@nו'@mP$`&"ōS my ZSj ?N2P A,xϒuT"껋6 5OH >oeRInBU;Y.d%|E;S|b *t,&\M:&,inxѳf/,<ʎ'+KB8wvlb>KO \+glo%* %gT&uY,F8\刨2(Ӆ<`-s'eբzcL١s'Bgf 8sI}mwD@6aq vDwW$#[S_拞Tj#Inb H68&/6 xһ\ N|wcD˭Iuirz4!rhlao{X %lfEY5nDuf)㻣)xX~Y`&mt_spYqR7;mʾ9n+i~ay+sJ1koLZo0ya#v um:Tao*}ȧxDכa՚1ܹ_}mf**Фڐ'.GKڊ'pQ2:XTWX4&SҘlz, jv X0K$;GlǢ aBbMb'WfXs6A=+]oRoycFqv(ggF9r(k4 x:~,!6-4<%j !#r[=EPXʦ<0o=o3mBI{ !|߷s ,רZ~f%rGvbiBsYF@w,_RM J֊IRȪp3}Af\F>Hj?9֦z.lvщB`]:T/y.㷔)L2)p$(;q_,6kkRXI}P9q[&zj.d`e -qQmx^X=1%6]o(w]R.R!ūڍ' UIihUDr)f`!꬘Mj2qJmN{eKR=HOA}|}o=bՎCf۲,a? InFd]oKk$u'^%q%EHo7 ?r DQD4P'+z^cŠXz[(Mbn"߮cn- _bb5״7NnT!\#yhk5ʟL37 un7^mÞ|3ܩåҟM@Ee8qqo5۠L{(:mɤ'6%9(kyϕE?'8Wf?&##O%q^ Dp M>3 amm' 0-{ Nm8x_u 0mi4byC.#>fcΙ1D𒄎x0L@ BO-A!`](xIYC? qjDɂniPi |Tz4yi{GBHc)D]]Z-{| G1%Jq,iC%6dkXa(F?9'O97aps\.͗l [/_>o.d,bX wS"A8%B:yHe)qѿ4@)o/*Է>|PLT-_ǵT age˄>C'}fqO>E6O\js.TUTt齼;#O坱r\((I.K ?" .~Cȡ-W9H ЁG ryg*( oJC!kt6 ~]saH47nq bgz<|‰x"!cHO(鶒t NCÌ] lp}V^"HNya'p`JZE12jW;P^-LIOQ{2V1ֱ#ג^Ǝf0o4m4y唹6T.I~㔆v5xVORc^p^OE'ˈD&sJߺy'f#n?<ڗCPq0,/ی%j!4@eײi)0usŀн @5 /EZ-S˸. H`z;"{91xE)??St<ܿA+\@8@qp+דôZtvSSqp&zP65*8me+W!Qቦ@5E}".Oޕk#c (wxrbdאopbH&|LC WTg)A#;3;BӰLoK(ڔ`,b4k&]H '.w]WM|B#JAZ;Hu3%P{9@sQZ )r{<,ԝe`A#;P<ʛ%eib_'@j<7ZӞ=X;iy]E! ZN_=b~S''廵sFZdyAm3k`T,^(?S L`POZ@gVFWOmT@i4V%5^"wwAztdJc{d[CVtdBi2v7TMH|}4NHaWL /(ykU,| Y~ D "I9Nپ;oMQ`[Z{w_-xίX/۠ }8Imm\k"؛QxMz'04}'N8?v W* t@*T?؇?;95d ʙlkȲ*$̸6&D>Gvdu[>Ûۺ6ᗦ~ ȗ!+ro7dav{*vU(Y.5 z~:0;@7/ &zG ҫNtM=FmtY`lRKt e| ]+64ۖ ĖČ>@wZ.P `)j(KGe{zK[Q'܎pBg2\ek,F*^PraL_=`™EyuheTwFZcՂ p bokI/fBA< -|CiW/%tgw"Lo>/0#RxG0ϼ>ֳ`b@[rfAF 2dcK=U 1J|,lƃǀ*XELI~N&.ZQ/Igɕ6bwǿQK@gPrCDP_E#o`N<4NF{Ђ)' ;bX?l:BfWy wDW_ư@Эj'CA2=T#,UL,0 cwbQD ZG r31SOVe ,(Q \2-Q@=L})0ּ =[4|J8=l𖀆4⸝a_aYrZyʟN'DP>6˻Fh.C%>B tXG<캉?EhGܣꫪgo7|C ,]*xIنۏMSVuȉ`1^#Ac11{_`Oo[`C"Ox3ą1ċǺ:^xk1 YL p첄# ɫhpsjmV5'#iDz BC`1y-4X$X:30*ɅӬ7kԚ0ͬìx01*)*NͻZi הHz4LMUqI!EzuT̐E }{}5Dkú>"3JvI^?3)!z(k4;F=+aكmu&h7bnOx 4;#ӕyL {OV4mfoYoGCux;<pRf: Ӎ0듡ӀPp?p'D ޲ >d5[uͣ$a/HL|% HQyI 1_ «+*C€@@U.v3<@"!cM1@Q"tbE~}smfj3 TgY Cʽ,s3MNJۅ(/xG3UNՄeɛmaz;9:: EkdFKQެkL:a\ ]{n>U6U.v6jr?+sg&l¹ߤGvלh@@SSyBz_.\1F4Y>:<*$yӀnQzazJ.3W?N>!pfȴ&m|8'U^q&2`,ʍS6py+ a+J-b]̓߷A-<=߯c wޅZo!d)!`O %\33VCbǬr)(اst XS]/S٥/΍6 gey? snT9#ɸ5 ۆ{rFaGր$<#<AjO_W^YQ>iQBO^3 ~KaONh>VU;r2PKEƷ)IEr)YՒ[YAhƹL eHz<&1Kb&˖(9CIz -jҞ D8W$,h_ ~1DqS":9˸(ЪU4.*Qw v␓"q+x<*`ׂ+6Iw>?#;/1 4_ дVT4kXVbr%%-'S2V%jSY(:e,q)Cxr V7<(֊ztao\?ٝ>hn=2BE\Ȱ|k_ծ1"Yw#,ygbTe>P?:@${p{ǓZ-NBSąM5aWҔ}4oe%d9l:O~*_hBw7@dMX{R;oLnM3nON#GkS-S|;Lf)Cp] Uo&}=I7#4%hU5Z)piy[aYQJm}9lK1>)H7/D P)Q5i2kek^(X$|Kj:0]omm3qz#}/Ew 0j 1F{'qPf4hkWst=%7LNz 6ϱSoH}Zr]sJ`h/T'oA)훏~wACtTNg$&3o5y'uCvPzE"uTly?jf5R"$S VD#q͍Ύ7q[ahzlC ݞ evQP<:`=E%{7')L^<*=F)cr|b6o D޵b<&golR mmG]X~gn֘hm,lx_'?ރ-}^ $ԼD5d_kk0AHKZ6=0͊k˫3fmR9~2: :$ ank׳Bb̺glW7a@A6khE)2ou4T3$#MyzncGv,RϨt͠7eC.}L5 Q$^.ݗFTt^N-vGn k DFԯn[R{V%:"#U.p%>PJ=hYpdj[T((s0@U4BR}ᄨ4X>"@%ǜR1x$k+hxظwkD?kom4yo 0 ]0qŔdҽz+yسnZ9joE1B1ĭ{[Q%L'j|R+~b2SN`ѴRi M2Di_QRb] #N}+f;7谟cQuPW) 3Vz9~1ne=Q{" ?(l%y?\Vz[-z;η6d aL0E ю{/W܂ẉ;ۓߺ!ދpϭ zr;0"lh{@r|jANtYoL|oZߪr6$6\LI漴T(Z .9[v~R㜄8{:,>ȦjN޸ڔZ{^ekK6~܎"UuX3qܓ|9CM``g$2efWv@5w":;$ys$VmzW3`Hq^Ƶh5!I޵h+lb~W-&%h`qߥ!zqp 8W"QƄJܩi,j]ws[~X.7ѹ^1G%.<\ӚYj&#{,'+CN=zyȤ^^w?Z:9ҭ!hy&EtƦ/%#V׹9LǷ0aQY<=GA燓UCJMzrǾ&~M˶0{">*ޫ-F[Ɓe\"$lh-/['3`w]ϐE{$e.D$džjU %.d%1#7&ZP=׉={ 0(xKR:8Bq/voּt!C>D~~a4rQ7n'mt8GĪ;c \r/!~ N:ځ٪8e749R3E17 FWzu ?6,zp&"DyS䃹GGsg)h0;NbkJ7Lvh/g`qw7H`+qKD=(q j"ޖGL|2c3:.Bvpgq5ӮOV"3QFyS7F Sy26 Y{9h4;o1Tҩ9.{PMG]7-/ Sq57]aqrhd`&B)TYoiwj3e]EɽhǺJNFNFDeA7]8)6|e4 |?ѢIF2.$gz/$Aq_),5T8f%Ơ /M~nxdK}u9tgVF-2]fZ|$ycŘG,!bB 2Fq-LmGkoxQ1V<%YME[?$: sv{wZkE`rkCuvr飃PF$31#6!qK]"W2&FΠMXtH4J{}WTD hMG x*4SK MQ%gq ܖgEg)zeep90\~`eMu*a7'*4fK UecA+^RCKQ 0 46.&󁖜)69PrBahsqU/.@^x\ɅN6=D5ΏBzOof+` n?ނY^e˝U8½/,:y0%)ɕ0K/ gHjPZj ~h$G}b)xZԶkw}#譴Ȩnl8d 1^_UjM(x%’  ?Kp$o Hq+djP1vZ>1i+`+]9HY#eI[IaICۭ /~!_GRqFPS_=ԗTl2 NC:wiNAa["jςL0V4Hy! Ձ74~\joSl}9P&۰ J]aKkၬ]~!!VwĶ G/X :MԹJ( JORIUB\hk=d1a-u]TP#[n'C^WBF#EWlIqZ¨V-, a,GZb\÷yc,oۍ:X(YTS}֝y[tGPPc;}7^GP[Dgn%HƱgr_͝DDWDi꒡8qwwQ}xI8"f!&xf8"T4 S6*'?(fpbl~g5=/o{QڱۯPbZۤ>T)gdyg,j2L*V F${ߢY/_ HMx(,EM7>08 Bcv%Qa}q"ClCT a!?FZuEʡHqq,~A8p|#[~ aetY' zeSN碾Jr ;~DE#\W/1mMW-\hv@pFNq]:7dX&S4a"9Oӈ 1e\uzzɘFUϽy;y(Y>۾(SD_ aTR׷F >?ph vs%,`N+d|;yq OFK =| GaA>ښyϮ r{}c@E(o LE0*㊒.] =tU?c=#*V4IDj*t"'!ūXڣtLh0 `i1X/}0maW&6ꨪ+y  [U[>bzl/gGhB} 6Cs #8ewkym$::4sPɓ,c#뭏Kk]{|sUbHo{v=,>߭}.Q22WZV1>g:69Z@*F~QAT䀠m移#%ddl,y۱Sf??+[CRypHt4_.!oi:*Y@TJ]R"qhR\C+ .sձFbZg z~D^uV 7+A0xVpsծ%҉BH=.m_w&qw\D@59_#C guipZu@՜` \S.NezC rg* aw/GwG" ݆=[x*}Qbϰ.7Jz-_;e[ A<3Z>+l98%"<*yqdGZ8d ]aFfTSsh`doqn3 6U 5+~XaP܎fWok 0lГyk'͢i^HB9[:+i8ߗ_ $+MuδֺM^0c `b=g} \j 3GQٿ֛m=<زG hRj ^^ZY] ;T眪)c/ͽԫ.$XWG K&&Qكc1d*HIE5 ~Wa&i$OׁcY 44A,t8U<w,u/OM4d;[[X62[/HjV`)P~ᯤ %Nx)OtoH/w1{;GqΫaoFIU&F쮢;:PV؈d5gp`ɪYkj<$=oڙjXBxCR]|aX70~~e ?%`1@/laib0%{0 YHx0 q]8_#dGg޻Mb6jn9[It~GRR=y20~]Q^*Ddei޸1bfZ{nxhId>ѷᘱ L Gpy͘;ômT p+hӑT  Bg-haA| `L;U*nv0V5>bkYz/lP? SBA07d? dqo4TˬYlYbԣQNF5(jԓO Oc^ }῭(+!9;XW;.M+6$|M>Ua_Ft'KiϗeRazD¿-h4m0}25FSFWO?OsI'6jZftDdž JBEFÚvV3E% M2+&MfC:;"ztVrI\ i~d> c7F:+TAfOHk3y٭̣թf6F{5`e勅.9:e$SZ~~L/kPxe,43J8¸T)ŘI3`m0XI/.2)IA8:0q݌Ev CO*6B2C_Uvv.*wL]XןBŭOz+py+5k~tXޗY=$w}4Z?d"DLAƴԳq$*fwz.Qm77?,0+KY%5^ӟEߖ j%F@l$w$t[q3h|tV}/}LszlZē}۸Ow!V~Y4LޑzUжTZEnQ}1l,D[@֡,f3DZA*41@ OtQH;ݜ6NaQހ1W/pqc'<]6 ػ#b¨b?7Dn-u-VŠ;!m{ʮ7Ju Vr/:+`zl8ڿ*mtUZ> V~p©%tZ?DI2]:"ZNE.`}ut^8Xgg?P|?X!Nּ${=(P[ZL2L.663f"mSa[J̯өL1BJ Qßfm=ml[ Bi zb_OR]8_pn+ptBmg`Ւ HlvxzOL؆N;\K)qK9I,G;=":ſڳC3y&X83"^DcL5kMAkL3d(fϘ5P_#@1Q#mOWЊk<'zQOS U~ʗk:=Uw%u"RdI)ϼi[7%8Gtf.[mat'ɬַnGyK3rI+^yv_XQv+ٷr^ hwG!%KlS,o^t, [mӯW^B෾ߺ|-+*gn%aZ_m!s[/N3j<ß:j(v߄iʹn( J q۔ [FVI Q*)kθИE:rCdf;`pݭ$.H0'({t,)]>D;Wɀ,~NiLlJG?jq/Tc7lW;3<9&[쉴\,}+_ t'NɮWwM(  3PWҫkAk #n-%>y%BOucqZ*d%â5#\VnĜ[)i{;3Ȝ)ky1jBM-Q'$zRm Mt) x$ Lyԏ0CZ{$l+bV%6ly"{N'u S{U߉.ENq<P#q4VQ9u'6NDتvN㖺"{ oXd"*&1_p:3 w,Cjli2-#(٤937ⷲvLyMؓYmpG$dB#3# W>QKKEef|#%-ixm9n9.q'tm21r:pY=]g#O5Es}k5$jmXCr-%nF:6d *%KkO;r"N@YhJ%<E7Ӧ@CsG!k+%:Ox]U(/&slƿ`p9KgUp֘=M^ =j z$wW?Wd{H:2v&]D^I%o0VM2<[Gd1fW'81!Œ"dCxs CQSkPT&۵C5eQBܽ,=.ՙ澮_syWRhhx[o!tIޓmu0 *f`\߶AZ>hI84]DB/g]ʽVMyF+oqc^~Is;"G00B;Y#HsH^.6Pm!k|JtuvZ/6"ץ/0#k?cхV%FW8?)3YDcmvnjPXD<_PGHjz<] t'yf⇶QGUBu[,3vv6A\UtG3@͇(5,qVch|>˵ .EϤVng&-(S5oz4#<(- 'dԈet,n3gf:4Rʡ` tXWN "Lܢl\M ~a$pd%YS`-QC.b%?VJ}=J G>7LN66'n,cF.8"Ny=hRB2I2܀G (4n 2ύ)J)xS@ʼ8VbADHxX $`&?^of{{ghn*w~2xEtmB̰X3r44H:`eP1H:$yUvEF+Lkl{Ys2pת 9x:bh(mvj=Eo|8zr.l ؑx'_H$rzL&wl\7@]=IM\Vyov2ޞ=v8n@QD=Uۣ1eVĐx Y xr[$] TK8sBt&jGiavZ_l0xk*l N'M6 d΍2o̿B ̕^Pt5R$O/[&EH#+Λ *S#/# X .]g0L<8W*{G@8Yb m'ƷXnHjrRLfsrYR-8| [1CyI,boH10q3]6 {Odl7Qy&mwʟ$b(22 %tm'PvIOQL?v6`TĔǰrpKtv R+N(֦LyɰHK܍7qR.!IȾ}XlҲIFBAPaQ{ϒgZ*8gFE3!{Һ~M1T|*i>dy{&4{xםSe 3rG8.37 qGSVٝz` z_sgw~\.+Vf(IO|ؖ&{F+yԲgXQj&F1}|SZA[d%HME F|7B^P<߰hb`H i14I&-bdt*~!&"wydPɧA4}g 1kq[Ǿ Ndl,%Zl5*w@kp77@ǎ#}J^Xĭ+d3j0&i2Cg23Li-l2{q{[PsHzZ\0v&ĩidUulU6G]>?mq+0?+eVBno<ܙ]]~-SkxPW,Q(ݔPTQ)X4FAGT w'>z D%g{5|+\)HuWuh|p\ͣ|^?x *s(OI^,9댏J<]-&+P{?"-zqm˷\8E3Br&y;ࢱsb^4k}/>(Xʄ0Eg]ILwt~hxdžUqkBoX@ޓ\FWqԐ|4#,7fiM2gЏ9+XׂfTx]Yr ǯ/L\ٸu`0S )˱#R)Y 'AO8UL8@h.IOcg@'.ƀD@ lgi!M (\#3m~u(~̀}jG1f_K2_Q~#uSOl@Yn!MXߞخ O0th#MQ8Ga>g 98CdFɛ9[xHb),nfq Weo>*W6GhT;A<_w,\aNC8KU)Q)> q*kBh]…DK `lyT#ꚨ¯CAdV~Fސ+-gJg 4l~TrP!AddqI XОVqύpwQ` 7E[1 CZ0X=|spA3B̓4!,ȉrIˉZHUQus?w( wP] /rp(Nq-ŝ|OI^Y'{2W\?͐,{톓sL'+1}͋ B_w ZJ7^29yKE{Zd] Uvb:M4#kΎS8^j0?(Hizz7wLMQKHϫ `<%MZa{䅑&y%mNe 3Ytja\)M6|bcmn 5'A@/Joj/_` IUm1ރT(S# 9\ !ci웺󣔠,.=<۠ ^-I/;pvbVYs)ͩa;qw62bi%\w%x|C<3|Nl5TX:x]Յkfk`^0Y~+w]];Qk)HJiDAB"GqDy/SHR K/Yz,^63K\} 7nD_1H jpQY,%r68UYJ0?LI.֜gynaoR֞ŐQ'dC\fDJѺBʿLt$_bٙ'qؕkxU~{܇͚_>Ep"EL/7 Nj|L4J^lLiL;j[ ,*V8wRS0uL`V .HV9}%=p >[C6y*M/}o1 i^] rM"`%wo>}Y3.f[r߄/)*ưՍҴ GZľR"u؁ cX..ڹ:6lo\J}|*?~L9@r?ZO!mO_fHHw;ȾwoS5~߹Kߧ~$ʹC|w#B"8ڡIǎZ3x6e i3)F[*xó3K}hH3u^J# 7yP~hή768i<|<З̨ xe] %"*~<%.>jp$CK|3&ґqdIJZ1cng]x45?*:S4ʾd~%B|qs}nre1"ޑ~ Pcjg =ƣ-RӶ8_DZ1nN<Ցmn}5mͭһt_*OfYG+Ocvs {tU :ԐVVǽhmiIz).Avәc@8`t2qRK?lNO =BGIsՑ)kL=2ӭ [ ,Bg F4d:οSne!Q0z\֞XCf.?59MIF5r;ې8_LJ/uJ@ʓ;lۙ4(@ખPupv䡕_z#4w)N%I4[bxW /sO/wL1 ,1gQ.,:^׋hS;ޣp&%" ~?3{oal* x*-1XMGr_بPT _]W`F|ڳ0 b^4'`;E_7٠: [O[3nۏPu83ֿ;u7ER?UpgH4t7 Xmy˝Ԋl8Jqcrw :>,KSEBtoIAtНO>KTA@尖NF?ĪԺKk\("([jZL vRkqH^b=,@U</vs^;_YA4y8l="G+Sa㡏=^^94ѩ2K`d&xw99W2CR"cXuҧDө=f%2=Eia L.׿`Jp3+*|,5I N KرaCx烾˳U2 Wng<.1^V'G W egDZL4,.&u=GR]ٟ"b3?CqS]F7ዪ(<|;3MrMX:SV.WtfSlXkγ4Њ-!M hn}h;irXMPz+}D?4|s=)| 4%l;%Ն'gaK&Vb=6_8جmpJ_^E*+b+L Ug"MjD*c pfps˥(K1͇l?p'z`_I` #H\$arj(Uz2-eeiIn5`QBH{"wsT$C%uWEYVg>T8G2wLb! E%i&[bJcHv}Qɴ$H5FǙv"ƶB](aqf(T@N\] b~:G;jR,>Nހ.e}SWmŢPU[|;Ft;IQ;#l2\;k[! vr%;r 8n9uql*!ӥL[spp8Mv$x󇆐PxYqJ ^Mi@И@kI ;9_)Namh_;:yXgzi oރH͚+,tngP%otܓhbf6J GWߠlg$^I.&ڥ?dbːIM#D=g[ӫˆm,V7cuXhqsDKkN|buWrL( ۏɄO& qKM+2ޠ^;>ܑ.$_Ks[%Z6vj5s~9$Ɠm{vow2;~b['S ?Uy7-٢e0[Ӽg·6>QoPͱzYm.}DI܏s4 0.9N;{(h<8@H%b74g/KUg(-k5M1&D&_VK,mt=Oח8>rkʟS< oa5NoK'{I+wsf ''uݛ#Z ɇH}y3w=2oR:!M;3y ҿ梂ZJ-0tIrޚ;fn%( &%w5_INǚcUW.񅱈ϭ?JLT=IWȞ.1H5FI0^F!\%=&Zv:w~ieU2P6Pwǐ t$q,eDcb( J.qԩ-A--RJBk!dgwayGmlCydђ %bV*.im;*w|`-=7!Nf~`{֖q5,[EyخČ'i@+MfGh3|%p+Ƴi4e"vn'hZHWt8aCkdچNtX/&d5ŋEAuBf6~Q7z(L"U췗U]ڜ3=uW1nLXVFl7U)..7_V~-t )W>K- c"4}g]sšqj}%_Y$\G Az6P;j$ߤI&bv-\-دW%G{qm` (:cWܟUD7>Qi(̃RtH_\B`DFPWK%#AE]ެۊn![{Tqv y%}}wNٌpq>iVoh̒~КHgS z+o?|q7s%|BU[M !M[@`'Z,~ Eu V[0 A =X2 `^+Q/շǁNs}?Sm6dI q\#Fi^:{"h ƱVJHy>urG]L2zJ;}q;WySx;݋Ǜ Dx2R$kÙկE!sRΧ}\* ~֣4y$ wU'SR|רv)g-xgA(9|M„Lؓ6Lhٲ-v,`U!"]Γzҹ{$rOKaUQ~3Г~@(V4B9+zC#eJ( Z+'!wi$Dv&Lfˤ#h6́A@媛 ?b ^o- {/1,46Q~݃8RbidA>1@-@g Bmaћ;׮)恜`]-"SC">iH癜AQ3@89+K#Ѿ/~ | \1{QC)(2UD8EmĠEIPqqNL?l6ǛOobUOsUj1ub:FTT QQ NW1l){8[D2}(7ʆ&Tfouw" +hJԐ*|jNm\.<*:Z&hdV]XZhw?|Yw/%dLY W tm =[Js.x1$ G^_-ޞVZ|p Kl4g ԓꋡ; z @]jw"R?gԴەע pR?RU?:+E552J8 bs;օ:& V<'drHT+. pow^KDKاU E4 .kgw^GƿWq3?G$3cxHLq#j?wRi Pkz{L+6RfӰIbd;3+S$*TmKo9W6w2[ j9oBWŏJ5@,%X&#=+qȐTz~:>4 Ӊ(2Ɇhp 2{ ?a'x/J,B"D_{3LA%H?H+;>s5t$UL<ܩߩLa*5hk D̹ڎjz4 >7;DK}+?jC N P=#`SdcB4 ڳ AɈ6<V߽ `ID砙2 ߻V+jЯ`^i=JOR|5ҾNʼs4]\j( ;8_wgZYw[Q<~Vo ސ}O\0aǖCiK2hOaZ ks+.Vc/UjXsf~h?IyH"<Y!Ҧ H9k/(ȃ ͽ yDOz"Rw,KTىû/P:%]Wo 8ëb S;3݆<ȗ4L=謾ɫܘvNP!2ۄ4[ъD?,MHcuBd0˪p)%ȶte5yeC8ؽJR.a,{ӷt5Lבm9$IeoOaw" t@P 7ger<݉OUKږd>S~&Tdf%|A+;r_M2ٗ w4Mj"ϗ y0P?ecvf*rqtpF6VM)d7bֱ֝5$UCQ7Eݣ[ Pz&v⊣ӟw%4eIȇ_^דA;E9&^bc캗Y#_LJ3lxBp21ι%đOKqsg$F*lx]7kRFc̏:bǽ}^sz*,];rA\UxJ[ՔͩV̐k>ϒy:80|r=mt]Y=TLj(dRZą^d@GzR 6h1*|RqO^#<) =%ye8Xh6jٸݺqty`yUФņ`[fv=IO42ZP)]*p/WV@o*f6,,cYt;Oit m -=|7ܕ&\#9GsrIBYU%?q;"g)KC?e0,D]OBïу4ͨ\|Z9u S[7=ςKC4w? =!IÙ/j94WM'?>'( O;EǀK5#ɞT/ٛsž߅hFdrDNbAзa&=IFն>^Qgu"-+=ʪN[s=$-)y3v`nDSQO'dO'ѱ ?G-+'I%{T"Lzh X쩶^е[d+~, m.nӠ4ś&:uSu> zezo C+4wtͪYafîlR".ܾ rYg g$*ȉn?<q ;k[*F6MVqdd mt"ˆ_4X$R}/Vs[YeSNڏcf ْ|}TwT?ȃۣpfo櫈F2_v>b1%IuUANM^%d핶ԟk zhK3Ln`W\!iӼ|OxX{{"__3a<H8(D\"6BcO6ydby^D2޾TVC>yvL h~s5'gl 絹o}EȒ~C}p}dF80IáQrmTk*$%TJWHnZv!*~zS!V]8Iv61APsWJj@*͑løYRo.I ikzY}E0s-=jn/$d-/Gf:U)rM.ST{86I]2V^cāʗ"ŠO>fnF oB h)^CHky{+2zfO@sO?.J7`{;].k"eqs .gZ5Ahi.WY _URۚA|g0=q7ͪlqIR`~']{L_o%TQSQi/n J= ('a\d  e''4u/!2'Yq;%v1:a{c5&,e G‘B'B}$n%U`0hTS r> L"46Zi]qTrk 5 ֬>|\{"_FBS%pGnTS"jrxFH޶O}ݵg|5 ⷖht׼X?|_G %3-C|PO#mK$!ycHmp4F6݃9M< /z>K0^$-6js#}.*K4"70yQzL\nq4vW=lu(I"̚x^぀f;#cI}T`ewGA_\bΉߍia#2G6^.OQؿf㰍^sR՜u(ȫvя֐߅sA}om>(El$۔dk`yj'T(_ F./Hbqí7T|+/vQLR̊''q]g^/~n#sCUp}j 9Vӎ(P<)AdbUr v^)UhKb$t ߘe;/˔52}o ~6$.صZxb#E&@Sc ,%qq| =Y wL.giz `S£oxV\д,,AXuovzb8߭ѫ:F3eF: 5|yxD@U7CX!,>(~;7lgg@G,pDðpYr&Y@3D7Yn;!*@49@lkpx4uS y. Tr&I`mMQ L7%5%-s!屶9 ˕-+*}|MnJY3uAǿEc+ aߌ d@OsVeB0ZP?mu} Ѿ5!!%aiUF|Ɋ^|H3'v`ަo} /}(fL#jzD,߯nֶ1،|w6Dmz WvG!2:N^_նOHj?|PDJR+]tkV93oZ@qҳH"}话q +bJ_foX/;UW3oIZqUuiGWx-*^A3d{ˮs9ύ~'4{su1_o,s3_&ȩ'E;T?_TVQyʑ_?g_8%냫'q<^UYZV|%X ӁmNUYybn_^9hO}.`Š*t@ԡ\ A*yA![0 ^%#,|$ZgDP]JwSF9 L=Nr1Cc;6]jf <~/4/`9tITWuV)JJKIq k懲z_D ؇}˖WwبP³IKMm6F)h$pa_faGp6'tL:a:~cc?¬[ rVXb$oO3_/#mNӦ#tw,9SfzƂhEY5>C̏`d`*&DjxI(_ϸ{ eZ;{<B=KoIH,->>w|nOfEeҔsjFjN"Yټ3"xO4o៼K7Yf")N!|eˊ"AZfeG9Y˼Z+VIq)6.=}X*|X0-rS3[+fguFRR'.EVI>."~=ѽ48K8Gl 9`T'N4sjGC.J_ H}Y*/y"NTO faOؾ (e0Xv|y0w'3BmǑʒhBKMW]`qD)s8׃-E^ќAW$eNC ʜSСfrYF.ŽV}7yKN[H11 2 @" od;r&eɈ\v;ūW:Gf_Z^Ng2C ak[{?ov &[)y# R$cc($ xYN_}>s6'HgcF J˗Vo8PI~ ݘeaKv/G"=6V# ;\$*s3v,XSM 3 kuZ.D~ D^[ܨ?|Cݮjw@oDܹ~u4QԯN (hg`Ӎu v#2c rtl&ѯ=Ip,r-5 ]!m_8`܍ O2F` qrN}zO9d',w}) +ΩJ_~5jڥ 'bOwtVN`E8g5=Y<&ПulqP@1~Ӛf*3E DHQ<ՏBtWeC(C~琬Ƽӂ˼>)_2%+AzVZ?<7(ɓշt7fbj?4#i Km2#!I*njުS& ).8g 7_M {@; ڭQ<5>8tK` Udf-oBLS Gz~nj[xN t toOS*.S+MYU/Y àVIFO# ?<4ǁR5YLAm?(7P+i)q/nbLI>7ձy'i_ŀ͉<e!o 2]"d_P`%Gw~԰&7Т3)ТHC X!X|!@0 H(_7iodfp?*R:9!(mKŨqI =M}drO_No8u~m,r g '>KJhiGuB*pRYNt]7[@dc_O7*ْogJ5:r.-TOE!$0 20mj?ƉFXE:vuxfB4OЁGWe,"/HB3"(21G YNx4 IQz 0,e.1_.DY禦JxA`S[͸$k@_(k֥S<)f`5ulv{TZ3;R6.#`z_EI,E'up u8 {EUte8e@7fzdp‡XR;faX]Mܿ5 3CT*  J%/ T[v@5B-C$.Mq I'czWZ+J; aL)ZHh5`CcČLV&9NJaw¾Gg7ֶ958rS.CIUIҩ*|V?oc>\<4<+-6|ZwB\<"L׿b!Ym|H򮁣 m+V0ۘ|SZLEω>/eZD]r<*f6o_K΋Gw&bwxC=q+d2cv.ms P qcO)P=< $Z?ĦNdr\|ep A8lqWݱ*;J9jf,v^N6X[H\""N7cn'*W߇d>07Ӗ~4yOWgɩ)p-\)aӷvvpXgG|t[k*pmѐD"o=غ;;ϓe`x4` y((+7b.*Y.rvDѩ?'^BD59NU$A=π9E`?Y6N/⧧vhy̧F ȏ2Y QnpZDG3TF&}̓뭔ϳV"S7Oxi=b N*O6 hc,^uR~+Jx@05b:w}} ۈȺ'GN${.GY;d.xr(q7MGtW"*F2QAC]kZ<4*uL MfcIۉթl݉<7fZXJ5Y`CXt/h۹M-:=Ch0+ĺ~7ήHn箟A.3Q)9xqC5*#n\ 9ZD bUe3)NL.`,`PU ELRrcs18SǙ15_?C|˻Gl0Dvޘ#-\k8Rq{i"kESs<::8Ը4NKblᏙBI항o8W 7;_ O;?Eޕl;I-ڽG]5 NY.O,YLl,/*q9{#JiXrx<*)h[V,˕q.et>x4 Ko%3^vϨfw5W-b4gdQ_/4n[ws,bfX$gl@*bZY?w9HJvJvq:a/ڪ,q ϗ/KWݍy= ]揊7C,Ӵ8{\ީJۥN2WI2WFۂNdlpUv%ͥ8tvV!8's䭿O1h I]c)]h?|ؾòdQ]d;'D> \T|ѷ ayzSF>#A^_g|W@PW a#j+ؾ"v1zv;Bp_zOjv6J$!A6Fз+0{$n葽LƝ9$DdJGy0mH ƽvSwc_+'EQU[ކ O@Ui>"Yʡ6>5D'I 5爜7?W=g.~G>yĘe?4Ƌz}и1x+1r|d`g]PA*݆%Vj~LO`#׼uC LsܐuHd XuapwQ=Lŵq ø}(BC3jyH 8C/i Zu'xs-^_GF,ޛ& kZ'4/Й|/=!ZեdֽRYC1S򦚆M 2Uey)d`%ұ[E.X!`,믓|%D׌S&TؚxX%n=KJSv,1gqhqÎ7bgXhJyh:߷M,Z:7 LQyDA8 qY"ב#2_,MbA =/(h߮`l N`E Zwץ7ud:jyt+ GoC-3'onA #=gT(Q.ު$2Lv8grswsFFQ3i2x)Qv'H^X uiZE0<4wlפ|JIvNЭen䔶e{bÛۍg,EJk\ca=̤=>^gLPQlvF;o>A()̝Q,=ן^r~ĎP3irXo0=_bY0oܴ.3He_^n|_KtBum?gK+𬶧)wdMu,2E$. L(^se\S 4>ei2+愣6~(pqΣh.MQ@p$n;(7zL(ԹR9F^9A𜾖tt֏$(JS^VTJN1dIK4# 5L_u?LRn׊l/!cG`ĻgRe99wW%XavJ]KIX}(gVaA?=țq?Dq^37a`oS[dUNbBw K-qNmwe2&? Sh\5DRPύZSu:` }1Py%ц c/x6Wz 񲿏_ MSXy tLAmo0v8# .}<|^.$2+0DMxVX/ +;f ME9S*tZFZG*5ӸQd>s6T.B.6M|[i s!VSÔPB#gpn0lEU#YJTRtu[wJ*i쐊U34KftU2Ņ9GXr -޿cĺIeS@_ f&,m/*E܄r)S;1z#'ә01s}i1ϕ'ȳu_ak~o%3reΛ| ;%X J<-GT>r*(Pdd..r[qW$vdJ0XHU\"ʵU8D:ؽKRA9T_u}m-A+4EҁC O ѻP+2d*]]*FPYYy_ &=@1_Ps+\lb4n^|--ԏqIDbCRU Eg&Rc!<ˆ+E_+0Ffk:ȋ@W W{g1W@$&$qZj"4!8H6rC DvG2&?az%1ݼ{Zw']5BHz63l]m8+YjUF *%6hXHwgLm~RqٝVQSd\Jkk1րb?#2$ zR%F;&?)GpIl'gb[I=9ִUGk߳gdV=a3%ͨS5k٬,ci^ExSo褑4 퐨$])g.G6Y 3C)N1+UsN\=5R.׀ޡ'y0䣜(Bcibnoo\XE/`l%9?pQ<5<va҉P-eT7XAR|*4cW* wKp{Rs_ Ё@bBZh7HC~g +=_q~滊 *_+4O7A>"B`!rə@)'u}^+ͭmzO^|tUL)Ff^2^Z9xWɒpY`q]K ? b6E=jx 2MgJ;;b\ N GVolC~⿕~~|B)e-EwVPf}$] ͟/ÒmշkXP訊pd7˕3G (2L? )`aR/ ep"1SPK@&MMarcie_Source.exrUT 9O9Oux l$K5 {l1Խ_}۔Jʪ EdĉjW&P0#s[[k:N  K61w4qr{󇱁;"- <>gmak"hl 9`141e6`2ab2ee7p7r71rV4p13poNF&&SD\MA/_Q0v6y?1 rFÙ'g'+B''';!7E 'iA ugb9*^?8FOR)aG^_L1ɘTd.E)GXj+Oԍ0z-Ij L|.[*PU _4ԔR)`mNtݹ/Ppu{ɸCܣf?SJӢ5' [835ˋg#s&œa۹ja'y1đr4 waU|=۰ޏ_9muD۳nUF$fLI~8c5{nRZfB!"ɒ Τ! HFԜ现s'4/s2?uiEІ09ZQ5MD9,8aaܞNVׁQ:X";Y;LO.OĹ]>J IKPd\Ei&YS6dFδ*bshaM/KGaKG,J\o?I9WCԿ%? Ǯp*Սj{Yf-uSlڲyץx?xFM`1?qχ-<7j6pf8GC8-&C˽&*U7xUNVg5>idR:#f &]'ŗ6 JMN֋K[:&y 4 A82 7[q(Xכ En,Gӻ7 5xyʋ)LvdB {Da [LURkYx.!n( -]+ݚre,+ڟ{WLpNoLjB{in1݆ЊNĞ7g& V[eñ!RZ)nXD`V}:V>ZFs$˟8; KsjRllE jyf؏hp"z༨i)J![31R܌/~!"=]Q34k ]:URT~<%(BzF?4\gGS]B7\S({oc^i7Vh\w/޸Gc"xGw&si#O3x%K#~44Yw 'r9꧗Ċ0W?swnxg#vh0֯-`nf^DDiᘂ|nvվ~@W3VwxwǻY^? xXyzqljd-4G*h`oP۽ _SO@$R]+Y]v{'g|VIGvw*W-/oD#YkGjgX NC<7&Tp ]^Eږó׾Wx8\Y9f]J[z#3nV6$zgDʫ D_u}>9_p_;kŮ-OJ bz9tN>\|ZJ|}cFnfv%V"ݾN7~4w(EKP+R5"sxKPgXmsG FD+;l^,O]EUڿ.Փ/eZge"P͠vɣ{S_RěÃIكDMlk+AW#jr#>SX4*Z:W9# ̤5HN<,1CO'n+?SB3LsU 8g"ܭM{ Ү\hP`4E[ g6SQ&b7L2K"G}{UHqcф|VD׀[ G>x*Tg0o>MqoqgY$tŝBիϱlp:yP=2л?3R[ cĵZBY3DҌ&t1|t^,~%R Hjsr+MQw-bf<}j쫻:)'Jwc[* {$̏6D8MI4 !Dԑ&PQH%z-Gd#K\@Ѱ'@sI pB>MH?{3#f6>#(JnAY?6:y`F^ʳ%~Na~@ƅe9:#+LilW"oƿuQ=yH!'ܦL8ߗg&n>@'阭$j?OnózcQ:SLU]ɦS۷9*旟v錴r}[)u[4hގ6[`]K1^]}EΙE&7]=4 ζat^  3+R_uGM\Ct$#dpƇ T*8ã9#*z/}|gf\kͩ8Mx tw3-oWۚVK##S"Ѣ'͸EV!JҞ;93ċ:~eI5R>p$:p~N5R 򵻁thJ YڷNh";34h= m[`-+2Vw}|f -Ǘqg2S(uxqh44Oc4D~ (GvH~LțW* pb]^u;BN.Ow_ \_% tfH%knLys%Jw}ē^7Ϛo.5nseԭ+8CCSIWkͰU,mAe$aQɿ=}݊x IAZ f0%z Q>fnŚ0x%1Jt~6OfYc!ch Tat <*E+~Ӛ55|AjӓIOoKG;(la w*kC ͇kxXWCFPbH)$y!G(яoיKL#=Z `1>8\VTkd*7$n-COcCϏG# ]M;ZmEvpey_hԜ>ˑğ1lyЊBiI_K;|6rè2YF珽FzhHHNp6rIgIږ,5o+Ff$*݇sJ*-l9ڟ6[<:6_ޖ:2ryO3@49ѮZuN|1NqS#I9.09Ik۬s]ugPMzHBBUgSja#;ExtwT#pc9dU{a|^cCd4pFR^& Qp6=|_v/{Q!?Ķ[nasX<=0 › PVRNvEDq#fC}As#}"T=:[_pm5(y0䣫6kMM;#&(Rd k,Ags"g2,pr`۸oW 訁Έ1on*߭Lזh>~zI 'pBs4]Rd߸tưd^=+۱z^u^N'gi0%Jlzol$)۟]E\"Zm%3^q^Rcp k5/v.yIr ӛKkPܙ$ZN)Vfs1ɡ3'7ȕ㼍RxUJ 9W@ }~M>Hc0 :iWJTyUg޼߶/OP=j.ѻ#_?2(<<{B*'{ pFg)4c K(Aā g1r\2},nH ]޿t#pίzy=ُMhGX rݼJbڮ{td_,ʦ2$QYP.L͈wCo(ݩ}s^;7Qyy&Gع?~O^+zF|o"ax {Vʽ +_8^9V#9EM%M2b+I` g ,?>9 5"Bm]'M+ܸڵ %wjCmDfv?> z/mVcbMˡe=;҆GfAϿ+lVq28bY?Q)5\_ \:A@\Ltՙ(FLb A,7/o? Ic-1Ǫ[[lvO,P pж۴= > ǫiS6] ]k -LoSr:O7Q6#̳f,jD,{::=e IEXPED.^^׼JUHӾ8 fJ0d#"0)Ѿwq 630cm:!p%7Ojiݨ8SCJ$2ԻB)NQk;B|ҳ@[ԘU:R'OZ,q|S!}l;=Pkq2aE6Eqf @Xkb4d.pqXk5qJDw@_~mC{Wht )w?CWsvhb<"4$_IJ~~A4Z+qMwhMbk^9%?ۛۮƳC=k"V# Fh#߾ 5Dۡ_¬. uG0R fZz?*r;)El3G݊j?Z [<87ǐ]GHwN5h%#6|dH#]}ԛ7_ovݹ(k3\qZR=oi]$=p,@־>Dv:$RDӻ\A{EEuɺŁGZ,b?TOTuvе|&/Ԩ 58Tć8fr2[T)D ] h/C.Ӊnl3NrRU]93O:: GwoRfy#-!S"g\b/"\.pJfx9FPs)_e, B%|B-]3w2S,^JSxy/_Bj%مے&m Aha};%Ty#+>ڍj&ܕQG-߯h[+Twǐߍo6*A惹z p„)/T׶(@`6C!jX;Uȯ 0";4cK%١SiVp*:MҢK*׏e0]Fw9޸N{AC( = ܁ďP7P>4jb[T`pg ?{L`6mt%t%SWuc` HFxRIn~Ff0E]od"A*ވ8mkɔ&պqFx4SWA2$}g_`VɑGLͫQ.҅|;%"0k|yrsɷ5qD7vh2Mej6>*;D%N|Ւ\oz`&o+ӽ=8 ~#Bs_&p tnlhqK/q^к4#>9 mf,K&)$@>#R]aBE%&,6~UYU8w` t Qv]`#@_Xz<|@-Ғx39>ێ=4vnedOǜ@xi1 >Bk_thp'N9a\ZcKlDNYe Jh=<3]k2 _)~$ jrN3sK !ˊrjL](I", XMW@43xHB9]?֪6*a,i<ǯ-{4x!r̵Lf/t`'](kgu|S7w}f!J ǐءiʴnMwveARX dd)#^ۊ_͕~BBa+~cqN%*<['M+]>,|$țSb t9)#9?Hss`}7 _AP:_{~sA N@}3NR Νt,Pl'AYk06Qo |}[DL>ղFȞ [ E07L2[l*w^54Y7B.d\XlȀ΅ğ~꧋z,뒨9?,dCKd*9 :0"^ %MO i`_Rs# Z䘕!QK:1]4b/j[ 8) WݿR?iM2gX$mm"*tdr-yšAB8yg%PF,;V͢Dn$[o`˅a,7MNV,onh`J">wnZ =~o[cOwvT~:d=) 3: &\s"PJEP0$[-\~062Ƶ Eϳ$l ϰ}R$$I]ijO k#=Om;'ʤBŋL~.73HKRH;ՍVll?XgI),)s@ƫ*h.qْ#KԲʰzKL`؛DO13z#,T6veL!-BvLmva)qi2Q""0 ~6ͼ`=ML)YLy~z(:J =iPVL -;B UDG{2QdF-?d? Fej~¡Y-h?X2 ew,˝V(c^f Tj|k>G2cjJVCE~l12תHGa3 ?PvJưX?iNaQ\mou1?3_nsVh^l9fΥN=OGD˯05V(`Y,]w\tbYREߧJP Ҕg(XLK3[W$͏1.7$Hw,0A o1QȧbdטuBWK8o9m j/yBU{4 L ΩQ+} k*N'<#g#8zF+,_ʙĖggKXۂS`SsVUk،j&}E6d!sSzh*0/?ٿ%Kڇ(oV9`lZb˜J=JS:4A ޯU"Kc*o=癰Nb+u+7+I`dx~[g7[`YQB45X 51 !MQ6N" D3K}?U ٚr;-R4""v\M5nKk K/5sA':s ĵI74HʹRwk6&e4b.ZU;s`%h1Q#^-fe᧝eNizNN03ӿG$ksZlmP{7O&h#ds!L9~> &.1XEbiڀ.6j5xQmx@ul,F*u',Va~%QIe`0ޕ{.Z@=~㗩D6*ikb"]cvĜc#(`ՔfP&+T3Vd8k{oY  ج̳W\GVpK '' qMX̥I _Z~i7!J5xI*yA⾋L?zGxY7zAD+$Q*Y}N!XHB'el`Oш辉~~n }|ܝU SNэ?VgS+B .e Pi9}VQ!%_&JN!R&, +[mO@y*z 6:~4ʂ\(&S֯3R~N\?|v/e`Js2G FBt<2{{\U;x"pՌь(*$qlvlS4-wjSwg[rQ qhuKRtl[ J:GcpH湚A2-"F %Q,]٫n2X^,<@br";38PF&@ȾF-hP[yyγh L .aョ%9kZ̰ʯ4E1l&q:mM"]J<Q5cSAaQp#< 4^fdxW5,|u5j&/GWD4d3j5-{/ufy"{2sXW 幦Atbg٨Mڝhr.SaI%|`S^W 6Uk7L ]zrNOߜb*,P>яWFB)#ӼMfB6,4}!UrRLfG50ᨎUs8D L3,* sFJ^S@3s&eR.ڄĪщ8aa6Fc/Hך֑ 4f |Ճ濟az#zvq* NP Vc8DhGb .PDVxD2~%MP(7%(=zD<|`j, U=N~ Կ,}}2kˡp갑r{=ǐe4lH,^sI).IRn[BS <ٽ,^ʕxZpwT9g!ݍ1BXOy1vR#BzS2Ob? C I2FO[G#zŘo@ϺGK3S` VTZY<ڜ/NE7&N Ut˚&'Tvi";}j R#$L6zlfȩ|{r՗o6DP*8g%> 'rS} z?Cw:m9 ֓ʹʍgvjkL,Vٻ %$rZk==Ɔ8zgpv4Gȩ1[ǻ{.JleS+kmN /XKy<66'M\ Q Jsq1}qZSg3:M!ۏ2 yfy=u`ARCwYӚ\a>SzQaOC1m3yZc`Rro`UYqciVQwcqRyG|Fkt$5ǏzɌoF:.?_U \tR4|@7oƷLsn;@2GmWzkՕpʼnސP n}$lqt39}g`T~ =ग K(i.Yo#~g iI!2a̠qh#/uh(t8*8X-{̓i>O&3 Egտd>yE3JƂmP5z-k ox7̖|CyPbRy ixJj;%[n$a&p4҉#t2H:}Y,ŃnL#q=0e:8ˉx=lۧ͗g\tXS %>DUc @Iո)\IF&phh0|6JCpZ:Xw.$p)YR̺ E3s @eߕYҤ"Ls;"upfԠ,:I]SЇԕm8(O݂/=P7.co`+xyI Ahw£*_WOQ@ n.xUgjF'OKM# ͧc2K`Rs;,p7?t|Տ{ }CF +'"WrQz3M^[m?ɍVn ΋h/~K:aSɁP@1\M5Rʂ,N[(&6=Y\G3/ߧrf!|LXnpuI?gWFÁ0oIS'bF 2' S1XC,؄I[KGxy :^70ƀK+Y?q&K7g,ڲ>UU,.4/VvÕF|X4٣O"t4Q<{^Y6-=o 'DZf̌꺮5{7ùJv $u_5=Uz ?\;6o|kK)/PF< _ϠVT?hJX|w_1R;. fHt4xǾ|T8 Ѣ#-0$ ~R>©Z GvWmfN[WWj'~~+ V[Ya,8FH^xtdlNᣒQ@MZ dyrj$Uydk %)c:ѻȲTºB\+wS |z};L;R ƣ<_ߟHnOgzݟ8]v*'1<l+gFiFFRK JH?2zZ=6Aw>݌%I' ECXM뇝\3czNY'bWwvJo .jcvz*d  4Pzqך5v4ϳSDU}"4s)OhzPzC}WT_nízol/nzQbm|xԵk_jNd$Q^4 H>ŧAw{7M\tK3HhlrEI+C˶Q=@YMC{D-' R|b,[+X_G%=`-PJTQgl#C Z\3JT=>4>M]VW1oJhxp^X -ѠW 25Zi3$aݰO]tG ,oK=V.jӓ6ȵz^Vle|M9)7cqNoaק}v1J KsKo#pXa ,f<>[a`pwFFιZ?9)lo%n|͗Z[^zteatLՅomde꣠fnv.dJNbfw^1U,uKt`I\$3+m{5Uc#^Z7xm> ec}I|Nvֱ̘E7V⣿2LJ޺L&fRt?ʉ􇷗ܓZ6ʐIu>dd1m9Zx >: x?OˎS$"Zp#Ǣ>HN ymggM?\d&NPVu< 94IrꐆGIe;yc+pbJ ?$V[i5( =Z4LѝFY@ޥt[h+h)@c7*3~lzx", omGHS34ɜ.:i=VuKdr,q+KxAc{9EK/,blɏg9Vk1ceJltXv#AN{5]KX,‹V/Oː3@,57.pa%h3sB*yOieNw<:{ N40l&$:VAQ1GJյ7I C6)kP$[aמ&-i9f+z\'jژ92ێ;.m曣f`)\DJajh X 8]? Xӕ'N+m*<&m0^ePu60@7Ym~r32Bos]>{{weZEm̖~2eG]uG& gqҦrVOhc[)Ljy'Ou8t /61>?MB+dhZ]wWĜx~'RTчo"ѷ 7W,nB.*֦ۢxȟ)մрf4G@f E96I(p9Ք1<f 5v?v}ZUW80ܭ;7Rwz=wJ3϶I0ebl>v6, i4{Ao REiJ]pg5+Kuj˭6ῲc~AfV4J%K8ܥV550{dxսSv~oLjB/PkI1ɠ`lPK]awBmt 11Ys=f=FEEAq "LPeiLmNU ae_y]Sv@]ʽ:5e>pcMyX2b02+܉` ~RtR|'.= 9 p{[ ԅ,S>ΥLRrU<)~ QdbM ݹI>/*=^~LM[ypN˴2d*jw8`ę9S9@׭5dhtH KdQcMw&QvcL܆Ww24A 7k zL\SiN}NIߧ5pb]V]9"DxXWjMZ^S]˕-=z(.+Gl^U%z˺6zw/ygQGj`97K`]^G4;su>x:鉼~iٱ޴] hy{Se04O6Aǔxfg1'7-ȸ ML+ K]eXpwǷ0?W-ɥm /G n,?T[3XTxwfre[t _J~A/[ϾKcNRSÊ]daRe/ՈRe{dY5,)C؆`Im}g_,d=+ӕ?̏ 9%yR4[)}#24sgLs %w#cW>Jx֤>ӥ|sȗ”91pe?8y=ƁGzCMQiڡT^zWNosHK1elhyGSz2^i)>1șCn^c/^NJϥhM+p~Jpգy8-s}j%u9Rh(&V>THl['rKǻ@!zVv]58;UW ƫ?t8Ӣ8.dƽN1Wqй|nRm>8 |MZZ6,;<|<Xpx->ǀ rRUN#" B3ri8Jс|[Xwym߽cWĸލBK 2b %}H%[5V=y MHc}a-;=|%m YZ|Rltd PQUQ6T20z(bHѓ78[ZbX6DTf 8~Me[<-wC~JP U5Pڲ(Qu>/x|TxNl#-zVS!dJl+Ua D`:uTH.މȎ8bj$T G=2iF@ eYL~<~ٛCqPN,rjɾ~< 261ܡ_Z,fxJ-0Ob"S0zB@oCWC.,oo$~#I4Tل"H \Єg=#EYyj!3Ꮜ\P(5M$Se~P3_M{ׇ[0#W(P6XcBSXcW(]UM RK$/Ɏz8tM|2xm2 Iu(OX C@1 {PU,K_C1gzI;gk#)}*ݡˣT?jP2DWu. bqӭc}\wib72bsJ0&Q"cle4 ɢ:ɥ LPuLʏXnӓ.B-IMgAP`* fK:r~xkOO)lY)(@E2z[rLT5J{jqXYX;ίD{Y\Cw>f2[8䂂Ex`͉擰Y|Plй$y G}1ÙUڱ.VP:0NY,Q9t0S$]m7}rB]6` DZk'YPڇ#!Jh| ;|ZqDKMv-$bE\k@hKHJGyBP򸷌ٓUl #L ;s^WA >"f.;P;%*Q#yދRGX3=P<{,Y@\<еw% qA[,ʮ]i̚4P瀳!&Ƙ 'Yo3~« \Lh& ~aA!RCAJ't$!K`ss`R_{/ +# $5\~ǬlZ H/$Ȟޭ090WԿ|66oJZ6ygbHy t ڲhDt? jمQ .3@6g̿Z=-Y4\)MO  t>C~Y>;0B/B#Z6~D_М/TQES# uzUȭLګ'\ R.)-?j<<}e5+>+l'^EF-~05f7  QLlC0{( >)$#y<$c&1vCCV,[n*xyR,gbo㳍z4`(@MHBߪ+,<y-`CSQMy׹X.cw\zه@SȕH֑ACItS)BVQNA"shPjvn[MТ2nIUZʷ];8t`NJ8>ҟOvfkmmT_RԚ5# 7ҍ1qo@7n(' ,w,d6Q7p"9J{i{1tIʀ@vu!\Y?tD\ `vOrz)ޭ*@ @q5Yc^Id :>dI=1Sh.a @["_>mq.0 =76;)- 'bA^GC+UY%'_9]_fStIj ?x(_4K'}I SILlR)ʄ1 ]$aUfVs'pdΰYe7hdؘ|q$'Z"+{w%ZPAH\@Y:҄sF!OB o*ppW)&5Qձ+h_~Iwws"|Z΢̝OGGp? Օ馨P،B^ESB?PʃUd K c{׊fˉ b>HɃB`AZuBk4J FykkkDqX hVY5+&. A!I3>6x|fjeHԳ R" pD% ^wF} |6 ka b$%} :] _荃dv(D4&_oIsvjq`ʯ(ςj: K|jBhUA %̋W8{ p 8,~f>% 4:B"de% Tυ RsdrDEYY9% 4%?tkiv ʠStP>Ծb 6--˶AMt _ڲTҮ"AH]* Kupȅ$Lu fL+ecj8 ҁW6sJAUD*+Ęw˛L~6 H'l_vQQa:(săle Hj8舞(/c&Ҥ¹0t6DUSMA͟ϧM;z\XWF%F~M۞g.a KL~*[BBxYm4W]XnQ1+ȡn_ipR'g̟w{Y߼o-ƐvzetA)Mbd 62o~H%+;yz,c}R2էTc噎k7c~u;bMG#N&W; Oy3 ѻM 3 cuq҆}hvQ 3]&}ļ=,o8 Y$-пedZV9%/vWVnm}" v]RCF BlysOx\f"ɶv$Y;<[FW*>R|6V]q3k%#"q!T8}`& ' O{cmWR[\| ) 8u7*Ւ|I`eIu@!Рf`(oOΛ u3wv5/ы4W -[,˹K pqܶl2!CLuJ| 8J'K C9AF [A^^7 ;e)5h[yY p765܊dmekw{K'@NNtj`(PS?g#Hb1a k7-9 Nb}S"޵Y%0;Q:ԟ].a"OHƯY w9+J\ g6fp}Emu_%zg*H=rpX>v`I{yl[;#XKMa}; F؛B4Tn MZ0hlתN sr.颭X,?fz5G«|pw.Am+;XYF{`kG:,[𡏴| 7M ݦi.G&%*Ϯ Uz٤a?v__&}wlPI:TH\LA8[3ZaHaˣۦҡ78) bb | b ֫#tT:,݃@_# pKeK -ʯS= 9Q(_i@t ~$=SܻEu͉xİtj-nV~11ϕma d5O]]CPH_jdٛlN: j?5fOfn(bˊ _0W(ue0.qVlx4Y0)xİ%aJT `};WpT7nZ-SN+^gҔ. ø=ü"^V8^O }S8(h1q4ALP،O妠͢yS͗SgBzz7u'Q$^n:Ķtb0` }h@@5`w+<HƟ~%A۰M vz &F?85J@8-I+!">BdbPep2WpYR ˌG}dظ4oڥ^?=+R5Kh^4 ܁Akm(hA3% t¢07_ i楾zX2PcIps&93UY Ehi6|v$2,ƍ+%/E@:rllPc})r <Y!pQ<'Rka4bzq 6apFhN>ZPhY,O`,㸕n!¢C:e SJ)4̔c^ϣEʔj!툯Z6:W߃&$ZS^V݄ ?'x)o&d?o#O(P^~OhnSw+J }NeeLFSva?]=nB\攧28R1 VfRKM%jYT'^u,_W?L̐yRz*QÜfmI4SՌS\D%P+g Y-YJ" %eC0th%_Dh-&~_j6y Nx عk}x]:ۿ7/7D6$Lf0Ű=y;|Ft~Sؖ{IpvǗ_XaE^ֺA ڬa?ݤ>jzݙԴuaˈg|okzįo.R&\ ]ৌr8_0o2]}cm޺3~ 4 ?^(dUe{zSO& B*&9dꘑHEt!ф?4GzCj[]9}ț?bJӦ_uoS ^)fd2=4iSi *R k Øͷ;Y|i͙K: N%J5$ Sx#H'rbϞe?>,y ސZ6ZCP TE0/Qu߰"ndPEo =vH_w&v݅ >Md,zH9?-8XO5v[_VtXi ߬,N8RÆdKպx>k>#NXܚ4Hs j-fTN[Qj]PH-]%s|KLCwmBf`1q'+XG$AU} Lt2쭆+Adž';bdg!MOKokwb˪s*<;Wod!tєb0@v{+b%Ěv+Z6{.Ϳ]{y39z#0t!Wލɔ*HµXv D{Z1V<,mdmzvgu;^j{S+a\(Տ(RԀTj om->q$S/>lbn~%įx7IϾr<^]LfN9)vi=u_tz8w* d?WO9u'7w)1J E!vyN5"[ p)ɽ!/1~="]ί@o % Shj~Mx B!a7HׅK~5h.9ƺy !)ñ^)&?!y^޼+`.Z_) i#5]W{Z9δNk*3ԖMB >f!g􊅾GCTRgn.ƫ?C'Wn ę՗6C+B'i|l|۶F|y!ʹ8zl B1^2Xޮ%Xnefcs !+;KܒwU`05Ă]J/y+~~<'b /3\26-F;ȶ/qH;q3=pCZKF!I}ǨOG6JCL}.*_7y7TnN_X̺ˌ˫ʦ-TI.go.XKuS!囹 o v+8ÄU|$U>mDX:sΎ $xoFs`U\W- Rh>,H5?? K+| vR֙tn-溨)LΩp߇(7^[4{ eg|VOd_Qm_7䑳 7JE+?;& ~r5Nߥf1@+#EVR:,:o3EBJc-k{5pg6 'Ma;.4س*[^`"+RX d*NJD3:P1{nKڡJᣈrLHSS6d,3#Em篮9ۭ}$/{b__yp |FyVՍlJ=g{H+䳝O|7û[Y9/?SȂuv4/=(.͚yM \m$I;!8uJ]ѤרCk(/Jf:Nzj39-j1I\1?3Q{3+4=6mGlH1< $;Ӎs򠖵TG7Թ9vC-BdPiڬ&oȆ5.S 7`_r֔T[x`x|mHTVXAN 9^)0a?jOg:.@׻Rt;y=(V纋 v&/jQϠ-4,0![A'6Bbwb_'C_ҟ)+?rHXtKDDu;ahHプD,Z]AvT{nVo$x QL[/j6mkGiz'i(`jQbos;.ZV,=Y]دB3Ǚ9H"4ʋur*LI7XնjԋؓV*X骺VrWʌZΡ5k+}jK髍dňvM މ7jl<+D1z>tNS!Gs?>Y53_u .xo*?x8A1pDJFA_HcM ͒B~8H3:h9o/76ACbI"7SIA1~fĈTB]5.:2+lb2[{L}pn]"% &>AK 6O>v`mߋM s_w,{w>=80 gBOr|1xv/g/3}*IJ 42O߄; 1! DaEsܨR_Ѯ*F-r!0\xI`ר(6NxӚpPRbzgQ@bI?<% s%4,h4wwX R =vztt: E_ޞVpawroThҧg$ Ts#ʊ5cz&}k2<|u@@MȢGJ]&9v3 /י;|d 76jՐO85NP_P0 WQ7)Il^$j;^$u:qȮA,8/#"1?$@~Lrp&`|beFwr,|-zJzC]pBr$!ZYksˉ_% sH3K$1I @E^(;o,ܧ޽ɯ>![?1@y-g4 ,:T z jwW[ҿQO*gE3y = s 8󒱫 3fjgu^+'"ﴷnv&{R!u&'EasVvdHZZTizN{d]`$Ĵ ԰Q)cg/{w"` O\b)NHf?oXRe&ß\Q D!_痻ܪW7$fLHR;"ʪh&=7xAu=c3A\q޾ZPē-"(@x<&D)DS` RYP _e7t-9E j"ͱOgRx[[@TqT&:_o;pSwlDӌv_(,i?@T*4>6 Gjg:qKl&&s$J'ZE۹;,OKh̄$d{8p̱~ Le'rrsR*q,i',O$,% 5a3Tx `6#C5e7?%KAh~*1/L2 ~ K|72WN㶮Flٳ lD{4+R%e-1or юs[yMd/sam:BJqS\1nb2w3=f!ϖ,ŎFlKӋ gQXǧwfR}*>5R %Sɛ̿ 0. >b7Ӣ%]evsNhe?~+ʚ?u[j"kJn^ED}'L&n%FB:>&Mce;3f爠'2)jTjg:SXg#mO ÁMsK)׀ _R?j7f⺮r݋H@MꊣNKm|$G~=lޝcOpzgbf6?Ai<&Gk$M,#0@MH11_0SohV}3v^q_ftlѤa䰑ǂwh2 b4. Μ>h~AeMѦ8G¬aŧ7l^[]#}mBD}ħm~ԢRZhGfIhSn ,7S2iMmv \-][otڙPHʾІ6 ӿ`=ӤQm^oUA|CXi/; ߬lmHSl-ZIRJaFAHI1 s󽝚J6RC̏ok&4iR{MG-KTsgH3~_9uC7~ly^^i'虜t/l<Ʊ Ʒg XUjD/<QgK(pfWTSm[6Fc=&G spҪҬ ZJ@(aH5}`P07D/:WNw(Z^x7o$]Gryd=y|FarM%,nyw{ouݻM Xm4hM# FS3Dឤ,.j*SXC*T-&#t;}Es)]"ǗRMj"ys/~uD7&0s⩱+v Ϊɐx[59z;;@n ԠUp ?w%FDENO#u&pϾ:\kрg#^]wuVɧ_9ߺY4tx5@ǰߘOu x0{i?6y=gku t-Orv+|JB, L|Y'\R?*q+l#yL5Tvo?]QK}8FՆ͠l\h~)6icǃP&[ =n_e%}N:T{;BZɲt8T}tioqs"0Oo7?Ch)7[9\b6|CF8 o`6Gkvy1?QK+wf#Bك$% )mHEr#*h^R<3:3%[R:2tA_}j!f?CY[&ghY4U1t_}퍽`G{6p*5cɠ/KrkZlF=(c4r/ Ż_4Ze_^Xhn?/4^N(+(y70-Hk}?XY4o}4krkD7"I!A=u%ʧmV1 `5eN@ȺhxL<dħ h.7pηz*RNrnӟn_*=mIϑ@G&ZoՑgW|ueXr[ۻ|;?W`N]x@ŋNnQVkCM vSQ#xhwF5I3d2)@lCVE徝iSFv>lI)w g}{z* ^Mn>пA^05 f~FonۄMENpgܝeާX>eg%erYǪy1)5p9v/F}LPaq!@O2ty?iԜ * zUE]Hqy}֬5w0Smyb#m҄л_sc"KgvwA?ǿݽ#˪ ߽8娹e.%v¹Xٖ9QݝaŎ(LAEQ1-LƏ|.x B&GC߱j,*a0O84^Ō6u]A;npYf}nSʞ{rd oi <|`^ח ih0WH:} j.4Jh"FC[x>`zLեuwdf[kMgę_+L0nfQR+=1ýꖷH8Ua1dPi ۪ѮT7g^{u_WYOیo*tY)h*Ғ3t.곈,Zs㿃lyW@%0 ޞoB>;OTu;ڢ&zTj3~cHI:? *?IxcNjMnDžCTu1mS{D:#Sg-.~jqG1rj4|8ݜ[;HECh}3fdvv"{^dNF*0SңTCsJ/y=ӱs''1A`a^Q۫^1f 5 U0Vؒ(N\M.xvKy~ФZЛ,߱S䢳)~;Qh xeU';uXeE(՜ng~aymNǟ7vhlvzF-~@:RM<^/WBhPk·.Aǟ<tE[{PT]9J%G뚫[ v4O+9.t*${qַ֋4j!0 bW; v+q[r_NwmKb>7;T \areMMw$yPدIJ)UZ QƝݮ'?Ch茛_Iw%YN~oc|;(h֛c1T}v-UeQ~͗iܮ3 Az>#hl_ Y! nrfG^mX2co[Z-鱑*h0I K+1!|;aA`ӂ8L /,Ń+g, m/{lmv =%X76w]So:dwR.FxVܥr[B?w-%Nx^ctz -|pZD{x&[ԲSG,nZ =~7ت*:sXdAP{T=nh@6HYДs$3iO9G)`A[]UhJZ0x˭^=OT!Ay_!S's(0[R┐SE5.J]ô۬a/{OAdy4Qͣ+qJ^Sz-"jXX.WY};C]Sn,v~!AwmiFi۞<mr)c/VQ)/>z;EyRE^0$7 }wr> +#}eێƃ}aJ M yrֈȠEzɰmWN%.D~Cw?3}s-25gHUZcI3`7 *4(C+`WP\޸ڬP[ecwʝ.;p|q Tw\`P;k n-~¾g6G)&QAe yQ47[| 걀5EFF_Yzٯ64l$(Uyb b[Ϸ];ǰsPא1R,#3h,yJ$^M62@pAeu J}1MX>u *ؗۖ d2XxesJ6Y&&5C>zG?krΨGS|PuRyNe*6hWZ\PEdXWőz ΰ&nBWS)LجUb[>Ɏ@ƫʈJV9QvU8ت1N毫TةC7L/˼Ϯ>Wߎ[pv&%؍v*DP3nWWk΃?[μRH,(KCh㹆}Ģw>[\pӹ)+z'+<[ _xK#n C X[3jƹ$œ}5t?Y7`R$ Pm(,ɯr ر "'M(U"`6&y4V, xsjAC&:ljƋQMhpRk[я ԍ)[٤6/"DԃjTl&5ץ<;cJ޹̞3G/Hvҳ~78}8OZK< AU$y}uk*@ 1|\TbO}=5D?,Y2BFZZ,Wx˸oǴAZe 5@XlY\(#n?t| xށ vi[Ȳ2sM1Zl7xwh|/"Rxuhrt},P>!P X$"S4|(}ꓔMlG/&ypC^*`JУ cy^/;'BubcLQGI&cRQ&өa̒{G.Lno{(76,SN5K=ރFQV5QVgUO{O`kEc +P\zsu|ю T7nh {4wlDA8) 58=/u:yvEs*R?sQ&Yߏ^Kz[85΀r!$15]ȢKuz=ܧ+kEdk_Hnp#Nj&v*-,zK}S8?72.3^i~#2V2kɼ~鮇&G:glW[eqf6/"heH7Q]i֚9߬Sx}O{.~PR7ϩ*U&?n4++NЛ}mU)VG4+I8g;PZ œGطxIVFRj7/$F̷x7u-sR,_Mat`8gR{&_|u0?IkI, 0%[K0q(ixǿRTßyzfN^Ov!Y0Hcӿc%ao눇kocfdMg(OέKrȂZ@ f?cB a} Lpҕ' DjlB$ӑ("J&RU+-] 13`0filat5#K|ً=)׍Oo! Ng&Lf/fXEHw4aQ03JOY$՘-ף4:2X<ĵ̌dmt\3<,%͙-d|.21*a%aHC߸~ W?d|!XG`ƟvjHV-U{ Udtm,8l"x|!BL0/$,/-)+_=TdOW%02!2kM|?IFX '.^G*9:s FɤY=CG2Ax Ľzꜛct +ߴKud;'}4~afү~)a-OÙڗ,00%,gj8*U=&q?:! KF@R2cNkbIs[F"$,D`a3G_RBr&2"F5kڏAd֔HŸy5~CMZΑ]PaeYkgĞiwHwk|#([d{:$$eu[ z`x0\̵خIg 'sx@ŔZmoUGI8'5z8"`ջj9r?Q1^y Vꉞ%]Da ʟ\CGya0~xԒ4G64su;J .OA (]Rl#pL =*?âa)RR$RMdZxhb 0D׹8k`uv/ӓj7+~k!Bn7:°N' 4d+g2ti5^BY>Ɉ[>1 9? 9;#L ,9D Q O d `i!G{ &!@9ʹ8 AHIvb_?:CDLLקiSae>LgCVԑ82%q)DuJ9?y`WKT"ٞl+>ۃYS٭=+8?n<+%D В:!&@C>xKp#>Cƴ|U%[gᒸ$~\3F F=No7xy33tѫ46 UȐ!|s3L Le6+!q!W9d}I%25MoSW? anaW-?AX#GbnW3 w 1K2N؁8.|D?'FF7.tūj s-pDžfs%V5of6'pɌ(t{~jC *5D"ds3t?^=kl=f dY^bٿ!v 5d%M "E$Ð9k걸~<9_uLJ ,~ 5t?Uj!rdէuccĚ!S $ 32@6LQTS#t+OO^h12KCkz (C]]zY&0XX3bBPsGiFdV"$,S.3_]y[]P,)z=Xpb!33;6\N0f7i6ACX1#N!gQE_Sh⮉dw1O^=Y̿#B=noadbYsjh:BW#6&.MGy(r&PX'}3stR_b=.(|}AE N3" ,ԇuS5(G'y@)]NҬZ_oLb [9kX[+n/.JȁϚ_I]Z O?؝MDE@N_rM4Tq֫L]vUPwSJ"!*N.Qì=*o @VnYO!t(wǿS8 ᣩ}И*Ld*G-_y [7yn"?Uܸev}9 w_xhjvIyB)F{cLˊ!ZBf-^9~>%zWja{v \# W,4`\AK\4ycNI[-c~ c_>ݱْPr>qŦK#'т܂)^eS s6}jE\F X/۟[.4 n CvY=T<3.#ALIRMESNIr iv6~XݎVWtϓ~$~n(Ȳ_3ygOoEPFWФ \cv6ǿ`L&' X%VθIgc9HgYQ:|,ϡyk ٓ>)a.]ϯ4'A ن&.qd@Y(sʑkCյ Ძ)"Ҩd%8\V~˚݂^C^g{stpa*RBvϞFUO<~Yu;̀XO},p/È- ԛPmvgUi]9.@_Mz<\y{Ml0hц:o*~};anݻ\,{PN:ݴw^4Joq-N9OmL7J<.\fso>[v锫)w>7GQ :l݁r A/GGN]W܌T Hz?Tua]Z%i"kƉ?\q[ \ !#-͕uPO\ Phq$qWZ"!$|aBɉǮ}Tg˞6EUU2 eT;r!0~ޤލ6^j[=ܦ6xs3 Eƽ^p8H5KT$jec=J$.*c/jk8!?5uտj'_>L,E= uȢafL ĔQ iBMfÒŰ)UZ[`^lC~. RWa'U=cds;=ΘQ!E#a>Te꼛vdXjr@ j-*'^ "nsI,]?K1S U8 |j(BGň%=9x X }DO&³WX.^kX OG* i45odҁ\n6v^pjlS R[䂌<wZQ͆XC]؈q̧ +x3CTA݂oku?/*ԋ]ʑImbV&HG,@+V4J7$!aT5ss=Y e%=I6XPr]CޜpB?_;'jc&m!䈭zܙsQ3Cgu)h+~waȽ /xg@3R ΟW~6Fҥ38 &P܁;(<{C&͉PHX>O,ZVI[ZFS7\XNa* e) Ł&E ,,e朩0Q:lkl6H0˙t/z2'#wxbgvha%w} ̿i mSI}(G:%h%+U2tFn#l!M"WenIڰE+ rNh^ϵe0l벿 -w0i(iTJi: h06vߥ2mZ8E șHHbvo?PXr(sflG")QB>iJ8.8ABo򨙬{F&ҰHB)Tvgy-n?ޑѿyWI8>>̇Q^ &5 >eVg 3fBY$`~ 0j(|/OXԸF) 9ufQKCCH ca""lQ]]}6@ۿ=mޯYCHؖB)i98<_0:'ٵm&[i$ XG]@Is[_eJwH7(]?;LA"dxX#R : Bu<*"BS2i!ƚf9 f]C{ܿJ7Gk햻7lG|2RĬZ@$G <+s!s ʀ`<# a=uųWQl9.cRHW/FR`Tΰ)R= t$OFel<\ss$Ѻͷ?9J~oNliErC`6G +1sAQ˔?D'Rs|J#O'?WE~ y'NhӐLaH.!4q9-oX% C{t"LJSmEעV%!8Vc'-KYpz&@E9ӈVL^QRW6LXF:ATf0G>y|;/ZٮG9.W炂nK`X)&LxwUd O|7T64lP֜ߛ[~}Y0QbrJ.uDРhbJ{S[0?]L;)ԢAO35Ҳ<sB%¤+%EP+͉{0Fx`{3"A2RDTyNkҐ38KhN9͍D*BG6N)v>KcɊx *Ȧaٹz0WA5oGj2k3읥164, YTʖD8xGc PF}\Duw mq&'US冿?A_Ajەfs9#Ị2=Ab9EVV-Uxͽ&/L_(pjꇶmX4e!6sdoh\|7G/b$ZM5[U o;t >kp|M\Ď8k}~B3gom8D9y'+*.cn|U'CGm7kGVʼnCݎPᄟ5DMD [fKhƍ;nQ{>D'Ֆ㓟=rGR-Ҵ*GHhJ\6!jI16aVj3'Ò 1 tSrOU.ThEJ%>Hw8K/:u+}ף0ӃN,G̳{ȪmD ~oW|XG)DgҨsI]PKtBIq[O8\&؃͜&F"` %0'mWan{9Lm*@ٸ?%yDa_.߇nAex'6-gȤdt!۾rݶ#kUЄ.z۩2s[ -:z%*35!S"JUWS@{zṳQJE @(`1kcQQ`[G2ُe<=g7BTEp \͕ $QCRFvL} q1)c]?܀dAGD훐~"ɇI

//ֿy5c2?Nm.s2d. 约P K3dnʝp{⳽ׅs@MRqm>C5 i3q?;6:2n罫n6A j8 Ƭ8T˄ Pct@.F$ܾ5$FOy +o;~⚩0-ۂ47ℏ _qA^| yP8dCx뷯y~u3yN 'vw8{|=B8ߗvZ"y;}Vgwm<<'D䤸/m~oߵu o SxoI̶<<@;Eo^\Zi"G'Ig4_WċoB[$½di.&ď`/֧o_B'؜(/)o~ZOD&3ϭD@5{Hko>ўS7'G6t?rC6p^<~QZ}DOC.J5_l?cK jMQN yEny6 *(\W!AT_Grqz6y7 @&F8$:͋v'!.6q Zi/% !?:YxGIq`ߦVxX{ۺˏ@ T0ٸkq+ 6aIN<'q~jῑ4\hCٟ66.!#EH>Py7~zKtqF.V%2- _Zkx&.8{D7kߡU*wmq1?i"=$6xOP=Gv5p)mb#dG͏ġ oom.:i[F^H?+_7~1i->4 Η"A>7(7=M=^jQ3bWqzNGz;3#0@E]Wt% -78n<-MS$r{@t.HA|8aS5{{7BlAIv-Ռ?"vkE?ޏGE3Q;f'4#)>:7kOQ~ЕIЛYy^1kI!@X x, ws@6[hVե2b]K"Ήm;(w ~D_Wuaj:Eur?ϸPo||3byI@ۑUd;2mο v?ov(ߧt~Yp.vbGϯtw267/޾@)h+wP:!xig_hp⿸EևZB$>nVv0yI ; @g#bA/H tSw~_dQ<ٻ@utn(;-/ fh! UG; ~~i$E,FEdַ]vwoWxGk}u'GvfmH/.a{Ɏ}ox̴s)ql CH`fr[}8@웏Go Y:BBL:PgP:6X,zw` .7k+VٖȎ&˥X/鸧К-xɾ ?g2ABD `![٩)pOѴ('blAȖc=|6L>]?L ށ+&8r8/@v }ک 08 Yp?!0ّ;覸_|Нw au::8ܫBW>i}HoKvKm^0X$j_J|$).寳VLuY}Ȉ\8@v=wZ'7a:)PO,@+w]u2Gq؄Gn~{DH[жW} P%v/u[ _x4W${D+!~Gtd=='?W:!۝_'[>~p?x][0'^_`Umr" t'b@Mp@/Ŀ{@h)_B,?.I\w鷿BérD]e+@w9r l}=|'KE6}Li2DG;Gd'#ht+?!h@vʳboqtx!kr?(]dG]h m{u2K)pj j^S{QK/j9~j~Ρ)۔`*x{8FE˗2Qgu_ꬣHU(RG:ʨ(QFk>3bAj2RFK,Z~yjǬz_mw&<~ǧ?J-%ǿH[cXzSr{c@9';*Y:Nco7-Er:阓;ʏ]_Hjzl/"냡y[Ή[~sn~ⱕ^y.o8O0I;<~.-Bڏwg>m |,o.=}'?L T<;ӯzoa)rRjswpb .K$jp(6xtO%y$Ja4-EҲָ(>6oɗm'DqSHVrv"qHO6$󋏗Š߮zeKa.(q)߫+4X0}kQba~{Y{͵'2@Vꘊڀ-; 2g[K-YLڏ`}38 +rH'Ɠ|Naf&)b@>ߚ:x%QOtNӂۛ4@_CsqGDA@z/z7r'4_lO;mV V4t Ms o0U?Q|[Z={?4GSp2x'ܶ |J *zct_g"OT vO$f\kag^у;ڏ{ol^39i.!sxaI@rωIOr۹EЭo/"XUpUq)" VeCGs)&{L{#ǼQN7J71s}@"+>kO(H4zQ#OqɏFZu7 NC磉(66gۄS@]ۗ%t2g`VrUS 3zxq6?-ojI?8SzIi핋FL+ th#% nm]7I(R)wng5V7;~_h]6.D_EC/N޴oYjѰ`pb q_M< 0`2eR.}d9G ID/En8{G)6GcQycz:x[` !}xx;z}?x"^1w Nz`#g|G =g򻶜d*-jmg_*E1'Л4bH'/psa=l89ѹW}6Qp$H,bB'(p18NS!ʻiiOu,[Sǚ&#=$I$`f09cˆ8@ }-5l眹~sb &Py0foOOu(nK66#<<8Y2:rR1P uګr.oux>9Gx'}^=y` H>F?m~ۏ㶿F;[m /ZdoV@\ tgeψ0z'q dBO-=B>Sʦ΢N@I;?oDgj+Ι]x(M.[ Rnm&Q:Q-VxۉJw<5Ʊb(mw=ekn~1=VDcު/;g 6F>) 47`Ш8F{mQOg5f]Cu FhᝡYI\mCc` Um^Qɝ~~*f{/5vtnZu,"/PgbV+b/{.7{sH4 b΀٘a1!p(>@b 2~ssWZj(5[F^(N ~z5$ 0ʷP7Y.]5_{=ob{F=~+ֹv{SNSQy]v`NIvSwt9!@ͦ0. ~CWL>*H8txK_{S.8Ė^`f,u+2$i+z?2$*s)a»+D;':af݊.p3$fqķpm{! ;PHF`;:hbXԔq"Qˈ Š~ #I Q\45 &|_@RcO#=YMjI5Or;2L\,?p^LIp@Yz6q;=t~kg4 ً^̧nTڽ}P߸/` ,mIϩΘH9=<<'qVb#h',bئŁo&!cn>"im*nf.S(! 0z_:h_g>z9q XHP2KH Chq~^{Gdcz1!, (o9n^?u^h\#hw}Mߙ=,9~Or'} ?\!dsvڹnͶxE)܊cx1g8Uߐfޒdf;%Y }7_y6x{bmB`ށ9)Bbki#ejyV)N^I߉Z =ҧ yfXqv!tMv29.s}R"Ğ>-v*sq$CRv8o$N3̕F7ܖH}i-zlRIe 1PBBL&+@ڥ./2U:b"E@%/R"$j L5G =ݫCWąe!ܻ:vMzҹzXO}ҡ?5ze][W%ϲь؄ĸi#l2][\[t]gO=ŭ&j1F?{<, NKW"^yvHyo[7\9o*9P$u D R&p.QbR{U$/aH^crޓ 9gz͕̏V|cfz`^$z>= OFnog $TET}om cgu⚶y=34qDtF b4,yGÚ؆5Qpo~c\qCikعh|஬61c 81yg)d9Sl7}up"/2 /j%K<4d5:ɟc(ڵ0 BLfC t5\mY+-Lk`sGi[ Yo䶤6f.5ArS:fz731@(4l٘WN%*_y[%/= 1l#a ;ƽ.vo?g:yMӿ 4`v>E8D?^o fI/ 280g:1| E:1UKBF;o"E.0}%OZlkeɣ&Q[ A*7 rH8W'9i 7/W1T?Vu˓Eճʚ:&F~J(j(dmeQ9jj5o'W7}"ۖl^ױnATAyکhzBj~t5@q l?Q^6v2yׁ+QLAmaGl?f n!Մu P#424B!dW5?hy<xhzC/SC 5ӅɰlBv&FP?Rq ~!?"H-2k[nVZ4.ej@](Wfeb+쫓^X5eU[YfZU1R*Y<5PX k鰎n%`Bu @hobKcBP$dF7+ٯoEpWS*iNI 2%))E)^]Qk?vRz""IC*TN:uBt<㯝 T- Z*P/4:USW+w ~qC;-kP/k5wIDE4?Huʾ UJ_M]!Ez ~U555PZ#dߤA&[Rjl.5raY^DPT*y`Z>oGz]p)/f:~)Qʷƍg֚_Esܬp.5 g)R*+7BᱭGek7)LE(,3&叒ݪT]dw=Q0٨1,<[?c Ⱥp]-~T*IrEFU0$`A`=-?ZTנC~IU0  P RH%IlIIkYZ RQ(\05.VFC!. X78[Xv_Y\VnHP࿰: $Qk TTK|E:G $yzq|]0|kRGJ%۟X GjjN<1O-M^qp?PMwZy;\}U_II#A-!k3*[2@kIA#C+dדlD*\,t &PЭW >lr6EbsfPqhȟ.=5,խD^P_ep9e_# cحփTP 2,ò 5޺:AW#(½q ]PY0GMAV+0f3Sa0<2 Jַk ՚5+}[O6/8h<-r3 _OB 6Z2~&~p"=h0@/k'Ӻ>l/;RkvZZj Q *QPoͭfފ)`pUY)<\WgjUͩVu7IzW?70{clRpm(w҆uR^l&~|xM-ǷjOfE9,7tQ3Q P.[mVծ͢,q*좚 aF͠ ^yXX&ˡ.eaxm-Tҩ'W(/nϮ6A~sp.:[a&" Ѻ* Riu92ڗAQMϫRV[3QUpY pQ,x{d9ǥʏ㏲gY.ԣhY-Z5hըэnM'`d5Q AR,eK9ǣ{[rrs|/mw &o|}1sܞf EyK딙NA˕C ra 5m[#Sz@)r;d'f|MDSIUlUآȭsױȕ^Ȗ6/LifH58~X{SoTjX DFplOLj;G K=οY<'-k$y1@y'.{=m81!V[袵?~Ҵ]]J~I %`$i|+cK4Mp88e!B?|ws, }楌;̖ǿ2RfDR&N[#B>tO'v7mG_駋7ܵgfq Ի (ũʼnmyq־xTeAOKpq-sqH G˺x5 ?ןT 9/9-sdh :oun lX 8˷ϳ|czɝg18}Akw~:f3"n}wm}qu" >aҰuL1NpLP PLhl*_?kpH؝/Mb)]π༹ndB*ccOӁٗ!gu7}xċI팢!og%w[sf 2 _`L t" Hޔ!0ae455< BISHt6C#pz0o o{Y?tЌd$2f4C]0z\* M>/?F$"; HOGֲ][,)gY=n+qZ8 A#&1HU`GhcjqmwWrkLqM)R0[mk"kFzu%ɸJyis3۶܊}`޵+ bk-p/Xg3i4P-J݄E 8f/@J,w޹cz3O%ЖPfHE.ZB6&!.\q:G]O9}x(u1FkäuXN/=e9mKG:9eDV%CaMpgpOΣqX/Јt2?ac25wR3eR/0B^ӏ?]z LFl'^_"37\'5/Clvk_(t`%91yQ8,r 5J˜Ix@C`7H~mۥ 1h rUչ!(,I_ȃ-cU=,Km)*Dr|_ihM|[[npp ɨp{lyNk݁SZ&8<9#[ v1!4x&@@8ET`ALe1ںa+ S>}0{c|}h<ҝNwso|tab}#|xX<Jx,LQl9/)\ʛݻ؁:#}Ȗo WY?\VV|nM F ,&b,1fP b o}E>O_8Lx|$P$=wfn2YJtJ>?c) {n%Ӈie-sŀʅ<&cfqQ $9@cѤEAALi6m{ 7b>YPhb쑒'I/L%{79&2#!7=0`ue"eÄŨbKY{?~w|i$S*8E_B]!tAvHp.ℂ(iv1<4ќc rjXI 1\sSZԂfCR?.d}$emil0Y %TQpicaW_%na?X} MS n.d"ׂ\RN1֬m!D#NYyHۧKb+ȘG0< m)k; 9mduȖGKVA FV=@'pΙ!/ q)43}s1S7Ϝrr+ܑ s/<9igZ~Ɉ&|!U&|w c„60Y|jBr4~fd6Td/ Y2Pg)pىiϲ/' L|@N_4[W w(t<0?ϝ@}Sw.k!y<4oϘc5R%8P!I|2Z':I Ʋ,H|exJ2e(xϓh);.^=כ~]vȨw= }lf8vA0OvmtZl K#wGf}Nwb{a+y^AA08Ӓ)陯 pie0S̔q~@FV 升U~Mpmf;l fÖĴ?'4%aU %<+^ 2VL v|yUO&S#2],l{>kl/~Zk k4J<_%HL(>uW^qfy6Wξnt#[WJ#H0ݢԏ]6;~܂;<9fu,$ ;Aa13R鸷OpՈќ$ ݙ:>6*S,}r|.Mtl<}{-H-- m q,evҌ ,pom^Ϗ%+_ Ф)f'}~m4JnEQ10{{PMIGi4 z4+!QrdH{צwϏ>f6|xJ 9JdD5'O{g=esGtPNBfQV8ל\VKw% b:̴n"($yLq PpTw4AJ)_4Ka\W.`'U9 Otf\n.:'m3M+o,5>kz Ĉ j7w@: z₻;aYt2m)@']#R&6G pr  @4QʶKE$jaq=:z@t.9NC3Jfw9jc\Z@IX2' O|a"H3AѢ$)`_AES\.!f88}8zWsaV<3P2 pDQp h'ҥy:%R äx@Ϩ''Wu3S 6qѶCc~|T@.CAb/9kiu7 ǯs+Zvb- :,zm9\8KE-Ә抢s92dLPWHZܓt+,`j/$Zu>݈ǫ̩#K#N?ِ5ӟ-PdWU. ?R I FڜI"-fof_]|G2}'E~:]-Bp"gX ]ĮY6ҲD3B( qDib"~,[( yaHIF7-p);9MPRAF/] R΅<~=cL#3wޏ0i^Ջ##x&縝QСI``nqGI >58},F ^=E>)8d3Ž38Hh/<861YNFm86 ;eC /!ɖ'|I@EV""7})^ Wfb6cUR{La~y eR׿fSٹ'Vɤ0yA1ДdF Dw4+Wc6:3<"_rYrbg xׂNDx`"{4XLNb%*f9-&|mCEzn3~\0!3)=c&!p"&~h&*AſTQ1Dȭh {b`< )ܾ4{: < YD Ʉ1  HD~J8ճ(d|p_GGg{#q4!5-8, \eq@NCE^4w]O;Yv{W_>~kp\\l%_o8=$ B;z< _t#_-wsD8f0pu~ wl߄mf}JߌoFNGℯ0uソ6ڣ1 w/0*!h=v6I"iB4kzYr\8o$l;dq\ypB0v=Xxs?Fw|n!$3rޛ1L#~/»`ID5,-57&|o;2:#,D㤝=/Da}l2k @i; _Xʄւiꁩ07l;38WX|KIΆhN\fl)sq}DvE:42-ekx h (INR`P6,z왷'քs82!pv?CnR8g[o+J 2b6qٛޘI`ekE|`ks3iAwknLJ!_ҏ(`QlgfJL\viYw3&EK6ZobycnNuq%e6WMKL'HmWp ?7Xh2#m$r* }%bOѕ8&? ( {!\R  na޸Kd$C7\t N:uAwGz903@=C侇3C [3v n%֐/)Ej6B6PV-]۔KB f]DDiA`,,XLH4ܷ/ 5!_kǽ}!. ={&+Oc_h`UzUX螩Dh~_ֲhBܠHaILe7CTVɗC^Xc;7KŰ㉎ܗ푔l) zE}r41y,u}0dA4.f؝7 Ž r?p) Yg̒g Ȱ0"G982ΞTcv>~k.&iZʌS`HЉH ٤#"KvMpݹ` mZ+'J#3^z\{nSn"cJ!{d\BP lqO]ĬP#7_ؔ̐}s"NGJk֬@c'o|$ܽ[E0)`l/|VYD3^8f9LxfS%HLd~cq(PE'B0rP$2LͲDg(ܡo54$0 m3$-a)#*BUa\ }{ sf3z|<<f ]~-Ύز 3n#oѝҲ&qe#.%(`6AdOAo(K> ʻbs%XhV8)C4oEvYOh"e;1.yRxvHĕ-{&;m4*4F˛Wfʛp焥7.\]}rg}q6ι4pc;5i',zENU{l]#X:~{I^1,r}>=Ir"uRwmݞ' D.7ռ#q@k$3C q/!Z~7d^vOyYg;ٔ-x],1O<}iH˴#7 o81B&bK#B4 KdxO)ν%F曐e"Y ϽsvZaygY͒sBf[xCƐL{PDxcf{$ I1|Z0d +{I D{ |Mo'+'{(JN:o֨E5jo,Q(#W}eT+NTo8~MqkȌTOWFc:~]A3i 0DQEA(C65/uZL!GQ.T"JUŭ3v~WVEUd$u:3KU&+ֲH?ӫ7(l~YӖb*Z]Y{>z~Wsy5VǢ`.TH]EU TUQ]hRKM9 lPYSC&Twk࿁G^_v Qal1_wn2Gm hٯ㏁ ˸˗8O*ó*fOǫaU?c2.$ *ܯj K8ID{)ݱǨMm2ѽcOe`(OSs8U/^Ii;*eePO_ YItcGCF4IbB}$]i/f PuȚTB=IJ>Vq+ӯE ~=~PecEz{%!Y_@g~ZwTCӏUg/l.++|Yys z`pf{QooY!Aj;_QN\RѲ*(/VUAY_02ZYQVD5ܿ<` )UT𷌸X%(#ŶQy>|QE,@*^rT3PO;iY |d`hR=bϐ=ZuV y0@&&w6bmYhh1Qq嚼Tw'%XQo֭lnXf-:.8zbZZ w*n,]Q5R׫DI-^ sy?шmFb<]>? \^Pf8 17UCZk÷TXIQ &X6N- ru97^/쌊<(2h-5rh%+2_;k3#삣g-p{\hy(E.jEp knn5Fz+ŴJSNF*xFj Aԑ֝*Jać |#-K6UϭNljÍ)( zjR1S ɦ.4w#Q)ͯQ0ƪ, jTɋ[1*֌T JU;[C9Ļ;w1HkLC9E:f\VξjX9 ` 4@'JKd=l) J Y-gck#pI2i4K]A-\h$I6WәR^ZkPAF;Sw5z-DH2sV5 |p{Ɏ[ߤJ2I(YꅁȊbG5"H^BwNFJ1*j Gow4g*)L3F5ɪuVl-Mרͼ6BJjr9# xgFn ĚTV`S˨gםd]ѨqݨNb35*zH(]/ HUboz2Q8eك'5`z*ECeq(;˘&kPD$Tg ˘oMX*Y(:jIinub[V_#h f4B'9dgWltלFUObQ6 0d=Ts:+31zdZ,}jyV9g;h1)V@mՈ?ի2?usVzFu~RluO$ h%o|;i& QjX˳dK8W_[HoƢ^gLoo5MVV ˜%+Oe(V%ZUo\e,jLT :Qn+w265`dg-Ϊn?jUVA ՇH#6Cm,c-Ɠ;uW%Ic\~ NPuŜ՛?C-,?FqԔ\hl>Zް+7n-PyǪ~ߐzkUD{Rʛ 5:yZM5V%zQw~g )UZ6[b#ݴw4ݺ ZQX}*g?і![9*(=#oR?-#,ֶgVeY0 {b̈́Ρ5j͜UFmhsUrqWȦJ#Z˂/VdeY5L\-4K4-4rBș+¿D[ AՓ^REzҺPiUEUs=سUd10^+_cUW욲$(5??elw3-5Ph.Qvwsjrм(XT7&JΚZOw,x{ ԙ\\&the(,bs1`KT5 bb8eP5 5A"84Lkn֔abvr.vX2\g 9;r,k[>nMsiLڍ{<~#K{;?>+u0)<@ެ/dѩe81`h%]+S,%ã|2쎳Ϝ: `P $AQKoK!己r~va X{l?vqLVI#1 /Zq&sNĥΤpp26]ǐڇ*36<_c2d36{-7WGnZvxKۡO># a ԟ/(>+'XYq28l_߳JG.sw@,1Mp:yoߙA2d,5%E|fkYyJhLY@6pa8x%D79.UBi큹oO+/b]Ԥ5kgiV&6Ӑ^,mZS5#"E-W견IȚOOXVP($|O? .?QT^J< kZM,O$UO=;XW}e1וܧ <-+s:%#);,):DY]ϓ=XX\oza:/f}??6 b(&d#Wtcq\1D&É/]dcsL拆sAic15 B|$S~~zW#;ol^$G1o]_L> 1g؀@zY{="W+)sGBazi('n!X#X9>+NdYDT!:\_Tz|񖞣%Oo< bZ=Jț#Cdo 0V'9&;ʚKs͊J`F!\k`߽A}:8?z>Ҕ\>M(B& ,;9QI,JJs( ;rĉ֙aoƊ(IHj 2d߰;]H\+o~SuϣBçD-0̤: aY\784\SBrU߀80 e.دXc:$5{R)6FD,qtFHzpۋ&鞗0$)|iy"dOxW zF? KdIFtrj+<@q;/gmbC/n?m>h|H; Y]'cyc)Wp)yE.#5LlFqC֢b90-Aѩ~` HH8dIK@ᔯ$ir!as^ź:Y"hvi>e$W*o*~g|+K"43sy&WŤ ҧKڹ}}j&%v8ǟxO}kS^[IGl|rE\D(P oTg{@ƙ*<&0-Z$biu";Lht0+~3"#Ox AU*qRTOQw 78-:Hᱡ1pĠ2}޿/ V}1:j.1C#*2PB8%L $*#Rzb$xB@Egog c3T=<۫f}ef_κˋ'L% -# R)4|?9|HѺ e"ܕ%r%n(Cw"ZRCd:{Wk"ދH>QX_-hjT1Ay6P m[hy02ǺFf? HJn"dY)٘$tŋ){ew:UBCZ }A~tP$ogwȂ07>3?IЫAfDA:PI锧GtȎձ!ՔCJtC桰QQZ ˃=-gX ?{`q-]@?&4ޯaI"@@{^}-g>{ Bs7]dű%})3fڌ0u oci~4F.5|8CP2hILc %٬ T>_iZ /Ddž/nn^747CO ?8RI[ =}gg~Φwꁛ~6Z>$A9(BX.Ҍ&y5IiLr ;לG&3-&c,E( HF@4: ivZzyr赿։Ķ-[ո(EBek zsk'%!L/?IlH+vi#\l4VP MS"z~&If.TOx $OqL 0@ (EAhl{Mܮ-cFx<"舺5SB.싯C۽x+'kfdIu_L |B^=difl"f"0*Nzb Cppt5C ѶQ Rs9 $#!M D,B R|_7n_u3)oVc(/?D`k%0^|x?u&P%yżԧ9?_<{quN2/ Jhc)&{oLяn,pӱL? $Ip Z T AoAF&@pZB<ǂ"@mK gĉ?>_u%W0SJͳρ.{nqa΋,|G)MBgΥrCt0h;{?GjəF$Mknx)%?e+ ϛx\{f~ 8Q$+ RBM0* z }/ щĦknk,v!F_NG$ݭ1CR89s_bweJ'w[7y٬cФVQ ePjc #u䚡ΗhtȠ'|i"Cp5B0P:PE&Pxɢt7xtZ!Q )\3GXǥOo&;2'n];6!o9}oZnʦىZ, Ǵ% Dm_%w]t??e&%OzO3rqIJ?N >cއe #G9(s΃ xHblh(L D@ Vʪ~G_&\-RJRv:[C׿{y˞gq[9K1 9b=GG.>ngޫ1>- dMJFqtp AsDE,8_IK yk!F%Vb(J?+"I*AS iAyEh)WaQ`nBہuW{= E ݔf$uZg+77,5&R>JXY=`5vgłQ0cJd 1>1R`h)#N@B^bPFP!DT^x|7.q7|?[{zIOHL' W{$N-38\.<Xz؜40 2پ q6kJhBShy{ M""E t@ G'jPIfs +m҉b2) ~Vw|Їk;i_ΛA\ 8%5pRfCœ.6.y\eKd1Ԗ򣽺)xy5ӝF3Tu }2S:s@?*x&2jDLcVJ+ yqȣӋ?7fB1)gSwigܧg?ϲp\/gvƍ#dkvtxx}|&0-5-Ǣ7E,Rfz:NЈIJQq-(SJe@0Ҕd)_3|҅^C 8?W߽n~xyS?9,ܼg@)u_⻖u&.{u卝g1oȯ n1,ӄ[*<lt'g_ pogh *K>F!i,IY yP!"u,gb򼨽y fhG_"f VhSCTNÀTO i x$9yy[nqazp\6IECwZAvb(ġ`ڑf\]1 4@Ib*s2SH{tV2Тhc$U FByO1@ [7 /m~:jRqSVz _4 n8$vhxAQ2<0썉s|Qeͥ0NSౡ;xrF$IBH-xARĸq~ %H&D RyR'䃡X]%^6h(6 ?%[_h"D&Jf3?yyv(:ܽaT!DlZ2F3~dC2"%qp@4UJ$34 :& =@1 vX|؎4y (V~6H YHp7#yE-ϣ'RAo~<sWR =?pKq7"pT (& #3vkxqYK2C)%\I4˲)WgSRwaLHgYV}@ HGM0 R Y|Ӟ i`M΂껨;l{^\rM%#oЊofϊgՑ>U&YU^5>Ӌ({g?ӂ6<@XHxdBY y)I1".Z~PHV U1sj)hq1+z{=2* DHQqd@Ya^$C'Zg3[E 95 5d;v:a X"4=RF?|?! =HbRɥ-7B&rw#dE_sƀC!KNK )\2kaa;B,,y̒Y<%b1#.e,ZS ifצUG]:Mx6@pfq} ߛRd Aj6D@24 n8fOҳ chS{!F8&HuY(d)%EfX?tRƳy[/J+_;>C/bΒ9͚̑9kc!ZL&$tiϏ-eo0ԍɘ@BnUӽ0:LCw-bAW&Ǜ$"x(̤ei\L@A,-uE0D -91ca(ˇ[b.k񿉉##pL2BzƸobBXL_ P%狿x[~y~ 3I ^:xCа0 0,]VJ}1&9DM2$y(֯ĘTPbJ(U3"eNO]J U?(cĿI2ӬC '#=Zq :_Xu3TuWfcL|a)Z2؇q̇~ռ)jz8'(.q^)$C!4G$Iuҥ X$ b:Eٛ bJF/" ݥ~?%d s"iOf\9 |#Z˻߯ Fm;5Hgi)/{1vS_ 9jR0Ƨ` w QU(d2YI ɒxk(ʨ4<-bH"x@4H Y sc24DBt?\ն#{>2zUsf)"/쥟|<cMOkҜ{vc-KO-\9%g-g^<5TPÒS2?<QT8iT* $dC4#! iPXy5U!p7JjB2-|"|X:7X-w_>և<ZsB?x[@ }X<@ u)cn>n@<9xw'5#|#1$GЭ Uh;iLJ1Qв igR&ARAӬ,bj`JpGmoK+JgE`p\$1Ϙ y4*G1sť՟b^sͧ6͛KC=Aa.qQޡҕzתu5H }JO墦IHcxE6!Z=Wϵ<,R^h黉t WCiҹ $iz-fL;CM-QY5׿zz׿n^;Hòpio͵MX$R@XnʋW:K k'Eq(S1DVKF6QZ~}-99J_cl[_#\uZ6i^Z 71 +~[T<-mY_aS\mk9BUk=zJi\l0W^EkDZ:]'I-piAk2> ,]؈(UÛf`FHyȂ]XH;[e4Hi>yѭQ oTbU;չ,MN͹'RHuJ3S'lYJf8-ѿB䒓 eܵ6(50u[-A&R;Tr $P%ǏT[s SwA+Ϯ6./ڠE׿8o:tQgh?WO5Q_Ӹ+_X-M!ʪ5Rΰ9N r*nZZbu5利++pSTVΑ劅Cw$E%#riP+ mumqJFUƕ#W xkG*[Xpf *[M;jc/O-m2WE3Sm.*qU7TTmmV:EƐ)/MkM̯6iwzZm5@mZjNP`NWKdnPmFEzDךjܢo_: fmpjPsį{uUMP۫=RFRkSk`i;X[{s[˞_ZlK"+Qc]r`/ߺzHӮSmMLn4EچQ="U)`jZl-VsTԞԈ C^natQ⟑jV՝ 룕\mXHuڀ)Gj5{i{@ ɺH*Qtҧ.;j3J-=/2W pui[چ-!2i6"\ZfQIn r&K?5hPi#G%G."FiUwQZHB nk3+8sk8\5TӋ eZÕZtr0.浫YyӲ6ek+bH[{XgEwUU^cqi>\uYns:+46#n:(9a~ˍm:'}fhxhGMZ5Z*U`$ Gגy+Y5T7FuhbOM2,S}Pe( + p⦦PJfhY6O.q-ո^[uA__VW)WQs1#-էUƷw.A.IX'`Su\t[kk[yLh'w2~E4n&O e4@uVrmVھ.trX~T=uA\ z)l0~mV/T")׍XŵLb:pwПtRPb%`)t\;qҮ5zw7eimW+\fYUX";X-XӢʛZ=%Y|ˢNn'3Gk2>R"P{E*6RcBWjk>ՅUY1\?8*~$RRe)^Q6a svՖpaWeZVZH-mDk鼱j8N@tƺExTEu(׊+c#:a,H=^/LU4p:/@wuWRL\MIOʯC[WҢUtJ DǾ//kȭJ `E@#r5K$zmPǖ;e幅c<]ZD#Në m?u A_ciÆ@kiVN:6REW-6^}W;,&[;B%|Oҭ /Vv~Kd6_7k}M܎pcbg׶'}8 _e0\zO+d_\"P t ϵ~tw-xz|řSÔ8%\Lc!+F\L# F4, la ۰%8ci$O!Y†.t-lVJP(ʇ)Jk3WWi6-H|K1%y}ޙCU.O[S%Yq'.xiK2z_f}^OwG 4{{iwpJѨ,.[ɾlP;99$Cւ@m͢D~[!}=aṛAp%E#) ՛3ciu@ǵ>\Py?@hԳC _Kn}:;mpg <۸:c:Ѧk\'ِx{p#D|pzXY@ aˉȚF"@1$Vݯh(|B\@ܯI`,([m_9h^~{zh+o 17yg&wAu޲{gKR2H=ҷh- oۮk8[{JӖO}g;uL[d(B[;XCA-zCWyEuӧx((4 H "IrDD Ad F&'Uo_W4:=4V"]!KPkuQeTB(r$QDLhJDLAٔTї(?0Va?$%W~iUu#T nW';+>h2ь>}=)xKMx }x %俞?S7}^.G, D]1@* p}zMH yN$ 5A Rt?YIP`$d$C9yI(`l{6 4'UǿL,Fz`4+wFt١'MGrLV8yLZ$>wɥĦyJ^uq7^}HXqfQܫ$ RXkiSʊhз[QƊϟLjȲNҁ׌ "qQIL1.gb\BJ qi.OZi`߽:|އTwZ>jH $65-yG`ZI`N3Wi,fǾr[ys9 &4:6w[v{[$D/$ qhQ7"#Z'ʇ%+K$YAJ,b$)@IN5h;67eѱkw]!2&L&Ȋ|r:׸Kz 0\b1S&G[ 썮#h@.+Y+24D ,&,`Qc/4b Ke+J:fLe lҖI?"t]Wg|յ|3{+ڠ7;5I s/U1č\[=з=  T6؍Rڻ)ա4=Ϟcfdc 6@ZM|AQf5Qml$@/a7`voSDg$_ļu;(r9>[>< CN0SONx_~+ au2x<&VDĻ3m~߼?*#6B bF >. ABd a);LBa!^QXNKPyE`ҭƙ4hA R$SJ]*4_/)@+\ٜwuۍվ?S6/hm;?ԡ m'>Wf7if$cաz30v&}f@ +~Q6gjk=^^"huS/#Pj7!~00H8 /(mcz}tR9٦Lnnӂ L_~#{<:s<NPpXXD W$u]w7 @ōL80HGd ,' +;2: 2DNG:fbj@s/~^k{ijaD5{HM,]ac_kYQdig'~v^ۚ }|kx}\C$ /aͧ,, VSQ`EJPESeI  tKD$H0:OMPuhH5#LS`r_6@+]^GG.*`xK=Ѷro~V:G7*}T{wiv 6嚒~\!e܍-O,7aDb2[܄i$+v$ u= B*Y˒ixqR1ZџfsSVeFHom5CӇ?V4Y<ʩ7~o6iH\+k2y}Y˰$p3ȶr;P3÷L-*|{4E6 >5TcsWWve3@ GTIVl0*` Se-ap<~cRe= z>iq6i.B!j|aK^|~Y ;_nֵ ˔N3WzV z~:iGћlwmE Nj*p ,̌ +i$ 5͚Hq W| /:P1z۫oiۍIMK6\q!{l*24koo8=p-nv߈[ h>kh:,=8f">՟@uCc.)Ix`9O8r7gyeH;B"IƠd4,`bA9> UU;+*V=Dȼ~e= o ^\{HpLktK~fZV2.1>9@ZRdP ʆ$cCѦ^ƈf lꬪA-ӂ42O=c7wB>{O|XͼVskqǣxI` $f4^껒yn5Gg'v.} 'cëYI`_ʄOk`KxȢn?#YeJ)AJRVɠ28ɫ)º˜NG2й(m.Ap&v6Toڤ'| {^gY FnA/nҶ\<0 k.XvڮǗ.>9&xM-yn:iG9#<`d- Yn2:DD{YHcE>0/~S"ocT A()@KE<]T4,[&J0M8 20X]^B6Y\lY}pcGnGFPpS}Je}~$0t|kdqSD%ʗYtmxH@6Go7߆suL C -?|O}L3G?Ϟsu>iS4U7ym-W6{`NtM7[CMKnhNRҌE2)?-n,gI4&gpH'$dI<-1M0 ЕJPxΟGt׎*U_H.Zm~;K~:Ki?ȃ8r_׉tݷ5]s8j0"JaKKqXi'$Y(!ᱠщ%/o%)WXULJTKQ,MNC/a.{xv_G"|v'QzecM{׿{k mWZs/ f+ah!IMbB<ɞv9zHczU@ `%>cIU#H$f^["LօU%d⯭]rVt֫TAQphvEusS b:'v,օItlji%GYJǕ?KZ’פ xj?yoGT*@Jiat HPA]~vIi! Lܕt S"Uh 2a܍_hvd߿crGhI:hO>%\sNnû~ÅF5~QSKLܩʣ^FuN'^gݢy#--bU-%4Tc(aPCLw _}h '(TO撖`҈ e c7* H0 .-?/uql֫']yOWV\c)Cveً.C箖wwK>fܹ$>_@f}D>-cݷ .SM"2- |g{`2FUX>% zF˱%;& b*>+%+A.ǩdD(A*Yl;\l(?Vǿ3yӼ 4Wޟ!?*j^x>x *Z 놖.xߥ&bD/]kњG$/TqPU(-Z#iCǃ)EAsJُAQ aЅ})YYEkԿjcs11m|Ay~a ^c] s>7׷[3ΒUeєIIOxtBLyD cXT:oHTNм29+eZ bI;ʃgcDi"/-bTu>M5-@,;_I_DV,R/mhrþw7 {mvɼ?;RǭCdP!`APS(X,`!&:N9NSUQ!'<; _ZfLQ1Y81XL <[?JRD/B՗^>A?~͝Ԓ:P(Zvlg*xϸN5A+=ٵz~M4xIyFzAM~&r ao,308 #hJXNP&Z)*e < (xpON*C+ $E,SOՃ"j,BB@cKЕCwQDi.̈_R{:K&L0Az^[߀+Bw\>&#dh U~vJ.[癿SRQKuLLnoGv }gՍ8(Ŵczu9/y 16/IUW>Ac&?$}qW" ? XL 7$B:00 ."V nu=-ARBŘb5aah/:YgܷJG}}7qrE~"}5TeJYxۛT4Uo7٦v+ v{Y|\b!rKtŋp \h`污ri31 jT[$D51p1uu7"̀$qSy-D Bi4^lҜ MPN­xڎY?7u+Hv?Jus{.˥ܙ6*G]$0h83<:$*m ;p+"2uu#g2S=G4_xb#q^D#\*}DOe:0A1%ۆH1{kP!|7|Ph?ב򁉶# MKSAҺm /nzϴ/ruzk"ml ,?#9L6PN~ȄKBN2PF7QkR\J* !y/\,Z|j >)&ZR*#A 'u/(Aݱ6pyl10ֲί;Ծpluk H XhG?xx˝ϬbM/emx`@EW b0v ]w RqHmTV-O:@O a,$jEBR*O:~+ej}P3L.;o#rcG-/w1D-Yڒ]De#ء9}!0Χ?xnÞxB ԉV`~5L%DZw&f.ы q`'iF및$ EeEŁVr<5m':V}3ٟ7811#g~KL;F;-y?9]upbb_ks&8N - "t"FdZB,rxgIsA f0-^d(WEjR TOB t{9_6sy+#fG4ndFdul FE,][U{4 lJ:-%S\RJ(tj{ԁO@sn n"Zl(%G`L] Z)R勑Brsu[C|M LC.WTG<;y_?|ܹ7tSgP?Dj\ІTMIsPvx*@Ro+~1a@20LCK@ߠ6Sz;O~/n̛~.ǥw$ѹ O`]bif&2\K_"y n̞;7.(|ⴚTJ}j$s-*.1)$28Q夥YȠL2-b0* ö?pՠ9zop{A:L[=%2#|S}D ֨<ufgߵ ( G$IB*t5I?ۯVӥh8#/ GHp$ߑh=h}s{UeP>k+ŋkE BqBŵ{Rwɋ$9sJ̙ܶ -+9_݄{*/,A2H-JW %LjxiC KF˦ZΚۿa;}.rhf!j;f9+e1RTX⒕0lƁ u6{]ER:+#!oq܉+g%eg%D& a,BU 3̜ N)} ^nW -GKo #bjsΦ#Ss{y zYsNKi;?Bt`")Wj4A_"[gUR*5mKz:fᒔ/QN+  iICr 2+_DR>0NS~2=}4r9GbOcېwZz 鳽$lw{0fniwtb A:禘X4PE&c Rlg͕) 2XB ~lԕLP8IɎthد6EwFZn A;A8T[ҀVB7?[CԤ_z<!:.0g!n|Grm=žM>dp*Z9`spGi h:ơ5d2x Ecm;m;-$yگS!. &h}` B۫*Bݕa@ ``鹂w[K2L h KAsEgFR $\ bYOw_ȯZfمCfK}D=~+z|z.TQwyLHzdk֒D>5Eo8o˲fz""Iɞ+/I2!^X>+7[&C;D#g=AO)K xRp%7>g7poŒu˳!NO͖ާ`A<lr® 3+{v>|3&U9 9"8݌T ^4w.U6}p`xh?V-nӭ'ʧ}/4\nu ;ol?BEfA UZ~װ5XiwLͫ &2,eW>x$ۆH A%m%y4>҈d2{o 1o"/2b@v CHtCC3IE=Ϣ/!^|P48 0 9-+x8"*[ߘ$orQw!2#T Ǯ;,]d `k2V$ʼn8h[sO첐̡}CY`5Q5]r;b{AZ=<č5ag>ޟ $n'Y5kFgLDVbB ^ l!?|X Zx2С;0nE@݆:yS-)\a_|<1qxһRqEtJB@Ϗ}YT]/SFdޔw[Wե ˵i­cQ[1)לƆV-8hwyH'eQVԓU hqmq]v+o[ U/Tj],T_^Xm0)*Z(&Y,Qwi<52'T^]Y2ns۱aٯ;ieQY}&1]_5Z>$N;pD&j`Jn-(XB m Q!“s 9Rw[2^qs6&xClCƦ;%  u=&lk]J׵l8~u+VT>ޟ;hJLz׋5ݔ7nݾ,bۈ4?7s:t)zRRV>mhuM&2a)b IeDha[86ptw}j&s7b/ ϯ1상ODjCYrr!./xWVD_ lq[Q݊8aTdL[hmGv2j9ᛆ8I/yT8=V-u%77ILPJ=C ?[`ɕKT|1C/X 9+W1-B & `-yc6xm.*8)[ DH\gbLB%$g@6f5tM!JDjP.E$_@&ZŶXo; 2A,S XWea@E pְ~8œ b %i"i꭫=C,SuPZvւkQ\v=*)^wiDΐbo1+''F -IA msoxt,d)@Hڳ)xyby]Ϡ_fd؊Qiy? ȞHHHzbؚ<#h3 9Rou1Ⱦ0:OƦ͹xQff0嘓R9R`WFJ6?fb͏ cbe1\sJz:AcƆFfqKYq";7_VEm^q.݈ϙiYJWz@7\aQ_'|@ 5Nছ9)6to2-=r8of6H=w.<~H3jY 4 * KU:y'Z؏$?wϿ[zZBvs*p杺Vpn*])k0s}_0kO=wT8E$*u`Yl1⹄tJE]YM.mW~g:Mj^K!U9D1gBGL;ڮZ#/Ql| G!IZsh!0-<v>ي O ߜĪl:~_yO'D#\MJbW8L|Z):ogW 1M$FeT7'DdtefhBޡe* 2+M%(BOGH BE,>1NqZ _ ]}# vdw -L^`I5΄"$cBN"+R?ӊsg|!)o 9(877E_ _/Ҙ85YSi|O;)$>)o=WRz B et1ZnY.}sȥ)> jAX9,xbމSI ]<ϳ!(bKJ^yy %}.wB#{mPP UKJ sM蝥YOcxi}PnW$"%/ 2!䣙oN jaL-~?dLuvVF%u_#1v䈪/-zOz's SVaM0+ڔNE5eAn*Dz%*{8o>% qpgw_v?(ׂ-'l Ҹה/aWӌbdfi>k`08wc()_E} ?`TNlo*=B}wo:᷍f8 _Kac>֦Y?|Xy|mQ۳x% > %WJY2p =+! u`M#3WA5;wwfmT|u`@ɢv_$;8x.a5:m$=dEvx{@S5-Sm up>@,1Enȧ@*bt,׆8\!h&\o\;#/a ^R;fNb]L "c/qZc%gK'#>)@#8[3r+qָo#}bݳXlf,0>:-KU*D"7Rl_4UlMUwx Aj C `?a,603.QS) #?/e"quD8p^ )8eFl[6=xZL|!x¸60 t{?{1c_wmkO ^ UK*jUi<{H!*(kS0.FAeWn4!cB.VT\cTݸuE98X/͸,WY"*6jș),;)a5(h8.|)SeF J~ ڼzp٣ύ)(i&eP8ёFn(#۴::&n|dJOU\So[.4`+j骝>h:ނ~H=Bښ| QVZ=wþ4_]a9p{7WAȐeH drvSU>N2$=pIoY$etO,?\]3w`aY, <'P68 ̵^$>Η.6i&vvߣ~Ik:gxg[[LDjoY~Aj&r" _iOܗx?&YY%G7M~^ D]Fu5q!\>/Eh31%貗c_{Asv 䴜/+_YaC%TuW?|>\@/idXk&dRt+΄8iRblt# B~I-+)V(6Ȳci";O @&,4"PWND&LDCR7B]UDɉA!ZFHb:'; U+U^QݕqS[$BQ v,:_^[(ޜmqp` xJ KgQ'LC@AC"Tfra!fn98 v oQ.zу[ɳs(+pkE#v$WBEe9;;;5uQו?0GzeK\mn;1(YkAA/_ 0nϊj$Mo| ԝپ⯽GÙZ%o%Cy%Nef>TcT]Rى 8c$ CtGbElfζ x?n/!:mk(X!L^,kzg_GW>2gsMJm2G ήq @_\{yrYj! lVa dqtW i1MHNGvUR[6b ={2[|`qJ2 L OCB;s5/Ɔ!x<_UD `hz+phM;eD<{ES##2 .| %8B_AJ.旚x($0^s8 }x<5~Kgԡ??:wcp]bD՝ BYfK[!H kxr~؄-pE/vJ|h~gn^QWY[I6gSAҌ#ָvU=UW( Wԏ%F6 &*2ȳD }+!L;yFK8dY6@&֕!< +ʼmzRzZoQf7a"E.W=Lˑ!K$ Vۓ J>ʩg\$8}.ҍn%`[EA+0?r!'Ιk9s/:pS[) I<jk?fűC dTfzS_UYG4<$Ш>1E9ꯑH,_Cťʹ669x.3)UEMn|`;S^\JT$  v!Vvj[9O3`ϻy@VwA\IOO"7>]aUaի!W>ĉm?_) yWrԓ. 2[.@\0g^=7|67%-~ `q˄~{~×l 8`xS ",P#Zg N? aơ i{?Qq#-p{$}(qh%Pڭ7w'JjBg=~"A#F|4&GEe}|%Z N㰼4Ajy/NCU[~I,ÕTTAzZj4{ [w=)VS,3QܽI@väv3&Z$LbJ֠8va U`l x%=q GRh52FEZ \Ô,iy|B[fb{x] /T̑砨ء+էjTpS=4ё5  _UWJ)+֤ aSxJ mX$)>]1f86.`B)5Moj5, wx]6{nm҃,~y?(m1\:ck fr6PlaG}oˤ\P8t8iI|ZA $NN'TjR )_阎vՐJ7jJ5d'bKe7 '31SUA]rٯk r{s B41drP?Isg v0hb =R8Emʂ2Xt`ec7sUЕiFOu(?ɖ:}O"aoPQ纩؄fʼn4紨Q> 1+ptUsՔ$9NfuiY+*q@Ag|5Eˋ؋,ሇ`w -'j|kV۶}Uӏ_CQ'>i Ok=+Ѐrظ|%wb.L -4z?N֚eS Vԥۜ/Ǿ]]H@Y݆+",rfoqO48C9y2@њ!! (N;&"RB.s˕U!`w,@_xɿPhk:v>|wP'f)xŘm&KMU>ғ/}͵ uvnI-m*Z${}P0V~8q^wڈkd[.fxXmR&=Pܟnwv|. 8uj5~]n1k 2]y!Ң1'_NWN bҷv̶X=>f17V ģ><2)fl {PwJ Ja_Z֨x-iZ@Ia`Lq $5LBMo󳋐rD4sCj|qNP{`'dh/KVs;+w@Ļ|o-m7{&@RA林VU1-oJv:eUiE]ЈCL {j<,I/yYVkFAтig?\tulrZj݄d|A= 1gmv0wfzz{!RSoq[4Z&+}D193MwUHpwo bHM}knp"B&Έ(.r6y_k[B̙ĺAEO9Cqvpa) {]n4=稴{CR.mLRۙ|q*`LaWzkp#@E1ir9pADܳg9(~vC[S5]0Ǐe!*sI?s{)9I\lW ʼ޻FuGJ{[;y(7=(&O=%N)@&&mqOfi][`?<ǰ2zzzYWWd1&a/}v*6\4q3vՋ#CtJ&$:Ih9CP *vԅdmQ& CGpg@ 7q.#9͹E%)hñw~}ΰխ=;Gs̠jC M9ie)`()VK&-V{^kβEV-%Ū8[)+Q@Raф_vO1,rQla^'`fI %lOsFl1N6{v{g eoN K^ʱD} p\nMۖoqZ ]KT~bqKHJ+qhb0fg mmCXqVB!gz5"!%w_5ML'-J֣tdmu}>q~Fv‡5l9|ry(\b>bO}1aFs? _Se>~ {SUi7c;g6ޭ3-ilϲu oAZ)O~|QłwLY|˖Yz6ye~qG!?eh ÂrD CpfM#&<9ژݺϖX˂zҖ C&6qRV*Zp+bI4QL)Qq2S:T`jE[ jKjW]a΍'рW,WJ#`rzi?{^qE2g彟F2gZϥ}n%""PMn=p߃h}qzO/ B Id5N ?ʃKl'z<ͺ ,5׊ ?AEtWTvY@vu;6WE3 M[qlD9Z+ů5)#bih΀z~7+ 5ǰb$UzMpyVjULb u,,骐O+Ho7s+Yu[;KILJ7?ň_ SM \^8]U׿kv;ԫ(ρ2X+7Kkf)tu`QT9[%q:M'W]Ѧk(Չ etxv^G.[nlԗy_wZMJU" esw[DdE8D7@}+8?<81qv5Rk mqTõSZi-O]~]U55ocaUsrK2o-#(^s bW:VU 86 >= bRG2ف'*1EhDw(xIrDa±t^=kgT6P㸭wϥ?QiW.ata{M@9!NՕYBII+hI=HD=Ͽ7ˠW_:'r&Fn#|;ee Fag%N5 k_S?WQGNb(#'xc<5 ?>Y6E5uS4􀄳2o6קE 62C g@uAV }p=Wkݩ6M߫f|ܥyYQ.}.Ƈݝ&\`c׆gԗuRq}-ob& R9zW:_x2:(1g(Q=njD, }[i?FB:QO`Oܩ- e{b?+YᕊޟOnնM\PLY۶Fό{qړ.^,X"Ov qiH,ƓF=PY(K>.3ݒ펿g+ÍV&qD8t9,$G3ŷp;qew']|y@ao'xubg>u6AK}3~ˆ5$u]|; 5O*71X;>{o2Ϩv>S$vq:GJrZ|k4Y۝q <2iS]<v⻛ROrzVר۳ $9<$dnۮSjtsHK6?AG2to|>vDs&>`1}YhJ-6,YiUD8JÊ+k~Бѡ}$WTOB Au-l^͑yدMe䧲ԍ 𾚴5߫A38^zf5ewO>mLV |B [lzh>q^:`X\JD9`Pn+zmE@Jx͵%T.l^8v[n|VӋP:kL-w]jA<;u7zR?P `ǝI^l4$iL -:\TLJ°zd{ )fVJF!RlyII֤[~W,ITbM+&Je 3Ny+#&ʜj'QVG:Od+,"_VPK ݞ֋=v<$ rbPըh{M$:HAL,C:TF¿kJyܼ c(U]P%~hcڵ"lgltC@ 9-C67mT+%^~u8f=6ncuGOgt/E/O{tGm.gv:7ٴO:^]I;zJCup(B(A+>~zI7wܺq폆kHKom073/?~3ܔr}b@W3Vwx7䱇\Y^QQiϢqld-tGj@}M075˃)4ɆL}RdVW]gIcyced!Uҷ<Jv]Y5!c$cPThoiH?fy+ջu ͯ{ռëH:}x7C;{"l2Rk1z\iK~WDodP5x9<JmUy5}'Sb`zu%G8q!}kL/'PΉ;Ϛ< YW)Xo̫(P̮D*V4x۷izpC} ik@?ǜcm8=u9Elp+v@j@N`tgmwNN'G $uw6\z80G3&8P^4-E~GTuPsR2ЪPJ뼽tL B&^W F!wtA񗑿L‰ ǼZs6I~j}E,Rg6_U鱎=3җb-Wпmp>yvUiTO2r]j vᇝWpBi7[fj?c?2IDM}kH@N >O! D_KG!>죃{84*::HW9Cs5hΟ3~1Cn+P)!&9Χ鰊8wkSk| +=..:4 vUÛ+wԶAI),Һih.c͔u8!Q%i9 +Y~ !1+̛"eo@"p΅f!X68<BgKq߻yO03R[ӦG%gmh rmgI;ŨyyX1=-f?W6aF8xc]<)nDT Wwu.wSO=^=8U1qǶUHt!96D$MI$ }m HTxQ#:qvۑ 0><9B6 #\R> KdO3UUr,!@TNEY'ѷlk'ï_S_&$q`jNHre)Ͳ-bYU7Qw\#gTZ m4qЁ=y(m A}=ҎNB[I:=|+WVDnbSeˋT%Еlok=5v2.G2XR?H4$b{ژRoYU ͹r]}i)b*q[&!mlPA׸wld75NGdz8h%JV#<dٹ$nw%hlM_Q?62 ʛiR"HԆkE]\AikrAm y9&_fHK`5ƛ*Pq#FD|î~e*|H&6?px5$8o\o E EIug zm@ĹJZuBc&DO0Z gzʴۿ+uY|DVVrF 5am_@p9+oiwkٛcc oUB q1dx֖"vw gZ9i7Gf2$+y*<;9]GPIfz;c8A>,X/z(3G1Eo3f0;x$v"63qxw1@ыx |ޮ'y5bIN`rMU=F] H_{l77 wÎr4yp埿L&0wp1a|+q:2Mqg/bfe,@V݁%,>֍)ﺫ-@ZtoGm -0%IXz/$^"OvL "MEW>F sӭ?옝Bll,ʆWa:Ɉټ\"U )&aso(⾊^+n5_ $3W.s*3N^t=Uw&w H$(th_3cDfȫtgNLW9=~gI5Rݏp$$w~Ne7{c:Akw >H*듹gRyX_*I7-k ۭ %[ܠj?&sK7(բ QHپI,:6 "l,{2FdFvd0# j0S翣 q[ک}47dc?TRv 3"3bs2!2xsC?Te沰Bƈ /Xi5ʬ ôǦFAS%[Z^FũU,D9 yֆ{6}rne\PdLsf +ǟqHyǾ v]}86 +n(MQkQx;&_46reؖWΨQKwSVח)CI&sChYt'uɚ`S|\`KSo%;>~iMgKavKZ@l?`uk PB)*`JǶ25IXToOjt"YC#LR%Be#e3=qBK Q`7|jE`hߏcrk~&_fEc1cx ק:~.>py*g9s ENkְ$sNO&}<-=ݠ6Lkޡ }8n4?>+boA]u@R~OW҆@*y%s<"9~<}<]ZC %_#d -p>U=Gvڊ*>=i|d#[I>bI^J1_`9~)>ĿvlzQge(ͳ3o{;#lHH8N7A1Q2ca+&#Y>Nx>-6[/жyw)y[Qu02:!V.$407@&9S`jo"z!:@x+sw|y[JHd5*>eπJDjՙW:8u$I:8'$ՏuJoB2.Zw/44Iv! 57/S wM^'[p0?bV3o5!?E t6SU!tPT﬇ |ێHk JP xОқJqs`{0y;Zpx9Ҙ%UF&v+ +3m9 " eu.nvܡEZyg8i7T;w;'B ޢe^WYC޻jc#EP_>Nt6'rV9Bz?܁˿S` FL逡!|—Ke\l,$; ǴNC@u` eJj 0OTYHۣ{hE$p~s@[v:̦Wo"R1e br~, \{^,{k0^L֓Vgo:QqVCqgүu*0+s /TO8qUmg\9(X7Q [9ǻ 4_ ڏvUݭDgA>xfQͻm-Ö0Z["Oo{QDOA(,!f, }b8\H$ZnVfr7 HG_J6Ǔ$n/ͫ$풥G/#"uE61fHՀj]uۤmό[i77,6xN쳝rݹ!ʻȳԯX.׷0DhN%@[ kؓJWm(}~̑ lb,/]Mm)o#,O>~ם ҁ%{](`Y#b ɋ_ x$tv\WTW?vml~ȝik"(\텾߅jlT`8U㼬Ae}Y]"0B/v3ۦU X֏=~gTzB1sN3Wi3fLbq'qc-[[lvo,P77z@n0g/Mtw18w-sW3=kM ۍW"ݘW!^83Fp 1䄑G'sAeJrxP{P+W "M$r6S1,&;ht )P-ۈm^ɄKn+YOMKW-7|DʍwjqBTfW8-|C>i[j̪Y҇Q` OOqSa}lB;=މPg+cq2aE6EqfTs@8kgb./hqk5qJ\@ɡ d )\WPa4Ɍao|Rl@8.[b>>`BDMbk^9%Pm١A,ʞ5YvwGh#_?4~`DR;*xŬ^ #<5ܩݠ'>nAU2,W|mxu& My͠,?x?,E<9 <3TB@֭eCyP%J#C=L3TroH8kl5h B-dz!]~l;2ҸۏY=ws qLM0g&"@{D꿈:,dژDPun r31[O.kc$`}| (p0raUlzf2yFwn^{O41\=Ϩߋ;uu4.Cޡi_z{f$ ڞQ|Z`; ](7SςS{/N]o#&9GԎV-VMG%t%)ЗвZ2?8 [JtoNC\KUv 1ߝ;tPK'.{q:2zCOš=2I K1P̈V<2vmB|[OAv2yyn;rMdCWf@.^Αl/^/ѣ<:1_Ծ#Сm kѦn>̣aণ/v;7dOǜ`xi11%>Bk_tɯNcA.63xLƖ(ܲ>10"Z7z|D g^ L>C ekH"!վT'TPf1ԘPhDoc6],te %gmhZ(Dd?/?(3隽a;R0생taOnn}o~C>Ҍ!sҖiPۚ .j۱!-̴Ӓ|v߇uo+~1W O:j P#50XS|hdYJH|?t_`9x#OH|01 ]_UL^#'\}@YQ2q-{# +4 'abD;NYaN]`yO_q>clã IG[[\ԟ൝ýέeXWx^ f+0GZ֫,UFlj;,{,7+~5Wuq ?c1ى3n,v3V}w^ >  y\":zi'~)&`}B1ֿSCԴ{* l4S󳏥4=깴(awW.FL#A/qsx|m4Ji|Tb+ji)C3Z$WũSn|]):6UoFTzuN\}e퍐="!F`iʛA ~^'c.fS "oih]X3? ?{7Oo+K [zd'W qP,ɒR|L,9J(izd,O(57rv, 񷐏:EYyą^̢#d>3g-}9<굔鮟$I+,#{Bs|[TYg4E8|D[ ܫ({@iBy sR g/̃/`4?ov-H)pQ$b53,y!^Hd .O:cfJ^ ٢ۈ0iBdfcUhyzz7%c,'4xe,7ut>/lp+KIw/l}VJh'Gzq#\hW}XlU!F+]-΋;ơ]lT1)U4euٿLYMK12 + ǘ0!\M;M!؍~˷XҚЪOӡX4fݣ&>=* u z;tWjOF*&? ;c? i!J5I*y,A⾋Ц#|O [@?ͨol>'Jhe`HӀI@cB OgBptJK"LZsN_9gTH'fHɛ,+ V㮀(Prr^@(͟P7@h64ٔ/rLq!.-@E \~_iS ČXȞWՎũ6 Z5#n~03ʹ,kܽ5[*cJ2@k*l D)6J!UݰFo1ƞںN\E<5}&~7|XPLna?HQB b)EK2uj4 2X^,Sf4M˪٥V]ܙ UScql VOΐHך֑ 4fs bŃ0Q_hjs:w'>n`51q TT4<:K!XSKĝ9h͓ Pkd`jQ[ຆz!u- T_ViՄZ8f1+^!83lsD^4KZO6z@ (7˜ziZ/1XX}(Ȓ iS(`.06՛;=DIܲ~':C]6:v/tZd*Ay09kl*mL0t#ͩ `)! ĝ峦ɚ-frכR1Cu,"'ʘ{.%a5}}($s')Z7>"^Cc_i ́ʮ ɿ#]6f%͕`:Nsz?0~քn6 Shm?[,VƳ&3^У>a|Vf$rK_-"^3iX=n=iW@ӷ'g^T걮VW+NtbSpzO$tZݵQ@pz .2v9Q8\^GG ih~d?E0`q0".uh(t8*:X-{3Siܿ L &ɳ Eg?g>~C7JƆkP1z-kx;̞|M_b\u nJj;!_i$e&p4҉#r2L:y^(Ňz3׸KHDLTjOk\tPS %>D]c Eݸ)\tMF2T놻&uO!T%it NP&Vz*jR{jV՝̮;PgtGO;,st GPa]x.ڤO ;22 _f /=R3^VyvpyU$t)9(̕uN \{gɾ-u`%MJި_\8r"RWe4)4\X pƙKF,݀<"Y%bjJH WbVa"ߺtz|XRkӼH_[m^"u.vsVvT| qicY>YH}}e7 w`|-9=!ӺP4Cff>VuݴmW8d\UMX&2X< mn6pݱ}_" ^J}1n||-=d}La(-js#M//6mS1\b] NoJmI!sdq1NN";H=ڽ-nm6vڊRnV_T V[,Y4Q$53oiI0hU{ž)`FXI]dqv7.r9(ʿrTf󌐞"w3 ciUA^yǏ4=&_.Iʽzzqh+Em"{!NJQCr+xFO]&H=Cλ Ƿ`7 v /e.O( &btL!7֑ٖ3,^D۟'z;tKZsݷ)QNqe2QuE_>oM.(.owzTQP;y핗Tth&[u{zOq[bhNufd(놩0g F RZ?' A_Nr6;Ik6jtX<-(τ N{'9dŻWR VcWDX=L[ m#en5&~ە?'RwXc v .*Mތb͔TUDww$7 t*#xV10Jӻ7œcqy\I\~RJҳh,q-WeqV[ͻ+%Z#b -Wan6S3+|SewBqj]|3DX±?I r ߩP͌J/J7AL=V.D- ^tV;H+إʴbkbBXBl +}gȏ-_v&;vg7hN#$cˋջx<,0y eᴬ7eeh{oKfr !KcKV9s_\WDB:2fgwFUki5Wޔ!'=$, Vej^RE'>n K=n}܌՚{MG? (u.5Biޡ B5kKwiO'2ljʫgSf.0o #{/hE'?[z_ٟޛһ{+׾Ԝ :فI03ĿUӼ+pgޕoUTrqO#9q5.EA R(n<# $f|/P6ȱQcHcI|~)JzI ΫT9l#c z\3jL4=Ӛ>mmVgד1oJ(hxp~X1-!w3 3zi 6$QݰOmtG _k=v_UqUZ=P2jR&c~ˍ8xhA)othGAGEB18Ʃq+&8sowM_@0b̯ciE vp;Wr ΗI{+9}GDFu㋞h[% Elw#.k#+S7sxp &}TWv3Seq]g}w[.8lM 漘{?$] of/jԺ1{k˄P"Ր-ɼN>|dnjiywslOX/>+9[Ydb-LK?̅ jUQ\s!؄"&7 tcwQVmZvt2%̂1$ݾ?^hJPk;55?mҔ<#{Bx :egé_H]ZAO^)Ufrz{8 гm4GS3\.:+ AtUczg3x>/{/ȬKw$-M]X{e_ ~ >EetĪ(lf`QdtZT2n U dx_6w,)5Iju몪˃_,bl)K&RFfy;Q,WONJCBGA6Gח}.=tK7ݾ?\6ʧڹ6xIV/?u69lzBw5x~U|\-?$ʦ;ZeZ2;'y0m`\b:$奃Y1˦VMVs_1'n«;^G @AATkj18tmZ7Ujեk6_m =֤YO(u\½%>qgX5e(=KdUoY7qߗ^w|3$hG5pH\S[UrxWQ'%}3+17#/||q:&NzoݏC-;V+AmTyw)up :k:lW~ +8wqbHy) 9TZ y,C*cg?iU߄jH!m[x?PugEǢ»K6s$`֗5CpרݧDHuVbvzMnRzr,N\Ge$ 6{ufnK[c\©- m tJWBk:[] АSOaX Jkq6Jwn=_f}jO\^7â7@軛t?czy2(HMEpwC';)B1o$ zyV,u;[WV9xy$2~$uƝjj1xbV;qR"?uh#3k҆K/ h3WܫO]T 1ܲ9UL/oqmW "p;gx>hТ$ά3 Qڷrj/ӥ%B29a45ө=vL3#n' x)t5b{[O=i٪Jg5zOиaTyi}jaW Un/?/fռ4xG5y; t߯i94mN̼7\!Ni^qOo) s@4M;J<R'e  {S巊r`Рsyēy-477PIv[>I |pq{$/7kMg1۰ht sӷtc;XcՒRbe}@G DF̷Eey-p;6k-B4^Wĵ+REbojyAa%Ȅ(‰@vɗz<&pV>Hv9#k YZTltd PQUQ2T20z(Y}Nɛ --[1.I")3Nt$S,MJ}9$vN F6¼ q~&0AЪh|'x|."n3$+Z}DFU.pNO{GBߕ|nj ,o2v@OK;+%=A?!EPl˷JzK;kc\E2݂cNHFvӘ%ѢY#W?+H3:d(2dJDAoGzN_rbO_Sd\L~ Ԛg4{ BTvmuȊъ",H Aoſ?khEd ,,tï%IƐ4Pq7oG^c;|H7+/T14dpv"QX|Е jUI8I@=%Z>մE11!;Z|kHT:&D4}kAH_T^5~%ьnInW&sIѐD8>DT UHq_s?͙hB5z @ySW]8ͿX?W}p詾"blpd41튠ɣ;) NФ:&G,7IN|RrP*T)٩Hؓ<޺~AXV `^9҄7SaްEZ'vx5h/:kLF:} 6\P>9|1BN4r>HJ_`,8f8 9cb\9VbG)JiB7]Pb@&.acD7rWe-Lp:}Ͳ#Xr D 8e} !%TUE+ۄ8/e=r|@Cjk!.``Z0 NƟ*(X0:",B"TGe͞CZi@`5QE݊?}5AȶRѕ6>58xGf,X˲w5~BV~ :GXh:[bo㳍z`@MhBߪ+HTy{-`CSQM(yW.cw\wz@@JiF$HvQ$Dд` ]r4(c5nsDa҂R&MhQ PKҮ60'h%mrLdBk; Q6o ޏ/s隍GsHkƘyĸs_@W' lwlvQ7ڀEr>! wbVTx $<@rz)ޭ&@ @ i-I}^Yt:>tI#1Sx.a @[ 2_!}q.003wlLwzSx[^4NՂ8.D=JG?&hyG΋JNJr$ͦ>\Ժ=rA2B-A0q^l Χh ٤Khڄ) C8aMfVk7pdΰYup\4EnlLO~U`LRN B?-w%zPAH<\@i:„kZ1OBw `:hpO)EdVKjĚȇ B蜿E$ʛ91@gQZʇ#JtST(k3MMevGDD;p28*?Py\NS`)qo1˕پrb&aHrp;XZ퓒o5,Cq\4¨ :[p6JBiаxh3 ! <1پvYndt!=z6:>PJ"gTUgWAϰ iRrS5Ry[]8H~Kxn ?5_rDS{}CҢ-e݃.~o{)u~%t ahş?@,v&P `8u)፝ՉDPV +̪@c[M1#i*ӑqF2$.* b/ũϏym+.`Xp*`]WJ9͂_z& /\:{c#6D #xnKMҝtN[I|r5N Le/}؁4/R#J]CWv*fN| *%wOK,hBJFCGv_QvġX,V&kJV;J#'ۖgrvITϮ=bW;ōu%SysbSgV}"s, lv\C%l)F 8#%, c*CT^tըB.a Hq1UX4$MngtJו7|Ƚ.rq=ow 7!6_RTa.ՋS^3/x leBf4t%TK K-?#!Wn:E&8:#5eHϨUH8?bXu,FZ~ b S[wzGKQRNW{e,\|*|L \ : ThEζ:Ԭ=ɥ{#m#dq/e)Ur=k}%[M>#tdn> ~P+aۤh!CsG?"' `UzßiGWgŃϒ΃֠O+pAhD9A<=U(ZI d:*ӳcOj@>ƴꈲ] t r,y%1s[xFΙM\$f2wҧtl<+ğR){:PI?9])o<6ߓ#+DnUu N3Ax9嶸h#>S(+AH^ 5d~qo|7wQAc2_R{{/nemGqyyr>񦁸 4U}/^~넢:cah? j_Pē|ĺlDMN?atTeYY,R_%Tbnh| Y6k@i@tdߕLal."4v@ FP? %v 5cK \b]xzV jFb,Ummi'{d-V>>(FJK5 652x; N ɈMgE KzF{Y+.@:݊]k)/630X5|3@++ vb0F5OZwe:g2<9ah>3'5G {q/6&g[xW+Q-ybicd*'[3K̛ AK[Jc-Z쌱;,jdn ,E,t9IqnpzъAM^|$JY7Wiz/K5;n v?X9evL.(Jx.x+9pLeo*⌸ [͑Wa?q24鲀"*K,bclI]W U@s ڶqw%e!e9K܈2L(_ɲsD ܑ6"/>n [^Y+tFH]qYd@8!"IL\k1(ǎj+ S" $j|VeSLjh&#* ъ.f7ʣ{ɷOeT_+):i{//+Ne{kcZ/*:~&}Wz`X$3>qH au4+m[De-2qXO3MDv_9U),A ǵ9c Rܼ m$nUKe?D_Rnq'rr$W|0eXjD7`}t4MWYj Yu31>@o`gġskL/ +qY*1gX7oSoŠDĘ[gs-e\OZ+ʔ+3x^ 2B6@N,Vhꫢ_BuGAϚ탷;uގ o_x5MSy.W[+7+{>rոǒyɍjM;u/ M}_˧zr5.ZW(ƍGWੑWS4 0TGM- deD[l,qԲԮrw@xp/IԨpsGāx:D6Ƃ;m]D!dDRd =4DHmf.{^SL| ̧ᷱ ΅^';pN~,:vOb KtiFIrlBWenjTAP~_>#mż8t/Bwɋ/Ѷ9V?7-O*8PMC_`hOΧfPqJ*fzi˝=̍Qud)t\@BvkJ3){'W-ct>C S+kÁe60V;Aoi+R'#twQ%uRº-)g h5nX?~Z9 T6 h;C4xaȾ7-^l[l<%$o}_ȞՎX<64!0YC+[qrޫo[]@-E گo^au)"  f*Y .re(vS4w |ZRDMwL:춿v9T},?X(Zn9|F<>.?ܣFA|:LYz ^*W]FQ'UtsA5"BuUEJeo?y& X\͸=X}42rI:XݜCK鰸-s=ﴛ8 5.O6E:O8oY0#[ /x_} e wf^Ŷѭ*oOi6$fQժC9[4zpmp'S Z|ƶF=~deyvU\)ˁ|܂wmg:j(YF[u2^jbFRh_a>eYE\]CaQ[oe!$!b1q5e[_18ҲRS ǡ63Ō~|W.82\.$W֙Xq|EẀ߻}n$|L|ȩ<7t4;v9Z<ƹ|IVI.uwKg vm^}Bp.w2naȟXBRk6>.6 t &3xwpq1ڤݐ;ZlE dO؞+aeDsJU[F'sɲ TP&^Ɲɚ>ܣoWOkB=ᅥ`zG Ҏ3E&ԍ7R*}"z|V_A@l!?>( |B|x-}fי=h$當w9U0"%|w,c>tkx@{oO{ FBˈڶAfyue0aBzwJނm@ +#rXjc5Ρ\S,M2dRCE[v)[L7IU'.\_B'ZТ6i&ty}/JmȻ6e1UVDV*|XJڇ5\etM,@nq=8=L:n}谐˩dp}^ʺvgCQNw(„jTS,hΛ2P4.rFSd3xrgxAo\GZFڈ|Ԉ^_ hN̎x,)EܴNff>^ 5e?xpeRTykcrʥV`cuk]'fxj]zjj%֯Zt9J1dٽpG2E}陂 k !9LY89]<rf^{8򙖚~:}`?'pC}pc?mɾ{Y~\[}C /%6l>T:U1 QMߠxXg$A*^aW8[G hd9/0V.n&1c;̐_f@j7Fin:{[ϧad^ag=<)%J&x#1ADQS}H:=²t@} ~Ȯ}daF~8TPƖHCZ6I$aWP3U zouAri|7 *ިa0a');`aa'jzy8 ן*X{3iQ($鹧 "Z +g̉zad|U\,-O8 091gOQRh#:_OC maF!vu;^$VU6Ua0١/CmaV3v|x氘JOzd`k?!<𭙪|ˍ'{t5qG$kX 0ϗ}4Z/shbi[d /R]ߴ*-I?15uh_$_T,;Z>WRc ̉r^:'a7S&)мWvXK2t9oi + l3 [CC3'.cFFkFl =}D(4o"yCK֮˃ !r^FƉc:FOK0Wa#dW=} ䷑- xZ\K+7)̠2WHao-=_ 4 ruu3+"8_cB%앧QTd0_땁@"]?8er}{PҊ?~cV>iޣ B<}ڵ-,YVQNE`=N%|lB&:!QEnŘj*:Cwxk Oa؄TNPvwӒt6Ir05w[yW!E ! ?[tC30o M)S>ߨ_)k@oF{ ?{^1?aH`g $D+JAOPE NX"! ]VP7A$(qP$~A~R gQ+e^c%5ֹU8¢{Clc,]%_O8 5Iʁ(ylY6c h.G408S JVAG`qpL[D>rعCCp0y]?,ӧUc nS"ӫ~.bW//~U?:?XDgFK"йmKQED@z9x\Բ@ybB%|Oڌ mҨoTbb2&*+[sQ"Fh0clU>pΟbٹh."`$aM,fg'VFD1>XɌEP 2_{P<|MdD%͟&6eJ6#MZ'׋$$/8Sr9]؟񋉑=5zōlĎ W5m3#6u#WD*C3?N u"eV?.wQo5)!Vbǒk[ T:5GZQr[)ƎQJAhEtI( MlV ;bE+Nˉ'EGNLP ŏrkEdm퟿t9B͖ /jCA)$eL J~8).h1GD`C(Idz:#eYZ45BFPDQA(WBؿcSfוY(i>!*~J}'M& n߃sqİ?+gU #篣f,*.F/!a%ԵyDvf<"< h ֔*塩#,}IJ$( 32{b 롱:'ǂսIWŇ ~+:D W&9_# Ѷ/LXB,&J(~\HmQIɯl6d/0 q9?\rBhW3'6/Coh$21~iG?ȿh?$\=d(̑G:낳uУ'*BUP$/ c3*Ȧ_o}V)K CH+ls̑5as}|s/7ka&I 'b` -ȺlAok I_8(EDTBjb,?KaleF/?[KnSDƄ0bHh,6;Pu.Q\$m,(*È279UC`uYIXܒaF|D#Iv~4*3񅘰Ex0׽r=Qhf!{"ʺe!#nF:D\G˞V!2n 2A3o"A?؟mTנ"*S(m ͍~,nyE#6KD8+5f?-rfo,Ky@-x{|KLM:51aALiPdAV[d17ɽIAeĄEL}-پ^^~k79}9y*28cRkZm:y@ W\<q7GblۘoC\채a}ϩ?on.Xzk ;ʖ|r+fR|viS;/={Qwoq5?f 'ِ<+ڭ6XL;d3,`Hi*nϔIFlpXf gR_ƥںZΔ zcU/׺_VJ W6|7 %~řOW|z/ i,ӝ"c|v m04Mf*&oOHYᱺ2 *Xe>~A[ :>@EHGs2<ii5%=%Osh:\6:$fZwTsR_D07ⴛH12.l=@A:"e$h"&3^Uv+`2 v 2R~Xy.@<#jg!9Tˬ^>_o%_sy[HZuX7wo^sWr;'B_'c z\T>wV9-\t?vg-{"s,=ĭT̹/2B2Xp g[&SoXd]*7/3k})mg\aw4x@OnrY(M3`A!^G~!ޞRf~=M-49s8bP)K|JG, .WzAlJk1EvGCr?,0/_fnxmXƯT~ks+ofPKCO-V:--˷[g~9[y="-ȧ/`RHP 3 ZmRnyAzkfJA^j~ljdr!d瘝OҨxwGd֩p_6XQKzEUfx9}p<)Lփ=EM"ovڐ/ i~e{5=ayjJ8*J-V($.ͬR/br*T.8k,y(G T"m 6oD3BsdD(a^9QyRO4=Cϝ7N;ߍ?܏h z0l%Aͧ[VGn7LiPEx{@ Xm*0&[K7-AQeo-tc'&)D칲8!KPȾOs&r- 18boN>V^΢"͚+c@f?d]$Ye Yavqi.}icDgG=H=ͬ.Dd t| >n,('mv팚#/Rf5ؤǑ5ӸBf[Pcߵl˱)-* ҙ 'ޯCŐ.vR7wNלn27>FDA3+ F3g9Y*#"f:/C ܋GXʯ|sT H\ׯd̞4U'æ~kŻ;o1񌊰9c:V A9_)4#@\*óhKdPkl[lKy}2%- 6V.f+zKJ8`grߺ5YhkNj(.u_ 9!~xNc=4]Ns&ylXp`V]{7O<,,<*Z`AE[鎩};>a,htfϰԏmބj3˗}a!*!ۿAwbQƳn,fAOv4e dI #e7{%οky.ZB 1s؍NPig/Vz kbcbSoCVM[ߑ}3ƴ=mɮS:{Ք}xVn'm:.(嫇{gn%٪{ 3+E%7RDZ\HE|[ojwP&h=9([EG='qe4e -Cl[rvGcf n_XH|b;-2+Wh:NkDxIhcЌ.e@Pmx>NECtg`E _/@<rD"M$i6gUʂբSʼ3h/PCs o[Zr\_~geEoݨg\Q-a,[dpacpzdɢ\CW==. Yk].W˓ޫytSM;=&ȪZwA>v\Q\"&Q 2c_fQѾAbBE{}MNVkZ}!vZ(h|r@j9p%SU@Jݲ>+*)|'cv|9ap/ggN5@-2?eU`=:i)2 xO+*? ʆ[d٠k!Ī4ߟu7@ySz|W#\e66ȣm3[^ yG^ߐ3`Dc6 9Z~tN3=?pSY7ݾ>vLiMhJhv,l^}UOP{3 OD'f1w戧Zw,9f=7J{g(ːш/D뺾3T$t5z&=O=Cvg_Xw<ކykg_q0JєQ<`qJUA~]d)1[\ضldQ w-O|+I´ {wB,61: RN”?e7.ΊyzR`?\kG O0X?FftjaS[kll}9XG퓶 x6cGB>}٢@@-MoiB֏epAmHSdٶI#̝szOc9;7+`ees77Mw*'V4 pZٔwOA[Uܣy+7|8ɕBx7m[oSc XӛlyuP3ͲMwk]H ٨Nj;g97g mEM6P۶T 8DI#Ȱ*x\cTv =fղ#51-Pot!*-JS1bf#Leuەv&c2˵+ĕ{ҙgiKWY+LJ>K/V Z؟kR 0~xVyiͳ̀u߳oc⫼/3wl&zb?j~ߠC *WʆƎtUBGtqذmeم~zviaߟ8YސU-kaYd jvm)LsX)~] + ;x4C5Xty'Q~g]?䪿}|yq4Ssc)ky'X'@Hp4GQ1*䅋QBˣEWazD)cv/vC.DN?R*hvǟJA|&>&DWwI; f3ו4@AaheH1oX H]#;3:[+*vUEE}Ozn|}?;\yshj >#B|q(RG`sFle/9Cĝ1V ƔfeZe+la^Ӳ_n_p0fxYӔ49Kjt?Kn˘w2Y[{ O6[m)]:kN b:7N:{ҩn{aG?ce lUfhKmHRG${6tkTla.ݯ}+._2#I;Ԧ_}.`F̉=gCMfeZgwsӛUǥ:8_=vJʍ|٧@4B]TNjO z OPl|)rbIؑ,i1ڰ$yݣxf/"vQ xZPwS{N5Z@2Xv~CH ;aM/P3yk>_8~F& 6+D:Oe4T*-<3k ~ȁ"6^!bOIzl!Re7W Cv 2|a݊,JôK?7s81@K?n B8Cmߛ?>gn1QF0~S݌=7wfJ㊁f?I>0O :Qgʘ,P@bp{r;O)ku8Z!60GpK*ЎzsD CXƝ-_|k'bN.1cm^'6awɉ''(cܰ+E`{nBFN^ܰẵ5ۀ y-&9+TPve8Y}/Pɂ;kc@'gP: b8ƻ@K+?6G>~aݎϠɌJyڙ9@Yt٢{ZߊJ¢t-F%|rh2QXmlGe3/ OOݮ&OZca+2y UOQlSR* /tHO UN }]-r.٪)7dƸZш0lOUoe"tG|2y CD"`(We3^(2T̔U̩MT9.nm|oUv9k&]}7Y&ēpS3^R8Hlp]- > [y%0ڲ-3DKfm?1nX&Z7y-ɶܒ2nO sf`ٴܮSzw[եGV0y6 ~{"WF(?3͍P#3ߊKX{s/$"DK/gOвC={W؟i,Lh%n!"X8=rSQ:Jl~3XV R*=ti"sGQd_RS]=UGWta%fN:}cM,fa{=;N8K1zǢ6i?}cSWN۱٥M/cwanjymd<ȯF ^V)bȑ&U/Pxz%A>EEON3! 0ϋlG/06n}.ϳg Yym+䖴!0ءA2 'l/>iȩFq0Wl.ڻPb(oN 3>1>'^U1mIjmAg$K gl~_0-p[A = U'#K~^6sD=|[-m:Ԕ%9._n!XN.kEJ xʸ'ge_y4tN` 9P8}Dŏ7K}y"dTd[&94G:4s@/-u~q\oAvcr Ttoeb_w3"\ߣvn])߮zM>ߴokmm_E Pdʺ~] A`r,yI9ʎl'b~Zgܰ+3> UsB b(A }sdFCb4 lߥB!92ZUR ի*ɭ~5@n ʽT[EK3uxg]fboƓCY3bk]O_Vw\0V^y89 Y*:\)U6i3^>ʣsV`-Ӂ?E>}Hps'ߘ&(d)Zz%)}%ɛla (l2D;4SitBtNhӶ;%`T;Sn4;BU0 Ci O^>A|fiJ/ens6 4SN?Y?uʇYʹ#ۢ;+G|ŵ?3=HH0cVk6ً\t,ATtOߜWY Sc6 r+۫I\d4};wVA;%a0NEZ|{H ZWߢz=nРW`w:-C?k!N ?T 'PPk/h ؃ _]}S-!^QGDG|} ~t𨀆Ij?PT8 lRk^?H i5׉gIȻ_?Mi$tr ȠNCpj|a>? 'CINa_ H_8Dp_{Z CIbz;C=AD`DЂ<;/@}v!W,F?j/COLD!ɀ~Z0C7iPcEj̧uCk' aQ2`NF<! qvqӒ `4ZA' 'MN6EX(DWjb69=050"bFOX[r[X.PPf:w j3:\M",V$3>u/b1hD&  k F ,i)@ÃY#1?_f"26/?d YGPMŏJM$-LiM[ԉ%w-$\T3]t*AOO(8!Mz:lh'¹Zu*~BI6-M ?RZ-7NOtL$>ԎDGl~ .A}_ .<ب,X B5OѰA(ew<7!".)JG7'8HQt80?&\"`0xpJ#yh KOC򕰿6A ]j|ik;!K:37) k8#Q"JVK'XĮkqYpÂN&hhcYX@/5琞+8)?ђ%81L|BܢɌgZZ[H(Ӌ"?KrX~"ᚉ4x@ Hڜ?i&jAqiKV2D\W@VNrD$! 1(`546{0\&uD!0"Rpq=!> Mb0 6X0d&bhiP;OcvjOtd>Bǥ!C68~Ǐ>'wu“ u8RDDɃZ=VO@ ϨOTZ'kay/QaR]I؟P~ZB#'2ғ-$b"v2[qb+Nbhܘ"ڠ$\%96%> Řb-% J_xC̡!=gDEY./ x z3pLz2N '+N|V 01*69I3`b5)ŷ^K$~|Z0cI X&Dbd+#Dj?qcUBdctA0YQJf-*n5 0zBVݢV3t<0N &뚢OZG%-\%אPX Sc7hF?$~DOP?cRAZ|+I?Hذ$f8X}#5FX?Tpҟ0Z^Sߋ?٢H ck^a]A>gG-hf@ҡZuOH2. pLJ!DtWRCm; y9qnhzc[)Iΰ^Eb~cZ_—PzkrCXFL'N}BWAd|y l"NA{7<ď X_'k*~<9~V+"ۻt\[${u3;>Oj0`! hG`?@V?&; ѨWL0NUA(LşZ%TKNt4XDm@ɀE0=q 4+>!2a$g&l\"Y2U`m#f*?DגK=X#obP'@dJV!5_ _K.Q+8Q/,րWxPtV\Vwu: >kn# ^@;^>Bj5dEGfA|j rZ UF a|IW'WR'MC!&VR/(]箾Ih*WݱZ0V鬶KO؟VFX5:TА:Z xRxHrȨRzсxf<: }E1Y8=2i ld/=qwL8DrLÅZ=aO V NjL,z6 8H6~5!dޟ^K*& 29'!t0uul9a"!%ho!^ ~7(RބBDdV"b]-~&µtzML1:"Cf!)/+$<&[D|*נ{D^5CATD@Pt:{\Z$Mh=IDC&Ƥw*>%>E!ƪTel'VMh[r]"N6x 'pA)q! NQwO..}!Ǐka)(w !(?ihL&^Y]r)vu"2D,j%Mx LCXtMދ' Մ+lΡIj($ǿ'zɅ26d'I}I SQ/6x&!auxբ>im#j,6p(JK_"h OG$c]k"?ѮJn'!5[`Mnx0P,xze?xWZJW\i  VL,*(Q)71())1pEW,L,JW\1i=Ĥ+'cw~~{㇃0~^I'8xqbKx2* HjV g }~Ϳ}ITSE]ڎOm9/}_~gÞ=?ϕFB,>Új$&i AHqW}R9<6ֲ~lT!K鶾h'rwpIڡc?s#egsJc_ 2IŐ*42$jPiV%KXc8YL_~y--&2gx[j%&] Ny-ٴ?l/F-6)rlbeGFm9wf7^IjoԑXCkU ku5k ^: PϘ"ṂB#ѽ-.a,Ŋ103|]+0Ó J] J*ڧmԧ>NʃbOKI6(S=9@0NYw>(GS/A.~YF7p'qmZ`!sO0ABC36VUᏣ}qiũVmYErn`j*]_oޘzt~ΐl%*B60i .TC5M%b Y}ԣ= wGZeN͔։ (dfVwx&߾no&&髞;# ehn9#v`^҄!ހcc樂jf>WJM +9h`uuw\j۟Cl'N8M|{X$sg yotCxL}xn'x>ѽ[!]jL3#骜J# bwz{ױWU9_q:j|uzx ,*Jk3 фݕjXP99G,rGH(F}=&N f_=zu5]r#̝>8u[ :8U9=ߧEb4x^9HƐl~rrWt߯n;LW m%q[eohH>A}Ns*2fvvH)B*eu_$J?{Bc7|Q^u<ƾ*6^Ȝees<ᛖmwxNkԶULR;Wn @Q$~g蘂[{e(Z/JVp?9>gAHH$Af#gq]Ťu.,l(D./Ug3ՍƇ}k5joXq'Kf..w1|s1]03EY %* ;|ٸ`oCOtң_V2g\@'c <,tA{# F'm0/`!<}u/Kdg,_t+ޅd F16,+S#g,`Y#*Ѵ'ehr]/wa)+bGCNv(%pP|NȦ4uYsbA Y7f#4&a;?Wb'LX&OK>෇_.W& !Eo d*$a9{x^5|ZN2 rS2PN8#.GFܒg3;hX)٘ZˇOX,q /|k!BZuBA|GkC!/k_105deΒÙQO^0<\sĿ|R|RDD**2[}bp_ے:{P 2 Ô|agiO]>>eh>9P~썁aS9`̖!owC~ чv.Lrj3, J"o3XrDy%t:ֲFXjسZg v'R.u{Ǭq{Gz <QٛR04MSwv; -w҆pEŐJpEXUhK4}u<[ ɉ'G\{gBR, H#o8bҞimT_TQ|Lrm*Mo4i$vNU !.ٺbik[6wj+|7뉾km{pwL*/mDž3 %F<Ǖ )OwF C\I&F8lQ ll]R !3`t9ki8-KF%iŒ"kLi)d;D^)f@; G0T44t)<^|lw}agNÎÞX 8y? )ÏDbQ+ 1!4Rgbږ7,Y9_/]Jj^"Q";H7fT+eDTͷʤY%FYEڸ*Ja8.cŠ虣AcbE_39!Cxy3?OΈ!s-Gza2>=H+3& ]#u?դR;xepZp k|o K6F~ADZ3Z)VB>b3$~pGD)^rix~Ylo){ث2|Kn%ULuC<;zc–0 $ B1_pJC|Mθ#]WXNuKqѴ}7Y F;t%SRmim h BAt xY*@Q w @>^+^ ,~ApZV9ԉ)|ΚOȃЊi$Pؗ̄!5?TSa9' .B@A2UwGCM<"eoUq _`:U- *QqYNK2eQv.W qDyk˙#9Y  UͿ$tlc%:Ȧ]0#}#덟r˘Pc:vONK%МjG %' xyዹ:Wd΋Flx yC BЗuNc`T`-Z[pFSBcUg>)CT{ZAJ(o٭+2^t3nRięa+yY* D vu{ΆYsJt*IFD~U͆a*Rum1؁=#KuǧJ *n$V )D/wjƴF* EX[@Vrp,2ΕwU߸8G8Z98j[:$˞x :S=!7V*.Rx~曾r>ѷßG@bW#kv^:} ] pS(̻T:>bwvcQjN@mK H"(P&=%b׎-~|}sxYHuu6֕~,z q!b EWI؂aOp$.;& GQϊ?:xhLA%EU]E/.U3kp"׆EAY[Sƈ"3ZH" C!/0ŝQf RTGs*M0Gl3]:՘&I':7|ߺ%+$a%Θ(#jTR~JKpbRl]iM[o90e,UmSG^Ni_(E-cwZf}ܷO};gK:qvU- ()gFīvETh Ň?؎GT`nDVe,C !GxqY*I(հV''O}?M\ #5Bu "n-V}!+U:ؑz(6$8{)T}cWH$"^oɳ$uSU(:CD;֩o"D0w.~X36߮;/l'Ie?!7ג.m@Ŵc ^ K'f3GdU/ FL68 󿧞APA5jE R#WxfY8nUH,m<ퟋMɽP.*xm:+[r+"վ[ahȎR].[bN!1!_fepƞ%?f1[{oLQ31kؚt~3fvyXƋR, cml:T*:RA7W9gB1v± -*~=p4' oKՠ3yc΁뤊:# iRft%WsiQ(6ϛPj`gAXzfh*;á=jBX:'҅W*U0E/t2gլb]` z$UAaھo'#8 qӞ躠ۊѰ/` z\ L"-hUxה V̹"WN$KGx`?g1=dzǿ^Q0}y>V= b(@1 b|_OQ/J_: E1`~~GO_iocޕs￈զR1鵢:~Z ʜK)~*y(?ʠMhܩh8BQK'<?rmH<_7q;}B{:?$}:WcLX24`7edXKc5Z/y&D cB"LjihZy4j=M4.73tdVG!6nܞ 0b(`S@@ EA""1_{ Zg Ft(C.VrGf^4~V^ ?X^'NHM%2*:ꅋ⋇q4 qS~hLtctyFo œVFOЈi\^?ԋq1 Έ:Աm]-N\ s6LIA?Fu}(VZM\pPAZ yXn6X<%syOUV:1Fj %ߵLie ߌr [ @BVal1+E9\4]ƋMDyxrQ5WϜuy=%錀̈́R0Nx_y\a4 X#40D>L}AqC /\r៷LOх*hhhV-Kr^?7}:Z_i/ P?S~m {h|b[/_?k=>\;Fhև<9}ec`:c :c)a*ڳv])ޞ__eqTYi`LCĈ`Rס+Rwf4ӑ׼ b^ gGV5tZxyF1:?NYhDi)lrM,KhFlKmkM m@CY0E nYw3%k ]FLg:@M&ŏpІ[{? _%plQ]F8hcYS{,G֪lM5)25eA*KV#OPzIE򹧝ضS 7B1* NSouDqӖ иf7z菭{-og ~tǍ`fk(#@b @s37ӝ6߉ff?;n K-PSRvvI`Jo;sŸPV(*i#PN3ClAnqueci(rz0ISFR^[-mht.Ac5ZfW@O;hޅ &~J9?[l/gS f5b%1VbUN|Ytࡷ9_rj1wcr;7a,MOl7(hҎ?gmnR5 RΎ%e]b! "d]z?bl~:?iʂeޚb @Oiܡ!U!<&77kH4Y߂Y[sEqA\1gS/wſ˿zF&6/Vt4v < >/Q8i{]ne8RnwߵS-iG?*/j3](` 0ο,~f[vc].z^u=A4澽!ӹWL'%vmk ksq,z66+ mnPڛMsz S?fa@O}0NS &١~ahc[҆ AcXڏ` Ri w{-şhzG*c.^x@?0b7tؿb!ג*0leGI~7FՖῇ1濗{yYď-jScgW6GqY5#f 2N?N|4b@ƈLʤz9(^E|l73LbKDnښޡx-%<ܳ MM&>^{n ^ǍF08g:@fD|{x5n~QSǚ9#y 2hΜbYPS:q綘v̧`̐^q/.JvO{Vԫ+r01@#I0nZ|OoO9C4P_Lv^&DUn. F(p!ހ9qhSr:Fofugs[s[&՞b \G! VvX0$rWffYƁ^JŖYoKo%\13 Wx`+xz v(K e),%J(.Pb %h(QC5h(ˠc %2$Nv:X/C%JA%H(D J(QK(%RKgiw;jffy͸"uwD߽M+ vVB $ b8/>5?\4֙W-AZf2 SSԓ9`Xc%KxY^ԔТaם*5 v}[0 1{ md3&æ88B!>q=i18t>LW|+/v)?|/9W~sIVxV X.>wԻ& -X!pmu1P6lE5qh:Ή+HVmHi#Ԅ7n?=d2_ɫ0shL>9܍$:xa$IjKtV.CQ32z1eX Sy2"9 }1㢘Ʋ1*EqOӚA ?L+ ᒾ>+>@J:;l&G/(nMK2bHKgL/$^v\ġZg`+k1\ۗLTC`āGc~B.Jsi>6Kv21'N8734[XޒL.u^9]t!ݾsWΜM )딇riB*? Qܠ DʢnIS]yVm۴y/?i~p,,.;\0UX<q=(2r)ޓ1m{Xe YF|Q~-i,'^g]eҚbO؟B 1od[fؤƟ4k0´ѷVvZt&ϸ1-&̂julX'ߝr[&UΚ'o;@ݎ aCXX|**h{83.w_{wkk-S@=4rRO>=IE7k)$Tm9~oqqw|O 'bӏ+|,倫6HՕ c_ΟڟVR[ҭ/B ʘ,K{dSJٻhaC ".\^1[ouvTSCOrN&iRԐP3'Go,I T䧸rΨSJnl"FV=)Z:GG'?Yp  ȢeH&8"=[#prҊL#)uޖWJj7gZ8?@M:v{炗mNvB017)446.6$}6Hݡ;A+i\џ8~56<|l$FV}!n7/.oԛƯu*ø8`ܲa B(#eܮYa"#rv]7o^7LtJ wztZZxry|h%V*p )-eqY䙉7VF~BlSkvaTf 兩of: )G9#oR^]39q9KN+lEL:0Wr-0㧽dX!Sg߻o:s{.:o,}|!C+;.Bw;&VSRUrfte eb;xAIebIqXgw~aLRE?]e5 ]@f `݂|xW8D}~Qv#W5./:2D\o6ڱ'vDh5W< H0;֢<^tX6h'b-ѧ> S&6e RXJ_;lhbx@  wdGavdp1uΜl 7sVEwZ~[H.xa c8t6sޏ#p:NR9v??iz-be8 r&+.BaswvX8`"#C;^kZq}`=c%UǎБpǁ!K˷ø"M_{o2hh`;wZցECgW](ۆ;7uu qdB1u,vتgH%5Q-{{)nL׮ oSqZ%*7ʼ53 e,ًV}Šq;t._(-Zb]4n~iwORY0C\hs,sq vkVV]-k$+08 >b,†9?V&ҢxHr >9rv)TPT;"(S=E,3CEgu1fDUsWO;GO=5ʜsJ;Tu< AsBnA [Pat!KΌk:Jc60ڊ;{>4&]OR[=h[hꥑ~kK~ωmwE '2*Ҿ7#ԌˆT]P\擗73hw/r{ĵ,V2.6uݸMjAp)!;3m ]pj:]b)FD@t;C (`Seᠣ@{:)p1ȟk8'YPڇk}:9E>䯾qf.w`"ѕkD$b;z(\Zl-4J#HWgvY'3պQ%䕋T!La* E(Tߓ'ram?}u-najD᜝t]]eB):{l늜= WH𰃕YA`(kDlO[^[hZ2ȴ#.,(.*1ϚZ;AS=j%jvX-#Zخ3ؙ4ЊdZӎзѢ2Ѿ+iϠ'=+&,+hlaQw4z|B_`彾!Z$*3S.qfʌuPPueCgc2J-.[p! Et$+U  Ha8eMTSqX1[ڝ_%fݫ ;T\X" y3?Ncʞa%mc;gc6x9>3r3 d&pl-N,3$d~Rl,*8p \^UQiAbD!*Sk!E9(n, {C6B{s<re^0.3Q9{+уT쵏-ڶΩ,O\q%]P8oۃ]6m,ٳa }GX! gQ]q &@>uOy%R凳k-/>AAv|smGMD}EX|첽贴皡n`C=kCƾrS됟hqѮ'o l=7i#i(_ے́9&L9χ( /WE]E'TmL vaL~ݴDw#+mp42ZLJ}~?5%iV{=J̖-ze ۺ߄Ə{~>UeMO\݇܅ؖNry Bdc΄[ |fP4K 1h CzQe] GJzi[]ۺ ݹ|$NVC[z%r*e$SYG}5(`N{.]yLV1_!GU 8uG( Y-(dTv==qU٨F$ats#m0ZU#\T/Tz0ZYYގ`dJSF#7Lӻo1GKsȼ5)}=ѺH$}/1& -A>yfZ~ಞN#;- o9O!ԕm)ts<`Y#7ר*@vFq9]Nvdf0'1#K,N8$tqPWqt[);?0^ߵn/n4#E0JR4fPvذܥ3. 6k5CQFn'~Ȟ7m uw N~'d>{XӓCQvQ j f TUa]}AE,bdD}pQ6 rY_ e9kcNoI$~Dq6 \4@M'=ʺi޷Ny?LS;£c#dɮEE !9TZ;Zv TWG/9r9_2hҪׄL֙i"a.r]N8d+_y&r״fWF_|. N)EU͉9kn  ;h\ (0ľBh 2fсh*.?sy$6/ZbcQ:58JEQ;`Wd3FOuo)T}8c.EAa@53]B(x.B零4 E!MB1xjё쾾mB]~mK&S)*9Θ9j{UiӞo5QeqUZBt4jEbͻa1_flQ^qyqxΠ1.ȹ0֜3ǁK'1p&/]νoۙY8b!{DA;vO uL8_Xh^4 ̱#9 ݢu&|ifl-?_ñ/}VdMM - Mi{*wtd`Q+莣P4 Rjצuy% FNUOg0Y֮d3ʢvcK;,e4Ny#5Ү=.-sb46`*h5kF͜jT̓>i;Z{lG|`֬R4=tួ>讹y/xDϪ:6YOfZJ*hgA_Y`rpX,hs>1UwĖ7F1Z0z+n0(LQ?;X.7;brl> }bZ>ᦷXѹnr#StGc Uxy2Gҩ*u3"h\XFIG{*Gg`e Y<4?`C6 4bʿt}s*?Z|b\8R7.2͝vq{P z$%K-}-&є=ekmX2dUأѡ `eg!As8c.kCcta},Tɒ7~?2c4{$;̨('"hSgYLJ$~:T#Qt'n_3ɇꁻtưҹBa ̑uE #45m`0x$M;9YqN_ ZXY8Q9wBs3dC؃0pƘEӞ|2o#I\n¯WE^zQ.^]/$x=@.}_W 7V%3kS!@x4MEÒ$I?Q E@@Fx\Dmh~#:k?ʀu k?1ybM_OJqdտ FJQ yeUz !o XODž{:u#M Qld7sݝuu5!/)Jj?/PO5{$?o#:o `kwUSv(:7@~'`댑&F %${y_B\:3?aR2b) B*rhDM)_+ 7~uOx:ejI$/{X5t?]8<@/ڟl:j_=HZws'7KO?;٣/K-`ZKQ"򈡽-[xCd=>:># =詽d#l6 ]%@Xr,v듫m@y"~WH"4STלbt9 kɝ._$IkѦE3'>)/XH[AXh?À1Am_E~$%VOIUku fa/6$! agju~+6 a>#$?S ~_i)N\Kڳ.3O @a Nj'Zئ#웡Iǡ㗉7%ɶΏ=yZa{1eV]gsT* +aY8g%G0TRSJGn&mX~ *tv] u/-xz_*ů{>ve?b ;PóܸX)3!{k;}Q;4rm~|d_gEt ؒj|koU~!=d^V4&D IIX" dTabX@RT:1׎Txb}mlw3mC}0qΈT{Wrk+& KYK(:A v?A/tҎv"ڼa]pyP=H;;KԒnXD~~k*V.# '  g<*rx[S<<0g8/|t9ny?C M; HO+,YFx/n)N<#y2ڛNﰥY({-|\F-~ǟdn_SL:L5Acgrh.k`8(9S0@a*"x8hb'īO 91D]LeTϼ)xJVʟEs6.cu2gV|fh[>z>kE0mmXe5Wz^е5d;Ǯ]SٍV0Dpt^@> KQDLM"q\"*α!:3!WGgs(w5Ҁp6;\C #Éj)[ PCXX'%{׉ٟδ`6 ;!!D^K݇l-{.}X=>a޸e]'˛s|f- \(1s9. MK"ȣƖЀ}MVv{>t'rF0lcYGUAPLN;߇̰E.p,;GUt#v,*Infz N%1 xi&)a8xi%M~>T)?࿕7T˃FІ;8vexW:'|&YYO A?]{ _}_G=]yåw7ZVf:h?t Dde+ f,x*4θgEKJ:W|<|jȧn}#PQqGkLL\UPDZ~ﺖI{NL;4Jvhq:0shx䧥k[vX_u'OavdșUkbW)fO|ݑd/ L%hPP!`V zQSr=kNF"4:*oEk2^)X~~`n_Ow0{feYe{ #ыcMCcs75g>Kv_6!wϼmw !$,صl ^Ffw{oAQEJkV#ke(<2%^ʘ0ޕbY_ceJ 7ïGGpG cazt`Rcן^WVyf.=2}̍ TB:UK/qxkG O\zv4y  Tu=2(mX>bwMsXd𜩜 MYheF*`NJMB pe8 ˨Q"zF^`fǬRY;+F%<: ;rcwqO'=$e \ &Y/O~&;/ZrAuNvLlgOo;]e+Wv1ٮϪC] qINq,, Y,xCD%nYct00Q E$C3r.O$ D%|O";wˑ""̣Ij3U59?|һK'4T;w(ģ?  o8L穒I4XSYҖaÌj(;GIq cCy vݕTdve"ӝ| p8C@6P0~et;E\)Š9vmp!W,̾jfT@FH>42 "]|UY, >=} \dJ!Wē#r =E="SvpӸ/N(niJ BTvMYU0$S ͼ0lvS.e᜕27*$nTa^:={fUǸ3?z?^8\-rW$3bmzE9$~4u|-OCo$BYe\E"`]lX`,e[fZ6a5E~* $[/{ h _oSG&'\)2 9]'#n1PȏB2wԹqp!m κ:z83xZ48n(þ48R]ҧѪaH@meE}ٓNCs^7|]GgI3d4FDW +\EKg>˜m< o:x  tʱ%F*wPMgE,O.Gw6uqcFwzn}ĵظ_`_>X9Oz/Av#+3[6z@"9E)ؕFAf 0 CYZYI*4M&IXdž|ْ"cs//䞓Q86dB:-Byx'/U SҗF\p x|xy7x֏s`[}D6A9Cj Cҩ"4q_P|Qx5I=Cvx9CZ=qZӼxdLlcgyL0>s}nw|\$r.,&M<3{dX'P!O~N+RKAU {IjWo|*~p+NJTUw㨐(cZ8[ ɾU=$XPb"&j^73&it^j{fnȔ{p}h+fC= ߫&obIo"D NÕW ÛZN>18L @Εw[N}Jy(]m4/Tvq,A䘉!>Ab*9da1{})gprϴNCLu4ǯm5#Z`pX,)(/y/K9%,J1??YEQ2;*e\;˥]Ty $;+ 9@ ݑtRibNj>,'^|l_^Y>/u$^I ~㿈_dY!fp(1޻>m" }ɵ n_ywtv.XQTcʍon!c%E s1=RTܷys;{Yvqǥ[W"fd&$ @l=D*~&'fC/@.d!lb ^f@L1>޼xp_x1CώJߛHL'\ =` l+XB[n&y], &,L v%p؞fܖ&<|,hHš@`ڹy\ĜLcUs@缇p "Ϋ+b oX((]'B ]ywa%h;@rSkSfzסʼK0naӆQ>&Ѧ bv-(I"@%0 4+bjDvo[İ-3(enKW~hL_* g;?>ǮKv-[۷ޓCt"p|чf:G$t_ -T總9O #/]͛{.A;a,]%# ,bx|3h2'D!rX~00׹X{ᓻ_tj꛼njO(%sbUN\y諽a4 TJIJ"#[+?[{L'чQ+"\ ((u ~9HGYH@=Pi|'w$${=AVBg|hU*KlV4tg_L=t➉? X8UgWXD꾵ƩWJÌC|c)aݔ* bVCLÝ.0ƃG =8˜RcNߧ|Ge'*yZgJ/@Y)l+LЧ{Nxw卫A_̼T@M9ǷO-!/mAs~WWM~<ƫ{a tj6໬qh O7(YP}B8JLB';)N?/!2}xjpsϽ}me,{vϾ=Q9PgR?=?xDFq4|,3>b0Ю OQ<~u׏JcD ٰ**(+P-{`sU< ^|<%KB\ `ԺD0f2#='Roǒwoq(/cr`yI\;I\\%[N&&rYONN/?fٵNfNlk, q,9\;Y];7̰?ILmCǸ=Et$a&؎͜ZX͗a5kܕv_Ÿs*[wîU-_n2v VV.zwM!KE@zhdK+!XB/h/*?w%YvWI=cV3=MQ6c+0!.;Ns*ET@ CN&栞[YBC*ɟv24RvoKšrPn_YA)Rc{tj1_c 4`D2$Z+i)ANA.;(f5HNE`O&yȥ'lDZbGpP vӎ,͛o1ZNzTμ6JG&p+pba@dx9g.9`ڶ~` {oSzXt.|im3 2m0.FtoB`D3*IE|ĆW_&Oi1:BŔM-Q5a\#"4ZuȖhmd}cUlSx[BRTM+Jk0~s.zuCf?PS)7Ͳ jW]#k1׭QEl$鏪l_t[no`i_zr=SDnߓv F]+ze9^@GlH%FnJ4cQcou6\8Dbz~r\_HWGbiDVķw  VtS<ГrgmajmePCJ;:hi^;Vzh$dcR]@7R-P@lO*vuˏЧQ\TDVP7_/4FWS_h]@EkG~ҒJoSz\j&T׈j'YAZl4ChK*SF['UVu]H6=`~|jAj ޷6_wz9()6G[0hhҬ]jEM&_S7^PԿ.VK7ٖ t8zC D jo+oV f>֯UFvb6ɴdKdk_R+=5ʣ-46n|mNs 'hMp T8jiVj:fO~#xuh"*I_ݸޡn,g1hIoSu0F~njq(ЯUMˌHhBHiU{'z8UwĈX}/PRK+7=`zXKj^jS2YO:S4qIT-_iEFk5V鳑__nZ5LM]x< PMʫ#Z)ڐ6oի6l-M0х^6%BIMkD0Q6_Ku4EQh7kkQۜ'`UpSdr#'o0>5XRv[V ^vAk*-Ji:'%bc hnhöG$X7mbץO50d3h꫈uZA{Si$\l;_n`x즡5DWZCSADuQRzʣGԷ{ӾuyuEFE=MȇzӬRik]d]lUB&? ǿonrF'm V74*YWzD:FEFxRF]SZ?tQH8/rk'b4?Wguh&ZQU:a7hhAze$hu-fmR| P?s~r3acuOcȦqp$hiPiJǃ4j HhFdjkUaCnQc ۶bZV~=EMC W9Nlش݂_e{Zoȵ򹭭]}R!5^xٿ- MW'ޯǟjqX h@}eI|pzgwhy74"oJ6EfϵV `TˀȶJ#` klrZ^)v a]W 'M|z$X5_կ>"jQ#nѰ *M^FD/Z #ldsd[B7pqF=V.lpؖpjImԈS߯ycUl=:q mo0`MaB<O˳ 8?.:.x|To9>q)Rq)kRzRJ*q5jtDbL{ 1jQaZ׺.:uu9\ux(Ҧ'|{ 0ekeSLP\ o,1Ǔܾy3f],@c0^ygM_y{=s}SJ$s .w|Q n $HP-ѕcK` rEˇe]^{k=K~ͻ`cGkW ?r$sN$el@ZLfMj즇2wn,󁌬8*~>~K׿}t#׻Z 2FeNJ glI4;`#Ȯs ~ O7~ǢM:}q2 ~K)A}vxSp셮]/ °ԁ<$xgYT#k ]t2{ŎSl{7WcNfW'QwmǨmNUxEt9Icnt'wSL[Re:Hi{YN<9u}~x.h f@lcwK WӋ"]¥އq|<1q{= G9_bL& o9$/73d9 W|QU]N*h(P>?{[30XG-Big~A@uC1<#>NS7Js}*8-[upx)齛xο mq5kV=[7nk@1dsBZB  x~oS`4 AN@`hA ^ߙ+{-/Y#?8Gwǖg&z8W٩üҙwx(A Cd 7ᤋ!̅J䙞E!3fyøW%4tH%<*4O{}tʍ ᨁAV>U8*#)(Ac \=*^u9NHwG|/,%ȝY!I')7bOt.^7̴/&/>o%㝮$#wOBD p Rw}vÁqū Q׃;7ܽrMxF'o8fo}Peq9my{zަECtzɢ!tjy$ゎ1Ww5O,&ZZ^|%gDvsVX]vׁ'?l:+ki 6|mV'_'umd7'ĺO=ŭ;+!yu>tw>&պHi*~sʢys $np70b t1M1TH!ıLJoꆋ!wiއϿgy:,aIVx#Qj((b/?rc&j(Sfik; y^~|iߟh(Ȗm:J"ipǯ/#ch[I nFdq+VH{:ݹ6#d?)CT'@`eĐȊP"O<޽YO?Kٍ:NVJ S nj ԽPX{I>=P.Ȟ>ՙwhƜy˜S;擘AfXP]V /;uϾ|_^N M@PeOԁzL =:0C*¹-Z̿ W#ϗ6 <2荛x Wvk~+6J+P?c {^.:lsf_0-B6ʺnaٙ[1(Q(`iT#j́xޕ*qn$3B7ćn\.0W YcE|| ~(C˙{{hI2 ~*S6VLgqw8@dC x$樛#ʑ # ?\%BINt[˶;79uYOS/[t2~NXp}}۲o&\B {Ao{Y=JvxSkpC4rw$ }lPO_ z^:>㍋pr/\!}O*h+_"FR A`A~Ѻܩf=X9gLS/ѵlΠ F?"F,)Z+ɟl=/I(HC);jIo !∟|Cg;w;?Fn)tYSyo_8bz>H<$dF^uλweyww!6e96(yuצ) ؍#<cWl0(!#h! 4 {!?n yKw2wg$_>2͏Z!'y@~H4m;!ZN&yQBOߎݨm]i;$W/0g8-8gS1G$78%W3-($)Ec_I$?Ă_O:3K}81q()U8Ho`;Ù.P2,`L/mp`z(? |*3Rl*u^-{(KiP_~_v :bHH .H2AEN`Ag<aajLNj^ћeȈN>Fd&rW 80~ƲĝeK<]O/1g>p၄+v%YDI*5UZR4S[nO 1xܨɒB>4Q>!9l+tԀ6jQz G%]xT ؔ~}u}Z&L꽵}CbMWr>pLB?h@T_jziFqZP|ơ ypԩ,*8JH!Q!&|$[PUO@IH!ApSb|(A'N ҥ$Èȸ20cbT)}zI5zDh*V5?%o/i&xo9'.@wX񎂺t19'Ǻ3*F1i Q4ߙ Hq$)&)DDE)PF vN$cIaH,eh;STpFخ*ߞՂom5 hjgϿ|/ t2bza>w2nrByt۾x ,CɲPzp|KYYe[!9( 0/`dUϺs ,^'D{yCeї_ӂ@WVx<4._}{ ¦Y2)wn-ť4w<>x4+ c ]rzc;|qAоX5OƖ16`V!W@H@(m]`Gq.~o _P*v|ґ(JiIJ,l.YX,f%WsʯE—zB9gI[jM5쾂12D*bw/fb3BF~ec}~L7-ϼswg S a(#j 좖z# $ $qHR$,0WetѸEiAA@S_8vD5?}j B  vU8q,|ο.3s:,Ǻ}n|)+4#9BгQd^{^:A $!@ b\b?*=~ xW UK}Gp0Pׅg BBDOV O&x,JZ\NK'A< ,sπSSx헮 *hsv=Av~q?34Jj?2;Oy%G:F!rTIBʼR\\<~w{;@0JXK#8 @,KJܜ6vGcʢ'Үh7]W@.WɬZK26tT m}kxNjK-TĴ8'^;f͜ 뎞0gDyL"y,]r*Gea@A@qb-%^%a3124bPYt+Gj/Pfͻ}Orb}@֒}›"qA[o{$oԣӥS]>]v5h!&⨊>>y I A&9u| L< /KƿOgh[$}af,)PE F!0γV  p?Y8[X-mT56CutN=@x f('^,ä_DzEci Nc )$x@ ʈXCJ&LӎZz≩{?1Z>yYʐhx>/Aټ`>;NG]#{3ؘ0&w>cs'˾3d2u@R qBW#$u< `D*P<$qDb{q:qqR"%8៏㿺zݤ4߯#uCF.=Wʡ:F)݁ oko;U°5K}8wNe0G.x9& OfA ^P9O J{pQ6FC ^32qҧWe5#/ 2%QB+8 U&su|k)ҸBn`JgLlHM6mٱCk2y 3S ̭l1"{{sdcMG=dko?[LH-huI5𳑚^I`(@ƚ+[ٶMvT;髢g8XѷkvmE&TOlRi~Ggs_Nf\oa̪e=mنkT3lOٟyRg;qh_mS^*Z5E?t!UK_U#aԭ˿u&Kթz"RuHjmIQnV׻*b@7KG5z-)?HS+ju0֐eά/ڴMj:]Xe,t]ļZ݃vдMD^JgEL;õƛ]x25ii|eFڮM7_ +mXnZUVp1`f嬒V)TY/ iIuh-c?G+I [ZLR GZږUlն6ۼ_m 'njGΈjꘫ"Hm߲Hݺ+q4MDL{]e񛢭uP-15:Xkw[47b?;G<㼾cjOekO}fX -4ZNɅ;yShk~%r-NOǡU6&&kk|o D h ?z*0!j`gF=Rz>.$~mn|jOl\&?QTZ9k<AXv75sj{i7`?5`U~}͐4ҬD̐?P)Г$6? >J nUR寊=ց7LX9%()9AkKa2 ;d [w,Vyp09iNL +24J:do\21=4+| 6%#s#p!CgSn%Ks6p 9Z^Iv ҉TcNB*o /_Qo':ܺ 3Q1pX]]>>7{ڏu-#5Ic}`&E05"C" fftp2zw[u}Ff98 6wyjzKP؎F:6^;:rB'4* ?3(p-={XcE ~xQNkH |tPů8IP(8`cV填CQyeybߟd ߫ >y.Ȳng';+64Kv+ZtOs_}pJ.;'0~ mB!3;c{FYx+з HbAPq:0rP B礤CBa >Eim&} ->W=Q4s Hlj[ˇr#@7y9Ay4{K[Zo^溘tgshѥ燵wIzZ=V]@D}wN%8x q(4`4@c pÒF",+ @y "oׂfz_oٹ#t:f{2Tp'fǴ)-wO3ׯ_Ag =ep31X;+]b밴&X' Hq,69 )~IW/a){2EEL־;g&ѲVs '6 B5iG"jijĬҠrҗ{⚇}T@AuS千1"QCA%Ii B .9y1gLZLQ{5kk[z,AYרϿ .ۿ4eN"lpJx}'pƶ_inyzs-n Cb !1[Vf\d.7d$)D?k:Y$ J H)N TD"|ia l?} jBE>S>ɟ 4,82i+^JVg#n_;01r /6+zÙ8`6\ςC#:~Ms2|8c}`_^aQTI|"O+V,?3k_ Ր{m.|&ܙNUs`G5֛l߃ iVj9l"8W\~0_if p<4 }(QP@a/`e^fiyc2b8 V22)%d`K [F':l ?vG=FNW:}`'*c_k)P8.Dǽ>= oz|ozcFӚ u^LYqIY$I -',A8JEh?Zx˪/@+pVyDЃ"),V~. ׆f+_94B7-ŏZ>)q*kQe %HeUVhX~ e7b>.6 wo}~4qM,4k^_<0Eʖ+ 0u(7v=$uO{B^An\kms)O9FkQ Ix@ kpVI1v3/>/t#%P RiqJyIR,)9x⢬e=K-b-@N}qm_Oa66ֳ;_~377}x,>&׳OI~뾻qɟtfh,44P% :82ߢh1C@tR aukX5t&#&0DqZaR7!5g-O޵@>zwm(Npp}Rfnzq$Q8yiMd#uz`(V[ž &R_Nз~K?-1343 :` FC 5DI,2!ĊDSA̱ (q$ɃT< ]5;aL~sӤİ/c kσ^ҝ zf9"ߢZ^斧m;l5C碄11fZ}>3;աh^RR.Ҕ3 1æMxHԱ"d{ws{Aܚ"_4/@W(lOEgAEJ&;;kkWua:>'"{l;f_tܐs5 &ӢУG\H;fS=gQfF`JRCɠq1 ( xg!"Vzy5dIE`&qÓd2Z_e))u _=߽o/~J56Cg8|40+[[?Ϟ13W\#Б殿"q7mug}󷇶;ݰ{\̊wD= %N**m&{cۅ*-2 %J0♠d)VPY`dpyRWA?짠}mbyZ_ /]zEq Of?[?m0NS1ڣڹ@euz66i8K>"3$u?Kת z "%Râ@ΠP TQI !\YAuwp./U lxpcMfy5]/~u0\M͙#%},L 6`5)'oX%Z9%RcbOSIx`?8zPX0t\ I5N$#)&+g(o:s\hD2[X:mcmWm5WLƟ1]p(mGĭO;ۑՖKI?Y^'^ܞCqM]bT  A&eU+b"~DՂ"ҽilDD'0%Ixצ%^/~;[򯎗ǛN؜ln>_32dp`M0ͮt\-?ss;}?fG"|ku Q1DTk@BqUSR(-Dq R4ż,zMDaGA֎Aj8A)N'u2NP?às]nؗ^o4N-h'5j*Kv^EYurw 7\!AuuUePMӰkK|qw A `$hpw,Hp_.YX|}fz:J͑,xуd0[\-R< :(OT8V)ϿPXr\+ r$ǡݔT(t)RO;NPe+2#?XT73n1O#H,\gf)bo )!Լ)7}-J-W&f.ambnEZ!G HK0-_o&BϜc}Kɠ6p„cI脳ˤmd_@/R<Ab#@$v'ѧ@+܀ ɞ` ?S(Xom#pIȕ gǀůxO G35ixl>Kڦ &mj<26쩝 2/m"P)'َ%ܕDHU( Y<:!) M$i$`]a+l {~SAbeChM 3lixԧ"*A~nVcQ%(8yyRTC*fR;?3_.ƥyn4jr['ѯjg^(;[THދo*E rH,FYJfZ$Bf 5Duvr\]~T$τfXaR;\;WVm-7S`-LA Ճ ֧"] @qH|ONcVzNajH.d庝{%QMh=:h?@q0 HŰ>k!zH"J~1}IN{;B72uRUI1{X?JOA`+ vi{@hozx4ycjiacZZScЋ}#XcS5iЙ2m@ L(K+öƜQom9ڃFSU vlp8XOQ9% dC$& d4][FDl.{ʩ 32 Z*88zؗ0(< wnlPm4_u$5f`b*~v57範i <&pP"H=2-@>xJŞX #0F9pwy휁j|hƮl8D}:>aWV|c>Y:$Pu_-g0Љf &Qˮh5~Q%ヲKP^e|G/{$fnduH㬚%)' so#E(DWԇ㖄*PB_D512JْI⮇IƸ_h@ eEYwAU!w>=_SZRz39GxIJ(ZMmܛf#G'HyNM6Ie*ܯ U+=-cQUCn32ޫMTOJqDM5R}E$ࣜ3SGoKuVf$b(HM'4*5sg@cXx?2'ڹ Nu4K_OpW7[%)/?ܵ6;޷hyfdq._f&bVWm:W UAX8Ɣ׌r>l$sƹ\(RMv1x!┬+~BO2}PUn\ vXn@&p BHGP2KiP1o3xDk,r߲qYIIY=@0^Fhba}Cү~Dؿ{WaoLRtZw?MuJI?D>'ә2YD5&/TgI|sES` 'y8Jt9pRNr4[+OLpò])Iu̐Ŀr\tRHB/})Apc X}Ša!Έ%k09۱,@ Ǎ *}6+TF>tM!͡; A4A*,B/O_E~E&u9NS\c|b邨;iyU?oM<]?K6(KFs,`=KVrJЋ~'-˟NГAg)n6?7*M.d?xarTcil<CI7@ ?4DB<n!7IeId X U&qB2x ә9-VcSEzY-gkef8?@O}u -G~>Ch[F?.%_ؚwdT, `eI ܵ9-&0W ?ygF'S1k-Fk) (|vq c6KOF@}j8d>?i3mO€a(Z4P;l5VC9:⟊mjqkX.dՙev^<ə֌ ;,f#-AW؋.@4r>1 L !唛̐OGgss^7O .˿WKztnpY!QW'=pw=Y6mvdѲ5ɮRڼm]lQdU?- Tpơ[-̈ A@JYM'/!'%9ט+ zDs?12\G3|9q>7 W5.q*x(Z.VLȑǠWD.`.Lj/| Bߣ^Is&c03M~H5ZWn;B+/T<>a.6!F>S~>c uMTT]B7DOn JpЇPeAlCD> yM@bZJ ^{p[~gtq܀@YͷyZXe!¹ꥐ(\bs6mNq'ipZ֊~Mg7a)^LMr_nOʵKc+ 6WܒT]a!-ژT,::f`ª:}lMʱwFsYak1}RraaYx/AO37TR-m_~ 7GlgWܾ$_Agc,\k6&?)φj$E[5ui6(;&6V~OA -u2sS@FSeٴǃa?)~%k:_r98vr@%IO^m.0?J6ER;JIQd)Hh/qMI ;k4~/c%#Ϡ^7O&5z)ǂEZ\]NZ(}DW٥A3թw^> Nrί=±v'ZLg fRtg݋yeb//{&_Pmb1JVP lo=BnN(Lv]IH>S(j:D#MŊe[l?f nH5 NQqj+PuӍ )ҍB.Vr-E';){Ȭ5Y"GeS.Xe= Nl =B2L~@ )x6Ms yQM\ 6t,3?t<o䒯6R1?'Nǒ"wDn8K'yQDR*X }hc\;{tFbz܉vNK/070Qұd,ٹiGJ,#irD߃nX[57G{]͉_~S]hAd1up*}_VqS~jPzz4Ҁ?TAOẗ́ [1#ZoY/FٍEBy:x-dZ7qn ["쟿$ܿPK QL*$|1i,vkVOVp/+ܜ]vf~k( ^ρ'%,ִ)ٵA4ܟxm1a dAx= /SIǍmX(FkaLAG~rV&L;Of:7٦ GepOiawo 2:?G"mv uEY!K[Xv{S[|-ߧ1ٹ 7kg <vZ ;mg /&h ֽgn.Tdq`;$?wۙFAaN[LǗֿX5OהZf',JzG|Z 7N HzogV AS >sBÒXEbcaķ"K|_g<@䩰 Z"z6BGg\탦GnѻAPeX}Àb&N]ΜXݗ㰚n) QI/h"{Յh*-j@&#b#@ ȜډQ s*AȢA[6ayzCž y\WG{VNuz>iYzE N[`e紷jȕJJxqXz["1tuS3e`|v^%,ũlV6mn s͏?J3?ƙ [(e]ykCo BfUXد~0kS YAXxn2(ew, :$8+n*N8dQi _bq8MV?) q/ڐ0J,̓fnΘG>wkۧp3'ƯUlKU_՝{>pW*(pS7|*K^DN9iß-P1vݗ&F~%^̋ځiVd{f$$obgjAڅ&S\ZcIA,ڂzǀ{2P*])Byl`_{'={!&Ϫǫ Ӎ ,w|zaʚΛ!˸Η#7O.v1`F9#6keocP^`Yj*T ʹbjLt*u{ |e90_贕P oI3xTn HR<̫` y7?VONNq78`Ood@XDg'Wʊ똸Y ^b ) As͍6IbWSXX>;C\ @3 ?{>ryJ|ko= ,1rBҺu0n>:9 r.G'_AȑgI 'NSv;Ur(\R z+[qj'Q-Mʛ۷5o`^rVOfT68 ̵]$>*En`B*șW6v ڛmuس'03 TLŬ Ɖ XEHXe;F7-A_1jyJ^jif',K/ >zӷ A\æb/.,+v5ZU%tu |ܯ|!*I3n\XlkQvV2*t*+pJl2$ZIE;B[V- UPi6"j&?KEC?,@^#MR-Qjd4a5'u_R+9^B9#?(L.p6⻫::$W})&čsۭX_~}ުf>F :KBiEE8 o^'/PCRM*i>F%JAc;jvmP]&h=<Ϡ "M|KI^<& lqOKh (%ў*% uI߃?$OfeGB{i ;#ԲxL\#0CHTLЧړ~i\ w>ְ%T6+RWLE+$'Rr͎*H{USQ3=Nsf =%uJ{bd&uG`JL\@bkw{t2] UubS`hz+-..qK QF.2)  &z@^A.旚(v0Q s8}x|l5~;ԡ8m\8/:nfOyp;[RMh[x'N GFף29*1iƦJfG{BY 7@|ҏ5g"mJǭWԹ[<5J1(8J7&+(rĄR+vLXSp%C2"{`*AVBP(ξc jvk]Gu@TF?Zphe] q^"Q9RR xUNe]=K~2 ^{t%0hVpZ9G0Ѱ+Wz öx*p'Uc'̻ qU}ծ-ʱ!!y`Y9񽣭Cy%hh&)I-ոfph$ ykJ3[%84ZAF xh-_8hԯayo\BCˌM[B4nG~ugA%d|? z:pmrP[) F՛VքeK 'pk*i.>aZ&&0N]}"Kk箓nN-pAF_C?bǣ}5_ ,\,Q݀d ˜v)}Qr`uv/M(qCZ5UD y٣2] z*댥1_qUPV=O;:O5rكkV9Ѯgᰢ)O $$ĔN@߄@Ye=j8EXnyK&mz`z/$fwgUa)Cıc*8=S>E&En]]Gpluk((PBˇ͕^!A S:IY]XJQ ~{㪿ZѨ^MzC;'~ȑ<f%;{EH%bwo7ً"QŦPEs&4FXE>)Rx-UGaw 뼼~놙Oԉ<˃퉨h$>IZ6frd 2?~W F\f{%ߛR1I7FI7aK!}Iv1%Ky+T1Sikh_ld%=I)d4zJ9-Hb}Flazs{;Zz{WHr9zkS|/B_KA#`118wPsGmUPYtH+](Ƣ _C_F9Z+˭7vd$ESTFf6gk}>5&֨,>8>y ߆*?EX%1jD%uU+I;L4~"s/{I6YP|)@>t[5|ttIHפtt ՗ZAErJM̰j1C ᳫ!OhCTkU%ol%&'|ӝʬ U}ǒTh.o>A@ ,o`'|)mcMXUl{Ƈ4E15,6 ãX ׆>vut%{aui9udtk hl*\5Ȭ$ޜ> 0DD4Qjb;k.kUyI=wCJjׄ}Դx<^_ Cc y|߻N FwjdWtziVqkJ|*96o{!4z?14gͮ9=&V̥W K5gۈhrvU07NDZsO6̷U=}(h^@QY)d#/_Л@m=ZPB'o_~0Bol?WJ lAXk(r_dvYR8ׁva5c%ò&Ur?{1#Wxm-ҭ/IxP~߿֠`믈 sc%DѺ4klBC|#4HSכ(_,BJBl>IJYD6f= >!x4S'1%D:ߔNHEQ)-5jBW˚T߰"-(iRi8ߝdYHIx)|7E$'VٶA\ h1og܄ޑB5@3h.R ,^c>6_]= cbN%.sMSYEcCAQU?.)=TL908~:g['61]\M3T]F9!FYq|$qNa$J?(#:~\[Ӽz\LO2xqP LD_ zCE;vH͈7zן;c-{Ngp/+ISgFL-%ChXtr4iS\$}*`ɇY*-Kجjs{qwUנϒ] e>45jVH8cod^3pX;pBI4yR5<ԃϜ$N_DrZ% :LqUtO[YquC[ۘF%Q}_9HqXh}M 9lLf;] x_ی^,4o$Qhmdhy$`,Nhހ^C .sw1cx>Z{lӢ<'*o+C,,٪H@NV5ܒK)٬TA>Q+dANW:KU #_yDh~ }Lc]֦aٿn5Dd=_Y$:i ^-Nק/>Rlk_]krK` ghܽةmk-L/(>eqkzX4?l͸"06|9 %ѹ|d╚ ,ә}];]#_K_K_?_sqCxf]%(`'[D<'lF&@8mG\YD,8r'kP?chdu5Skun&\s.WFN|c{.䞬ߟe|XYW8ժ7cGCu~$>D->1SĠ {Rj%3cp57%k+ʭRvhSd\.۱RT C:?3fWeD/o{u[LZ$n Cvjo.SL9YRb1c"6}M&:|z6ى[݊=.khW^zwLj9}9 H]es=I4ZZmɛ :=*H417.򫙥IޥGͷL `o:Sf~j z! ,U y^A6bÙ_SMbߊkF&++mE.Nu!/f&6r{ק!]I|5oܳ(PdKSVo-Ibf[*UQ7!DKg&HBcR0ee!eRObM7 5G *Pc*U Fd-D͈1 m#\}W%ѽZrkP_R%e!$* j/kpSUxk==5jAu 9p@Z"T cTV{rY[gb M SgWj m`,Վs6%5UFQg v^87b#B%%,ϥVRʑ5rF6(8"*,Bj78b|Qי6øϧTBGC-~;ȴEEA&@PQ5hx6gn8N}{L8A )ZzlG!&4ש5PHOE]0P "BG1@9jϳ@ Jxjou&Xbe6{) ʳ`QUlP{'GO^Y_mhߢ`?nVj2ƦnJ+!u:z i-I;ށYϮFu43qڷ͹5e;cלbOnd)j>t8VVM#.:1_ٗDzf\9g6k[R~6Q| 1,ٴ/=N*$[0ܣy{{uBjOㆥ~YU%É쬼3-YaTLW3ʵEP[qr*nCnfrm3߷(tbJ4qe& r6M(v$8dx-L#$Dv{.^_B0ۢT}Gi}Ȣjɵ`ar휔~:72\>2պ>qre4zy~v2s/C)9b0XrYK#lZsF24|53j3jŎ}40"qa{g ?tf[o{HKQ3ӓ^vZ⾾yborw9IԂ^¤?+J`8<~A3oEf~:~]__p])RqxP #Nt&)=9a~OΌ=-a ]ꋯ^u{⟅mpTd88&꥕(EƑͧA8͚VDc{}+WH26*Jihc] ikjz^˓ّU4w;FBt7 )>yo_tY0muJyGˡ{ϬX"m]a [ԏ|h#{#"bt_u=`-NV-?LJ.r òީNu-^]0Y((6g3yaK))NGNqb 7L(~%TP?k./T(L]`l__t(["lQ2K%ՍK7Gpm]\ydj{=Z{Z8 T㺠`A5ĵ!9縟xs+LA_Wkq:;:rONcZhέ҆ltZ ʔMW˥h!%E wWWnS[KiqPjw| ɠC*FhX3,FMGbvԮ!RõD>]Q {#MϘRPڿ76KMcP~ ":4*J_k]xU>< ZSsyF40፾Uk7]>,FGc^'>OW TF#*\++Q)L:Ot]ovd=G2 VXb,37_9]Ҧ`6aSM{+ Ys. Y|dW&kY*%8'+:s Ž+ɀk'uS?:6Q٩vUpUT:A:dH*Dr(cy%2Ӊ#X;a[qu]负_ېlO:G՟Vp8ImW `/[eܣ5]j|>r>j-[> >Ͱ.vl2?au9*4.J" "c Ztwʓu\fJ+&SDDv/4#3dl5A)V:5ٞW''箋oI |\;ֳkqRJt";p=e13e@?Ո 0ݽQz<,(TaYK pQ\=[vz UܣsJBgp2ڲyIoun\4fB)Tq=UXٍK({]#qǙ\?!0}|ϒ9 5{7C{dzx|4]6zlZYTB|| $+ʲJG{|.kK'ە>h?vJ4-̆~) ,#xIN࿣<Bi*޹/x2;f8}ɋ39e$__x[W7=FԆp~V(MO=^,~>'uCw,,yfn|#\ b=,f|{ԔJ=3<'lfgR|O}=LuָфyދRr%:?זD:ki~(-Nh8Xξwy$!RBqDa}cmmϒȳM_в>U?^6Tx_~\WDO=ePag\k' y{_=mL)nNpU%Drٕ&:vNk/.3Jh>/+ʜؓ يZy-yfg?wNf J )'B 6L=Srsc]5Ģ 6e%66n3 <*uտ O4z8>6 h"#"(l&U_m&;l[ >@wmtL_SNYގ[˯_4T9QGxljҫ|?P[Y0qfy*ryI1pd_]GSt&bchO51^ˆ}v4 vUYyh)i4ׅȕ:Eÿr>0Q|In6@>keJpeՑpt1)K=m4f٢l:)y3 W}9wnZxfٕ Hj>cw|:)m;F,ο;*$:q*"yh\hq}˻ J1&bi,P}dc8?[*C6*.ԕXuy1ȥ ^NMwWWxNsUhߟپnpll_^_b_Fӈd6 [&zǯdL/:w^3e} )[|,Sf#L'^JKWgq<ff-.G6|=.7 *܌1 {1CUAe(4 %g/ 8j0bhV?G5_ D%5QOK7>!V`<\l/*ΠeJcBOP ѦN8~m"ί<tI/fyD"5d:"7_TɆ]""Izڎȗ|'U0`#ToMq3L+KD|b@ o]KPVa]AEQ1$9Nxxzdq-Ќwf_RAoWhmDc Wwy2x/)R^OF?,HzS yCmKNqp}*ItS1$nx@~.FCN_wtX<ht{-׈{0.tGllt̟}: #8˵輷=  yr:V$nƱIڪ9N&!vko0Y} ޏٝb7ǫVE˩ P-rGd)t^a{SQ(xQCmKpzJ.޹wIWV=SeEwyh5f(2_oq@OD2,W ٴv h1Tl<.꺜CkҖdoY5}{ݲK^;?v\JCj(P+4FqXvSo<[]6+]iLAOKjGY7QCyu@X*}?-e󗓘9o -lo$-q3sբ~}_zmrT$CYŤvݬv$UG1YpppnE?VWY,T9q\4 \п\zP7lQkb #'{(E&`2ip4S-2%bšg9tDHˠuOH75 j@pdC}ph&G'qnM#[r˰Wp`ռhd͡rW Mw}k 1o\nPi,<@=Q7E5b2:&D$t;3'Gxw9(gwy3`Ȫ6XDE7(I" ^İD5>L'{Mxl,?%xfԔeȴCpFUͻV <P񥆥C-"u'Y=MUT /u9[lVN"S}o79ҥ&FIVj{㗬zt1pikA~ʭRlO־!֍4YBIOsbzCueb穖/C؎CydEe_M Vtv4\-Т'͉nfN(&V%]Cy6Dh,v*fڝjj3D͛-w (U:5yދȔ fO; fr Q[Mᕃ'#,?"]kVP,H|ܴRb:~ nLh~lXT,K7t '#2n<1'ʚ&5kn=镠Sl#Ri+uxtxȔȰ&;Դɶw +lcf$nߣkG~~;qi ҃.9)_{!ZMTlsCxxĺ6ٟ_,#^2L 5^'.j-l+ K.b__v|{W|W| ]qL]s2{R+?\x,d}_2R ; ?|K4?%OJg7mP|'?=:2¼ lϜJ"NJB쪜΀tnO2Ь*Zk;׮ J?==g,Ժ.ټ>n_>9.T:זP=L(^u50fͦp~";j#p]XP|Co ~Jݽ[ٖ.{*Z󯀯}e4GND6"riZly"kp~6^c)|3GΧ8o15i^g/|NƯU5#[g)%>89xI:MEfE~'C,[_|E"߈q\:;;Zʡ;`X۸xzN|za&n%ç"uLFVޱ>fv j*gѡأ^e캵pafY׀gw>y-%ep$5!;-KЕ؊pE.(s/΅iwCnHQCiQN#w{h4Q$CSCqƘY1O`E䞬P>o& s٢CU2i&/t}ɧ~pwSx]x:nX_1 3|RFתZJ URü"m|K7hξ_jӵEjp"ӆ6 8\I+'D}L?:8 V_tD+\OG|+26=e9sx ^' ٟ<'\~'?#1wgÕPhr:LT/ʶK-#rmXrvuJSuCZIx3{?wfb N.vҟt-Y96SDgFtiHG@y2 XEg͝gsȈB28rN5ڧQ3a8ُo+dhBu;h: dNl{_1/;K鷙v4(ozY;/P\e[ǿLssp s0ŷ$HP^;'LV @|Mxv0NNt_5@w*_̐$m 8&V&Tx*4o|JE}s?\9ԍ;g}9(ÙeMuPycEV_eoõv] Rv3.pC6NX71WگDmK&ClC)h-Q눭ڢ?ɋkUbe=K %/_R!\~L݈F)])?,4M͆oXZ7jPDPKLFIɩңD`0 N ȪߖHԅ ˕zPHQ'ED~R%տF^YaP`vH茨Kn9j& 6P3dk # ^pqIp_g[ʅ== 'MU?*I@7tmK9D 18 2:b,Dڥv*侚ʭ,ADg"+Su NaoVBL 3so9*_b/i冄DoVNn^֩"D5 7c?7n|$h|eɥ1 aВˏ7 p2щ(L ڒM I%;(.p>3gCEkir&r:i hAnF`/4l8rqSbGW=2>XEq= !nklBx %e*9Tµ/Fr[Z*QLm9u*IN(Gя:VkOn\,C:zD'%KqLH"}q?/%j ")hsgS<` - ;FPY < &t` ڏ/h؝/enJ#E"#n,{"vI8b|rz$vlrH1y)t$ ph;6eϼa9߸!4ӣ"}4 FHQ0xrf ZB ?(yJ?+`21XaIYCrB!ړ$#P#n haNM32 DB0ϿmK B47Z$!e8hAd!hܲI LI1ܨ$tt)"("Qcnh>h!`hpCUty1?IH'#A%!i$U&hˆۈ: = w( {yQBC`G!H("}Aa[\%+{j&, 6TPT`}oH~ Xn.<+EȪ#gH;5d:o7:$ U\VP$/B-=)_o;?!_L~` AuKĸ(6 5ZS2-Iޜ 9gO Ga=ˍB 1B({FtT>\;sϭhE&d rKE2}K9]%e5yK;_!َx[NlU?}G'8V Rp-\B`\b]1v4*%H1 l!,q$ #o~F"! .ϫhҟ舼C jNĠk`Gi^:ev,S)PaݯA$s>H+)1C% RQ$Є(3ot! ɃVp>UbZ0+PXb O"/hp˲+=i10ES=RqƥDAqXtC_֨}"lEnQ _`3ueCƿIQ1CP0b(bL0۠x.MSD]Zv($`>϶e5-̿b-NʰlC=AҊMQ>A$WU VyScX/FCs/B:PXAH 8]{O'=_Ea\ޏ+&&*&8!/#:AP6~L"@GbսHwIMDU*,ۄ! şo, #/cVC];ms'%7{"ڟ(5\`(tD /  7>dcۦFB6[Yv!eeOylqghѕV%ߴdQ;7>>{ϯ{Vn3>1MA}J7Vifsm6¢X4q;fN:<))σ da4/tiwӕ͵ /ÓMR/ذ##`+bWp C(p ws?adi׭IoB|nk SHɹBu'(J88Mb5paJXu|<lx(p5`ٙ`:aм˄6Y+}X(kbAK{c$^)k?ܝ+`~*3g@n/i=ٰ]􌟞ZY=،E6XI(5ypY兿yؤqhIOp{2\ivZxnf~8#{9A}s8Cx^n)IЛXx9pQ9~[(H|2MAj\F-1bpbEZ7\cފsဂ_2 ޏcY얬|mlg_@~< s$j8;6w)s}` ,qciHzH{~ }^Yrq--$p68[_tO0bƚOFx1;vCx?"?u1?rjWR6 3{>r&ZTfg.r}{3-8؏!e"> jؙR%F`;qUyWğxL»VxP`A=)eJ&wOHr`\/^!#. vZ}?z6_|u*K:'e^\/o>lR̂I+5kzh X| \7̣xUVh  8l}ܮ.xyZcGù_j=^aGVw#z٥@5 &Hhqu[ꓗ*.ƜȎ'eg͖0X\jsӮKC.di\HG\7,Ha0~f Ό-Nw=Tg_ de>>Iĭ=S{Uѿmhgk)մbڟQBh"uT }]  1 U5hGp1OzzOKUèvr sxA]YVa{%>OμgfxRNokK䝬շ5G ]LVt+trӬ] _#wM\V2 9( KNqFc2>^9s?x->nwpRb=ԓ+f__k4?ǫx=y*rM_'jT{oy6m\Jl6`HJm$;ǹ(-oxKHx2,¤reo}Ю}mȓw q\I턈9R}lyփLD_{^gP3`2kf:VA]•(Nh<Μ%% 4`Z*6"%k-D$opn̪ ~ sRyWCsNgL.4[FԼu)ewQ&87>k (+\7 u.'M@[ u1g%ӝڐi;{cSKccDXd}=~T1Z-{߫+Lc}|C )q k5xzY{aoh<:˟OϹ-۽el/ĝ.֭1% >O̘Ms"]ۡ~| 2RlexVY;M8~Ξ6u5v8(lc4Z`FچđIʋoe}~km +ܫ0>&dz{&|u6/mTMKۀϛYQJB3SUj˵M5h zEiV.8ސ+8@B{ʖmSm`ak0SQ1F,iOXǬj߶oǛkG Gda`T!&;\elEqPK R*Am _|!f`<[*yCünd*FZzϪm`?@0[E|\qII.?E=q}t86jw)*Ͼc;U&&XsS(0NײS%i1B;&bqj1۠7tߡҹwf+g&mQߵCuj3|C"5OZž yTu-l=ÿɮ5m}t|ՔSXNʏ>A"4]{7Vf6ƹzbJ)}KڹAT ~jc= v.ˋng~RP*'p(,&U͟e>eog%TjIb%Cz|9o&S5[#sOJ59AaQ0LJM\J'KYFsގ߃6ج+[p .FuҚm8鮈6*ثm k{=E4~:Id dMfópDHv*NvϯDYu(Ѥ.Ta=\JP#Lg4{ز><7FN;cZM~ ۝$ pY G[G2ךr|Nw i)>[&bFzRヽxGѯThXl{֧QJGͥ f ܢˍ)v6{H ;^Xb ,| 'I^c#eS^$[:'Q*8pQ;40m .ǁ`Tva omNw1 [kDIuʠ 6&uou8ŏܲeeZRW;(Dƕel+U%RE;^s]~XIjj"p:0gVȹC?fb㘱s7%=X.t.7?=†K|}fkF$U3AM|$au j/Nbkx4~IN1b7W.b}n~Jexx94ڗGv!9wyΚT[,Tr *;,Y_{p̺stLe[ Z;UNozgxy-_jjz)T~`k-оkZ-XZ1ȱ̙ud)K3=U4<FZ<6oe_aO}butuoiMg+kizV=n[m"]tXa~5Hk>}y3L|d$э=ǖ IlT7$!`+E6O{NAJαBʁ[$vui3 ҽJyKy0P Yk=ChIWNsop$8f*ƀmjRNt?qxHWZv:2V ,ݺ3q&Gt*> F1Z~PNf^YW,Ig}4C刋~ _ kyM3A{1Aͬ~yF9|Y{z?6E!ÀnjnzsG_,{fF߽_~9θ/3h%~9-ퟦTV$]_l(xuT϶0}nk ˦K镵FJ%G+z6M7oiQ*-Ϯ)|/`1no/o;L+& 9kU<˷,-D-%6,:5%dD_$kbYᬓ }O?"zgyN凍L]t{^1m=`ƚkl?|X mdzX6\{S0\EI"[Y*1g7׸{-^-Y'y]~5lpY ݔ}k8ѧ2Xhlwpw~CVϯ:]'ئ(TJ$F14\ttNzϾc3үWL0^=HjX_h14-IF.e]\]7 rpW>n1ʜM94ر;U/e֫)ys ]ˌDTݔWe-`4qKء)+xferB{Q}DqփL;嵖8n9W}8|өwcip]]$Y;O:Yx)9Pp݃TZ^\wYSVZ4]JQ,ow~M0Mm^{i;js,Pe'u7?PۂMSPJYE;~o%t(/1h t@eizє-^ݺ}"h颅kN `g*xK_f3 h. r0-i0XѦzp/=,˒\F(|D)b5ڏWqk-v_~ŒȂ9Nw}_\~ҽ8M|^eb4D|ri&_?nd`r;&v_M:9mS~L0S! 6<$K. -FzÍM3dlu~!t4N4>Uu%}LjIן}wkzkl >N&_Suqzi>|^ oug,;m8(5^85ódd@y:Bo<9C~K B , ̇jJ;"ShrM=2LXዾ*v{q{&"!v@RHP ;5u1v_QJ7zFJ/C;}ʋZ&on /XrNl_;j[I݀){B ,2?5c/>䥿QE͚fbr!OVlg&Mt㇟St;f ǚfG 2Ketδp=tT;ȸB  uF(@ۄ*Fnu[ztxTFR/+^.̟˴5ȉ1#bùͬRˋWCnftKR3'F$\N1`{ܪ0t' &DXvU+5w r 5h>PI)d7Zh)D (-Hȕ+)i: A1pLB.Y.4 IU 8@VUJYŴP.]59D 1ɏ)N:K/`$JD-S_МK҈O,$WA0g\QqQ,2r6,+ z{(7̊VaXCT /vdtȫ![>c'yL̯4?pçH,Mj %$I݃p(J保 8so+OߝeA@:?~;=JE9e t'Hk;7-mnCTPg5,G9!]E'7Hb2 ,L1M GC  foJMBSp^ EE{R0/uOl2cCTeɈHxJ}8$ށQ?F B{ IJ(H n85x3BΠsC*(2kr "poAPE z۴tȠH\\1I+x00uaAqcY?d)CCP!AA(PinZ~/BEkFo2kOCO ӨIϻQYk}IM b 8)ZƬ&"@.9%qR֯{3Q8$.Yb䦿=a0Vу-y+M,"kNHYDLkDɆ:h:z`7G iHnZ#TW`.U4v\gNゑDϹ/8Sv1 'K96%iG 4U%'*;󎚴6.=c9mEx`Aj|x&p#y'8R1׼6\ZdtIh% ldf9NJ3&&wOiD1s|P@rvF˕|хZ_g!!"95Zzh%RᮟukYG˙MtVO2I&R!ڱ]x"\ w 0%x,'.>~9kqDpDŵHl}ξY2}#TޢdtRACЎ[렳}e9yJJho~cUJkyUw^ wڳ|_MGz-vrndj.z5$+H xnfQ6hm97˾;K:r6K|gP( |){f{uRܨˤf:%s8 Dw>k+Gkőw6 3ƪ]=p(-7zrZQ[l8|8qi8Ls P-{b}Y ʖzEri^=~l-zi6$`i$,1M~՚mOwϛ,! O  0ԶEny J{Kg6n˿]x:n>rݜlmNԞ9<6h4uuN?D==]E2h%0[/o XiL<YWmosqt21SLvy Ttn wA>+]m, im9 Mqgi|7]ڕ=, eś'kI{l]]t{;)x ] hiϡkn}п}|[B0Z~y OxƖ f~_}]ǀwc&g֒iMߥ4S>'j/t`d5g(pܻUo$?UM9ȵ}{u̻X5-`>нm-Oi\ޯT|g|o$k&DsyfX6w{3bqdD_9+ܴ/k*wSoGV~UVPT d_'8{ob'hK _xOC\߭Ni_Ьϵrt|SH\pMG ;9fZLo)n&D+W|=!g!Tk̬hxEM E>.%c9Y~d!w{_:u {hUw|78䝇a6dlY(,Th哸\7w5}O^4lu9Wr/#C>]5R;_>? :/1HZv2=2_ߌR"[-uS e{s>:Ƽ?]30#x>imuw/[;dɲF_"^R;1¨^"| .oPV[ej^fnb 1qZ8wqXcx'֭J.|4޺cR6m`)l~kzrlŽ qRzo>LTI7gj)c: :=h$#Rc3u_fםlUr֏!/u6I=y*w`W޲J8l}}/:Gτ?)tn5,vcODI02%ͯss􂻕yUuiֱ74QV5<HpuZ :0᯶ +_" Ko|O~?hocq nX(mkBM{=~T & "Ff۾<7i8f+󒘿TI-J x}\p;.sY6XbT<nv}dSfx`C@ZxƉƾn];zcqGGWA8qk?wzPBX޲nk4>0.YbX aҞu!n19}ع趣5״ Ԓځ"eX3:8"gSV̸`OKk_gĚK{> T=&lDsU@Ah9V/F+i6vұm۶mc۶:mZ~/p8ǜWQMޯ\CA,$x)W{j^{eCVV٬ƻF79A;ÛԯS\*2+'z: /dݷb:I(Nyg9Dݟļ Z|v{祻$OU{Gn &aToTDE5N'ŋ $or"tv͸toײE.3ҏ^(y*u_ԆCeS[<zvd~Vry¦ԎsV?w8?NxDdeXz>yEIٳtNwIny_nz$$Hpa6y/ON(f\{C}\E ߈-FO4@؅\lqv "t[+ á鍄_ =nA'_ݶNC~^ݧJ <|G(s!F5ߤ!ƜT"ڑ{4ǻ\BOf--+Lb+.*`ujCc4لbQS.r5pۿm-vo/R/L>] Mz_>?.C3kH3L4-' ?Aek{z` yy3N+ m\ݱoqu]#c??)tfUdD !Fշq*az.jZ1'tBBشdsAyNҋ<&Ah rls٭Sy=G0>{ٵ>(.?iYV(Y#kx!}f+:d(7y_WqV>1Z[~l6線0 Ww]qBQ3 v'$1D^KG1[:7Oϻ wh10Kz!wh00람g`7T >> =i8?L1#zP5dCҖfZ Y-GYq^2(]L.T09aͤ, N+?SNg{G=K殌K/ ۹M*]'mCo-,ѣC{ 7-.{Hqm=0W~ϴ%XS%0-,-kɨ*9(u[wķէ",uX[<.g8 NDd +{]W_̣ͻ |&pVU" cR9M& %.-1v9g_'b|oVU[ ^-)~F&ٝ-}rnvHmBf%7oۣqv,URHd[a/Aϰ2ŧSrI7./$߮QA;d6> ';|'1V3έ^g|g敔hn?R;3]9KJwnϘtSBǺFK= (Pֲ{^/3Uu+W۹:7/s3HƩ"܇Mn{љ"uBYHl> b7,mbךQH'pufWSN<|6{h'hsf[<9>>K2n1DŪ#=|R圱k'엫h)쳢k]_Y5"/=Cwq#W~\1[* ctO9[I/Lpzz'!Iko GĽ36j+GHBZC4k5+\lG+.J}%"KүYv⣷oJDUk+*h\6Jv]fEec]Z-z.WIQGit"K_F? MwupԮ+{_Gٽz} ֧P'K`g~uhrs n5eӬye|-4zJ>`Ÿ޾NGer1뭧 @)='v_neCw<۞5Ͻ'xH}6\9"?WrWZ=7c,)0a废؍\Kub-/ x&3ݧ~zbkDEOw-0zN[8{J.+}؛ US2G԰Rd?[lW6.[e+r\>Efu#c!A4Y%¹Wp,n . N%RڒNZV{YˊxN r# bί)ە=3z 2?&Wdb<-C,S.[ f~>r.jW]lCn/"ڳJ?no,,aߟi;[ N*89-rkico ҈of#+r˹uWD)rE_]..;ȍ[+o[yXxP7'Zx?e"]lW㯳x^5X؇lٵNcǦT*ZǍA-N}Q8`)Dm9&h)_߆8}qs b/Gϳ3RGyoԳaȚKJGპj{ŦtSN% /Vxw>];k#Xg[foql"xOu=0_vfc<^~ka3gɉ*)n~|uL3r<-XL+ۧ2o-diMzn+V Dm-B[usUW /=}/i^lQv@D?;w16MG(blL)xAE*\ 'H+DR&-ItYpuGYT{ؑod:&\I9*| {aI` $H~'4QYm1LKɉ-L9Rm Y+ʼn'D˷rx@A#NBW,/!B^dTE$N7ВTO~131T@r7J->{FׇׁOف9tHatːU( /< H'"oMJ.B 26:;]V!pɊ>n*# ,CI|_ -…k 6H@XENrKCJBg; ,wEH|W #YҬX,JD(%XDhd0GUb2,|< r`:w"(dbV}: .LcJbZxɹ~ܢg VkjZct%H@ş>+`U ђX%PEJqLei HТرCs}|~c04y)6_%w`vAzH-Vteb$ riqz:#teehJ163ɠDk>1xb+zdjhױAz+<`C@8l"#1CV.-:P@N :[&LC~5R-Ke8 $F* ?Y~lVD[$r]W|BTfBk?,xؙ֚4fh1x(-Bj]gPom0a "u=) AFŔRN^C2HX*ZݩDJ o~:8'xE!OqEg [ҿhPAt_6\b6E`.draU%׊D*V ywL)N(fFe-b%:` d F B#LՁ, GWTR# l1>:nu#TKKzju" 7e"c9Npmnr"w^5j= q)%g+uDl>BzޯkJFFuHZ@ac@9z 6/E}HG>GljxTX aߴ O%R:]$1EE*x+%?wPoC , t4F4ls) :&+':Fz_)( kNhjfQJZ{H 6':4uX*oQC x9 ĀP Jjh NxL#- cK=e RF,Pd6P|Qz+ˢ=YI<u bYpyVV!%JUKLg,2)?{VXR#p ɑ֜$FVmapZIGHJK?lWI/x%4f[m@LUEz3PB Qj+UB1 ݽUKKǝRC4PL4*0ll.89RSm&˒jEƉY=A" ) QwE%O dA#ϸ}$R0SLdLA4I`Ҡ4c{B:(pPpP`܌)d/VM<5)t?$q|]9JT EqjhM4z"%yC}@WZ# sEu%NbS|"EpM6MU[˒hn]MZR"gP .)wø9Zh.`ZJيJv[vx_xs{S[%j ;=>ԀA0kE!-8A+SIX_2JzI2Wl`x.8`>ְ t:J`ٓXZTqvȊx2\gФj!FS. ? U8a*xJ~Ǫy5f0ݾB,7:|9Iƛ p&&?x>?63#7q g( ƴLPRs9ФGBJW_k}2>W"NBODby EoE(-?ք'ZwcM0֞M` QGPiB ڱqx`kH'\QYpe80 PDt?v2tݩ"-ᬞ8:sѩ0IK - #خb: CJk*\O°Jш=c֋{B?'7)4$ $8B@%x6DEÝ0cD`p Q2?"gd'/4J QHW {NEj\14,|[֬a}s*L%FሹJ˸KQ$B>дZSܰ0!С0p(2Msla]=}?PO,Djum r{Ql6ҡEYEh@hKq66s%\p$:.KpWH7[- B1ٽcC8~6]x&:,VYeؾۺQ\&3'>V<|K %RQ⓫HPyo;HFP,EA ½F)J]t309oGDIQCLت'D͞ r2 ֐7ZD$!0@eK;gw03; p TS ԓ=RL'Rޒ 6j>G*  +!ִQ\jHy(!lXiGAPC[@j,t*;J]a*ICSpBsϧ,O!FJϤ?!Wܳ '6O/<68Tiw!̝&f߁ xO7O"p}m.*`3 GȨJkYOJa%rcwJIr/JnA9m_LA `^7S x'! $~èU>xA,:" )F".R\"^ 0aJGl%]@XpW9̱zZ/ a-p}ue/̡Ud0JcS|?&JLp(Pp LRC0X(RM|–頛`%(RA 54ADPXC$9hFQ5QMnǂFT(@otJinၺT@|AI2EO?8+I5%(jʈبl4;t 8"9?38^gbpKGȃf>t焍J^bM-o`ґ"0ưt! 2o-#ۡ Ahws{wG-<L^`/D"R:'Gp%tg`,sۻǴ:YrA4zE1r1M~NlDp MX0".@br2\m.=#e~RJT()wSl(:l`>,(HDR=eKJ_ .N9A`V=Ccz4q8OA.,><9J¡u\Qi#KuKYwHccʝ# b߽!f GL=GdTΘf@`}wa:GAÍI=!\'vJ,Bc439nځG-M_~Emit#YF%ݓ;v( >mӑ$Px90OhHI- C1A7~޿|^Zg`Xl , mT"8= c ,$/NܐjU'BFHZ%Gj&p/|ä+Lk84ɔ|~1B# ˹O-z~6W$~#~8;cA@@` "rgs'Z9 % Q%͓Tc 8) wPI  ƏkwP%{~P3[keqPa*$CuCX˃E Lo-(+#b7Bfˤ)&1' @% #B x@ L=>>Kj*.DvQb*1nc^+` Onf+'i.*Qf{= y::}r~us^\ޜ5n:=Y^V16<ӎXg4Mg^_Dgsm5$`Ʋ+ ݈AFC_sʹpU93p[)q 1l,p,S\$+_Y"/Ƅ/pjdjٳV<nBnN?ǭǟe!oK{.QmxM.Z:[.)o^,bK\i LoyVd6Wz_q˲J-o2݀7i  NuǍ _8:w7H}e=P\#j汆5Qg{{|i^BWC/ߔ-7ukE?W9BO#.wu ,M^N1M?M<Tk\lǥlzׯȪU9{M"~g;#؂T|,:/;}N>X𻟙^Bfa#nKNQ*w8'l Mڳޟ].~5yɬ+Ϥt͸l?_Gb/nP:Rr5|DkKL^)@o술~y19&ɩx'A"诒o7|'8+HeNjuv۷cqfX/KٯעcXUm=_F'+@o7n*k}{臼e`QV:0y}G{XIu_8zE0.tzydAs};)5Qf^,ވڦˮ9ihK=ߊ0-il׮S k!p'r(1He|Y=*FMD}P!ջ@{'gzص{i "ۮNJ8Y ܮJi_ZĤk4~.'ZK9l}]r_َ^5AwC]EDt2WtkrڰyWT>y2gI _G-"l:*/2RwksD'm* ٹsVx$Ec**^4|5ZO _!+Em$mL'I<61˴)MJ9U:\\;blSt/) jԟn_!t/P]>=`F}Dϥ@56/ޜmvves~~dXhL~.-1S{,pE3&+3tTk&Ebٸ\$s' 922u碠lN~W1=qq~f==YW\U==}`FՑXrH:ߡNJזu ;cp!ݍ%0F!l>[u񿃧z7T˯'!!hy~;46v}ki9r-S/n鵁Jv ^km"z[ M^ݕgrZQAhgC*J€rYhorYYN-5 l;͆d'87g72:Q>r.l/+ 75핏~,9>s779JsEM {LN_wobȞ-F5KFx;Qi3[]6˛I-Z-SKezQ=cbBf`x9B_o5/8:DpUY/ Ց|34M!Q {'yn,v֮ܯ爰[L\`XI4A>g} ӆUomfeA8WCO@Zx?:t.hb!DA҈ԍKQ׽wɬ'[4#fAݾ{5݅KN'53ݵhD+@3x_no JjD*^SN^=+  O؎eg?*v4>cܦBu-\& w6b1|t 4uJnwb\Rơjk%Wq+1˴&nwDOu܅==r[~~'*\nL sfk;*geS Eg}ApU`f3޼u-Խv5%B ;i9*1>|J]]אqyŷ*LxHɾ^۸:ߖPOre%r5.88M.uZ8|B2OKQz}w^i|8SY@XzK5Ɖ)=%\zJ9W=`%<њݯ, ("GWCզo¦|Ӟ>S*ܰpn[}>%&|r12]O EYt$9n7';T1 Yw*Uպ0Dk*uA7"FnNװrWk/G'C|?I}[˖@~f>SS- VʺENJ+7v˳kFEZD|kRi&Dus@tlV㹖b]$66/Oə,Q8˜l6hdu47"'Z6ZvK3~ua-WSY:B}%K?ϕ ^u}H,Q.>nb֔!B a4TT-^Z/זRtLP^6^uAMZl%[ ȡn7)jER/ sb8w'`- pSO o)!IoESq@I[@;R~] Ħ۠t6Zi-u暚Vob^Wg9;z.m7Jc+3rfLv#)<4 g~j4ʿa7ޞMHh0olw a'_0",x[e|df~y>qy.KhleT$[K*ϔ~ KV!~לm t}\menRo&t kdg-v,=zԍ~&rϸ+x\L)F&u.ni!ǭ$luE=>^uNV pHT \߸V|`Vx_f-ό%r[,'@qnqw ̝Ԫ @^`~3crՉl~%6wP{_9xsRѺݬAx=Qvz5Fj ~2KP>ܞsܿ׭Jxzr2]c6gvnxt%~v[)QBg`6{w| Xy8m#O?+JuФwa{bv{"ivuO]8ԒU:nU jkCg:VK.\T6mʚ@j=6do#!l{xdӼENbbo鱗f݌=eN\33 |}96|atuH#laaKZYop_;]V46X6ޖnjʼ~gUq۬?)&5. 6G3跱,Rܧo8.Iuu]㔆bڵL~K./K 7d0Μ]F?9MoY$O>E\i.O[{_mX ovg qJ3M^x[t G]$cxwh;]ƁR%W9 KuwK:v\xT齿mjL?mٰ6q}Ԩ]jvu6' {~A*ܵTYyO op<{Vysg3-6`gkMqF﬜O?pLJxs;i]%)S&0q5Q_ۣP朗WE05Nf-{^0K:_QN'r91K2ߔFi;cr灭۞*d8".wWBP4ێeQ;_s,Ԟ\Gd62,Nhy~ffιvѺ]R"ޫ-IZEӳe9+XY(.K*xP?ѵ {̌Hu; 9!(r*/ F;}vNyrrH}fusom1]Â-`%f ^cUF@_C*Z3#!T,AS:I:|9b]Td6{=_"_K ܎O|cd[8'hsW=m5h#㇡x>_ѷ#dX|mÐ?> NjLDX}pM |pGFk<*YKq#ru{~4ۖRuk^F>RJ2f hFzbZZpq5<_=(oZ<(ڢХC|#{T. ]nd&CXOpE*lPDw̄9qܢb=p)W|Xprs.7Is*6]H-}1J;⪌l[t{4+E{&˳@Y㝋v\ƽ-W^;˕Tz(:0|щaߗ! \Bw$t m`uXӯA?-#ϦQEiEPM~(ޞBΞ[z~Or+Z}SDGKӨl3zg 1 k9hjlZwpm?`z4+\ؕ4oPlj7ד7omln}Bpzu۳,S9h? ;;\lѬޙ|tiCfZ[H0q~2]cM),ӸmQ﷫Gfg;?(>9u3U!Q\R4P)EV:*Y+i*)Nj7Ato$vsmvK6޾WwEV{uZs鱸l ΁o8;Fb?%mvnd M,֗Svs>*z6jMTjRjlwaSÃ~6ϊupގ𔲧깋vnCbt5N7!-2M!`XS؜y봐sr nٹu9&%^m"y6Ϋv"z~s)mj^cf2C+McMn n 47qٿA=k+NG+A|lZ7dU K +ܑ Kr70 +&O{TE ʧmW*{PuR{;zy=j%BF} Q"mb%P"[؇֘x{|0Wkɔ^'z8nWd q@9(oDK$%qwͶ`r}Y ]*018NM{R]u=|ҫדtS*?]΁°QX@xXgkﳥ팃}j+Ng R|dC&b]ы94% ݿsT~_^o׍c:;G| :;߭']%u='X]a.Aȹ;s#Ui˽4諥;;^Hoϝq:@=3yvmy}gO)w@X[AF~l&듼n/G+0S6&OWsŦ^ոi{wZn:01 کؿ7Ü,@*BNOGș78/]l*9_Aݠ~v2r4߱giy#X3qٵ37>X[HyYXbycwY{ԑᵑrxkaful^[SEvy zڀ} Hxa<͠|2NvkXa>x "ѲZLsm_qV]9x6cx=ը۝=믹a1VH'f)1m'E)b!2_m. }6F޽5HODC֔j Ar DKA1HIF#RӍ@sDAEkAE!dҍ҈+ktpx.YbZYҁf.F1ځrPz#*$Pg|{x>`'B)B+r? XSԆ¦чxUhtE(xlS|Sײ+cr禍{:)1DdT-L3K@9mqx;611Kt|PV]yI"U |KCI8'6I&6_"%7ʹ)*z_xsF.\ƺJbrRT eiIR 6D~в6gǓ9ݕrw~ra .h2/LLXd"l}Pf !04 >j)CIP:FTCg#;c.Q[2N 7J #"edycgS}D t#:y :9sgtKh :.w㊨4 b`!FiuZ%j.U@ F8,bkv=zIhTS9Q`_d~` O ,_Ap{m~$SXTyq1&ah7Svio1{^5'\,"T!D <#[C1 })JOprԡau  ߢQ{".5XlNWp,wPJR!+]̐LN焝["*|M q GH'Ii̴DZcYR#+$^C< /f^&x1f1Gi7"tBcr F u:Юkɒ d  2G6dTUʊWp-64#un0'8l6/Ut G:$_odtN= ;nHR+zt:ؘ61/ڿT0="JЛxjJED5t,ϱH4"h! bT}Z3HXw}G`J&i 9Ǎ#0:&=҈= t9PX1*bS0B$6`cC))I'ڎQlAVj+(DF?ۘ1> {|`iIpPFؐ0ĞךaB(06eH<0QJp`a0Z3 ja S@&h C)ơun%a#  )otn @c AJL32 ?%iŌtGz#[%]IzZsn4*D̀5UC]e$A_I"[vYʢRJ"g" S\fy^(CɆh\ @PZ`^?޽x!;R)R+ \tdB&ǁ>9v>/MnD!b,qHܓA%#(4(D=X Qd}  TbLwaȐc'|R JHgM n@^@ A4p]n_cb <-68`^b n| Vm)'HQ@Y >+/h0k}}ET%@["S,6P^,tCXiHL4׈~(]{:h |^3Fus:Q1iPׂ~Ve~{ LP)6d/۩Z  ,Y"B& &t(cM\Jx$" N16)b *Vױ'NEQ _O{(rAcCKk4[A|u \s #c0qU+x4ZX46ryg_{7rO /Hou.4ږv"P*Z"#&V]5Zm: VB&ƀw" E{{$6TyNGXp-ǡAd-%(D T!մWW\NLrND&L&.V%!@­i%"arVhRǚfׁC/$XR&ahz0flv ZWOP] KYzfq N8TP$>#f|u 5s~g>컛'Uedv5dpYz R;Ҿ V{ m-? ʅN- v8bqB3((P%8fbfkPA{(̅LD*G5+]ATA^\|ud藜?fN&{(UUc4 LDd5-\,a(E._ORo ;.+$I ^*B\UT=p\^~w-u-@x BᏤJG~X3>; ^-R r8{UXd@e~[\*]iȃ9Ix~r\a_T;XyReEz@?'e`T?9_qBm}埻_Q2*Ȃ!)!2IHU#nU O\o;}V;-Xɸ\UMfHmj /6Ɉg/JSJT$F1THR襊J l"-[>?Em ̎_$-*D#HXDyTڇ ly5HQ.G)(šO ;H I2Grkk&lo*c6D8j2גfp4)1=hF7PdpL@og>̤c$nh 4؟A'. 71{>8zԨ轈 /}h>tQC/\179},fxR BXr-ı#TM_jqᕛSCz"iuAJ&rr0,܊zꥰ ,}̿T+>uLGjHX1r!XfJQcCĿP#CArvKsa p ?.?u`% EҥT'p&[]*̐TIF/,Fhҋ80!~7\p):Mo4;])V !}%1-)΁̱䟬@SWʬa"`L)Io~w95P6ec8:Tfi!ҽr{NdR36MJ(s߄ b~ 0Bn rur2&r5y`jp K;R' R˂)+")68 :o|CEgX7.|nF@R #!Z,qV BL ` z"SlarC3¡Tä?``PP~UAIJqJS_& Q&e= p&hiׁZ Âqr%ѠrKt?8.qKsy CHӸ< ,3AyZK+Ƣc# >PA+-ɇ /Fw,s!l/y0o+65I7:l̔sNFNƥ](fG*Zl\w(zagxB`Xc9h$E '} D>В$NGTЁ90X;Y s&aZr{xׇ%졇!# Ė{0*|Q=?΃rpb~_E oRDY~y0(;*J žFהAP(2v( :)]聚1J# +f"P[xŸ/HH&B-:BU"*ƕ#ka %5%`%%CQ'F'Cx-'&`Y0CT~34T8 ۰ML3> rm _,W1CaLX >Js" }<,^F@Pg-A /~6e0EVe<`ӳsY9=,RH U8.U+W ~7j қQ˱HZ W=H7 _lT  xD4RGm=w+_τ䠞(}v_(J*X;掌 0<DmB濞K߱5 +ѓ qQ;!t?1T@"gE}4{tdF3E2:}$.U~EgYY?zFUiD! j2OWؙQS_K_ݕgBBV_m8D^qЇoOg |"=X6̌Wz6OAA_CD< G,o>Ggg7qtnyO*{>e>n?&3蜶JIΐxce沿bQ}=ɗA qB~'N{:7.aMdf_:śt>:mӔe0vei!}f5Hp 'IJFyqvVD,"h<@&!ղHnOm:رk|.$~NwyM)VQ^乍cQW]M՗ʽN׈Zcl̵ O*ㆪǶxooM_7L6ik{?Q*LnL]FW2VYb wHyggH6Cnp]PP-K4j߆g2)OVΙ (sZ7u&'T?`.PMz?9bkq.mu/T$$lcjtFk:Wf2M41uT1p2ԧDSkZ~vשׁܦJ? ݤh5w9*w,WQ?q8}>|. J'Xv~<=`칀+con] bRjI0 ]OFΥZt31A8uBaǕT0B ܢ'Ni-گ9k>?xJ_:.Blv/ԿMÀwg7h{tBFwuBjyo4}K h5(Aw7ds->S.W%ًHoo0d*- IUPp2P.lOrsF&MVZzdFxySsVv1(=tWmǥC"b=V[/=`bϘӝ}Xw~zRn`lt -W~k1IIi_5$eg.|#"{SCs5o̒#kS%JLv:=,._}dRf1/*W@?zѩ;[;Ls'mvyZX8稡q{W./`ׇ4Rz;pWEKZK^k@*@en7zoLc2ݜOjVr=.0OZHxT`cy̟zfba%B4d pR?x}M ú)Uo*ՓlROS\4%ԭbg>fgGLX-ˍ RAU^IEl/]ϸyш/j,ULC? n"u[&2'^ͤ)/4l|ne#>hԋcUǻ&ruMv30,dĥnu6‰W$%w\U}3C5_=ʚb-y,(A!*dzeNǜm,'!aòzYhit)u rt:+N7v.kw>GR3:z8ۮ&Р»[Ndcɳ=wǺ,eڿTe2Fx64rV~ؔgTj/ >J[D&%/e]wD>\z d2$?ML!9n%n-b"w]F|Ksh݆536=r}qzwπ| aw֩Ju2yRkd,;Cc\h#ψ&+E]>d)ξ x=%/ⱥoŦlci]3dfn퓆M bG2h|^wkMs}81 bDf R]̅. S욕E&"&ݟWcB/UA9il԰:|G=Ѧjzw.KSl[Er/8w4Z=^ Cɳi$EetֿxIh;s}:>vJ5=.`$.d_i8TxŜ~heߢr7I7r|,}?,|0q(-ue5Պ]juؔir>{V!3fe4:XcIPq${ЧS PHp˾}yW[Y|*IEN/#{ugY13K{g@+wt'lvMsOq /~6HyO'wnNؽKs ܦ]2};Xaį^I/Zr`0ؓajqbsTT}qixW⑫W,olx2^x6pk6Ȏh)ʒq`Kļ*fy豻R' fnF7nSP:f`~  ?'Yl9~ϩx{j5Jh pr>7z\xԢfW I$ %4<*6bP3yQS(NYظntf8m(ŭ>WƨнLu2qVf(+s :-Uy[.*0i?kz>o1gc<919_u'vox>ѺaxSZ;Gp_f6+gWwʝ~g1Q8OU/>rPN"iiH 3QRmqB3ߤ-g`m¢X;!ut1Շ>ߓI~jJj;KQ }Cl;s.[]^ayrթUPRs;2I֪4\+|do]!+%ji8~tmyj{R_#)C462uveO= ) v=WPA@CϷi3s,%K_>cm+[LDDWhwxyZ6e%>SCc]}'U\o+|| :چCKC/l;+;3RG{ߨMs[VWGے"3G۽dR`Q#>ҫۀ(?A?7Ɋ'}x_뷄۶?X,x/NK(hAźV|~뮒lUB{SgB:S̖2CO1+Ϳss~x>ؾV3?YS xoWpHF"5x;넡"C&nYgjUE2<apu9b?7gߑ})࿺,>ަPe>хቍ|YKe<y#Lݫ}^;r6+}Nm 0 .u`gk>#/O&-e!kd-vp_+vd͘l8-Ύv8(Y+ E\o<]1Y?|/rW͹VP#}\Pm~lm>9rAYf+IU3L o«o^7/)f:I6?p::y 6b?q9 W=it>& {_p2aLr/f9@~d*2"ϰ?ax8-9,&]=ReXlcu"ךwۧvX7.u#T;JjXvjWz/&3(cϣnRo:,oUl̍Te q_?sUw=Ų g}6toғ 4|QEMzvyuU)Swk҄ogeZ+/4kxVc٣>؝x^z pQk:kqYuZ lk^QV5,r$k7c%'4|ԃVS b^F6HTvFXܡޘ6^\ ,_V޹؝|W<4{F[`S2F <]g;ߧ4wA[ E@ai6 k_Ҿ]$b\[zw3 "܄mΈ|PކTQ;aNJA&zk`3jv.K2_ #jlKԓXI<(z#+^FmOgY3e$\Iv0\:u; }]SlG~뷎ʪ֊y34 B1~6rF!>;Sܵ r須n\ڟؘZ銆C?H]J5ʷGV#W-[v~33]="ce%ș3Z9 FtvW|\w8F?;n~S%#a܋U`O-Ez8zͱ,яx'f؟ ޑ1oy$Qvb2O5ݶIdcqZQ&;/>䩿!/˵(Sjj4?c۽`f2ƦX.Au+lea.u79jet!bq8sn>2Rs+{85Y\5VPݦ-UKֹq籛u 0Oc?I|=V(jFhغ?W=E 4<[߶>/;cԧA h>nGNӇQc_gXgܽr~2z}{+]=8 k$^"Yx8 j]ܦEP9}Yv)4Ψ ,Ǒ!qV'}Vr/pQ욊ĵeT׿a(hf I"tW9 [] SO{9W^㺄F͟M ) \STcf7R^;q3s SYKϥ1zZx3v4Ȓo)zhzuw1t~_JτFIQ)[9ǻfs3|ut 9eEaN+9`~7|yxl<(14wWQ/K>tNQbק{cNCQqΩ}4e~ Ga~aܥȋ`0&_(Ãۼ_FОrHប|h7کx}p Ev^es7^lnw|E9Q{fٍX-`f㩖5dT "ʩ^ڳT)12zo%:N:r>*ώ]9@8㗃gZJ7LNGwM'锉Իa.w۰+Qd*;V)az5Ytra3Kd D0Y+X]n<仲WMײsJ?wLW 4 e< T"KЮ{l".[;C[Ks 2*>#o8/#,8cm\WwqvíbaiN@8g+DZ2Yt-'zܖp|iV9f б^Ur?V6_tbV{qm)OY?\vnkm qQ2ۉ8'L;*e߄UU㨗Og[ =Bvvx]5.Z6 ҕz}2j2^;_9豒]3y'x% @?(7:;F*wJ +`*d$A?m0C Iyu;}G$Ť_v\O)< Pi1H,v$}H[!r:M[F#l= &8{M;$0?]Ak8*Jsq)Ln@}i<-ՂrarXL яI]XsOL@szUj|< JҶpCMhydOl@QnoN0cU?y {Rn x>sI}{vDzi;TYz&3CUB;FӢҫO"*U:׵UdzON9ڽ`V0i刾gVGΡ%+s Bxx\=ݐ`ᘾSK%ʍR^AU.fg9]5yggtI1%Dj8QhZ{?3"c7W=A.2cH _7w1wcUeGt:9Ϭ@vQ[7mX|d'R[vCNeQҡ{Lc{Z_ut1" 2jz.f׻.97cP"Бdv*].xx:v/p']R9tyWE_$݀kD85n5hYSacID8 ȒtOfYSy}uaGOY*|#sG"a6 P)S*8nmx ེ:zkxY~5{@+/T2;y/eoEJx,7wp5L̿Iw3P6rqIkIP;mS~ψv{JfBQaAzgk~1=1*e yYxEr9΍qީV}Y}ė4ҕ yIc,tO[`n? |ѓ7@(7UBFZe\ld.7'G /RL->fJ׈Bge5m$\JZ)X+[ajaPY"UaFHK1"y(į7$?VWxix/Rg248&(P☡b(,Oc!YFB3>+q%aXa(ZP`M \fG­Ó Rb(Œ,`d!D!HMoKI=;qP$W DwuYp`P$+<@T$wDp'iVb~3Cp9 [N,'8 G2"dhh<a FJ$o~T4H ň,nX#3 Nr qm0 BB‰ 3EA~~ B+bJƔGK*r yJ(<>  #C1!L  \ nwj6fjg?~äC A@J؉`BFP6p~/"$b „0P<< GDLDqYpQgI;)!(6N [%2(juBP~%qp4"eb؋ aC+;ǀ'9 D,P\ X3,&yi)?2D*Vp敐ǯIB Yq0 2<6zA~DL_` -N0/ ^<AŤ,N 5R䀟X3 !(̯,i. 2D"Z+d$Gw D 7xh3bdE@_-d?#$X?XF*8 )d %DV6P_n (EJ6|1'ՔBB2B! $xbY/u [d!$7 E`B{) jCKb(jA1Ji\0hJ$ A g$ :^UU!_9s_I/ m.@(W9GaHN?S2 H}Dmqʈy> cjp:5XYᮒ#@'͠ "F`)Źp$5'9 яßNi`p g%;*{QO$"-haZe$ S,!`[BN $:Ϻh ^$frmO+)IxB#k> a~cƖ킸S-\ `X@gGWS=(%: (mG!`},Hh7c|܉?,3 c` @K28)I%4t/$C/L <_AKEՃ$T2 NJ`VH BƊඅ=GH%H4% txLX0p0 -0羸мpc8e8Ta[ 7I ~8Eg?~rD[bpC𒊈?W6uJb!ɶ ?ƀq,ژ_4oG1/h3:@h,^j 2a?X Z. 0l0RpPxgQ,4`1w|R ~b$HɃc5UYQ D"8񇐁L0Xt;Ts@&N t*0Oi[VzBpX  PEyX y+6 /@k;$Y&ZǨ @ g[ 'pGBqn4f4@xI<_T?dPĴh[F)*)p.T)*Eωxp+œNbHC#+2$A)^ }X P{b^ ~ ~Zbg(+2VLk(8Ix n YI܌ E:x ABrB | GKR $pD)ۃ8"IWcd y$xP[چLĿFØ@ަ8ܫr,Ƒqr-,ݒ%)d瘽X$pp=20 o @ R &RL"K…#_ΊE0P ( # ! v99V"!`HB_GfCW 1~!2,gI)'¿\#JEi`_AQHgVlH|!47(6=HtDfV8MK(VRsSlIH|bT!]=WMLOI~TOŷ=_?˜J;?d8 rW'cPV *\GJ,/%JO@cې43#,g$m'K(\ O2"6'O\. b<32Q)c~<%i3KR# ,IAJ%8!;LC*"y イ;Ɗ)|0#( EmRPf^Ofb)&CphB8T+t\-$@2N{܀@ILI}XvӢ$԰\NAs +l SL~a)W(?VAYqM`D;»-H\$12bGqn[| CHw2F ]!Q x nl":=,z4=GX P q˂…)LYA=NK1[¬8X" ,-#IJB^J3Fb ͂ !Em9B ?I<d>/27 )zS4ʌi )6'ߨ(tKMU6^}D ~JCh:eQ^>w8[[/ej8h^ t,3E6< hл+̿r@ҹ.d 2vY7?rW 䍼*vz!LO7Sj_䤆(>ݥqk*Qg]Ġ٫L5 ld{9n\ѹֹ@^G%]) (i{݃?ոa]$_Ij9(;Ҩ~ά*\KuLY:j66mJVeLRqֵ:"'F.şrv=֗).*qu啜:CUl{|xMY F~y o{ב_XmGa*s6UOrNm˿ˆe3]H_(YaLCd0hskb>na? 7ܽt5f%#8,4VW彺p\J1;Μ%2Bk8ҁ¡_(oI”DtMw>%4UӚN_ڊ,W>8Z=a4;kTǑqfg7Ǐ&g>9`uedX܆SVK~kҧ_nzqy`Ąݯlb_yG[OԙY|4 LhOh~Zo`.k&m\a2\|ǵ][y"bͯ՛l3i 'CaU M.{^d#'آ]aQQy,ω Yʺߚo7ݢ:u3٫}?Z}?zRaK\Z4ɿi}Ha6,nz?\T@a+Z֫WrڞmA.xN{ E%*~{$u`2sPfrskZ6|y[i8l4S6=SR9Kn:j-\{S oItNkԴr}N30<Bn7kj9DgRM.}zALnFro[=|ڸγ[֟oQx3}âg Y#Y}ܣegn=55u88\hhq2鵂̣|ӽgsaWmht#Gޑ?!}_=hKL~&kW w)[ |Snѿ̚%.8_r̮By(;Y 3u3S~2K|*ۙ6^ Sac)=lXpqЩ_&6՛ms%hMȮ(c<~xވ,7/x9)~E?u97HܬR<-#^V#f)b \Wd$M#7_Yk5޻ņi-x!yhtK%U"cǪ6;w5K/JWWG6ikG9^ e{'zJqJO ?B^&V>ZcT‰wӟx˰&O!0dF8ڳ]0=k+Uj_ ;]*@[SV LW+ߦR^e3|dCπ߁%c/5n4W T#*W~{.ktvs]+N{s[A_=i#/ۦ6WwyJf`eZSc/-ȺUeޥ)pxke39HM2XkӨ,vڰoֶyY3"zhRDifoEYoo Zma5r[Cƴ,fk0]4~Mt36Hf*|+l_Uu=\4~l;tz{UStOtaCl_QI]VEV_Zi!#WvV7,X3Ѿ_뷼n3zu9^)ix(772QCm%}*$뵧4ngVNҙ}bP^rOtڱ[J+nqP A޺:7Jw֕3|;HY{3FǣNK}yUr9QIɑ:ure]Ƈ{fM{b0K,wQًiSbR2Wi2 ty3᩻u 5+Smh*!6UfY uȠowOlR,Oowo}i3x{İ&%Ɉ$]:M 7sNX17 M^pgN/ZiHXGan՛͎{;ߧo(Hqcy9 K ICn Mc]׀fY{xaG{A39Ҹg#Ŕ{at}Slʛ;. Z^ jN\4BU?vttJ>Rm0u'lkvN o]KvuPyE__OZsk*uypEr(5Fe3g\Maᓪ ms-jɎrG \\#wcUTٳ$Zٙ+jUYQcꯅ6rWY0{rpѪ>iᕶgT~QdeѩO1z,'u+_GYWOGKOGd _Q_q1]9iڴs)UGf|dQ5*ش}v|<œ˗ʬJN nYI_YOǪo'/Y~ ^ycosQrN/lpZ֬IN$~ V;k%R\]€ɠa.~_{n܇A\eۮĶ 诵^yy{^Nqx/zklV~Ro9,qztmGS^σc]\}K 74q݋SoPUҹHmwrUZHMUmZ+\/%{ ':cڛf͏U#Up?C  tYRޗPKRTw? ޙu[⼢ɓ>rLTC,eqT=_QwWtƽ/L?mq+¬#_W[z<&%sƅ;=+c_|xY^i#}Raj,-vCB V[=f{WE3+"sҗt e{vgO>Qn#\C\{pU\:ۮd~|[cܯΩ_X;u.=+k=3sEwuO+#.i,=uNC6> vu_8=vM٤vŖ{{>mO|iJ 53J+՟K#8H4/|Mؾc"XtQ}}❡fco$2Ff/{PqK61TOU=zxW٭ n_.}Ӗ=o)Ϊ+CJ7[:[qYt?=zdHĒmnA"[_05pIO=89gCgX۵XNÏg/KYJO=$P`y[wg1[1n0hk|ö611@J*l1pt}QGxTӱ^RUjv`<3X|P\{]vp馌yz>۫ztU2&^W 'bg÷+<}UٳU)y“iɓ.ŗ+y-jMb}Ir;w~ZscmZS,]ھաw.}^FᡱbnW<'gl~[$z*W2Kl>Ii8Pm0g' VsդQ UjrQpAX^UۗI_5y W>}`bfU*ߜyYv퇮=|Kǎ55`‰9꫼ISyK >0pOS99so𬁪{Ԟ2 +[ݵZ\"} jEk]1NV~ʦ)v3&Y7OΛj%׏' _t3mcmMߴz}l۾=Vz sQ: fyJ%.P]em' 1rj7kz|Ʃ':LlaXS'/QK䛽ߜ >Ȩ2;5ewdh<`}yrkWݦft+/m Ju6uonIغvɳʄ:'$ >cHi/bvU,B}ȍbw0*oS!Ho[ F,sA%p mҙ{/70(oU4DsK3yս:ce|3/{Jd?u{B>QgѬw:d' Tnq!6єqsTX{0)DtO*6Ncoن28'{r>Ysw~RC.~k (wN;h W.ّC 5x:x֝[J߶]YO*wJ^٨Z̢[8`÷[Cgn}{6|0#suTקlvv?ZŖ>7Mu):?E($E~uG}SϏ~ωw/M7hv戏bL㗟{~SJv9&gyAk`-} _}!tRń[{VUJ}(v_7oy?|?M۩riKv$vOIѪ@#˸s{* @V6uй?DŠCWckÂ^Het=I!3m_f$7q\tϏV#Ha@=%#<;]4<'?@}*<s[ߔ j>\1>6ax/iR#z߻#v5kRF`.S J}Wb/v/NZ*ہ꥚F,4uuU)%5/dny&uFع!){uRS4jw%Ҿ=uЎ۷"N='1X6Ni8o|, 4k16x^ɛwY,R+ѐuWY:՝mk 7O誼Y!7mjE~i_ 6;X`R7)Y5XkqʊIܰ Ղ kvwZJ]iuz:ּ-6SˮǶFv}1O5>Oag:?/̙ٝ>賡Y+YRM?]\䮟4qN]7=oj;l0MsS*J @UR<]e0tޢ-.ʆN;I3G^yLPy ڼ}Lt=qxLD>:%ؘW0~lVѤ׷67}`s_/x{KJ0f=(p`?XxދWdOg(ˆ1%ԙyƄ߸So}ɳy'闃L9^ыd.G.ڲlrgcb]ceT~`AiDvIu3Z ǝ5.x:NgL3)_ID8nsMuou N4PI3B"F"IP? pR$A"H4EPj ?x-GSBxw 0 'EjH|IZDP CҸL&/Hޟ_?5 ` R@RoB!O .BB# "@8 F DH@7!IAp @zޢ /@KL h' P뙾/**` K\|S"?AS蟀&) ? ƾ#DD|h_OR +@ {Z) F!)a|h `T//C4,Paه ) dPb1@a@RR_fQ#$$d\j$A?$Gv4t>)\Dc0P6[$A&#ػ B8h"؈fNd>RDF!Ї? !Fbb#- ,Op1A!s .! 0q ` kû 7I 9!(F AL0,N8a\)9pTĿqAވ @!:=Cl@rHLP. >XpT>HZ3̹c4m4B d H!YHT?^E( ,ղE $(VH0C#:M\mDO0,:8~ hQ! Ƒ")_!~hjbU`20>M~'?X# @BNF" JSC!+P@qGيȊ$H!C@1,s R@4  HPJhH0L@Kp`\$]H 3dWPA~ɄFK"m8B@ (LY ]rI_1b|ZHT(ģ4Um8iT?\@xq?*JB/~$[lS,sćҒEsEZD2aT84R~Tf (f dPDt@,yqACD&8%ӐE$#d `/9pi07X+ 0BA(RaZ "Z><aH$PAgXK X/~0-,A]&ABT\DLR9R}jq1 %RHU (1d B)l6Q!2ԉ2@!`X!Ė DQ Z.LY P"dDJPȩ]pu4?buHBl`ql5g pTXAL򠨃Jr=- & .a @Ah0v>1 ~!. X"L Q"Ï?`c ܇X x_ 3 %pR4.B`Q0 ,p_ @yXT(eΑ,CKiB$P(}=uHl Bh1v Fž00EAݤ X fD<h\ӜauAj,rʕzD;^lTI@=pF8Ԟ&%eJ//Hy!-PC2C1sy|>tvFV^>9`!z:@vhW5hHP J#,p8XFmrh->\D5 c$'!%4!a<{?I &@,ɠ {+*z8Rܶ h @1MTP|,HpzgpP"]?!=A|ۈ٨&`0?+pu>ToEViNCE .\NR?`7]I& c1쉃xDPrM"Є`K9Fahxx2vDAnf"ώY Jd0 !|jpgq $!#"+]`Ahf- :bTa''baZ>ۜP$,v_6AX#H#$"B?)~пr j "BHxH?!&FL@Z&V>2nt'蝣FB\[jXd B.AC t?@L{hlIv!@P$ cPnYr3Z , bth c}O#v4{6>| 5}\B/J~ 'V, Oeivw=s HqP&H7D}yC,iFA"u>)l] \4*!4,b:(DlC+p?H#="p O\*w Ql8%6Š 6wEa69ؑ6FRAb q\5؜ ;kˠmۑ(0gF{ QJH 8cPS0& #ZH%8)|b(Ezz\O/AGrXB0R ⋀P~J˰c/ 7%Z88{L>AbCBz:v8 !q RO}n'3]0`PWa@(A0<(Hʗ=cC\ؿ f{ҏfxHh:DB-܃qa.'{3>d(ÀJ@Ynv=% F:iJR;7| " >2 %aJ 1̟:Ä bE*4E}7) B;P &ep p[1jt_[G=tM&3 S^1?XnbmҔhtO: =\oL609fэ;,ǿxkzkZL]2Тܥ"jƦ'fx:ca@s$[WA'jK:VT~&Nqk_Tx} 9Epadq#Ǟcl\d4;e߷ )ɻJo~u›.Du)Vv;wVy{w=~рdM{J䂵#s0h8<>`ll486VgNo'(0IH9R9Z2_̩sƇUS=nj ҵxW[?8ّ{*/]ɱ_e}*VnJyI{D7:[soU$r`QI*k?9&``RU} GG-u< kscڬ^LjųmbrLn}PM7tGz%v0SANC;j^:;kh_7Z7wzZr^i4=y .] Ya/~k)Ӽf> +d2NXʘ/I~>i]b\«R EAGƝ1mvS.*CKXYY9t7~+0P5M`OSɤh8gYxꝟTwךFZؼqS{oG'D; x ?N'-  `wf/tF߭[\NT#/ړSnR `[>cks6ili ~u-%eϻaQq~gY{%Zww(N][݂L*\R3ߢ>k2C-~YִN*j ݖz`˛%{ʝU_n!q1{ƾ/=jl{h;ʛky?yo'kվx4~!.5mp_k;F5]X~** MH26ITՒէ5E /4MiY1lcوoadrwMе^=ٯo3zM_+eȜD_,̛xG1~\2(I18DŏscsU}/ی}wӨ߭V79$iUh2~^vʃ]i1XZ^^y~ew$]y붚*>2.`vsUc.R]tR6v\X}heRۦ[^qʣj'kԌ_"OS&.E]{ƘU32{ VR*m/zbzklw[+_] q]:f^Ïul2 4QO >Z-aܻJn[0Z9\=n3bɭs?Š{8uht#}ၦ[9"-7SP}ࡨt`rc$-Gyxnh[=zƧ[Q'UWOs60_mÑ3kz^- *q7Wm4Im ._EԾ71_8xz/%g`.纪]&{ iw5[GF7|GQ׳ ?_HF?-+wSLj^_"s!@>Tڲ!|E{/i3ht4YXoɤ>n|Xriˋ#_.m9aҁ:o}>Eu4X.ad/P5U?98li?ڂC^C̆O[}Kٮ叟iF^?:n` .w 4/Rxur W=N=SE*p[QW]*4tdœifcD%9V& ?y6~,Y2aokfEuqr3O_^EC5Q?S]:l5mi kf5~$:X<7 .*?nQ"ؤqL=t]so9 dFXZ?o 9VjỂ]dy ϴmf"Deu8m=S{7R]Z:+rh!)O z6.2 ]jj-XVqSg,T}=6g]}_1L)}Ww&Foo/!r=X*75s9.}[MGfRr;mgw];waτ+:8`¾bwcs.;vק펒ĭʽv ^ޱy_-'4|.ˏ"ٓedr{Z$'|&Әn:/47/+p'[Mi]I jWF/t=JY6|\\zaԽJ:hS;j4JުiqT}!:EZ}߷\~d:)\9'SV+ջꢤەT ԗ]l-6ʱzslpBEGw Z-os·.6=;Y6?8f݄N'Nn8rLY?FejSmf;N Djv"8a^>ݟ?0궭mzt҇>ݙzfʆκl~¶GdӫՏsL[o~Oz_hVۍ*͆c@q_pJߠrWU?ɧ fuI6Y/Cʜckzl o>1/<-64_ux1jw_[3TQ. x mu\g-?x#/zp!Ƕ^m!}a_uPeP|*˾m _/N|L)舻f&9ce{.TD^s^ Fo{px kkz8.Գ 7MdqmܡowBwn[\klQU`<):^nN^zbB%JElozfN3]fRkk ˽j6Fku̻ |yd1q RItlIL):rev=92sG4jirrFno L{ ϗZM6VWԬې n`̦QSϮRj]qnqyIfڭ(|n I{s9'N:oԒ)Vwΰ:>6u;-m΍"^w:2y5/ǯ%4*HJvkTީIF~5owt~1ܾ?(fМ;sM}w\s>篶O/'*W~x|{d.Q-O7+}:_jGcÎØWZuڜs<[:g#.WVkؤ{uqFk5Oc`T6\IJ[Mּ,8K?[ˣgK{=c=Ycfas"MkmL:4h/9ul!Ul}Zz S緧1Ee覸`. qvM+9[}!l햘 +Gϊw:q4 mlj6Lt-aEs}<9#B%ܥ׀>kIĪ9m&v߳ݶU3KNVV֒[4(*clţј[T/C |vsYe׫eI鳻w5 ^}VOid3(>z|'@>ibH}욇z դ?/f]}dkHJh/ z ՛.YzҮR8oTf{(ǧ/lv8UƊvK+L&I\9z"Q^O~(/U_l`ph|č\ }hw-8n*]o+w&'oz8osbܞx륿)kĂa̯^w#}m׺22Bk7 g/vAJ5UD[0t/`;^U5"w;Sַ]ţ*t:?!̅ A C8c;͏v,ZxڒͲ@y}/6s+ǎ9K㚃>T=4D6oӁ[ǭբFNuZO'mxqu{YKmה$-oyÓ\˓L[-!D8kf c2%6V~T^Kʜ8\k^yϻK>]Id?uǙnxaU*6-؃OkNs[|J>x)xpb`#SyMDg ҞOas&9Nmuל%@30ĵV}RU)R)V<` ?ss??\_ɡ ϼ;Uߑmٕ na5ȐJ[1ٛvƃO|/ze3dd[]vm~xΦXW^8iT'}垵E3'6\5r8b~гmވ ]N$dӎaRV{y`oڐ!2-6ΎQdM f?>4t.K+nfVXsx|]i Q֘i/BXd$cL6n ,:cu+EZ[LjZfAfe/,9=8;1^iX 5Ewy!2{ܸ!)9SO:(j׷ͳ):.-:0(J]a,ܩp{tFj\ne=AS1Og'O8PqW} ^;[IUhVS31+_-@pϓ>AKE^f[lgjۮP+̂׷8KL6ϕ2꟝.^gX/NJ9ia*YM:Rg_<]lԼK?)Yﵒ ?6of8/]VȘν}lmDuɓpѹߖ_ntq'K:sWg<_0d<>mZ _rLwFΦ}I]{V3%,EEׅGikC_Q؆*خ5@'}-UemjtkqG_2.x niSo*&HwJ[bŝpVDeRA`+lo{y#v- %NJv!{䷚~pbC9Soz01m7~E.u6;ק 'UvY6l\cZ ?1eoRRYoĹ; 5 O{^^y'T81 PIiQ_wVsQڮVhN{Ɲ83-mhg mp\Ѳ1m ^w$.L{^)lvҭyW.Y6pJGq՚AnJG5 W̦AOˤœy S|/U3[T==zwI@Cݙ6VW/>F=xoGNi3lt_U\qtЊxYUr.+Q)=akuO77Zsj&cQ6;$V[qy ka4`٤^rShxMY{)WDkoQzV5}OztI$ Z'Ob=82AgܶF*yViGo$:ETp`86Yê.Qx6AM{_}wI-Qğe#BN9qY췧5W5ߧy{Qo;=&7c{Ж\*w d}PwV9sX-4lޣO v.[nO׼ꚫb== Vz*S:mfv]9.S3~QzwTGUZ[u͞Cj=)g<ttWIa֦3><=zJk;`~Oє+%3u=tv:mfkݤ/}zC~:CM=wCss6qOo&VJ|q)<5Zo1#̻[}}U<膮e y+mo7>Dr[~v?p# @?M_±ddʿ}:VzwORU?<Τ>gv]7 ^2oxc4 'i,ݬ=H2b%ܹ'$Y>y3G-k5%%EBG,UEoc=Z;;l1nŖ++?K:?v5_0=M#R;wI(ѪrqWlGr]緙OV=fb&F{:*˜ Uy?ˮX^';n$M#su6M}먰t#g-okM F5tJ4|➓lra֗ oN%n%oZ_5fj"[?oA6ܽ7']h}|+ι*WM#_խĿJ#P}ϋJKmo|\}H'CZ60EikN,i?'\2rawv{v[!Ijv3.٪*P"<(IKҲfLGS^/k7o]ҢΪx̝pȵ/ ϛgdoJGUOx9?'rlU@xӌ UNQV3DԆ Zb#A%^a6 7.3Cjc=i9L,O1w]пŪ5轾Tψҙ}PŃi=t өZ68#yYex<#λTN:]hxjjرd-~P8hidf{o/YvgNP4AR$ ^G'2Ig~GQ4ΥNpâ" nB8v%@h, {$C<.^4K." "ܛ /@F #%?#pB*&{,1;"?B .)+mIpv ih@*;N847h9|`ChG@;ItK hAD㗇Od3۠{8' >-\C!"igO0%?İg84z$|0 OQ0P`!G}!0KA4 R-bH |BpH h/Dˆ@XC"]H$AId4D# G? %"{|Ob0E<{Wh `ÃCF=~YޘJZ . 0.߉(@ ~ 05w: 0 #`AO xd]/m63(d Ky AOk0x! \@aJy&Hdqb0!|!waHG9!0 \! b4C _Le`G8 XIt-{GB0pqx@-pu0pxLDHX$Dž`Ÿ ^nH4Ba0>!#p䓨D0uBoU٢J2' C 'bМ |hII.?Elmqq<6< 23VBTXH wq_0\@&{{ ! CLơ|`-Rwl0z"?(H  Ãyt G„|pXɉq?χCQL޿^Н(&Pia`oD_-#?` #p^"4(A)KXG,4 @0l҄r -,/(9HWz{844&z,4¾ǯ #SD8M pHKX1b @>BZB{`bd,@![p8cr DOUZTG0R*Xz) c,E9}ThND ûeBB)RHGXޏ~E4+Q#! Z eǸ0*i )M҈V?¶|+ $Ǡ#`$R4!pa|.VLr# - _I[%%V@CxHG2 c*ɰ H24~5q^,O ~̈́#`V$$!|4ŔQ,Lcb 2C\(6@Tze`Q<W;Z7f<5z.DG!5#ac|h#?Bh&0q-DD7bMj=C#PPߤOPq *z dl ^ \GpBZ,hV,I>-{}v> `I&h3P0DO"QWoLDW"ȉ 9|lJ'P& ((`H`ξElwݛsP<gB2BjO%1gMD,W ,'AE(~Cm 84)\'xHbHh#ض?B D-i(a}G*  C(*\h(e'\? Jϴ[n`8g?DF08qA)ƌ<bo;G`d#I g*$u0CASVx'"zcp^.!O C!)$$nNP2o[$#&,h!2d\  c46.$p0sT@RCH2"|..?GE'".jCy$&?)/cZ_x⟩ ȸo ̌ rx$y}7R>h2#in&}0یg1Xa~@ @,qL^N0f +?1<"B.aj ?S$QCsr8KUYFnjrѶ  g\N`e BIDEwPQ,<8$θb1| GTu9;RH5,J|?#C0w2Q ;*6Q%`va ~=Lq~8I0M% dg)= @e;8bb'hQ x+N(u/೔bj- `ie `ܓf ?,``M6`(wƒ(F)S3 8pqԄӐ Pa$;7B?⇂!`61D!Ĩp!y<&B90=P X(o ) VAFHlt)޶xϘ~ʃOG!fҗ/q}DTƚ pjXf( X0tAu3LE"O?{_hSMԘBhÑނ8NC+GA^3Bxܘvhs`={dvh A]-qq<_Of;WSHy4a|K"p a $bGԘ}_Np V`5?B 08߾?X EuAk "hc(gQI$_ 9TqZ.̝0PJ0vi!n<$"і19r4|"/14$с 97,dfev`@;C?pQqTC=b %ٳP~?*YbCco\Y􋤄H + V6} C @d.@$u .jflL9G?@(w+$#F"#=SThG@ɧXJQ!ewhˋ:J$,RL,@p!<=V0 cY- 8+YsrQ<0^Wȷ!) EP5`)؅c&O0e"Ό0$Lo&X pl] `!1ա"i9 D#E*T 81%$ ! =/ خb 3Luӟƥ@pj#$LL5?9"F4FHbSLv3~yH.1oUT3Z /?8I5hCG#ZV1bL1HHaT/~|Ǐx #XKqR'PMka8hgr4Μacbوn0'] ;f(.@s3w=$1} 4G< ݈DG dFԢ%*1t#S@p?<*m5g gC NgK0'1$ՑA"vfR&ٝ0O<΢6E'ᲓdE^OEĄH4){>X ;I]o*DG4̶h24 [(ֵ88s`%{L2I6S2b#DaOivsa\c~b&3GŎ 8% Aob¡!0`о{i nb5hVA)69E5\|:x| \M]>J!)JP$")2eHJJ4iϹ6* !Є )2d(;~{s>Yk=k=dN&o׿z}RG&M.Bf+C*M=nzˌ Nx?ݰm\ߤs אfBmj,}ez%BoƍVMfuEM_>"jz}[&.%^VMjPc,^Zs:NHl,t'StTǧOj'm,<{̷=1h1O𪠙 23,i o93m.-jQA:&.{Tw}V>s07j2ކ?<y3ZPd3?y2,R ^'̎#J=c3>Z.aު~(6H]8"1pMV ?g 0ٷRd7FiP\auV_qT퇾<\Wݠh.'>t?VZܵIm`gm&?޸ ɺ?Î+, X3~ACw%4_eNsMzz4 0~U36~3mC4.U3stu+~5!{>`9onr| ϧQ&{VKZWoXoa{9]V;)w:>~tX…34wN}Z~H55~54nuN>2s!1`K&ir-8=5vz/sOWBīxs;-G&ɶ,~jӖ8Qm8Z,_H+7Nii2*rF>+kV.%6 z}>YvhlX)ѸƯu%tF֌YyEUŠA`>7x3~7~tzuʨߊ/r9 <n-Z|RujW%>,ܗr?o=~[pWzC)%ݐ(fg{gUW38C)sF8^y|zF^Kl|X\S}jq:Oc3&uYn]?d$^:Kwϝv*~ǟyFplDd'gֿwY~ +ewõR+{^@Fʐ, /}x{eKs1~9?QE0.yh=yd=}QMoEϿ]Zc||f=m#Ϗ@eJoc"CmSlE71Y? ɿR{ܜ"7F#|=R:PC0>wmt/V}SӞ=XW؍̎)ᾅGʒvk,o4kcY~=!ǎw)3ĥ檄_`ۤŶ^(6\85Al=xZ_ŖS n[YtW벯$.\*]:阃ơ];RS/֦`%Shװ >z\K_,涩Ï^jy̢@NgOb}zOHN-cLs9CX"5bV8dH]{Ƥsi@ZDPlr9t"uQLWn-.=ztriӕ|ya@egnjr\zPiYRsN9;Ŷʢ@٬={FՃ<%mumq昅[۷tO{sƵFqo*U0iYlĴO>g7Kfpi † v{攙ws-JR+˩qQmz:'_y)$BjNzH +'y]L=d?BYu%Nּ3՛M[ 3,,}c/R֐W/6p h?f7o;j1+5TkwmH繏vNü~}>YA~2C IUȝS5}oœnǞw3cM*=BmQ[̨{kXk>&t]Ҩ>o lK/eFjڽXfg-u;XjωF>?$]sΒUY&z^kka-#Um1gݗw*ST$2ۋ3cfW:%{$Ǫv `8%1uo-?4+Ԭ[_zöE}\0rZĮ0hYt~[~ֆݶDr1 C/Lwc->%'JV aR^4zu E&k|[iV7447T]fDI:f9鲹u̙@g+dV}SHR+S2r*>}uHx9N*hEquo#c<{.>&tQPՉL;Wy~뤋桚_?b?-oڄ~?Ӹno߅62#Zb9Rpy̶{unBLBͯ7pU)ZoQ??zϮzi}v757>Z|W{>'@OGuk w\*/J ˆb}LMOx95[OY7<(]TW6nzu2ͷgO O)=K#]+5ew6_|άalrbs{s|O~X֪'l :g.8Q-Dz''& PVjfU8{9?U *t{Xk磑GW mۊ`yr"wzdw\T5Tőثa_y9׀)j/˕X.ϊTӗX1~zbBg%LIP ^3VG31ߺ4N4;k43Pn&Z-%gyxYs[|LڎJuXQ=o.Ykܻ?;4=s_Gy:w~c腌>2_ȬsbOjT&qG@YCm+gyͳ>0nqnR7睸uסE狢Ӯ[r3~L-p䙋cOBδA_MRff?k~cyIݟ-h*mupG^;~RVO+OQ{]˶.sd!#O8zF2>|:;|aGǻ36+nЬG{|R-L#o^M sZaZv/ݯM %jRz,bڐy@ͼ_/}ڻ$| rr?:qߌ4m ™_iNvݟwޞ|>aхM^}sixaO#u*z.lDY^*.R}/:lX]lINd m\0Da6Y9 +^;Y \P--k)핮QҎqۃ=z0:{!1CNgn}3sĻg?]vrp6*Bxk`g6k}0i*f0\cLZ݆ӏ9p;bѢ7ndTqvWW􎾵=Xi$Nm& FXlS+;ܻek ԩgRDؐrF"Vh_Ww۾y<[{ܦ^?JmN 䫛m|}ig1~ZݟmIO_2~qNf[cxPL'FмbfyBx~auU}ԉvhP <\._luQk4UORXzWU3yO0άy؊p"Fb3ǯ, οzR~{^;}iy!-]!I\l~Xt9u<\Mb1z09raQOvJ(:\wmϋFcl@} '9+9rm{n~ n+TKL/.sV쮥*:ci3.zΌo:U 'f.x$`ha쐴i|dm-~?zˣ6A5g[5^v冀["쟘N46Kox`jnJiz~?y`5bᗣ6_8'Ըə("؏JՕk}6w/}Ȼ>x&>"δ3ʯ3 /mmKޚ>GR2aW<3_'a|W~.;s-ߠZvL|U;8}9mOu˯tX=+P=yK[ޔ婆wg!V\jזּ<<̞I3}jsNzFY祐u?I|=K;g4zXym'˖Q`_8Py♽s䷚|r4>xԹvkﬣ;Q Tz Ϫ(4:{KߜY=péq%~GeEӂ?aV#R.3)\ *o1ϩ^}~2=8']a\mVqqǔ֔؝%!*t+mk1rp`_-4pYn_r"YS Rp`J`dlYb߄g&(,qIXqyl'={K. desG||Zf?9>Xjyh6 އ6Xz~y6cX'/<;rez+`ZSIv駛AVX}s ggURZ L#_WG:oYTqDjޕK 9G^x 4;5;JaӶ_ظ01rU G,VeQnP\u&ޮw 5bҔ]Ơ\>֝-wgIUW AMOo&`bI.:aݠGoY64߭&勳GG{ƀ;Fz(w >iCYBof)O ď'\v7..~yC{3_Yi!UqnM[4f펨p;,*UlXVJb#:S_Vy6~R퍧hm't|XV)06'7V7,kSVٛO\0wMɯVc[}>~ӛcu3Ģ~"7g\je,B'EG3V*1c;6~"+#)ӋT+e2R_=|PW~ n<eqn]/8zrJ8JF*?2?sD\ $^eϚ[G0iY7Zٺ %3ݻG@vC->t+_Pctλ17'?\;9k* DyUiUK8Y#:IxF׶ x YdlzZZC$&d&%6w Μ3;yjjT&o!.pp12 nvٞ`7,Sі{Ʊ[I%*g[m ]gť?yںTolMf-viH((W>pprɏԤ}/8|r|ynS֮ i򞠿Å)c'(ws+ 5?sF̥K.LQܶgy$r]ϨCc?mbg݋%N*5$Fj`^]Ň;K^|oל =W-O&]GMUz$}{.^N ڦI-G"Q6O[WyאV[dn[Iz5鱠ce8hHJfo;#"v _gXdQܬs6LJN9m贝mMSΉR)ч^-p!ݘ"yQOW;;qûqyuaUF|qkUƋ߰c;ǯsǷ_%{OxlvhV%-&nղ;w-MO?8ygnNw7gbѤ?R?C?Fr=7߸Gꪶ׼ɗ>4ĎSf"sH?a5x]׽]M[kw~!kubPnxLկhsup8e}uIvVZ/c/{N/UY_;suj7b~S?}#6L}v:x?\>h,Fϛ>Kf~r)ϼ۶^@iMk#*M|8D%le6 _1*ZmԞMR[)Wgm`Jp?jSGT guC#,GWzҮcrY%b2tcs]W[je7HS;xem}>IGgxv4Aٽ}NU|ЉAfUҮՕkN61]e?$`/`z?g0@Ǯtϲ> Ŀ\2s}z;MÆ lJ]kRś.pd7?/ܼ&k>tv?_veMűI7%168qY6!C:V^) ׾,1ZU2OغǦO{4x:OMc ]/,pyTŻcU<%_o&q7f2;Ws#|gN(Of}/\noHD7!,srwImdO"*/TL,Țfp}tf5Ɨ;&9_{ G7Í? W~!ysd93kQ?0ڇz&2[Q6`%O"h=# GnZ"/0tp qM'.82);&Mؠ'ۭΑ9ڻ!h%} &7N uWmihY=[[TҪ9(UX:vνiw.\&vnz:s~U_E(}S,!)| )'i s4 O\8м@J@si' i] HHp,J0x8oI_)+s |*$s7| 8(K×@.  /0T ivu lp4 }!4؟1  n0bA ǧ8p 9hp9ܯ4KOB0ੑ&8 x2i2d;\884$8A4CsF' -d-LC{yȬ(\M <G?D ;wgMEs :ߋ/5h"xC|'GDA$'@.g` E')<"?׍GI=ǃˆgۓ<*E292b0ܑ Y৤h="#h*p0BḀIq.X =idX*q$ p(4dfM b 36 ߇ RuдAH0A xh(iD+h4vbj#A )q!KA0{I vy0Q#d_8$/\<<%apXN?^/ PHF +4, 4 H6Q I&QA!A$;€/p88R$ +Ž,0&pj/&A)4?+N!|4$>!s$Յ ;(֟X'9`p\_АC 9A0 @\<>wOGs3aS!njE$1RKY  c :rShoHXP,q pqn>r$ ~x0@OH ]SL܅B  n፠N"}1~_@IMgo}9'DgIJT1Ap&@NPl>K8g;:x;g"z-@E+YlDiR@i6B/Eiix2<HfW s' h&H ᝀ.-N81Y(|,?V%[! %4a0^#FU4HlPd0<`ϡ!V4r^XgE1ax$01M@). @E%ՏR(0t@UX'+ )]|}!APH裰GeGA#CY:+Z x8d*Xf($  /ЭxR4#LHf)Qk |):ED?NM3y !DU&b:3B $@ }L f1 TH)~ ˁ3,蔦)am*&ħHI|{x×R4 j߰-"VcEzzQ) LB4?@݀?=tF'2*p f>(P&1C+D\XBF f:44=LHSpP͍XpF - x&G@ c8y+nP f\C2PbP . ^( X3xtPXQ N54P4|0,V*(f˧P_!1E EEPsD6 0# ׾$%qC$a񕸟fw~)Chq|x=A܅ùsg/P_Oca L$3+t"H*p'$>nʱS̱u$^@oh"ϸY=CǕ&@I3?D4,Իk? Jtب܀-,u+Ԃd}B uYO2򋤼mG}KtXȏ[04D|E ?WIR\e/A@yU6qd4l 2=K@ ԸgLG)P=~ӅMu1HryL+$:1 v B ?BE]+Ѕt#Hɗ> eH ś:/tzb_@Msb|@Fu>*B|*|emJv; ^ `S KP G[ckeo߈I2Aٝ/3(y a< sv!IJjH قhO霓"I(L"5q8 $SD:ۻ>ʾLxyTo?&l5{Z`WBDÂ~C{:l5+?HALb;15_g 0XtQI9[@7Xa p :(bm0(?o=Q<)Ae0GLmђ2e(şcFPv(hfb]_:ثNS PjO>`.؁:ms1MOx|$MLM}+Et 6k{X3TM̕ʿu΂'f zG2(pD-@fk2(3 ?A.0{_-\E(![}IZL`F1(|Il*e;l gF[$6fƒiW `(|& %7Ҽ'q'r@BQ &G8#ጔ X=K rɱqi#NBLй ??ٽkdY*!@B$u -N B@`Ǖ[F(sPg |3m10[A=^!k!Q=,Rb@?ݧc AC5q$I\Kp0:daqH0f Ga3i184(QTgIt!i&34$[/h,}Ȟ_?0xÊEg¥ԮD?'>&~Q\ ]JO2ESش'L o3,gãPTq(f|Fb C`!e0p ࣮?K UC p b d=hI"3yyIc㇨g i&ozety^ *i{tp&, W 9B@[Q zLƽ_R(z%~H'QLKRC݈GX'y x~؁ h@Ѽ' v6טKFBQY g<a|#EE* KZ~j` @HR\ڏ1 .NTPi(#Pf[CGhAً s&F<\aMr7wV$Lq LMMzpoCK=˜'"C/ﻔ]jlvGYtWN 's^`>8,u!>;x @߁+P@Sv)n@!ɮϬ`C0ފ=s]aIm9x| T7!Re-$-$TH)Yw: !EJҢZiJI*Ks}733{<lj / k @+e#r&Nɔd.; u?]=hTCUF?qhGQV˴68t\wS@uW ׋.wjK%Ӕrw}k/ivi{:>enO;'EffuZv( 4hXYC3s=_nzXz_ ^#eSroQh9'WTCƠ'Ecs-G\<0>u x6:TкU餫ђ]1َuͺ:3FNv(t{dV%/.2gR|Gl/ 9=_/ubWNQf}Y9Axׄw?Ф ȗnE,#ΘH)Sڑ)5Ҟ.me5=!ѠdGExӣ (c_ovjm >O8.8WL-G/3hTCVW,F됞ghs3[;}پU+6ߘh7jnzJ̬ -/߉~LRS^mtݍmJLtԬL u6%{}k?闽cvyO.߹GJ>}Vن_GQ?V:FK'R_ ""~돂 l>MݱE7o<>+rX);MjÅ[^wnoViEI4e5¯VY\GUJY*>;=$C޷,_``: ,_6vIuKۧ0ظ'V孚C_ΆǍ\գ@/{d1=SwW5_t)]mx}w+3'2f^`09qIf@z۞W>w Dh\+?TiwQQ(87|Pˢ0iIpL-o|m EZ~v*;VX(8"uѬ;N׶'&-9ˣl5|r&鞲vOwUro3Sl _.S+CpʄlݑX9jH\tWcc'6{}v# EDBq?g^ ҷ=[s.QVGjKѲw/T8C&Jo7+Yuޕ"IРGoV«]UK|Z޼ֱ+o1vzE{FsӧD;">BCEdX'1P)Zj`1TwUQ l? [>sِ_ă wmO^yvǯ*+{.~-sZz{v@'LNSφv.. !N3DlnC{:VCɚ:?gH,x9UӦg'VdxHYvj{-&.(c=izj5dd֝%;S`N!㔓~w z8gL9*Em2/̺<-Z)p?=oA:MP"и??C8~Ӯ &!˿r!h,gaVAֻߧB_{oyDyŃtwIu_L୭mz6+>>gvo~W;>~<-\e5I%cK:SjZTʸg6iXTܿ5*> /`Q='UР'_;NU sQzz%tmPlUi{|\d8=m&%hS{(GesJ\ӗQ.^bX<_ӁL^q_᝽x.2w:x2;(K\2?x\raRU7IPU@TRs qg5'gڳ3y?QU¡q/jV*LuBrײ .0;vG)3Y?Z3P{˲=N=}/Yy>,w;㶞:izI'B~%oZr'HT:6wJm2 :{/:Vqnoy QBAe_;?_r\2yק[^ù=z?ӗpmըȹ[VXlt dINO}cHt,>қ`h$}f6?zv]íFUE6ɪbivӞԘ ;~i5;yQ'so [qAhsk\p|dZq c/,]j;w?Y--/w8E<0u%RϚ[+*Ft1:жppٍ9Uuϳ{8 S7Hm7rgvW*0dX֩mzqzGd-w]s4M_wJIɆ1ngr/Y{ _}QՖZ1wgםj^vRF_FAST}O{`l&1Q/9Y?ߛrѪT|κ=*Чɸơiud,pE/{{{Tuޫk7fgȘ7 ӻh .\R;c^?_dIb BuFAIP= *h]|L%T"P.9*Yfԋa%d'z6FkWrX4gZxYŝvп24+׺h=_[M/o]KZ8wZw|?7ڬnXw9iz#<4e8Y&`^V١M=V_%Nw/6F*6zS~c߽:np:ɚCڄ7.p xZ f+ʖ9kQ-'?^]ӠvRu~giMIF/ĞPbAڽM˟fMk+BNwʖsң[uo*dFgV}ZR?i5{h݌j+!y 3%/Ge?R_6gZ֋JgUE݆W޻SghH/ĩZ I"Ä/YVtvwMCs$FULjcqF}AdmƖ/:_; Foݍ8r/y|n>w!:XsoKwكIv=;{ţKcL9`k`e[ƩxmH(;tPmMNͫog-u!nS[-s/gKT.qk!WQ7^?_[/^ 2Ql}xyAbhࠌ%#ꤧ|Kzcג|n.q~q~/MmU%F)P} 5 gduYE<ԅ?3 S/ ?ۖbb4+ #-x":+DtELɟ,pq=t{x-wqaO>|/i|l8zk^lV@o џ |dկ:[aڍp`z㡦))?kBvqN =/.xQts`*Rt)J yHI J8 g~;ǽM|-]1-򔦼J]?/H9dFC_4~_PIRVaDЩ:Ra\{K=_1-G=(_' X RWZٴTU -a9zЉXюV6ҷEzǺ}1/#4b\ ?;mTnǁ^Q}Ff6^]Gǿ*g; ǎկVP[3{4lS^Zs%|WX$#~'}% k[c|f׹'at}ڒ7FF[De&,g2XqnIιwb.ݼfJwj*+^NWJfRSo!])8bVs*5m˔Vީ0rcb}Q0X5iAZ< ~ %~@}?{;)&Tu[լ7LF;7? Xo{)^~=;s"pW %Ѩ Mz\}|ecf)Ls {Emkc{T{9;++A_ϢV-[ו8n"z=0QOguxDZu~/˛50'e¢EU\_(f[Kz̠ GR_ZIw{1 ~#M=ʛF$n~qSp9=o鰜]_*{gG4/HI=8ISIc3wt}fu͒~lֱtU7-vWvkR\݊1 3`[:qOj;ݟ$$LL ϣʀjsk]uQC*Bu%:Jӭu *@MQg^Y~ %(M҇O|zXى:$] *mT^ oQY/]Nn= Xʬv1}1⥿]×{8I02eK^+*twc.'%sDyᾠ3D4W9 o7wk筿"EE_?k AUO4~s97=ƽj'k~rǢ)]xgαxخ+V^ .)kB\=\{@i&y*7>;iZz͈.k|W5UO =y!~?v襒GR=DO8zI-͛%yGfM`{酚Eq~͞< sڒ o1H3=[__^sl5;vM*Ewe2瀳!*A; oOxR̐樿ɿu48wma-tpJYVğ[waMA=ӓ6%޵+S*mrwnC;Cm~Ċ:l;:?I% R^ɷVX4oĂWMnxif:Mlf0uU@Ԝbuе|^#@S^?u}?Gh^OO֑C>fu)i1@3k pndWR6k![!kݭwg|3r εqCg6n;T@D[Í;&"I+Gs+ ōj+nrՓwX%xwWfH\c2p҉6jW2_+oo4kљ%8d2|-rl77n+y|27ro$'ɷkg!j@Gyew=>IC֬W*cVF``DK0ÒWW(Fʟdp Dİ#[D]NH&iF 9al=To^uw{nuD=kn]yI._E~=s\x_z#qnފ>9Ύ 濯NN'>#/jsq!u% vqg2UQ>1',=ʍ5L=z{WXm*|ܾ/C"&*Nt'fK @}QDVC{n_W=jW~}V|CuM/YrorwF׺@U+sV_ ܐyZ^@J(#ƳY σV}f U#뮕{DN(vblU$\}r̀8vY"Py=~zmQYBINu)WjURCo<3t.0xmiP69>{,`??WulGV3| szE^ǥiY?X4.1͙:ꗏWPr^gqӢbOg}re\v`ۇKk YEFKe[ڡUezd?P,F0{'j #f|yʪFNIt7֙s[U ,{n+Qh5ҢJc g7|X6o'\u&/{ϱ95ƞqWbOσٛ+ߔ9K;ѹz_JaFg,aƻ)ZJ-jjIF|h^#(o n2.k zvWe\Ȭ |*}Uo?&>na3W۽4EKV蛵ɇ[x Hqo5zxoCw}?)x1D!} kׄtR zZ5NN?1f;zG.~@SE,7AJ,cls~|WD˙f#_lܿTҳcA;9Z<,D9c4V'j 3G{f5/~2,3><8%׾-ȶ KS&Ui{Р :~Rq;Z1vQmJiU\Sf`e}?-|\K:wp̢G{ob'9Ie.lYj <5R0drz嫹:mc/-pDR4 ~Īk8:N@@ | LA_-9uP!dա zC-ֶdcr 1gGK}tkl7[26|mg-Η %WޮsZ}nh):SIK]fh- ,@e7[2,K= '+< K ?9oŚH5eXJfr}4]]O ;M>1mOS RߝF `Β)m#z-C4I뀡 \\y~姞5#-?7.4#^W/vMHͽ\_i}ۯހm@UD1M;y $4h73P4.'+3gLk^aooϻk[L5F)%\Y|?b*ݩNزͻG~(|$@WϨlFQEwf}";OLk@,g9zdCMƩEFlV~"#Q0G@_Nb.snAfO; w~rDpJlL X(0x ,{`LӃL,1 ,FAe2(tcL;b F?ٙyB&^G?y_=XC6"X`:"A(6#F@ @318fp0`CpʂX1l䁣Le,<HAp3 3a4Б ߅_΢.N@ctcq (FN:3Y8+γ'`@ΆhN`3˜x8 NRKvg?|r'#ck@}˲YP"H8΂4p )*H}gc1(^:$<~q# F_@'#x(:T/4#c|@S@aD7!Ʒ/RƝ x/~Bq#tR0I рًF%CqCD |p ٜr[,(xLnhcP2# /Wd?Sѻg >` fa,Rl@8!,뢢qzH("ha8&MP6 C>IGiP,6? I\P!Εez? _ 93<|ebit(yI$}z#sf@&׾L%`>ckaR tF\?7 Iuph\lLHF30ƞ=E f  '7f> 'LO?5?_?D& Btgų ѡa #hpah3Ƅsd(jRl :&/ =0FH~[ǙA$M0Cpit4Xi0#C06 c0& ?)} ^3^^ ˿R߇ KV0spE0Bq",4:;ØSүi`jK <@2ϝ,ol/! 8d4AF#] gBv"D3C z0, / ` eO_=et>3T+H SQ1l/Er$ð=00Yl@aHGG-cB ;z?4j*FS{R-p6󼀛Ԁ7wh PIZMX ҿwD*51A,"$ `r^X@p"* 0z `R9, - z 1/"2#ڑ?ܒ8?fVߨǟy,K@SGdž>9a jz00P&7ŒePF$F#%2d4G8:4)+`;Lʠ~H sT-i AFI-|f"8cOP=BpN0A0Iiay`H~䗿TFY!3 Gl{i)p& ?203HtDFayp3tA0H@YRN0`l>'8}΢{a Qz2΂[7,A:ň N^R,QPq2"|n =U_t8_0.hՃDECCBϊ@09EaPPgCEɥE .y-O(vU d>$& N1HphTeI! "CGC1QܦjQq>y|,lONR.mK8ٹ!  ,z CCڟ!tx"b`tR 'ƣFot";'dǩ‡8.ʔ_7` `r@ QdFp 8!t$1 A1PkGX 9&ʙ+Z1.~(8?mv^|?ౡ_ &@_v5le)@+\$+.}k0a8}ga :Iv8OX&rx~d'^%Ɍ>?S>kn_Ƹ ^OJ|ԂgRB@6U^d٘?1"-Ba{CыE/?m1Ii}xM$0ZWH0e OF :>p% $m3( Gˡhc FcA 2pى$ʞ0V8֯@ݏ!P.K1@xH~Ͼ4$͵<{,У,f j0Ժ cZcr~8Shޟ1*qρW/ϛ?8>y)PB'r5/f06 #FHOECM`9\ $cZ?eh4,L`ˌS RD2@XHtD8&?zRo[z06Jt:K8?Oam\"ݘ  py7]pAO\gP!HX,&m{Mz C  C ۙ\BL>pS-'x0A +\LϨ0v0,y耆?((<( b)J#ȁY e0/;B 6 !G~?P8o8Fu/@Ǔc `krX3 \\sRP搋9O+Mks1~&$gpI =laP#%~ g;̉F8ClZ84Oy]"%G%6'~/{3c s"ȟG^h) /h0SO]?*?HRuAb!4dABG]MI9&Ty?LE ͤ\CJ?A̤ +E:6GPlD0?F~W$ 0 뷟`S!%k=ouwc 1~ג6pƑ'CO`cT׺%RGx zCKp]yN8$ 8Բkx\@#QQJX%VR8:%*r;z9̩((*X蠢/**vc1%|3{w}Oٝ;yS8^ Uk+'^=ƹ&γ_k~cˈs{O)RM 4u]pks_؟(麸o]+wnCʺL):^϶h_aW7#z܀/*_he#NlkBֹ?9? )*La ^!xݜ;}z=ЌAd푉·[;{ɚ}UҮ=zvtv=sil*ƌavpgK&up9ԳE/mټ[Ubf켊s?+ĮޮݳF$o7RiL)>Uϰt}/Y}ɎS%n-Z06fzs)?6Oҟ/3 u)j~2fv$3,/oaaQl ܶF|Kv쫭gzm*ܜꄄg:_eٝ=cX613 ֮ثsoḱ֦3EqN;{&쨣^9HKfW`:]99c1_ޜ⬿~2@K~_zD@'(F~gjǀqՁuiIBSC:6&^X.~/N/r{K ||eUKW#V5:{^\|:詴y5 dWMɴNLG[V3c;?k[OLwkـNrާtPK:(Yaƫx5anC[N7mTe8|oo< eQ# S?jeB_Q,9v}g&SO8LޅN,g`=+Ćw`PgW0_^bUP.znW*f܎_o[\zV$c<@_.=U~cnW}s!z3~k轷߃Y7fNWIϰAuq'0r}'ZtHϚ.v:z=R0PFfcƊj7@oVS Mc,\+MAroO\9U{]z|x+~F{ݿˮmk4R'fop s6K_pSSE•3#8=O&߽! /qrs~\KH|e2G^P$^__~>b<}Se + A/>%1f~,~1ZnI.KsvŠgJĹF_0}i0jƴmTM$~ ~?ÿʅG<lװXuB&=fQ$t7U_ܮԛuU^G\dK{[#KCI^95ǩ^sYĬm}Ǯkwٻ&4]ؿ_x*]r~%:s|I.z`бA ָqc߼N}o4bl'x_Y?/WCuP6q)b7@3g$"r͉q[զjS'M+!f0rC&y7@'=-?8\0d2UˬXGۛ}K8Gg0[}%\{OBT25q ,dGz ] .kYF(ɑf8;%*T w謎WzqWWpq̞ኆi~e 6Pxl˟' &?ҥk׻]|3]gݠ5Q/l`ג /ʒ6KY|kwdY"bM[4uϟѵ]P4݋O-V܄2 3 }ay ͖,(ajA?@Qtι!P V_SL\d1r0pd@s>+&UHZ%^{@9

Y>5r';WX'[8+=Y\Y)b݃̓\4<`^q]/g==+gʂyV%[쑋zdZ;kVfl3z2m[-g>ܾ 52u̓Cz~b3~wZ,Pjs_\~ ;՜nl-ȗ'O*.*hоL A5缂=y *ci0)pg`Vz|e>7{X`M $NfҀrҴZO%lEft4[[ܢS1 q m |$58IASZ%]:,{MsM]T@aS(+nkӋ}*(,Q 2aGբ*t~lo\ {*J9f*09٬{%Y}/:\lw1RNU`ReR[< ,STW#.88N_Ka'96:M@('8&OlæԲ)$1@H% M`AMIx$HfǑPH@F`9 (EI0$E@‚NŕC RuGrpN e+4%nQ2(OzG%p6s[bL2 JJQYR)cn$ `b3vby%4Oq (P^INOm*Y T"VYSD.pN灖ž $AC[l R d/UBg"1U$g([vN Mn(dX5RgA>H_49k?m7qZBѨ!yG'"'#߸8@ ?L&&RF|}g\@  ԅ&F  u6'H}kLV  =?}R~{ F9Ώ>m7fkJZJ ?$9_NaLJ7?5|PGC 3>6)$ ލ%ʳ<`:LF'{pi8 8XN2ǖG-yD.$ xw6Nh!hVB$;4kV/"( 5"_l d&KE'JP<@/rR<1͍txC;&Sv]-۸d^1X=L3+Y6I?Z/ _g;" BM7qͯaL&Ƅa/P%8h ,eb` Y!AYKW:C!mA@%Ǩ*66o z\)TUc*LSP[oN?2oLDS!@ f6Fy oHdn~%tDRhם\u?ՈsF, Rm P@&g3pQT3[k2ELgJmKEQ͎!]ᢁUXD:(+Kh~_DJJڲKWR2B/(err6SBoOF2X:Sg# @eE3 M$,~rt5'_h0 4JKP 0I3G EĿ!JT$?$[liId{lY2;%ųЭ}kdU/T7JE\ϛϖFCvQ ~MmOnvԛsb`7AFo/!I"hzюԋlBh1oTIYiԂY^uC3-J;lK~ſu ~eAP_@80h"b"3QQ]Am~B٤L-d?xP&:;Y]2.I)"H?~ uշTP=OfBJNdC\(;qOH$ 8]_:! s:u[Dj,~EgGLRPqi)> ]ǯB_2:?R }a(pfMCS{[Jc)")&PB .uB)B辄FWa [1gP-%o #IW4Gd04)YqU)gsl;gس !hN2a+Hܳut<!Q͝-R1i45`RJдVo gtOYbhH4d$D`H*_TU ^:7ͦc4jCi ͜$h>2ECqLUS3<^g`,"΅+CUgY=AGS'C6|-x\y~/!::~a&{gy0KOh{ VzBw 9&+/|vlste%ҼE^=ʻ`|Db9U3Ȅ1%v*k9zu4{YD هy whFUG,mR^q3ËYvۖ-Lbhl!px8@|'(06Xy~@-' pqӧn- G_EGdhmwv_t5/EJ(e`7@l`վn.`Ӟb &m©X*'z)R$HXD,)Bg&}Le_\z̀?~oVK=y4u 9Oŕ=ڦڭUվoqӌzNһĚ g/uXܙ6_qoa1;"7Gz' Ϋ{._U;_u)AQ{[~Sfgg\伝sHMN:-2mí,IN1c\xen/jhRܳ E^ClĵzsH}>^˳M+ՙVZ@86iְL玗̎1_f},zQs)cuǿ*\߶xgwzfxJOorˆN]gVV2e>5uߜ 7]Wuyfά\2ԣ㿽nzz|ͯu]7Ͼja6H.~)ORSʏK\{:^ط], H/Ԟ}$֎%"(VqECfOӜ6><%%JvuͺI,z!{6UW\Dgg÷v{_ I3kR6̮*Υ]P*`ܸvK sm\$͚Eq]jBZxφ sĿM1<\[9K>|Yj]} e^ɗ4KTΌߢMAZLxo :c'#V# Cj/qdXms#D vz@l#l^(b"Ip]V[$Ì^\x%Pt֊Ԝu.4YPCLDݎ+R@{4R껔v%v!*Nwm@#Ooyoe ʛ*ZmRAzM0~Y}& =N\Jn.kqwԀJ]ZRNdQܖ"U#Hy-BrVևleڬt7=YDJqSlfL~d+7^rC`e1F7| "ʎϭ;,햜;OX|WϕmQde [&5~鵛W(<*J]3N1ۜ3.z_׍? Ye\$U=-Asv ~x>'WӲ*uc^9NTӳݕ:ߜZt'hnV1R/ƺE"yW<"]Ldo/|{&]˾vmrRMG$s~G( gCw㔫njg(7m7 TY{ʘ dN,8q3+[,yl:?~̸m_mhOI}}V I{jhG6~2~ʡh%۷^ M.tS0HV :)W*ﯹFj'$mnJͼW Xq. $ͬLŊy߂z o'*2m5_cl+&Fr=\6ݝ└5TIEbzENds猛IXq%6NHZ[ }NH#‰w 6oit< B!q`v45ğ|z?{;4ZAܽ)#lhp  q:ʩ #*gA:vBGF^~w64h?I8 x?ٟxXãAj(Z6+QrdDBO:l_A@9FCϥ _ AN1_O {]C| lB`8u s*o9NWC܇fQ/#(VBDաq0A֦ O|s ?-b@C8Zp7 v+hX8ɉ0!!!?`=A?!{t`Έp\n3qv A}5GxnG)d l, eP𸯿Qb`ap0O|!UW"MPL0J6f' cƶBiD!Sb[./# EyM'>! %1L]h`~Lv F0 ! orm,w"th"Vס:ntcb s(fጃLEWÑ$[ f).  5!wcb7;|d$rE٭04좂x'< Ox'< Ox', >ƌ;v淊oQPZ|^v)9cmο.~;~wv{v;&ųyA闿=u.n>ᇏ}_|W7stSp5[\9{7o7jĥv?q4uwu长.c+]rK/ť).åz/ť).Kqi?.+).Kq|_K)p^Kq|_ )./ťvTT/ť).åz/ť).Kqi?.+).Kq|_K)p^Kq|_..%Wz6]zKuwT/ťvT\kť).åz/ť).Kqi?.+).y>/ťꕿwT/ťvTT/ť).åz/ť).Kqi?.+).+_|_^+=y.%W;R\*~_;\Kq|_K;R\OkK_K;R\*~_;\WR\*|_KKqi?.+).Kq|_K)p^Kq|_K;R\OkK_K;R\*~_;\WR\*WMe.j~+]_^+]).+)_K_;\(gy~KKqx_;\WR\*RSRRR\_K)p^Kq|_K;R\OkK_K;R\*~_;\WR\*RSRRVuwu长.c+]rK/ť).åz/uWx@q|_K)p^Kq|_/Kq)).åz/ť~|_K)p^Kq|__*~_;\WR\*RSRRC}SRRs~Ƌ\2;^~EB#ӎ:EwT=f wXdG+=.;tP5rt!߲FG/&j10~+ḱ6z_3P~.h0u,ww{L]=:t~9|ƺL] Mn=@0H_/^3Rcf D{=uwy \GۨqX{`]=c?c=#+-U3ۊyglKb\aYKLq|˴[EF\ てÕ|ogC0?6{8~3u9\\_S!dA}01 =ƱŖö8n tI\!M\cEZ}E#qX\i,U?fo~a#zxi1Ǵ~6ڬ23gLlpx1 8cEܸOtcT6ՎG;^/fV9k,9had<"2F:f-qaG:>#O.XOY1 B#A w >[uA1w)!my`2'v Ib$uhr\߻\QjҾ<~7s@$=jvaPgP1:,1k!`8f cjl !8Ƴ5[.\N`~Dq*)2_w]!8b;y~<. X_1;' fpw!G0M昏ɵ|)gÁF)5,a猡0NI v4Rø![ȷf|%~q>@mO~m9  Ӈ+ ak?¬z[;m=pL?ǃ~pGk:h䏉C=.O)/90_+N8` yl˃"+H1`hJ//Py@%~-flo "~UAp@f,rDWk\p, (yK7S#,|;vaqp lg?ϱ#0/bj߮]f$g~o;5v,CarG"r^y9-Wa7G`{$R~{ ArBaf 50?X8[a/,0"֓sE:3=0xa!oscx'|2OO N6`䑈I's|[ݍl}qo:lh묀"?/<Gs`ߕiy.Mu;NJA**2[o ?ۃ [#!_?v џsB}>g9tBGQCZd7-\sFv}-m@}~>};a>7|7o+NH?Iq@j"2Ɯ} ߂ (bFĻ>b跥x?֠D{$~<>XYg+{VAaZDCgm@EX4?4㼧laհ֡(c s:_=q,,g(.O(PX.v..G}M>5:M~cð@~Ղz z !A_b1aU/[7xLqbov(_g@nQQv nq#C.PT/& 42WX}|(h=~]~H/k yB| > | ّrCB V{}-l'Ňq=Ǟ|`dXlC b`zlwp?@=N#79 ۗ9+tO[kl*Yj>?n~X@OKxbɮTUiAaLV vg4AF_~*}}C;vT7ڐ+?_Bik$9aC#x-vl y7 Ї}U=a>i55O4GWieP.`L3!Q/[WAqG9XPn6: Ly 3r!+iHy} 8^XG|6=5Yo*-_Zx>M? ssoKPK@<(&QTMarcie_Grade02.lookUT 9O:Oux \]u}/`9HP)( )-rӦk=s4wQ|Hb.~7ڜ3G~?_?㧟ּ?ӧoy/?<~yÿ{޼{ yÇXt~y~?o~1Oয়_2_/[{߿wo̷.{ ~zfv"zǟ>~_?柹 pn!m{xn_n)k _s2xg:[˿Owӟïo:Gϟ/\6 slOeC,̾uŃ:Ϟ\ummCqWFclGozaO3jsۡx]x)}/x)>rO^?y=%/%K/)%x}WtKq//^O\&'/{|%O^?y >ַ^#_ơ{ơSJ3ơຟrm _q/ŕ_x)>KWx dܓ/iK~m+c;&zKƩ~=IR~=IRK^:nү/mFKxץK~)/7׊՞_KIzR|_9.R$uܤ_ =u@y]x^_KkK'R^/뱏I4U5NR4k_q~-xi_K~)/dܤ_+^>|_w_ү8ѯ W~]_u+R^Ky8կ/m/U:0|_/%_/W_q_+^ڮ_K~Mdג~M_ծ5š2NkҮ5š+R)/TV]+y)ү+x8կhqq_+^O~lgү _sׅ~]Jvկ W~)/Wt׊~)K:0|_/%_/W_q_+^ڮ_K~Mdג~M_kCCiWP~)/Wt׊~)/W5|_/7׊O_" կ _sׅ~]Jvկ W~)/Wt׊?WZzK~Mdג~M_R|_Kǩ~xiR|_/W5q_K^Ү5|_S ү)e2]kCW_q_+^ڮ_K~Mdג~M_W/µ~]JD.\Wu~]ׅKy)/TVyk\k/W5q_K^Ү5|_K~)/_K~M_KƩ~-yIK~Mq(J8q_8vկ)_R|_Kǩ~xiR|_/W5q_K^Ү5|_Y_DT.|_Wׅ~]J+zR^O竼nWR^kux|_K^Ү5|_K~)/_K~M_KƩ~-yIK~Mq(J8q_8vկ)_R|_Kǩ~xiR|_/W5q_K^Ү5|_{g~=lj~]ׅjWpկ _R|_Kǩ~x]z5ү+x8կ%/iWx /JSZv/J=W5q_K^Ү5|_S ү)e2]kCW_q_+^ڮ_K_/%_/_{:yCf"s/^GVrvl[]ڊ=l?1Jjn?V1pC,{Ťٌl8jt1muk&-O?ligzE{pm4~5}]ݫ55 a>f3`yLsa[K>[w/<ּöb2q s  9;iaCaMO ȷOLb- |&G>o1 G܁u+\Bؿ i)1\N-tmΆ1;SHR[۱%g{h\<Ȕ;d(W"wN7†vBE#ÎvAጣGD~Kl9r|*qtr[Bz`mLNXg]|=O`tz2:nO:UcOzW"a ;~ ?yRvm}=T>E 9= ôs\j_Gwu~8Yc_>R5[<,ۄk`WcxX-n-ͭ#Ds0!#qm7(,0yqC08D!knգ 3H }kv yKA<}voAP Ou% kߓ(첇qn)𱙯cع|R))<}n2OC3W8:r֘;#5O`[kH'VƱ6c*3GLџ"b޴#sb_N>io1|p[*ߑu[b `35͏۹Hşf䀗G;r>usb,s08-@w}^GU3.u>@Op6@ zr#wmg^?{;{v<ructD}6p?mH}!=/ %yB9mf -smˌ\8>HG{:κwg*Ɯ[<{,>y';`C$&[a)*!\"8ӿ}l-)&78<.>72~/=tdP(Я! Z>O% n׍tgqQA>PAo%bg}?do Gƾgl;I [cCCJGj$'{p1=]Ilk^0_4\=%ϺDZBdeR1h_lW$4 ިQy A?֘}>/( ?K5Q9 Ԙ~gɆk+XcM{>Lu;jRgO͆9Yo:A?0ЁS9?Vw:s~蒻yƖ'w1a'C/P/⫡ڸHtmT^;nu"w>*A4:ܗ oy 8SَjDd }q{.Dz\я U0&Kv(D9TX5-C2Pq[eFԸp]-S8 $upYww,fZ  S߻@o <|io$yCs0.7\q2bݥPWy.qO~q=vQE~sP"퓩dYP[<>^ i%qݹΊ~AAHL\mo}A 6\v{$. [ٙv]( n?\<1HwW~ڙ~{CKx;㈉ƹo/Op_=rq:?O05>/pnC{iHD#+Dχ;׍t \Yt>|+x(0-%a(zy-۹mu yEϬ{6W5m\Zi{h~|:\C>}3z zθ}Y$JǕޟ:)0ᾡ|>;A`_@(^c=s7w`A I]v}5TĝgVִ+nV<Gވȑ%=ݹ> >@9Z? Ȝٝ(wN ڹ.qW{}5T#.ȝ8>s M/pBqJb; ]!q~ y/3?󹶣}a;V%z>G}˨~/s Rst{ CPK@oW9DMarcie_rotoGrade_01.lookUT 9O:Oux KoFE uZ|QJ$KZE-t06cÐd/%Ggx(IxcrpFoWˋ|+6_;eйx;rR~q1gxQ^~vsyw;Qgm$պbW|ZNX.j{ηA!)*vQ?dlϷb]n׶5wUh]Ze;eòmk[Fq1iaYDaه͎^/mU(/y\Iګ?\{nuaȍV-Z;l{Sgדǟ>~Yn.o˯~;xo6q[b9nFnv_ J%+7'e]Ys[cP]?bf)[>a2}O |OgܵeMp.ru>}>gaۄM{-7Fsam|eγn5j/{l{k @<Q}j9ŧ3s\qg\Źqy=\+NIjأu?vuO?:6_PK@*ՅDMarcie_rotoGrade_02.lookUT 9O:Oux nFF֩EHWAE$BcHK#\}SAFߝ;!<`SZO:y9{=l\l/oCcןVjǝ^g=J¸zqV;q=>V򡼙n5-Py_Z].f=SuO5 zW_Nt㦋fX/ϒn.91ۇf8>m7륉vj$'zk6ÆIwnVV]nw|wc93o{0aK<nkKvܔߠK;Vp ^V[/+?xe n4O/+x?7wژ:?rզwlHɳ|2LKlRɕ}bN.֍q1W\Ei \_V,,W"s/rR\"WVy~<@._bB=?~^Bp\\/?bU}z^:\Oϋ9vW.k.y1W"sKqNy_bX\\̕>KqNW%Y_or/__+Y\\̕>Kq!rKq\\죿BE._bX\+p_䢿>KqNWE}b"s/>/_>K7Pw☋+}W;S1KpbһxYeurr/__+G)./ry\̕>KqN9._bE._u\̕E.\죿+G)./r1W"s/@%_bE._bX\*e>_+Y\_bE._u\/e s/rR\_ +}b"s"/:E._bE._u\̕\˽7G+G)./r12KOrjnnr \ \s/zxǹ sKp_B._b._b . \˸}n%Xw/p1/p1/pn.r.rK7Pw/p1/p1/pn._EW4W1hGYeurr/r1W:E.=_/r1W"W\8%Pr/r1W"/:E._ ";._u\ p1W"/:E._b裿+G)./r1W$lzY.uw6ۺ;a+<.+'sW\|b;Pw\+p8.w\s!+E}bݝ?s/>/! .Cp1W"sy 󇂋uw _bb;(XwżQw`ncn?,PK@.Marcie_Grade01.exrUT9Oux PK@;Marcie_Grade02.exrUT9Oux PK@&MMarcie_Source.exrUT9Oux PK@"'9NMarcie_rotoGrade_01.exrUT9Oux PK@ LM'_( Marcie_rotoGrade_02.exrUT9Oux PK@?JTo2 Marcie_Grade01.lookUT9Oux PK@<(&QTH Marcie_Grade02.lookUT9Oux PK@oW9D>_ Marcie_rotoGrade_01.lookUT9Oux PK@*ՅDg Marcie_rotoGrade_02.lookUT9Oux PK /p opencolorio-1.1.0~dfsg0.orig/testdata/3dl.zip0000644000175000017500000013431513223553423017314 0ustar mfvmfvPK q>3dl/UT ` Na NUxPKn=9zaX=3dl/crosstalk.3dlUT *MVMUxMK$v]E@\4PZ )Ҁ}#:wg[Ego????_˟~onx_n~{>Yyy<~{|~$8~^(N0{z:/ <:rK>}}: Kws|p[|s:/^Qy:ma}yoe~c ~ןkga}uN7r=_vo6ðAޯ(yM>_tb|:΋:-uן{'_ywRN &h]n=涾s_Awws}}<әaXk~7'_i}/ri}q<.n糓fu ~Yo~OAyQ??;w G1|;3R{IGi 2 :>P} Wy{΅A?.[Gܞr 5<^Π }8׷Ǵ%Tx{sֹMֹ{~}΅1XA?ֹ0?q/59%sx߾ss oZg7oZ_7s*{:~~_~|?cswЏ~m-b2?i wʹN9֧Uvu2vAC^'Z*{I>)d\: tʹNoZ?8i  .WY׭'i A.{{v߷q=ut?)pB)dZ'7?N:~r[gvCYd>AC^gU~,/bqst 5\/_i ߴl:~/>7[ ߻+U'i]~:^\?~:{uߺbz}ZvoYr2K9 N֧7d2{uv|tʹΆ9/U~u6o]0\U?~|<>֖w} }ץF/g|2g׳ 꺥g?׳#u`O׳+u;c?יnAMS;tLG##fl=agȆ##fܰȆ#flhw66S>{cM[[6n0e [F[6n09冽[6n0eCV?_-lj|]BҾ0f o6̾a o6̾098f o6onk?oMll|,ĦAo60;h0;h 60;h [⺄y[HccOo Li3͞ڴ73ͮzV4fc=:;fkao=Skk^okknnݚdƽ[6۴6mvӹ6mioM{6۴٦6m,f[{i[ssv57 ߺ7ܦ6 io ioM{msmnpԆۚO=57n͍m[sz7[oz۴roM{m[oz7[oz۴ޖۚuۚۀƶ୹qoMioM{nڛpo7ᦽ 7Mio›MioM{nڛpKjZry|]M4rx7Li3v|r3v|َ4qގ4f;>lgImrڑ1)w um]Cޘ7sޘܴ7roM{cn9٘7sޘܴ7M6s|^2۞>6.ܢݴ覽E7-zӹE7-ioM{Xݴ覽E7-z-E?ߋ]E7Qoэm[totn֛zӹYo:7۬7stn;stn֛zӹY?&u^JܖE7ioэm{ӹmo:M~stnۛm{ӹmXm{ӹmo:Ml-~\۹[tsE76M7cm |ӹo:7Mc=7M7co7{mn,FXo:MVo+tnέ|ӹ?V7[s+tn[c[a}ٗ-}V~̗kohj3 ϯݻɖԯ;l{v׳?$lm}+[-tl[]cƾ5oѮF D7-~ﹷ {hf߰pnao6i;g+f}ogs[m6~{߰ {fd {߰ m[ڐ|ڦ~k mojmֿao77쭿7C[VA.-mlrKrEcƝ ;4 а3@ ;4 Ph내+|{elbs!%OS pz3 / 4ILMgh:@}&3 XNM%_7&`EZZDvh:@әBo3-4ipLt3-4iᘤn=\sia.]0׮,.k0ׯ "+33/34 Mgftf334d^Ff @@sf@PnHNMgr0`i'NM!9\r @@@Pw (=$\|H@L;?v~0`q`i&!.)?$\~H5 (Cf.D;E4)bI3MiR&E4)bI&)"h.E\ Y G$`.J$%L;Kvh:ig %L;KXoYoחea*KGSYb3%'IXs3XX彏nn$DGI}=Kr]+J-t$VXh%XhE5k.yHzuKǒ&W4\q ghعa犆rE #WrE \-QhrE+7VnYro^8Vn,\+7t8']ܙtѰEN Vz/7.Zyc颕GhE+7.ZY8Vn.^rs7KʍEcƝ1vpГ1vh.c2FKo,c2FK{dn.ctq,\hZFK73 ҍ;i4AѰFN %~4wAo%Vo.i%?ƣ (j5r0qHqXMghgh:Tb}v> .\47h.op7\;7r8h\e\ 0C>SGә:tK=Rqr\s\ࢹEs P:r;\%\0~٣Mgh:GSك׳ 0e.\4=h=\G.Pȅ @] t&34 @я\4@h.p\Y3 @P1AJ!0Cra>sHڙCt搦3rkC\%5C\&5C\'5C\(5!.rk%@b (Zr 5K@Y%sa &FF4t3[ᢹ4Esi@i @P1GJ$0Ir1312IәILtfcIXo2 e.e22 @ @'IP(!#Ka.$|&p&34ɤL&$>H 2K&d4LhLJ&d%2$@фnBP:Ix OZÙO|t擦3|B'd4Oh.,O'dI2 @ s!%334)L)MgJ9&)%={0a.$\JIYJIƀRJ2R1@K9dbJ2S1sQ1UZÙUάtf3B׸FFsY Ͳ @Y B$# V+0XK,Mgbi:KәXK,qoܺX_/K,u}Tby}˱o*X&e]I%6ceK,(?!mȲ>~o:x÷ˬ#<L[zbK_[Z|pGK657[ZtcU7[ZvҺŖn.rs{bKk7W[Zۑ[ZEg_74PvI:M^e4]R?%e4.90]r`.\vɁo^vɁs%sG{Ar80ӰLC&uRAS&GAs&L 09h`r`\Ɂ 9#;4PӥmNRLK1Ih,$a~ﳓRL̥$K1Ihb`.$\Is=& $sH0(ӰLCQ& ˧K LE<2_ĀL*er1( @ƀL:Te1,B3ϒag,s癦 +kgXi.ϰ\a<Ê_a(ϰ2pV +y< Pa(аk4ePt>B +#԰\aPJsP Pa(԰jX 5VJ +@Z PɊL6Mgi*ٰU +%VK64lXilXJ6%V +d PaٰmX 6xtƛ]a~V74oXi.ް,ްoX7VCx Pa(߰PpX8Y18-xWsXsXs%X" ( 8.À20Pq!q\ub@!ǵX@q1s3A :-stXi.\aJ Pa(tXq V+@E9#PuX ;Y1iL;$vWi+ͥVZ-@iC Pڡ% vhj;Z,C PIg ›Q:g 3>sYu.\ Cq˺|<ϙKCsm~I\BY5syh{\"Z߳=X@ra<댅\4rX(EP s(BQ.̅\xBQ.̅\̱{uυ\4 E0Wra.\/b]ytuƊQ.+FhTa%\1Jb s(޼b s(Q2`bf(Q2Ud GdyCF8OX:J_|dݹrdKG0a.%\:J߄>Q2̥dKG01dkG0a .$6$kHh!ec~ѐa!e\Cʆf )R65lkH0אkH0a#e\JO:. g\\L\L!I>FbQ(&$ I>JbR(&4I>N-&@A'*PS=g4z랫J4WU%z=GU*PJU%z=DPU(+T虵qi??@u:P'NTS)~?VRN*TDl_G⣹vGsfG|s*U>|x7/0Nߑa._Yʇ|s*f*j._壱|Ň|+> X|4ϓqb.a%\J^Cs +!sGJHs +!VBVBޏi,a\"/?"!eX 1b.c%ynA;X 1b.c%dpdX 1bwvۧHs:#ͅ,F|KY12oQ)+#fwF̥KY12bKY12b|ϯWm>UX Բs5P̚V<>ZrV(gt Y>^7 |,@9GŔ|,#g,gsrEr( ԳFQ5P(9E@IE>wuE@I"^Ң(iQ(JZKZ=ﷹmJZ(PE(CR֢(kQ( Znon}E@YEP֢(kQ(d-kE( ԵFQ5E@i"E)mQ-E@i"EQ@ڢ(mQ(J[YE#}p(PE( FQ`DRޢ(oQ(r -7å(oQ( [-E@y"뗷R"EPߢ(pQR4ĕ% (qhĕ; (qh@+Eĕ% (qh@+E~1w͍@kj\(PEyEH"EPȁ(:"E( \e.2E@d.ygQ5uQC!.RG@۽cG(uqd5.RG@#Q`RG3@kj]( v#ģ8B].rG#v9].P(wq8 LDL(PGz8 ^"G@ɋPp]G@ɋ#)yq8J^%/lүwmz5@k6k٬#e/ueׁ ;඼v@˖({ٳ[M˦({ٵe/ve{Q5uqH!/G#n/G@#P(}qĈ.U O }-k3K_m>f8#~uܠu]2AlI5Cx\c:nn3>Ϟ_kx7_H\ZB_kWFu#XIf+'+:N9'@q (xg<3X?~||۞+h̬%e]Ͻi1VҬYAKKi)hi ZZy01Th<<-s=.+-@--"ZZEhi1hiy~q-"ZZ"ZZE4ahyD"Z^ylAx<yjހk֧̿/E48'0RM`3}#C)asxV}5ĀԘ jL5KpB5} jL!SL!1xb:SGr1e 55S@M)h1\ݓL45SM)1f\M)DSc Ԙ쇩g )ԙB<PVc (1՘d5T@Vc* 1՘ ].S"1jL9yzژBUHmT!OaTYT*FPk Q&HL! )M Lk7֦ Z ֦ Rk&x~(x*`Q6Y(@Mm@`rU>prUFU`rUk}B66yrrۨB<]5ٍF cԼϹ35[j[j4Oy Pr(o8-7@ywOM@zqxYn-7qڧMf-7~y-7SroԷ[n-7oԷ[nO,u Pt \n֕uؙ@K P_ !:\q9% !Z\qy%jGgjUjHI!^![K}.[Y,ǖאBd9Y-Dc+2Y-Dc Bd9gˢrc )̍Yx3c Z?l9[i-!ͱHslB9"B9i-Dc<.-67B<یQQcuV sl9[^Cc B9y9y-Dc ؊cBsc )Ѝ-ģB$:>)DV@c+ ѱD"ѱHtl![Ec B$:<^-F7"B<-*d:W|}OsU\Vd:ו΅e`2KKDsmt..եc\^"2KDst0#}Hn1B\d"* n_o} [EeUt_w+z^͢w-z^w/z^ w1z^-w3z^M5k3\V@c+ ױ\"ױul!r[Ec B:f:"~zB vc 4"z~R[Ɏ$;Ɏ.D B$;"B$;Ɏ.Dˢ<.f7B<5d;N<]َd;َ.D Bd;"Bd;َ.Dˢ<֟.n7B̓֟om|6uj|@Mu\D? dǧjvZ[{ߥ,/ du>Y@n?xd2 V@c+0-Dc Bd<"㱅xl!2[xl!2["EEoVnuXP[2lZnٶDdٷn]qxsXdٺDdٻDdټXAov/۾uo_"2_"2l`"2`"㍭Sxc+P[2 Lƣ Bd<.Dƣ+2.Dƣ Bd<,Jƣ Bd<7>:e(㍮d<.Dƣ Bd<"Bd<.Dƣˢd<.Dƣ xte]ƣ (&k!2^xB&k!2^x"k%k!2^xBdu>(㍮@ot&хxt!2]GWd2]G"хxt!2]%хxt!2]GWD] =+P]2 Lƣ Bd<d<.Dƣ Lƣ Bd<.Dƣo]7z`eZe=N2{}  dcyP~xuxso]~xuyRc,㥦YKMs2525@K 1xdQRx LK RxYQK\KMsf rxq2^n/792^nrxd2^n>OF/72^n#q,qd2^n/7xd2^n/72^n/7@0!@K (_x )Q4D/Id, 4D/QCdL͢dT r5DK'6V@c+P[^72Bd<d<-Dc Bd<,Jc ؚBd<(;2[@oly2Bxckާ""㱅xl!2[ 㱅xl!2[֨(㱵. xld<e5xc )-Dc ؊Lc Bd<d<-Dc Bd<>0;2[@old"㱅xl9-Dc Bd<"Bd<-Dc ڨ?&㹪 x.+2@o.,2\Z"eDd<ұx./%"Ddq~d2vqV[W3xOϞ@[=wAuKW7ծA{_3xk^2Z<ym =nָo]s@[G~c֫΃ꖖ'5joSn4j󶁌}yJySڙl %yQc,㥦YKMf/5͓Rxd2^jGxdo/7@u}Smv/=@K~2^x)"h$d2^xiRiH!eGW@ƣ+0.Dƣ Bd<"Bd<.72貨2Bx Bd<"z|Z2]d<.Dƣ Lƣ Bd<2x ).7.Dƣ2q M#}de3]f<o| ^2yld_X?kxS=@ƻ}?&π2xˀ2޺k#y޿sSmje4xiR,㥦y2^j/5@KcRx,RG Pƣ(QyR(.㥦YKMd2^n/7@ˍrxdqr P(q?4xir㗗r</7@ r@ r3 )(qxܬ?]#xd2^k24DK/GCd$!4DK/OCdD 25R5Ր2YCxck7ղ xld<"㱅xl!2[xl!2["㱅xlYR&]Mcy~[V@ckxl!2[>e<d<-Dc ز-Dc )-7Fő7ղ xld<"㱅xl!2[xl!2[""㱅Rol1V@c+ "㱅xl!2[Ec Bd<d<-72آ}Sm/[-@0/[Cdl 5D!2^x"e !2^RckT{Nc+  xl&㱅xl!2[ǖcBd<-Dc+2-Dc )-7(㍭oe+  xl&㱅xl!2[ǖcBd<YAd<-72؊xckmw_ xld<Bd<.Dƣ Lƣ Bd<.Bd<2Bx+"㍮o+  Lƣ Bd<.Dƣ+2.Dƣ Bd<,Jƣ Bx )㍮7`]'O>xA`2x""D&# 2xJ"I %i '& e HorBD] j xtd<Bd<.Dƣ+2.Dƣ Bd<.Bd<2Bx+"㍮uGW@ƣ+ G"хxt!2]xt!2]G"G"хxt!eхF92ޱqSL2^2}e2!e<d<-Dc ز-Dc Bd|/v}ZKvS-52^je4xi.Q,Qx2^j@Ke/5d2^j/5uR(.㥦YKM P(qd8/7@w/7xd2^n/7M4xir㗗r,qxeivM{6 vCw%#x^nرa<{5T_??_?_۟֏?ϿϿ׏gǟ?~~}?~?>_ӯOׇӯ}zu?ׁס>X=:~_, c>~s{8^C}5#{z=mjpvתY^kgzS/VCo{5j,SoSWٯ^p>=5%{-k:kt}:{칇gMg<ٳ5=gsgMg==k:{YSY_6>55={=˪k޳gO|6'={=k:{{t칿N}:{칇gMg:>{t;=k:{$gϚΞ{{tݳsg==k:{Yٳjy?=k:{YsOwϚzSYCYٳ޳gOgOg=UIzϞzϚΞ=5={:{_>=pݳ5=k:{Ys3=k:{YsOwϚ{ C5pXqXqXqXqXqXqXq!Z3q%Xq'Xq)Xq+ඳ/n>=pݳ5=k:{Y~6'9{NwϚΞ{{tWuΞ{8{YsOwϚΞ5=ty?=k:{Uz5u^SYٳ޳޳gO|6'={=eNgϞΞbݧΞ{{tݳgMg==k:{$gϚΞ{{tWzzZSYٳ޳޳gO|6'={=k:{{`ɫ?WuΞ{8{YsOwϚΞ5=ty?=k:{YsOwϚη_ao{~ϰW6<^ {j3j=fg؋P{ayyFVzfMy}y歚yVzf=3xsj1k̘yL <&xgό ^g{>o wtfl1[`.+{<3zk=jxW|jx}jxWj0j(̨Pcۀ`̱򜣦)jj&0P !Ar5DjH !3 ̪:TC{!@ Bj@54 j(80jH̨1TPc`Ԙ.ƀ@cF @5jP;yTCI y[ϝn{[n{a owޭ~ ^u0f j((QPCSP }*K- ¬ @5j0Ԑa!TC0i3 BÌ; 5FF0j7XqÀ:̪!TC#@ G@5j?0j@̨Pcː`؇J@QF tĬ@5d$jIԐ!,TC^T!Za+筣KJgثPkaGUϰV<^Z VGy&2ȊDY<gi"NdD@dfD&1AdbD1AdifLfi "02 FI0BLc9NJ #3F~LdbF I"5D&jLϱ!2TCd4FMͣf45P`45P`̱򜣦)j#j&21P I"5D&jL!2/f"3jL!2TCdzD "@5D Ndb5D&f12 FI0jLQcd@@G&LdbV "5D&jL!2TCd`7:k;z/uխZ{z/v٭j_ rzw߭wݎL Ĭ"@5D&jL!2TCdT#j&21P I"5D&jL!2mp"è!21@I0jLQcd#5F&jL:21f"jL!2 PCdP "'21"3jL$5F&12PcdT#j&21P I"5D&jL!2;2V[G?3l =3ϰW>^߫aCx^fyGVy3<<kitJ`FgF1ܑiD1AdD&1AdbD&1AdD1AdL Č #F&12 ƉI0VL12ĀL̪!2TCd$@ I"@5D&jL0jL̨12Pcd#`@ #SL Ĭ"@5D&jL!2TCdT#j&21P I"5D&jL!2mp"è!21@I0jLQcd#5F&jL:21f"jL!2 PCdP "5\s{[n׺{[nWn{[nvdb@D&f!2 PCd$@ "@5DP3Y5D&jL!2 PCdP iF 5F&jLQcd#`12Pcd*Б5UCd$@ I"5D&jL6QS5 FM45 FM45sn}s}.s\+94vϽs}.s|nȜt5LdpE& +BY]ʂX& W2I"5b椫ifpE5+Y]Q΂vDW3IIIhN" teFʐW 29M+DW&&Ԝt5UMjpEY +Z]Qׂ芾& W6I9 Wd6 m]ڂW 2Iter֤ MhoAtE} +[]Q$' WV* g{TԻ=Omp3n[o` nFpb骡͌+5V8jpTcc9Qc+Xᦧ]7V8vINpE{MQ QUTq\QIte  WV|ωue++$\YOpNp\E**sĸ UT8ͿqE 'ѕN++$\Y='֕ppeoqE 'ѕN++$\Y='֕ppe UT8 Ipp**DWQ 7e++DWV8ppe{XWV8HA•n~U3ۭp]Epύs}spڹ>x󹕟 Ǥ+* \Y 'ѕN++DWV8HA•ȩpL•p]Y$Ite++$\Y6 WV8AtNp\E**DWQ WT8&]Q  WV8p]Y$A•p DŽ++@WQ 'UT8 Ipp]E+r*ppe++DWV8p]Y  WVǟrCݜNT>T.zjg*|6'T{;w={ 7Rfvg+7  +X p3 7jpTc @+X AY1!v ~( n4qo (~Q' Ǥ+* \Y 'ѕN++DWV8HA•n[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y WT8&]Q  WV8p]Y$A•p DŽ++@WQ 'UT8 Ipp]E+r*ppe++DWV8p]Y  WVMnczlms}s\ 8ʹ>wn 'ys\<[pL•p]Y$Ite++$\Yኜ Ǥ+* \Y 'ѕN++DWV8HA•n[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y ɭpLtp\E**WQ UT"1 WV8HIte 'ѕppe_P~zh7g*/=33ÙIj3=g}{]ĞT 7ͭp` 7@#Vz2rPfF+5V򜨱 Pnjpӈ+;Q$ 'PT8={NpEE**ԳqE 'ѕN++$\Y='֕ppe++WQ$ 'UT8={Np]E**Y+*@WV8p]Y 9ppe+++WT8p]Y$A•9sb]Y  WV~p\E**WQ 91Atp9p]Y$Ite++sĺA•p;%nn}s}.s\+9=*vϽs}.s|n1 WV8HIte 'ѕppe+r*ppe++DWV8p]Y  WVMnc•p]E**WQ$ UT89IWT8@A•N++DWV8ppe++&1 UT8IpNp\E**DWQኜ Ǥ+* \Y 'ѕN++DWV8HA•Tz(?=3əǙEOL$jz3վ=gbSf`[*lV8[Xpa+X68nPfVnjpXPc+X6 9V8zANp$E)*DQQ Wdìt6WEtI*"$\ռ$񂄫}$\wo[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y WT8&]Q  WV8p]Y$A•p DŽ++@WQ 'UT8 Ipp]E+r*ppe++DWV8p]Y  WVMnczlms}s\ 8ʹ>wn 'ys\<[pL•p]Y$Ite++$\Yኜ Ǥ+* \Y 'ѕN++DWV8HA•n[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y ɭpLtp\E**WQ UT"1 WV8HIte 'ѕppE7x:O3;m/g*'w>]qϕs}n \;޹>y>pN 'WT8I.pAtE+*$\Q: tE +*\]Q$ 9ppE+*\SpE 'ѕ.pApe ++DWV8pM9j* \Q$ DWT NppE+r*p]Y$.pApe 'ѕIW8']M+*$\Q DWT INp?Y P~zh7g*/=33ÙIj3=g}{]ĞT 7ͭp` 7@#Vzmp* ͬ+XPc 7@5Vmp+rpD((*EQ$H 'AST8ATȩpL•p]Y$Ite++$\Y6o ઀ઈ xJ+At&=uȩpL•p]Y$Ite++$\Yኜ Ǥ+* \Y 'ѕN++DWV8HA•n[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y ɭpL]smus}s\\9ΙQ$ϵs}s\s+?IWT8@A•N++DWV8ppe++\StE++$\Y$Ite  WV8Hmr+p]E**WQ$ 'UT8AtȩpL•p]Y$Ite++$\Y6 WV8AtNp\E**DWQ WT8&]Q  WV8p]Y$A•pvS?OL奧vrqrS{8S99I~ڻLoOTؖ 7;[V8p\Xh 7@/V{PfF+5V򜨱 Pnjp.X؉ 'OT8 At9sb4E(**DUQr+*@WV8p]Y 9ppe++ UT8 Ipp**DWQ Wc \͟Bp5?j WEtuXWEt"?U] Ǥ+* \Y 'ѕN++DWV8HA•n++WQ$ 'UT8={Np]E** WT8p]Y$A•9sb]Y  WVWn\7羹>qϕs}N\;޹>y>StE++$\Y$Ite  WV8HqE 'ѕN++$\Y='֕ppeߤוp\E**DWQ='UT8AtȩpL•p]Y$Ite++$\Y6 WV8AtNp\E**DWQ WT8&]Q  WV8p]Y$A•pS9nT^zj'g*g*=3>g{TԻ=Omp3n[o` nFpbTPCY5VPc @njpTcV8&X QPT8 INpEE**\StE++$\Y$Ite  WV8Hmr+p]E**WQ$ 'UT8At͵b \&᪈jpUDWDW$\=0H釜 Ǥ+* \Y 'ѕN++DWV8HA•n[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y ɭpL]smus}s\\9ΙQ$ϵs}s\s+?IWT8@A•N++DWV8ppe++\StE++$\Y$Ite  WV8Hmr+p]E**WQ$ 'UT8AtȩpL•p]Y$Ite++$\Y6 WV8AtNp\E**DWQ WT8&]Q  WV8p]Y$A•puc婟Q姇vsS;9S8S=ٜv?SS|ڷLy* lKٝp `+ V8.p4b+}+jp3 @+XXyNX 7@5Vy?npD'*CQ : 91Ap>p]Y$Ite++sĺA•p4++WQ$ 'UT8={Np]E**\StE++$\Y$Ite  WV8H|1~W76HOO3\=sb]j WEpu+p]E**WQ$ 'UT8Atn++DWV8ppe{XWV8HA•n>U3ۭp>oυs}ns\;g~Gwnys\<[yW8']M+*$\Q DWT INpM9j* \Q$ DWT NppE+r*p]Y$.pApe 'ѕIW8']M+*$\Q DWT INpENsN++DWV .p]Y$5 礫ppE+*\]Q DWT8II•ng{TԻ=Omp3n[o` nFpboW nfXPc+\+ω+X 7\׍pD`(*DGQ='FST8ATnF++DWV8ppe{XWV8HA•nӯ++WQ$ 'UT8={Np]E**qE 'ѕN++$\Y='֕ppe+r*ppe++DWV8p]Y  WVM7B];J+~&՜91~ ꧮT8&]Q  WV8p]Y$A•pgWn\7羹>qϕs}N\;޹>y>StE++$\Y$Ite  WV8HͿqE 'ѕN++$\Y='֕ppeo UT8 Ipp**DWQ 7 ++DWV8ppe{XWV8HA•n~K^WV8IpNp]E{WQ UT?+*@WV8p]Y 9ppe+*PKn=O\C0/[C3dl/halfred_truelight_log.3dlUT +MWMUxeMe=r^F'>ivM{6 vCw%#x^nرa<{5T_??_?_۟֏?ϿϿ׏?~~ǟ??~}~XO>t?_^O!A__O`pi~HXOz͜s{8^C}5#{z=mjpvתY^kgzS/VCo{5j,SoSWٯ^p>=5%{-k:kt}:{칇gMg<ٳ5=gsgMg==k:{YSY_6>55={=˪k޳gO|6'={=k:{{t칿N}:{칇gMg:>{t;=k:{$gϚΞ{{tݳsg==k:{Yٳjy?=k:{YsOwϚzSYCYٳ޳gOgOg=UIzϞzϚΞ=5={:{_>=pݳ5=k:{Ys3=k:{YsOwϚ{ C5pXqXqXqXqXqXqXq!Z3q%Xq'Xq)Xq+ඳ/n>=pݳ5=k:{Y~6'9{NwϚΞ{{tWuΞ{8{YsOwϚΞ5=ty?=k:{Uz5u^SYٳ޳޳gO|6'={=eNgϞΞbݧΞ{{tݳgMg==k:{$gϚΞ{{tWzzZSYٳ޳޳gO|6'={=k:{{`ɫ?WuΞ{8{YsOwϚΞ5=ty?=k:{YsOwϚη_ao{~ϰW6<^ {j3j=fg؋P{ayyFVzfMy}y歚yVzf=3xsj1k̘yL <&xgό ^g{>o wtfl1[`.+{<3zk=jxW|jx}jxWj0j(̨Pcۀ`̱򜣦)jj&0P !Ar5DjH !3 ̪:TC{!@ Bj@54 j(80jH̨1TPc`Ԙ.ƀ@cF @5jP;yTCI y[ϝn{[n{a owޭ~ ^u0f j((QPCSP }*K- ¬ @5j0Ԑa!TC0i3 BÌ; 5FF0j7XqÀ:̪!TC#@ G@5j?0j@̨Pcː`؇J@QF tĬ@5d$jIԐ!,TC^T!Za+筣KJgثPkaGUϰV<^Z VGy&2ȊDY<gi"NdD@dfD&1AdbD1AdifLfi "02 FI0BLc9NJ #3F~LdbF I"5D&jLϱ!2TCd4FMͣf45P`45P`̱򜣦)j#j&21P I"5D&jL!2/f"3jL!2TCdzD "@5D Ndb5D&f12 FI0jLQcd@@G&LdbV "5D&jL!2TCd`7:k;z/uխZ{z/v٭j_ rzw߭wݎL Ĭ"@5D&jL!2TCdT#j&21P I"5D&jL!2mp"è!21@I0jLQcd#5F&jL:21f"jL!2 PCdP "'21"3jL$5F&12PcdT#j&21P I"5D&jL!2;2V[G?3l =3ϰW>^߫aCx^fyGVy3<<kitJ`FgF1ܑiD1AdD&1AdbD&1AdD1AdL Č #F&12 ƉI0VL12ĀL̪!2TCd$@ I"@5D&jL0jL̨12Pcd#`@ #SL Ĭ"@5D&jL!2TCdT#j&21P I"5D&jL!2mp"è!21@I0jLQcd#5F&jL:21f"jL!2 PCdP "5\s{[n׺{[nWn{[nvdb@D&f!2 PCd$@ "@5DP3Y5D&jL!2 PCdP iF 5F&jLQcd#`12Pcd*Б5UCd$@ I"5D&jL6QS5 FM45 FM45sn}s}.s\+94vϽs}.s|nȜt5LdpE& +BY]ʂX& W2I"5b椫ifpE5+Y]Q΂vDW3IIIhN" teFʐW 29M+DW&&Ԝt5UMjpEY +Z]Qׂ芾& W6I9 Wd6 m]ڂW 2Iter֤ MhoAtE} +[]Q$' WV* g{TԻ=Omp3n[o` nFpb骡͌+5V8jpTcc9Qc+Xᦧ]7V8vINpE{MQ QUTq\QIte  WV|ωue++$\YOpNp\E**sĸ UT8ͿqE 'ѕN++$\Y='֕ppeoqE 'ѕN++$\Y='֕ppe UT8 Ipp**DWQ 7e++DWV8ppe{XWV8HA•n~U3ۭp]Epύs}spڹ>x󹕟 Ǥ+* \Y 'ѕN++DWV8HA•ȩpL•p]Y$Ite++$\Y6 WV8AtNp\E**DWQ WT8&]Q  WV8p]Y$A•p DŽ++@WQ 'UT8 Ipp]E+r*ppe++DWV8p]Y  WVǟrCݜNT>T.zjg*|6'T{;w={ 7Rfvg+7  +X p3 7jpTc @+X AY1!v ~( n4qo (~Q' Ǥ+* \Y 'ѕN++DWV8HA•n[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y WT8&]Q  WV8p]Y$A•p DŽ++@WQ 'UT8 Ipp]E+r*ppe++DWV8p]Y  WVMnczlms}s\ 8ʹ>wn 'ys\<[pL•p]Y$Ite++$\Yኜ Ǥ+* \Y 'ѕN++DWV8HA•n[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y ɭpLtp\E**WQ UT"1 WV8HIte 'ѕppe_P~zh7g*/=33ÙIj3=g}{]ĞT 7ͭp` 7@#Vz2rPfF+5V򜨱 Pnjpӈ+;Q$ 'PT8={NpEE**ԳqE 'ѕN++$\Y='֕ppe++WQ$ 'UT8={Np]E**Y+*@WV8p]Y 9ppe+++WT8p]Y$A•9sb]Y  WV~p\E**WQ 91Atp9p]Y$Ite++sĺA•p;%nn}s}.s\+9=*vϽs}.s|n1 WV8HIte 'ѕppe+r*ppe++DWV8p]Y  WVMnc•p]E**WQ$ UT89IWT8@A•N++DWV8ppe++&1 UT8IpNp\E**DWQኜ Ǥ+* \Y 'ѕN++DWV8HA•Tz(?=3əǙEOL$jz3վ=gbSf`[*lV8[Xpa+X68nPfVnjpXPc+X6 9V8zANp$E)*DQQ Wdìt6WEtI*"$\ռ$񂄫}$\wo[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y WT8&]Q  WV8p]Y$A•p DŽ++@WQ 'UT8 Ipp]E+r*ppe++DWV8p]Y  WVMnczlms}s\ 8ʹ>wn 'ys\<[pL•p]Y$Ite++$\Yኜ Ǥ+* \Y 'ѕN++DWV8HA•n[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y ɭpLtp\E**WQ UT"1 WV8HIte 'ѕppE7x:O3;m/g*'w>]qϕs}n \;޹>y>pN 'WT8I.pAtE+*$\Q: tE +*\]Q$ 9ppE+*\SpE 'ѕ.pApe ++DWV8pM9j* \Q$ DWT NppE+r*p]Y$.pApe 'ѕIW8']M+*$\Q DWT INp?Y P~zh7g*/=33ÙIj3=g}{]ĞT 7ͭp` 7@#Vzmp* ͬ+XPc 7@5Vmp+rpD((*EQ$H 'AST8ATȩpL•p]Y$Ite++$\Y6o ઀ઈ xJ+At&=uȩpL•p]Y$Ite++$\Yኜ Ǥ+* \Y 'ѕN++DWV8HA•n[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y ɭpL]smus}s\\9ΙQ$ϵs}s\s+?IWT8@A•N++DWV8ppe++\StE++$\Y$Ite  WV8Hmr+p]E**WQ$ 'UT8AtȩpL•p]Y$Ite++$\Y6 WV8AtNp\E**DWQ WT8&]Q  WV8p]Y$A•pvS?OL奧vrqrS{8S99I~ڻLoOTؖ 7;[V8p\Xh 7@/V{PfF+5V򜨱 Pnjp.X؉ 'OT8 At9sb4E(**DUQr+*@WV8p]Y 9ppe++ UT8 Ipp**DWQ Wc \͟Bp5?j WEtuXWEt"?U] Ǥ+* \Y 'ѕN++DWV8HA•n++WQ$ 'UT8={Np]E** WT8p]Y$A•9sb]Y  WVWn\7羹>qϕs}N\;޹>y>StE++$\Y$Ite  WV8HqE 'ѕN++$\Y='֕ppeߤוp\E**DWQ='UT8AtȩpL•p]Y$Ite++$\Y6 WV8AtNp\E**DWQ WT8&]Q  WV8p]Y$A•pS9nT^zj'g*g*=3>g{TԻ=Omp3n[o` nFpbTPCY5VPc @njpTcV8&X QPT8 INpEE**\StE++$\Y$Ite  WV8Hmr+p]E**WQ$ 'UT8At͵b \&᪈jpUDWDW$\=0H釜 Ǥ+* \Y 'ѕN++DWV8HA•n[pe**DWQ$ 'UT8 AtpENcppe 'ѕN++$\Y ɭpL]smus}s\\9ΙQ$ϵs}s\s+?IWT8@A•N++DWV8ppe++\StE++$\Y$Ite  WV8Hmr+p]E**WQ$ 'UT8AtȩpL•p]Y$Ite++$\Y6 WV8AtNp\E**DWQ WT8&]Q  WV8p]Y$A•puc婟Q姇vsS;9S8S=ٜv?SS|ڷLy* lKٝp `+ V8.p4b+}+jp3 @+XXyNX 7@5Vy?npD'*CQ : 91Ap>p]Y$Ite++sĺA•p4++WQ$ 'UT8={Np]E**\StE++$\Y$Ite  WV8H|1~W76HOO3\=sb]j WEpu+p]E**WQ$ 'UT8Atn++DWV8ppe{XWV8HA•n>U3ۭp>oυs}ns\;g~Gwnys\<[yW8']M+*$\Q DWT INpM9j* \Q$ DWT NppE+r*p]Y$.pApe 'ѕIW8']M+*$\Q DWT INpENsN++DWV .p]Y$5 礫ppE+*\]Q DWT8II•ng{TԻ=Omp3n[o` nFpboW nfXPc+\+ω+X 7\׍pD`(*DGQ='FST8ATnF++DWV8ppe{XWV8HA•nӯ++WQ$ 'UT8={Np]E**qE 'ѕN++$\Y='֕ppe+r*ppe++DWV8p]Y  WVM7B];J+~&՜91~ ꧮT8&]Q  WV8p]Y$A•pgWn\7羹>qϕs}N\;޹>y>StE++$\Y$Ite  WV8HͿqE 'ѕN++$\Y='֕ppeo UT8 Ipp**DWQ 7 ++DWV8ppe{XWV8HA•n~K^WV8IpNp]E{WQ UT?+*@WV8p]Y 9ppe+*PK q> A3dl/UT` NUxPKn=9zaX= 73dl/crosstalk.3dlUT*MUxPKn=q76/[C ~X3dl/halfred_truelight.3dlUT+MUxPKn=O\C0/[C 3dl/halfred_truelight_log.3dlUT+MUxPK7opencolorio-1.1.0~dfsg0.orig/testdata/itx.zip0000644000175000017500000013030413223553423017430 0ustar mfvmfvPK &?itx/UT fNfNUxPK&?4(2itx/output.itxUT fNfNUxu9eҭg+ @ l7=x_ʽcm/lo]Ru֟G/wG}f>:Z{迴]< Q|MW%ԞGs_VYQ^[wЏF{?Nhy7}v}oQטvߪ]}j;jo=콬|'VWVun|Sg/G??xTz>g˧nרh >kGk@#?k g0#Uc Sgȗl0#,?O1djUYuk|J_,oQ[ӣ kgJ+X%~riu,GytfɕYr j~+Sr_#QeaƈwfNOfEڈ'|c9JVxƤӤI7^5'}I_k_1W%»xgMEXbWfwk9)ʌ`0-C׎ƧbVc{uF王gSwΜG ebLb]'cxG~aҝ כֿ/)ebxr|V+kq8,m'qsюjwf<Gk,vfͶ:2;'>8O Οܙx9?n\qT<9+=8,l\q-V]4raRf1]NUc<_qΞb4(O;Fzo&G311_s~s"0CY^י}4.r!9_9g\ĎN\%hV QZwn6bcXoE\.-uO3oq8w|oڈږ '[l<@`SkET ZLmcf,z1y85rTμnåEmэO9\􋓭E,Q|η<7_|ɛDqк~2X+Eܜ*cs )_ks9}⒚K4[]m0'|yF@9[W?yKM0gT7G~/I\"5=I|Խ.GMoly5$aS.͟M'I<50'+ ciM+,宽vs'G^KKhSbAm8GoEռvߊ[5V/5N+n8s/ᵸS&]64$8*-t5&˩XQΎ=|u;hrnqq3D)h\o7_#B8~G1=.{+{Flk#Ѹ8Wnإ!Ů^8s#)ana\m[XD>2j c sxwyuuKorz!f0R˸9Dqk8N1'wJqoljIgS1qg^F#wq-S/c0¨7^\qaM?Gzq={F2x3> ‰,)}~bH9򌊥dUN '7%G^Qg;D23߻:"ңȚrR"&+kIQALhZ9q8rr֋7Z~*NƼGlQb~jN_Ia4ZyP쯝yez9bz|Fasul=wr42xw "xR^&%n "Qrf=G7rOm卵xt]y>9q ԈE3Xw9DIP:HN^GqdPĈgTzK|A/MA:6ey&;#>ܸS"WK*'~W ~ťnKM6. ;W֩ &T nE)⺉:0M#kʑU=#nbEL;EůT+Faab};']r*c/rbf,cy9e3.Sop +,f"zD1yĕR+o}a̐fOnY>ҽ[xū^_R+7Ѹqǫ:YjOuYPp}O?rxwS3]J5*I˥rfr 6q8<i'7"u8m}V]3Y%K|3on)) s5阈m%k=#ة74^f s4wF>[X%=VoKpۡŐ Ȏ7"xw?&e m. iⰯڌa KH8{3?kU3H:t 8/2A2W'2UG]4qjyGI_SVRZ_X\19qW~΍hg!bx>E#,%+_ueL*V&:5X/J г+u*l&O_q蕸͸2FL_-oXppHfqQ_XXE;IYl1^pw';%V'\.:NY c4}鑧Rz<e{c#U?bʽ.o%E/m1u_\M΀jrNsoԺ쭞XW JURi;7bsWu4l>5d$XŹbl0D]el=Y/w/>∑qQ̴=nʣD|Yzc?LPc g*U+,sS=E7 I*}-)ܕ;:+j5O&bՑ~WM< `7v5ԻTЛRjvJ!Q֖Fb.,0 sDdU)9.ƭ|~e\ 4 >壸! QLrns3_#O{ojK%ڳVhmD'K,^{]bۻ<;b.<)q\GL|SY Ʌ8u?1"JX+_d@J@nX߼C/&'r,ޙDa!~ûnS`7:m,ږuKQS\ۈ'I\|V@v1}QЮ &p)-λcAn+Z"r9AZy.Gőj_Dx>۸A;#[RMƆmY r#XaR0ZФʩ9~xJyx "nDȪ@7oA 5,hOcR}Ngή%I\qq}"Yˆzz>#Mqii\R. .Ļ>mWmZ7c8ʻcTD0?g>rN|36NJ_Du$(PO㋧I y<ȁw>jO vUr˝rv.IxO$b`9y,ؖ<8l' %A!]Y;BBhň3egutLP>#%ZhLxuB\N\Pƽr/B/`k\nfpҿQhVX=WB쒩Aȭo %Ƶ\^,Ĩ.*09 2KW$fR$.b>#9򮌅W[\k˕:tS'*DRL03ΟH+vgr;2h K/ӗ.xJ|=1J꽽r1F! qDMe]K ${kFa 6w'SW PEi+2!31"$J _WKURs8w\۠\/2ꇱ941'cNwѫ`#_ms0 .Ӵt|]q%q%*s>3F0A4u+J]:Bإ02`HW Af5  W@+#V:#e9betLJIw)s^o% R?ꢢrE2yT䈑ƚ@Hkz$&%(/5'futW- ~P;cm>uחryO1u"6_6b}IȷVܰbT~_xs*pZy>f1GJvbElk>1 (D]iP3Sz0q'ClG4oI3A$Gi^uP^?2]oYS,M+z%!!uⳎbWZfuǦ,,dOCvauFf:`/@W zȏ]$ b * 2']~] )}uOPr`@$CߟOHE#]KZ?U̻R5WVgDE6[3)~<QyB 9mx20$[d䭶xgfɋ5iHɧjzK: !M4]g?e*?S-xC#J=S˼/n'Vuq־NX;h2HQM 9`Ϩ ~29vC;>6cK,H,;P梪.2DZֻO3$X2yWǎZ.:Œ:@ D>Ak] Tu7ފkY6cS1 iXqjR>$t=Hde\>>!F\eGbS\JjTq?(O"\!gs ʣk["NXB$B:ڕA.i\)λAOTc G:u0 bn7SiNB,\Pɋ{1~vM"/)4v1zAGE@ۧK5r"wE˗JE!)s1RR_n"qfҷ ^_}v咰`bz{)ÞˆM̢]n5pq$@^ک.K3_  Y|c-V$̗WP`EV>U6K\ߊ_Eyq\goRbt^>Vbj}L! Wur$Kqdz҄}+i^"=jjŁ =gEˑOY$X6|JYwu0iN!󍳄zw&zコ~،GLL>}"Qn+gF18BZS^.d* Egι)/N0ơ_~꽛M@z$.4T&&%%iug7wl"lv0Ul4T-ЄPTX ,&6_^oB,D7J==z#vh-„+g1#7q"WN1;Dzp!n&a].9) Wu]`c]G!T0 hgް*OzT.G +JE0?^|ek=RgfCUPDD)kOB炎#.)a"P:+hqg #J28Р 2KQ"Ѱ GrdtdXN^\%PAIK0+m$Ԉ҇LO tEH[/+CTEjg(qo]XlHJ3fWX媉zkt/ʦ% 9R##y'^τ=Á8lScF$ƌ{##"B\ؖusC%/7j7*%ԫze6zD!Ϻ".sbV(D%FsRDD˫ 笳j2YfV?FS.)k#\>*;.Qn}UXb?{EhnXSuϗJ(7 XbS`+Amn1J 1Mx)|t6weFSi;p'@@Di#/6( dX(5E ^G? b-LV)R*r qU'zX))P?Jg9`aUM&!#JS^] ؚJ cXЍA%|׏RA#uޗJybN{Iʹ?\%/"+ɾ_m{GFo\yEf"t3E7bZ ,mF^;NK?勨!q"fu]MlØ~9p9}d1k.Qt--gdC 2~|OhJn) : W%P;iJ+jj;%9S1pBh>ƿ8`ގ+('VJJiYhv"ў'_p wR|AK|x$6c{R*=0UdF/ۀV>r9(q|9VVB(EYW,}Sʴ]bF[Ja- +vʔOL$rRz5(?P3`X2"hjڤjyb2zhY Rrft\U-ziQ_\CˣCL.9-_(hdpD 1Y#R秤m'tHAgkш vr!uE"B{A0bXtW*ˋ>^sҴz9EtQ%r_4(Gx^ b$J<;@U5- O{IGqǖt>Yl (O%o7'FGT AvdqfYG(TutMԲ&|5gv]` Q*L*/wXR*mVEfeO!` k)cUf wu8+xUM݌Cf?c*Hesl1祝bOÊOŁՃTM&_xHRb O^yRurPAO8wfq>Ud՗+p" Oۊ6HBVlk-ۏ(.XTˑ"I!;%4r@+XvR,ܼZLt(e,Jiґ uSwȕAK82%]GryoaZK*~,REU.- GgGIʎхjC9HYL8XB.U XXsD^Giһ4cZ|8lI@ 8IQnxK'W}$?v*m(LqCd} "ʆ*)K|4!v,lFrNaE6“RrTnXӺJmjO&Oo,2`7]P>ϒv.!(*Z}ŕn:̃@~64,Ǚ8+T>% yݏ<| \1{mxPK)r ]} o*?22Ey$2t##_,Uaheer't5X(`vd1`7-(cmT|g$,EЛĵpjIoT [0h]01mU;0)Ʈ}Q/q$X%!:x!2bRx]5v&>;΍㋎Ӛ2ά~C/&Њa,⁻=ZL?e%#9bS2 Yj̉n.q"< H$_^|wTLI<$Ǘ+T\V℔뜁?CٿN;^ `RΗ!T_uDM^68ö~tL?)ZNJV|LX8B/l̕@vJ5>ʫO rCʽ󨉵r-m\7YZΪ-V!Ӟ+93s^8M~JC>|),o`ZUlSpuS է('\hLg\)xцZJrN@\IمbbaHҧi&NYԍmQ f˦y!M|@JJb\WEx -Kr_&JWDCOl*ۓ\RlU-`[|,= N5~t#1e3U@% ѐOqսiQέdA& )/ -b *Q ձPQCvQAKU~P^|SU|7 X`Yȁ;h*HbH%=B99~0n)>EH'3fvS,]vRg<T1A[/̙;.GGS}=}a'J1 c1_ {Ig(o|0MsvըY):+20>/o=mNT^ @랜SF#?(5KM?ވOŭG5^oB%NTbU2@Ub\7z| r`W馡M+<()Tu_lJ!,nWڜL"F|?N\Ճ\K:(CVkiSڷ oF'[ӠSq1ls k8R1ގIS Q +%eeAьdU}R c6q32hx^KH#TTP27!VzPYy8!XJ9myJ LvaQH%˵n:6qᖠ$=Why36uaͤʷMo*jqWBz -aw {~ϒ!W aX\Cҽg:Fa"_4>s|9iMrxsLc,R`G1>/~)j`nCD_qݜclXBrm\Qr Bհ,3JZi-7D~5bP:S$%uG<-$.iocܮs^F\ #q11<7J>icYOk|"Jb |\ ]iD-mJ ݔrLZP-p'f^kަqfTzS9=~d˼Dٙ]j Cc".Z0C{XA z^SK1#M?uڅX>"X- |T`Vyԇɧ)ܪV"҃$jR "WI$yav~bNBZ As45_k`R%ΣRqJ֯A u#I~Uggq;s 􆕒9dOhv^7ds "*{M٫jOg"rC Bl?GCՍEr0qCbV=ȡ5W_IDz/U!EyepZ"|yh@U"vV'jMl${c@:ORu8|{Vgy-1R~W$jH,qaGhyikm/Vm^Z%| [B5|w%< P7"#MKݒβSHb qb^HdB ' ,4 iY̜u-8!Ke3.O4~-(s#I|m4jCӊk#eWӢ6N)Dz2d| AA.߮2ޕH#l#QdWcRbnç]ωMgW` DOY 2bL9'2ۗÁ҇\,M>^8Tק4RB=oU?JꗤGgk!v,6.9d;=v1)xe*BʆUo"1 sZ(&_值5+1pP1^!&)4ѥaMEb}~*(Ԅk ̋rj"j}A5]xJ1@ϫZ3Ro9C KXwhVBǭme:SY$]UN@RiH%EYj;NE9B' 88F>n4REm}Sݠ*=ri~٪gaYOMD*!jr\$v,e=%?yOV' j eS MK4%)9ϑOX}S Ĉ^-Gعdה[ڥY \`[4h77b˓R^\'5hPyr\R:H~DV ol뚴WB2)SUԸ)7Qg 9"ֻ˸Ej+w6܃}LMezl'~n'kgrmVEҕmd@-Jؑ/%&5O06S ²G\OP!@$qa"e'[ť'=ct,mWF2ҍ:ӤxzK6|˳ x#:?dNI)ᚢ\i&apXlԇ/}iDx84-qM AE @M\W_x#U>..尟GgDUr4!PXIzFqq(Z27u-_sdZv&^ C0P@׳\ 03N_Gl[jVh읆';7>]oZTnkĒ]wc$a9 WsH)،t^]me6I_;N#t'MxVKJAFp uܒ0re[exeb '%huNYR(K">0NJ"R41/ҫO_jeQHrD/K$f̏TtOe"Lѿ˦ŶEgpQI NkMwFY]zMs|$;\bg&Xlgv#QgҊ4AmVNX\Q=_jDG P$q;⣲`"W\է5tY% \{ @fj*@mWx&b-&TނA[\Z_J/hZɴJ$G0pAwR™UZ\x}  F76Eud1\[\ L΃HtZe,C0C{Q~@ϧcc-WyLI{%˓nJ`P,ύH:|$Az$ "-)1\tFE]o=jXΛ"NE&dd^ 5qdԖUN4Zȸ)զ2.Xlp d<axCM^dᙜ.A LnU^g! M4@I}'hk%Cǜ Bʬv )IIZeYtlxq<Unw{UI5*mdYHRG%h%dQ)[jp&OVѱS/4 m idpDDR3J9iPό՗K_W[iv_\l9sE-iE[u*=UXJg/HdM)}UxdC\H285@RS+I/֒7CuJ*b/c}͘R1K1 ,oC-Xx(Una(|ȣؗ\[vl·c^![}2Tf;<&h{zi|dȉ=N5 GmDZ@:| X _K?v?V.F~$_C ?a8zȊ2>'["?BGvfæ4۵<n鰑jWAL^=qJS0@>%c6WidF^4t-A҈mjjp.B\Q:ˉrp>#e7>r?gp*\f/q8ǘZgg#&"soRIAL?$WhU8ݜBk~T;aU+2ewYY|R1+oj4p#ٞJ0N%p5/,v>ݫ0lO{/GX+^XԎd֣<5y:==w*%c}|ZeDL2(c:I]_rEa]mU]bn-Uыu(+*]RY!&)Ɔ艦P `P>rIq-Qûy3HՃ?N 3:5i|xewmYMTHt羬9nv]uQcAlb8lىv#r4*ʤW R%Isv٨#q7lEX [n@IQx~RR6mLKxۺ.{C}I)-W?F9Pj Mro¨{n#7j*ʟ*kb"p :P&qOt/C!/ "~%hv_խF<|  o;P:,l0F6 PS8,ѥ8M(Oɯ„OS"scrggB>jݤC@B9b䆍Xa;&CE=_{"lZa4#LL'T|e_n*Pȋ:1IxDr&CT &%6K 'e1cDC0"|lg'f6LeᰣF|0~:{SC/#BuLR!NRqajz꫁ 4_X:ŏ 5RF#H7H 3-Y FvcK;-MI&2F&«A-Jԣ^yUW8_: x_K}A D姖0.TA.ZwP: /Nv%ӋTMD^Ҵgx9ltEi$ , Kpsu;r h8J|E8rxd>ٴjU5ǘT QQ./`uPlWQc2zif~,ɰo59!l2xPݾ4r|bDK Bf\W-;%[hM?_f}^o13sx!*T87~b)FҢ d\{u+@.Ȋz+QhpDͦ^ˈSYSoӥ*\ºsoQ׈_qG* lNə5ƐJN2KlZ]tb搬:T0L]FxaC`exO.Dg(S]H9w|jCYq1]EoT,YDCث˃(o5}DrPLmLq#_ce9qQa&F{⩌脐xRKkBwOh1GVr|kSȞ>Q=_ r %x d)Ȥ jn]pV_W8,/?T q#(eMb TUX@w$ԂIdd$]RfvM^Qlޡ5$gTuZi@%7Q\OJLsb.&B%7&v) ' {R/lXIi%X7fgt?õkٔ϶T d4ǝy>TEF!^)k#dPec// |z >|GGזQ ekqCSg|qdp8۲~m)H7؟/3/\ |#[HkpW&m,.FW'Q|Jz\&¼ dTz0(b &0>ӟ#1;)+Wͩ 7Qu,Ot+LVA1.k,[wi U}IQE8Q.8rP?b&z/ζXeM"@1=lz&%R0JB(H/m -21Y6H,ߺZ6K3)w)'LPi[U i51եyT46e.P)p5T3^9 a"O?//#sf_묄tm4:ʵnt3lvճH<='Y5;vPiZVծ(sTָ~xÞ\<ռsR:E[d%`p‹Ȩ7xLq0|5Xz]fqX>9gT\oך(\X|XX$5Ӥzu_Vws/ M6%ܮ3OWIn~G)%T"˹g1|AǝݤYmY(qfaGt5V/5q|+VWqZ\<6˺~5C%` ӠB9}}Oɵ_Sau+J)pnP˵]ᵔ yH/$N?r\T_=R*$h?C^r_Uya k<ߣR+Ic\ -cJ&NA( ?Y%̿Hr%P E2F;P81|c5: vN9:ҕ쳕c8I][6{|Hm,!jz$?ނջT3|YCh w+u3rUS^siO)?snCE2t2zfC&\Fέ[ p\sB2*mDzQa `~WSbƷ69#,͵b`M&)n"cr(5w']Jh,Eygk @L4+pMuë:VfR"g,(uK ¥;psI)'K9>@q3͙,Yp Hŝg4AY,>o-:ƒ: ۑLJC*P*(~&#IC\@נyl&*#C5 BOa餮/l,ט#T]h Hq_S__bxRpDR^Q,kr|tg*]  07 tP(w匃|Ydt}B>;!VLsɘV1.A;'W˪Jzdꪎ}78H&ux5q S7(N65pGDJd\B7ϯGݲ;sKU l ?"gp|CԟSt/?] B}=T\ЇD^*JgZXh|hs \/ZHW g"lGFbNiFҰ.'8pƏr3Pb$_᧯Sɸ6Ɖ@$# DvFͱ=)G~_F35y#a(B;7q)o %sl~g[ij`80gKu{ M*!ҙ>Ғk=c`m/0Ωioܜbn.կZZP[2=V.Νe3_*W#h(BOssC#PZ'gKeֈ"5)Gl=ˑr^r>PJH*׌bͭ7[JgJrUrv1S5mjOqּDh|Ƈqd();i$9M%#'<>`T]"Ns0MƤoR>S:ɑJgki3iXXV=> 1ǽhgDvrOCK]^K'YQ'q|+K?&2\I_ma5̠K|u*B x4UM`cbE&ל/ ?TtQu[ rՔ#b3 USf_?P h'r>NK]{pPYwjE6,S뱫&2ToCo&}IXrq|ڮ,}cgx{xn . ÿd.궴gYH\\B*"DrltM01IгUpJ1@[w&Yqf=PE88ٗ\Npb"*?sBTeQNZ+p%;Ld}e/U;RWWthvϗj/]ŵeWB"*KwdJgp{4%8773Ď'wr# D#Uga\"@SQC_ tGSorjZg^QwwuiN_'([UVA,m)>dHeu޼eŭ&Z\ſdh뫥γ.WmdHLF#+KC\6^@/3a&E9q~=_*nD[e.` P)6c}#d ^0Àș9N},sZFI!z%+<@dQퟌH9")7娈U,%YPo;(6 CF˰ѭ$ +~fu8eSDoll& :ܤTu:Q;N ]./rN7 詙k-|X e~0mpV5iƅ4>7?հhk~hB&W}Q'*H1 -bY59VȉD+@3@ٍqi$k+_eoZ}A r| $Tw3^vuC ֊ E9G6{ck6@f!wy]QN)GHaMD#ݝuZʠ*]!E@'֋`jX9DnhZi-ˎO E(VbXn氈 y,t%ρ4#2+PRkıkMUm'GJ<[@I*zdx% 7SBU%KTs:Ep /nΗ归3˧KgH{S^ %ID69uյ3MSe``Kd}4<:F<;9ji.{;j@UlV#OꛞJ _C<&I+%V*_#Yf | #;RZfq͟Q[pTY Z\:1ǸCUެ'_^G&ZHjŷ3)ܳb\qd ra,߷[C*)hoe?jmw7P 2"k<]UG$.ڤB>DIvdj6G8B=X\5PRm ]rBP6 T hH1v\XOq'esP98;fs;]7CLeL5 :RKG%!ݾ؂tI}u{!k1yMN5<1e߆2D2-m1P!τ sR{z1SU<%/sv -m&ô=)#r?qF_?U*QM=HbULf0$ſP+2|,rxRcnURTRih4_Laqz[ar>&=Rt$TIFp; 0bJ [a-'Cv%OzEz6uuM PR]ش z* \)gW^D1~IWt#۷vN~Z-HeGG䥜¤,=O`Tqe a=Pt'T%nk/F&ZXCxP[p}Z3M?rwbmfyM߬#%Lb6WA Jn`<_՞Id Dz~G[/E-dPJUUژ[FPgR vkouɩcyG$pxU`-*{XKUrx^ak>LdM[kƨ? J͂C+-tq;^KfkCŗ*{:Q/s1ǍC_|ɤTl-]4/#{6/O Vl=Q[cGr'Y*/)Vt?{5 xcŠ"B?|ѠT6׈IY|RQYbpc ǘ8aIpeUȦ]>`rMg~mK sF瑤X@?\v!3 =tP0ʠrJ+UuuW nLtM%7O%= S SR]h8(% 9-8[%tҮ٢rq_]]&/֥|TCf$?~qq7Wg&ްCKݖ`_[/¨cwS%>U}}|Śs(-RtJU.˨RI \XP#Jԣ$C6ҥb~F2"a}^uA;{I8["/bȃ@n,'AND69v7[ԇܾ9ڿ OJ3%NX&eVCnDfF9YX=mo_l˲wt_NI)TtrO{Бa22rfǸV@Ƈ[R*u4Q#,OUAi**˼R>(;Soh+)W2ˊY&֯#t{aSjNA 4 (r53|] =u|'ESW{re吝x/MQW^8rcZ_k%8׺rot`+q>KjtϞBË)n / El#[St0@/ VHHD^Ho=;2j"kH0瑺B :sYHd[{i:?L1C[-0SS|Rv0WyF"zjQ j-s_;ݚ!}]bR*U]+'s=f &kĜBu/qT,`{&RA7m&QS\]yv Է-Wx)1wsE!Dtz*w@Mѹ=dJ3jL\;bJgڭ6=cJ**lޟdM{-Ev#U/ yF')b><|AUlCK@-bfćK ǖWV\l<C-jK鮲ʭ׮XǓmt-o0(F7U5ΈedL[?gJʇԧ96F[MMm$u?YUTy!I8/T|Nr)Ϫ|7fHb;49JK"'Y, DUU7rP/ nsztǝ[*[qqIŋ7"D/k6RU;KU'a:6`غmAFsLn`A-ĽjE^Wk+dckܒ.TiydAi~C{Hlw[un},#ZnLaXh_MzRi¥V)7>cZ+䫧A.륞Hj|31!%q<DK@!׀ީ;"r+u)piiFk8{)Y:R#x7iu= Ka],mn~Vqc̶꙾KKFTCMkG#Ɉ[&ѪCi0q #, ^HыwT^|ѧ/elsvUGTϺ Bk`sG ]b:XafJV~ ^w)U R ۆo4GdQ]|SA)P_X4 PkڻGo/75;äqv \ack:&WCk`*7>&ۡ!-G6$E)Tn-)Un;]rxt9jJn=,k-'X.ѳ OtI/aO yTFz_vAAǢIXC-2^mټSuXn Dvjr`ƸqG@g*ܽX6.r1'aY'f,YZƓVCq%7XQ.{`c3|jSw__x<̗~t |'hg@7gId@nTt鑇D`_ЊȞ|'[QngUb-WMm4Q?;L\2  GwSR[iuHu PiprJEHzSڛg|{Tfp,iS<'Rv(´tHF2-GU!O*:.o֡N_RM]*&fY'ҰI<̔o~TPJ@O*?%alJ\,,(^:nC&a@i] [KEzo#YN,BjE긑6/-xۉĆ[v)X[ʐ 3A:bY|DκMEc;jߒS)XPMt~7DE HMg;c8FP&4m WpH_jS*2)دr_u bt%5Y!8w[6VE,BͤSRoɞ`PS6"#D:م -w#T ʼ+2ޘ1nsVݗ5 ?=9"V:WuTh4Ťh"x@&;g# H N)8NϫTE s2uC6lØۼ1y> Nكp|ђiIa63Q4O솟nL-/ї)+EM쪊 TRqs6e0˚{ު+%P(&?%8#k,QWq/ #q]o>+M\RCs ֺ_װ\~Woٹ!!^{^K/B" 5*/צU@xnE6K Qo#^?ʒmU;hl)%GGmr C k/wGڭبr_'8񹕛w[^}n:2+)2"6P`; oRFq>yu7XqxM4!ѲTU w~6^Cgj[&aj劣Ź!S&ˍa=,+U_|Y {9xe375(5ޮnԗK9 `"ah|Y]KJj1 nw_xͿ@cACǐC"LIS|$dC6D Y 1lW>nRrJ^Dj.MJyfv< tC /iQG$Wb("Īn2q^a߆r 32Z&ӷh)~GV>U⎠Lg*V͌]ښ&Si ә t`p`b3Xa>чr?k+3&(:00q2|{XطG|gXGٹ} kTEݙخGZe%"YOtEWemDz( ~o@9#1` 22b8' xʤ!#ȁr\x[ \.$l=uU1O::C5 5op}YQhwOdȊ_~z]Yx%2$<9'E6nFZڥ:ܓ_~ٚ/瑊*)ѼZs\%U4|LU @牼` 3 M= 9JNQzv6n j >//w_4<Õ󗜤*/Ue۰|4Wwh[ʢ <(G*Ӯ8KJ h9ݾ뵍ً8ls nѶ>چZ"AjOYil7m=HcQ5-(z}ɒGR&Z52x gktbBh@u+Am*/h;\hx<_ \zҘ"y5AJÑ6E=IXg(Nm5H([n%#}S0JӪEolT7ZEOT aq2:?fjY"kW_Y*gn3L ԅc컿$k >1HrƓ$R_S)!2{WFac!+X9_Ytҷ3W;V܃Ewf1qAdǢU,?Ek"l$G::&6@ս0R Cq,;WbU6c[*,M>`/Qtx* O(n|eSGIn\;L1n2 *xtf@ bAuD|E,y\}n{Ti`~ 8a C]axSXf+W>ui̚V *tOǐIUqUu8mz9e<F#9PڏUM;IR_{γ-?/02g?\zۯ [&V)@(}}D>_\0Z:QwX*PutG_T5 jj'<}=Bѳ2T/"5< 'hw/l fF[g>.*M1s`m_ᤡlzkmCKlf< DY\<|Q _+ ]rP@-"/iWy`ƹ6m|SV78zLyET^/f0)U ר&s# 9)z>YU&g,;didzbuNiܲ<_̬V6#9sWz{rIvT =Jb)Qo;LxU3B.!_~_XB](-*>xi: Џe@էyqw4b6mr2x-1Ie1˒ _GuϼwJ9F`%"Zq[{R+Q#1F78ѽӂҵ\BJΒMޝ"]Az,xޞN,ҕ,zsc1ְ [L@=Z&uy3q)e 3fcE6e!ƭ:rHawy}VwZ%蒣7by]?|*?y!)c RK7}QǮ>r zbm{ڪ˗wIRhn_"?msÍD`c[@Ecف@#Y#q1OAo4lkM-[/u9_7?̸Wf AղjQl n?PGzvI|6(NQھlK SEk.]k,kk-P*vJLtW;W]-W c:C #Djoa89_B25/y8_(9>U ,ո3!^^bֈqDƒ(3ߑU+kEjBZbbL'9< EG|-;񺏏<79VIq#΃LV_.84f F?]ټcڠlMҫ4Jܪ1fS5)dEke d TKGPiN/<+Puc-HWb]P+| ,oZyeܐ!TT/T 9M_OZ:og}:SMm'.CEbĦ.B>?I؁מw6 =Z0IF[K&  UGzm`I_ƧD m|5 (˟mc%TQ} k2T@Ll-cV4D(v_iߦ,=g)DRlS'M;*WZb4xQr&m\CrԂHKrGT- DPK.6˥Og3/Oɯf9K MÎ&@/3+NOD5鿾ǔf;1ſ☸_oyA/iw:Td' oiVNkݶZfwVՠ%+&P{CGidŃYygIfD-&Z5%tSFt6D*{ȫկGby$9*v3./J{DMU!YuySR`+/W4/ίLQd H֛X>7{J1P6KڠGMf%4}bEI)X=I;r=Na"U,|e@! _iOj3MUEQ'jH~ɵxF>o^Vg(nա=uٓokb-!|4WJnVpF0lYsbM/ťY>]p9 Ѹ49]89N1ZSt=Jd {R79KS\+q:_/͗OU)J퉺< ׆wABW.[x0A,6Z{@}F~#ac3(g1"?1@Qk+c8 h,H Dk #=e! _Mt/D`◒JեW,/|9N9ԗ(eqtZ Ua"sQSia;,8.cb R>ѿkY(gGߩ;Wev{yfsR[#)v@@vgK̥\j./]տ[[m}]U\0D.u-$5b[վ]e#K_}w.r6@7G,->um\:: 2_{$,qP}rlM\_,l-E݈+7 hno4`VK/A˧~|PmZ? wЭF/pn}R7~||_@I[gڕ ^SN5lw#Y~4#"3-Kq,H[4$; $0Sei^?݄h??=3G=T4m}bҩ4Ucc4~/zM|N\=]aH".G$fSN+J5 MѮ-(5h9EqL⚕& n-BJBg*WE;?迬0 e(SUcK,7t|ST69OkL46Q _B_xR,Tcp9?C5b/}x*<_Dߓ¨:GnqMJ$_^ecW#_l:7%e_c0N'ܣ8 m94X,'B\>Ϗ۴F Uf?yf)5OBl7_j}?/fmya~ KHZKdqFs%G\XE, fŒNBl,~D#QSl-Q~z"U{[m3yZRϣ g);e=窸BcJY>*|Tj0V]Kq,WmG -iKF2%Ox)Rjz>9_Õ",cn"Ї\URMi+8lG_T[>mmAu&l˽$dHͮ%.1J OȺXK-Pd8hO,Uq6*7UֱcqP01w:\%僞 &>Dp[%.2T?kN l@!닧HM$DM4923f>J Upkv}iG&^5LȘ6Ve#66Vm:+M]or±,O>#: @Te9|U-ӾV̹96%KIS"5 ^cqGAU+Kl燐e֣%+2*̲W䜔װO>6@PS 1,En%}YW7G)KPA- !jʝ+#6$:ڔLP߿_GIR\VAal"4Σ ^:) SwIy6a"5סHtZnӌ龺J+"٭(lXfmuȄN/ {g' .up#*U'WЎ: ^K4&,p??Y^2f-.@Sw#Wޟ<z_MVD7l6]¼xf<~ݩhFˠ8DU4MTpgժsê${`PXL-XMEvY,^Sh: ޔƑ'j!~_L~rW#k)C}_'RKxRx)m|.eQk \4Ӻi+oTHq [ |~P5|"Z:{AYw1;%8aIа\רYvڄ`ҙ,JW4E @m5DȗO*uZB>(Ni,kK^G"W5ww1ֱ˖9]s%i<)!l*PH_sIP[varfi?j=q y_fx!^Lj&LF|݊ahzuivBh׊bB׸t4n0@%~Badk:1ԆTn5.n2e3ug[ :@i+H_gct\RAQ*MyR ',Tuf~:W`bqgԨƫs-&.QR\/'6ѝ8E#sqj傊EYM}Zb?]K lKW2dkTPSO),;Ob|:_}f,kji/tWՏMy5}-Q#Ӊ)es>QKI)tKöYRٸ+D6IWHGç Aa:Ub.7˨,;u0^S/ *^kkG>14-YϡC᫊A/D~Z ՞!R ~b4&˴,$RZCZ"vj/ڟNltXT^]<$HBp]X3EZICJ-hUjVNrܸ!+tȕlV|9Z,N6ez֙VL@#8s/4} w0>D\eGRBAcgRp7fRZ5}?xP휯{iLIrV_!VZulN* {5+.m3_OO".mW ;rO.lsz.m!!FXni L_=M6ߨ^cpcN?R^ZO;;ٚwH(=bs衘v_ggI@(|%q_{f4} s!lo7 -BuZѥצMNuiW(Wz%VE=k5}15}=$ |'5rB(7Aw{>Kp}0aܸM!AJ75WzS'kEpK "/T{Iet-e[j=iEdxQ^A"kڈΖlE呥mTo 7BOmM?)F<؃Q (MvDBZ3'MEr t'QeZ5YtE_B?Dy!@c.Y\O,TeBmmr\gPyJ\YJs ڂ?o$A ~n(Ʒ?e "8I)0_U]UHOD;QCiIv(9v>R>l-,l(pD#zxn20fp|%ۃ[ ROsTNK=L~[%oUid!0,SՙHq6@Ԁ\_Ort)8U Ҷ5b)rğM>U0HW9쌧؈6b5$&wl6GRPf<cYxr}&bB}S~%v#z@1Ә+*D ܡYقIfխpk5\0I!'傰}Iz#oq_8Lȇ U&$ܾG }苲v/$1!>˷ɮU{,+,4aݼ_پ?(eI 7 :Qm;v~Gn-ٜk,3g/ Қ!7_IDc# /XJE9VuP Z6|w*vE!PZ4;\ݟ~H~$6^7:?)6|JF-_Jba5$*qQXPN[߸/Qt-qXDW̟ r{\8["̽أ՗\aMD,\\QJuAa&Ո*x'HgM7pA{,9hE ! [E-ؠ =EMxCxVȬ>IeqץmA};ekʛ.LצUK,\f˗ncc)~"m_$[g P=W $'Γ$|&]S‘[M. Ґ̾XͦUʪ(n 9 T1sRxp=(b˫cZاݑz#،1ȅxz{*OIL˶ B`+Hѳ 2t&/5\R.Hva[ *_uQl*Q5K`_W).C=y1?$;Ov%M$[I#Gn.w>o"5(%4.RYȄjQk8`^xwk)ˢP3 yJ-4cE5&Ak_/X,>n%ޭp.)[bÍGj E|n== mw_R LD>+ W[|O >:#knΤ'W%I׵Wnf4)TU$xTnͣ\W׋!R6\Y쳿l<b5;WRFlq5 ydr M"Kձ9/Z Ш8*)J}}R5Vr57~zqSӓ:icL854K`]|\?DMj晥{oGZy϶͇t]I^7Kq&?>%<ⴠcQ {ZTmk,/ԭ='EدE6C.6l"Ϛ|J;Xv(mow±3Q Gc@hTU!)@OpAWm~mU|]ze⼘1E;ra 4_g>J12mC-[l O]Jm1tI zvJ;_Mxrf/}DlS潫y%5qc{PXPW!_:%XK;H$S$wF#)YȼXdžoӔAIV1\JÂZV# jAA-e&x r DV~.Ԛ>eDu q nWHsEdr3hw$=3/Ո$_S_[9hVKd a~7Y4|ܲ M ԒAijEO{ #$?9iy5Ax;_ b3UydݩW?m Y~9^ZjL]raـH:A͎-JP-qLd; ab՘&dn.۫)4RҘ0_ '%]Ur£me%jҶ(.]w?OMmzՓ%vFr\"#je/^F}٦ſPZ[*pwĨR%ru۝-yʵpvLl?tk΋fM-+H*7_꽙)L8$Nȍ%Uꃑoyk?uPk1r ;?%!͡,hkU‹Ӛ;(" *ףCsTv]#poko%d+GgHT3{#3է9hk&`<חU5Ɖwx))ϝ2~ ~$/Kv#H}n6W;47xMGUKaͅMu-׉}'B{g_l}3*O4Tj= "03(~ƔP#WRE% ]ƿ3M};$f$&&M5ECF~OUk6]_+fA-fJE֙n# GS7Bbq_7l! 2@rs#)>GZp>8wg)]Wګ$ss;L=Rf_·GzDBn% K t:J^BXYI_ wGgroΓ؃ #l+XbpIMK/Xg +=R[K(N +%M4#*_10K9]a7<*_/ӣ=mWX6LnGMuHP/I3 =78]{$d./y ¸d2+&8/G۝5ޗ@7jKMH4Ua䗋 G)<r&Exx-=7!T8k+˃K8L*dkPe߿f>|"%n t/Guapn7rR㳅TU-^\R3)0i֐\ã,Wƞpҳ6rumD^*;Lt1 QFIlauKMZ7s\ߘM)^&_|َ^U>n*\8#+4 ڄ i UDצ򢰖ss,j켾xZIEb enHW7ϔr[UZIfXfPK &? Aitx/UTfNUxPK&?4(2 7itx/output.itxUTfNUxPK&