Compare commits

...
Author SHA1 Message Date
Patrick Hodoul 94b7831136 Adsk Contrib - Fix some weaknesses in the search path validation (#1535)
* Adsk Contrib - Fix some weaknesses in the search path validation

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Fix the Windows path in the unit test validations

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Fix the Windows path in the unit test validations, part II

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>
2021-12-06 14:04:55 -05:00
177a927ff5 Fix add_test calls and change temporary file creation. (#1522) (#1534)
* * Fix add_test in cmake files. This notation allows it to understand that the command portion is a target and to translate it to the proper executable.
* Remove starting backslash if present from temporary filename. A starting backslash mean that it is safe to create it in the current working directory.
* Implement a public TempFile class.
* Change relevant tests to use TempFile class.

Signed-off-by: Patrick Northon <northon_patrick3@yahoo.ca>

* * Revert back changes for TempFile class.
* Add comment on temporary file functions fix.

Signed-off-by: Patrick Northon <northon_patrick3@yahoo.ca>

* Add FIXME comments.

Signed-off-by: Patrick Northon <northon_patrick3@yahoo.ca>

* Add -C flag to ctest commands.

Signed-off-by: Patrick Northon <northon_patrick3@yahoo.ca>

* Add `-C Release` to ctest commands in `analysis_workflow.yml`.

Signed-off-by: Patrick Northon <northon_patrick3@yahoo.ca>

Co-authored-by: Patrick Hodoul <patrick.hodoul@autodesk.com>
Co-authored-by: Rémi Achard <remiachard@gmail.com>
Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

Co-authored-by: patlefort <northon_patrick3@yahoo.ca>
Co-authored-by: Rémi Achard <remiachard@gmail.com>
2021-11-05 09:22:47 -04:00
Patrick Hodoul a64e4d5d48 Adsk Contrib - Fix the CDL write for CLF file format (#1526) (#1529)
Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>
2021-11-02 18:01:18 -04:00
Patrick HodoulandMei Chu 198c888ee9 ConfigTest - Virtual display python unit test (#1481) (#1528)
* -ConfigTest: Python unit test updated with additional virtual display tests.

Signed-off-by: Mei Chu <meimchu@gmail.com>

* -ConfigTest: Addressed feedbacks.

Signed-off-by: Mei Chu <meimchu@gmail.com>

* -ConfigTest: Addressing feedbacks on typos.
Signed-off-by: Mei Chu <meimchu@gmail.com>

Co-authored-by: Patrick Hodoul <patrick.hodoul@autodesk.com>
Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

Co-authored-by: Mei Chu <33743518+meimchu@users.noreply.github.com>
2021-11-02 09:30:04 -04:00
Patrick Hodoulanditsmattkc b252372b7c Fixes Unicode paths on Windows (#1363) (#1527)
* Fixes Unicode paths on Windows

Unlike most other platforms, Windows' Unicode is standardized around
UTF-16, an encoding not compatible with "char *" arrays common in
C/C++. As such, to support Unicode correctly when using Win32 APIs,
strings must be converted to and from UTF-16 and the Unicode
versions of the APIs must be used over the ANSI versions.

This commit introduces the following:

- Utility funcions for converting between UTF-8 and UTF-16LE on all
  platforms:
  - Platform::Utf8ToUtf16
  - Platform::Utf16ToUtf8

- Adds test for these conversion functions to ensure the conversion
  to and from UTF-8 and UTF-16LE is correct.

- Utility wrappers for "std::ifstream" that automatically convert
  to and from UTF-16 so that filenames requiring Unicode encoding
  function correctly:
  - Platform::CreateInputFileStream
  - Platform::OpenInputFileStream

- Moves the file default compute hash function to the Platform
  class (Platform::CreateFileContentHash) and switches to the
  Win32 UTF-16 variant on Windows.

- Adds the "UNICODE" macro before including "Windows.h" which
  ensures all functions called are the Unicode variants instead of
  the default ANSI variants.
  - Implicitly changes functions such as GetEnvironmentVariable and
    SetEnvironmentVariable to their Unicode variants.

- Changes the following environment variable related functions to
  their Win32 Unicode variants on Windows:
  - environ -> _wenviron
  - _putenv_s -> _wputenv_s

- Updates tests using SetEnvironmentVariable to use wide string
  literals since that function has been switched to the Unicode
  variant.

Signed-off-by: itsmattkc <itsmattkc@gmail.com>

* Moved UNICODE and _UNICODE definitions to CMake

Signed-off-by: itsmattkc <34096995+itsmattkc@users.noreply.github.com>

* handle empty strings and use const references

Signed-off-by: itsmattkc <34096995+itsmattkc@users.noreply.github.com>

* only use wenviron when unicode is enabled

Signed-off-by: itsmattkc <itsmattkc@gmail.com>

* add ANSI Win32 version of Getenv

Signed-off-by: itsmattkc <itsmattkc@gmail.com>

* Add CMake option for compiling with Win32 Unicode support

Signed-off-by: itsmattkc <itsmattkc@gmail.com>

* Throw exception if UTF functions are called on non-Windows platforms

Signed-off-by: itsmattkc <itsmattkc@gmail.com>

* Throw OCIO Exception

Signed-off-by: itsmattkc <itsmattkc@gmail.com>

* Don't run UTF-8/16 conversion test on non-Windows

Signed-off-by: itsmattkc <34096995+itsmattkc@users.noreply.github.com>

* Fix CMake error

Signed-off-by: itsmattkc <34096995+itsmattkc@users.noreply.github.com>

* minor CMake adjustment

Signed-off-by: itsmattkc <itsmattkc@gmail.com>

* Clarified CMake option for Win32 unicode

Signed-off-by: itsmattkc <34096995+itsmattkc@users.noreply.github.com>

* minor improvements

Signed-off-by: itsmattkc <34096995+itsmattkc@users.noreply.github.com>

* fix macro in cpu test cmake

Signed-off-by: itsmattkc <34096995+itsmattkc@users.noreply.github.com>

Co-authored-by: itsmattkc <34096995+itsmattkc@users.noreply.github.com>
2021-10-31 20:20:47 -04:00
Patrick Hodoul 17e52e38c6 Adsk Contrib - Improve the OSL unit test framework (#1514) (#1524)
* Adsk Contrib - Improve the OSL unit test framework

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Fix a Linux build break

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Fix a 'git rebase' break

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Some improvements

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Workaround to sucesfully link with OSL

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Found the right fix

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Add more tests for Grading ops

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Improve OSL library find

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Fix with OpenImageIO version requires C++14

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Another OSL cmake improvement

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>
2021-10-27 23:06:09 -04:00
Patrick HodoulandGuillaume Papin 7360206858 CMake: remove duplicate find_package(pybind11 ...) (#1521) (#1523)
This duplicate seems to come from the PR #1371.
This PR spanned April 15 - August 24 (2021).

Meanwhile, PR #1410 (June 13 - June 21),
changed the CMake logic around `find_package(pybind11 ...)`.

It looks like former PR mishandled the merge of the latter.

Signed-off-by: Guillaume Papin <guillaume.papin@epitech.eu>

Co-authored-by: Guillaume Papin <guillaume.papin@epitech.eu>
2021-10-26 18:50:59 -04:00
934b80829b Add Python GPU renderer implementation example (#1493) (#1518)
* Add Python GPU renderer implementation example

Signed-off-by: Michael Dolan <michdolan@gmail.com>

* Move to apps with README

Signed-off-by: Michael Dolan <michdolan@gmail.com>

Co-authored-by: Patrick Hodoul <patrick.hodoul@autodesk.com>
Co-authored-by: Rémi Achard <remiachard@gmail.com>

Co-authored-by: Michael Dolan <michdolan@gmail.com>
Co-authored-by: Rémi Achard <remiachard@gmail.com>
2021-10-21 13:45:04 -04:00
Patrick HodoulandRémi Achard 36845c3f32 Fix install paths regressions (#1502) (#1510)
* Fix install directory variable for python bindings

Signed-off-by: Rémi Achard <remiachard@gmail.com>

* Remove hardcoded lib prefix in RPATH handling

Signed-off-by: Rémi Achard <remiachard@gmail.com>

Co-authored-by: Patrick Hodoul <patrick.hodoul@autodesk.com>

Co-authored-by: Rémi Achard <remiachard@gmail.com>
2021-10-19 14:01:47 -04:00
Patrick HodoulandHenry Schreiner 2d318af010 chore: update to new cibuildwheel location (#1513) (#1517)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2021-10-18 11:18:47 -04:00
Patrick HodoulandBo Zhou 445c45b016 Write converted image with output colorspace (#1420) (#1500) (#1511)
* Write converted image with output colorspace (#1420)

Signed-off-by: Bo Zhou <Bo.Schwarzstein@gmail.com>

* Check if outputcolorspace is null and set it as oiio:ColorSpace (#1460)

Signed-off-by: Bo Zhou <Bo.Schwarzstein@gmail.com>

* Call getDisplayViewColorSpaceName to get output colorspace for view mode. #1420

Signed-off-by: Bo Zhou <Bo.Schwarzstein@gmail.com>

Co-authored-by: Patrick Hodoul <patrick.hodoul@autodesk.com>

Co-authored-by: Bo Zhou <bo.schwarzstein@gmail.com>
2021-10-07 08:33:18 -04:00
Rémi AchardandPatrick Hodoul d950ab4bf7 Remove Python wheel workflow running on every pull request (#1503) (#1512)
Signed-off-by: Rémi Achard <remiachard@gmail.com>

Co-authored-by: Patrick Hodoul <patrick.hodoul@autodesk.com>

Co-authored-by: Patrick Hodoul <patrick.hodoul@autodesk.com>
2021-10-06 16:06:55 -04:00
Patrick Hodoulandamyspark d331992d93 Add support for OpenGL ES as a shading language (#1497) (#1504)
* Add support for OpenGL ES as a shading language

This commit adds two new entries to `GpuLanguage`,
`GPU_LANGUAGE_GLSL_ES_1_0` and `GPU_LANGUAGE_GLSL_ES_3_0`.

The only meaningful differences w.r.t. stock OpenGL are:

- the 1D texture optimization isn't applied to ES, as they are not
  supported at all;

- the texture<N>D() calls are replaced in GLSL ES 3 by a call to
  texture().

Fixes #1486

Signed-off-by: L. E. Segovia <13498015+amyspark@users.noreply.github.com>

* GLSL ES: remove ABI break

Signed-off-by: L. E. Segovia <13498015+amyspark@users.noreply.github.com>

* OpenGLBuilder: use switch to check GLSL version

Signed-off-by: L. E. Segovia <13498015+amyspark@users.noreply.github.com>
Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

Co-authored-by: amyspark <13498015+amyspark@users.noreply.github.com>
2021-10-06 08:25:47 -04:00
Patrick Hodoul 9c5a324184 Adsk Contrib - Fix the analysis workflow (#1492) (#1506)
Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>
2021-10-05 18:27:23 -04:00
Patrick Hodoul 2716337500 Adsk contrib - Various improvements (#1489) (#1505)
* Adsk Contrib - Small oiiohelper improvement

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Try to fix some memory issues report by valgrind

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Improve ctest support and add another check for OpenImageIO

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Fix Windows build failure

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Fix binary names on Windows

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Improve code around FixedFunction Ops

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Improve ctest support

Signed-off-by: hodoulp <Patrick.Hodoul@autodesk.com>

* Fix cmake

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>
2021-10-05 13:49:45 -04:00
Patrick Hodoulandamyspark 30ac2904e3 Add support for MinGW (#1485) (#1501)
In these cases the build system doesn't add a suffix to yaml-cpp.

Signed-off-by: amyspark <13498015+amyspark@users.noreply.github.com>

Co-authored-by: Patrick Hodoul <patrick.hodoul@autodesk.com>

Co-authored-by: amyspark <13498015+amyspark@users.noreply.github.com>
2021-10-04 14:27:48 -04:00
Patrick Hodoulandamyspark ce3042cd10 FindExpat: allow usage of expat 2.2.9 (#1483) (#1499)
- alias expat::expat to expat::libexpat if the former is missing
- patch INTERFACE_INCLUDE_DIRECTORIES if the property is missing

Fixes #1482.

Signed-off-by: amyspark <13498015+amyspark@users.noreply.github.com>

Co-authored-by: Patrick Hodoul <patrick.hodoul@autodesk.com>

Co-authored-by: amyspark <13498015+amyspark@users.noreply.github.com>
2021-10-04 09:30:41 -04:00
Patrick Hodoul 15ffc9a414 Adsk Contrib - Remove the useless cmake target on oiiotool (#1477) (#1494)
* Adsk Contrib - REmove the useless cmake target on oiiotool

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Improve the OIIO Util library support

Signed-off-by: hodoulp <Patrick.Hodoul@autodesk.com>
2021-09-25 09:47:09 -04:00
Patrick HodoulandRémi Achard 7ec43b7d93 Remove OpenColorIOHeaders target and hardcoded install paths (#1471) (#1490)
* Remove OpenColorIOHeaders target

Signed-off-by: Rémi Achard <remiachard@gmail.com>

* Avoid hardcoding install paths

Signed-off-by: Rémi Achard <remiachard@gmail.com>

* Update remaining hardcoded install paths

Signed-off-by: Rémi Achard <remiachard@gmail.com>

* Replace LIB_SUFFIX by CMAKE_INSTALL_LIBDIR

Signed-off-by: Rémi Achard <remiachard@gmail.com>

Co-authored-by: Patrick Hodoul <patrick.hodoul@autodesk.com>

Co-authored-by: Rémi Achard <remiachard@gmail.com>
2021-09-23 14:06:28 -04:00
Patrick Hodoul 83d3412ff2 Adsk Contrib - Better manage Imath dependency (#1478) (#1488)
* Adsk Contrib - Better manage Imath dependency

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>

* Add the OpenImageIO_Util dependency to OSL unit test framework

Signed-off-by: hodoulp <Patrick.Hodoul@autodesk.com>

* Fix oiio typo

Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>
2021-09-21 16:17:14 -04:00
Patrick Hodoul 156d4ffda0 Adsk Contrib - Change RB-2.1 branch to the version '2.1.1dev' (#1479)
Signed-off-by: Patrick Hodoul <Patrick.Hodoul@autodesk.com>
2021-09-16 08:45:42 -04:00
106 changed files with 6386 additions and 1274 deletions
+4 -4
View File
@@ -122,7 +122,7 @@ jobs:
-- -j$(nproc)
working-directory: _build
- name: Test
run: ctest -V
run: ctest -V -C Release
working-directory: _build
# ---------------------------------------------------------------------------
@@ -130,7 +130,7 @@ jobs:
# ---------------------------------------------------------------------------
linux_sonarcloud:
name: 'Linux CentOS 7 VFX CY2020 SonarCloud <GCC 6.3.1>'
name: 'Linux CentOS 7 VFX CY2022 SonarCloud <GCC 9.3.1>'
# Don't run on OCIO forks
if: github.repository == 'AcademySoftwareFoundation/OpenColorIO'
# GH-hosted VM. The build runs in CentOS 7 'container' defined below.
@@ -160,7 +160,7 @@ jobs:
cmake ../. \
-DCMAKE_INSTALL_PREFIX=../_install \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=11 \
-DCMAKE_CXX_STANDARD=14 \
-DCMAKE_CXX_FLAGS="-g -O0 -fprofile-arcs -ftest-coverage" \
-DCMAKE_CXX_OUTPUT_EXTENSION_REPLACE=ON \
-DCMAKE_EXE_LINKER_FLAGS="-lgcov" \
@@ -174,7 +174,7 @@ jobs:
run: build-wrapper-linux-x86-64 --out-dir bw_output make clean all
working-directory: _build
- name: Test
run: ctest -V
run: ctest -V -C Release
working-directory: _build
- name: Generate code coverage report
run: share/ci/scripts/linux/run_gcov.sh
+15 -3
View File
@@ -47,6 +47,10 @@ jobs:
sse=${{ matrix.use-sse }},
cxx=${{ matrix.cxx-standard }},
docs=${{ matrix.build-docs }}>'
# Avoid duplicated checks when a pull_request is opened from a local branch.
if: |
github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository
# GH-hosted VM. The build runs in CentOS 7 'container' defined below.
runs-on: ubuntu-latest
container:
@@ -267,7 +271,7 @@ jobs:
-- -j$(nproc)
working-directory: _build
- name: Test
run: ctest -V
run: ctest -V -C ${{ matrix.build-type }}
working-directory: _build
- name: Test CMake Consumer
if: matrix.build-shared == 'ON'
@@ -293,6 +297,10 @@ jobs:
cxx=${{ matrix.cxx-standard }},
python=${{ matrix.python-version }},
docs=${{ matrix.build-docs }}>'
# Avoid duplicated checks when a pull_request is opened from a local branch.
if: |
github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository
runs-on: macos-10.15
strategy:
matrix:
@@ -399,7 +407,7 @@ jobs:
-- -j$(sysctl -n hw.ncpu)
working-directory: _build
- name: Test
run: ctest -V
run: ctest -V -C ${{ matrix.build-type }}
working-directory: _build
- name: Test CMake Consumer
if: matrix.build-shared == 'ON'
@@ -427,6 +435,10 @@ jobs:
cxx=${{ matrix.cxx-standard }},
python=${{ matrix.python-version }},
docs=${{ matrix.build-docs }}>'
# Avoid duplicated checks when a pull_request is opened from a local branch.
if: |
github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository
runs-on: windows-2019
strategy:
matrix:
@@ -537,7 +549,7 @@ jobs:
shell: bash
working-directory: _build
- name: Test
run: ctest -V
run: ctest -V -C ${{ matrix.build-type }}
shell: bash
working-directory: _build
- name: Test CMake Consumer
+63 -37
View File
@@ -6,15 +6,11 @@ name: Wheel
on:
push:
# Versioned branches and tags are ignored for OCIO <= 1.x.x
branches-ignore:
- RB-0.*
- RB-1.*
- gh-pages
tags-ignore:
- v0.*
- v1.*
# Workflow run on tags for v2 only.
tags:
- v2.*
pull_request:
# Workflow run on pull_request only when related files change.
branches-ignore:
- RB-0.*
- RB-1.*
@@ -22,6 +18,12 @@ on:
tags-ignore:
- v0.*
- v1.*
paths:
- .github/workflows/wheel_workflow.yml
- pyproject.toml
schedule:
# Nightly build
- cron: "0 0 * * *"
jobs:
# Linux jobs run in Docker containers (manylinux), so the latest OS version
@@ -29,18 +31,8 @@ jobs:
# environment versions to mitigate issues from OS updates, and will require
# maintenance as OS versions are retired.
#
# Notes:
#
# Documentation fails to build on manylinux2010, maybe too old
# doxygen ? First fail in PyColorSpaceSet for documentation
# referencing PyOpenColorIO (eg. __sub__). Consequence is we don't
# support python 2.7, alternatively build without docstrings, or
# fix the doxygen issue.
#
# When installing doc environment, Python package are not used as the wheel
# is built in it's own isolated environment, hence package are listed again
# in pyproject.toml.
#
# Due to documentation build failing on manylinux2010 (maybe too old doxygen
# version), we build on manylinux2014 image, this requires pip >= 19.3.
# ---------------------------------------------------------------------------
# Linux
@@ -67,6 +59,9 @@ jobs:
- build: CPython 3.9 32 bits
python: cp39-*
arch: i686
- build: CPython 3.10 32 bits
python: cp310-*
arch: i686
# -------------------------------------------------------------------
# CPython 64 bits
# -------------------------------------------------------------------
@@ -82,6 +77,27 @@ jobs:
- build: CPython 3.9 64 bits
python: cp39-*
arch: x86_64
- build: CPython 3.10 64 bits
python: cp310-*
arch: x86_64
# -------------------------------------------------------------------
# CPython ARM 64 bits
# -------------------------------------------------------------------
- build: CPython 3.6 ARM 64 bits
python: cp36-*
arch: aarch64
- build: CPython 3.7 ARM 64 bits
python: cp37-*
arch: aarch64
- build: CPython 3.8 ARM 64 bits
python: cp38-*
arch: aarch64
- build: CPython 3.9 ARM 64 bits
python: cp39-*
arch: aarch64
- build: CPython 3.10 ARM 64 bits
python: cp310-*
arch: aarch64
steps:
- uses: actions/checkout@v2
@@ -91,17 +107,16 @@ jobs:
with:
python-version: '3.8'
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: all
- name: Build wheels
uses: joerick/cibuildwheel@v1.12.0
uses: pypa/cibuildwheel@v2.1.2
env:
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
CIBW_MANYLINUX_I686_IMAGE: manylinux2014
CIBW_BUILD_VERBOSITY: 1
CIBW_BUILD: ${{ matrix.python }}
CIBW_ARCHS: ${{ matrix.arch }}
CIBW_BEFORE_BUILD: share/ci/scripts/linux/yum/install_docs_env.sh
CIBW_TEST_REQUIRES: numpy
CIBW_TEST_COMMAND: python -m PyOpenColorIOTests.OpenColorIOTestSuite
- uses: actions/upload-artifact@v2
with:
@@ -117,6 +132,13 @@ jobs:
strategy:
matrix:
include:
# Python 3.10 can be enabled when numpy ship the binary wheel (which
# we use during tests). Building it within GH produces the following:
# RuntimeError: Polyfit sanity test emitted a warning, most likely due
# to using a buggy Accelerate backend. If you compiled yourself, see
# site.cfg.example for information. Otherwise report this to the vendor
# that provided NumPy.
# -------------------------------------------------------------------
# CPython 64 bits
# -------------------------------------------------------------------
@@ -132,6 +154,9 @@ jobs:
- build: CPython 3.9 64 bits
python: cp39-*
arch: x86_64
# - build: CPython 3.10 64 bits
# python: cp310-*
# arch: x86_64
# -------------------------------------------------------------------
# CPython ARM 64 bits
# -------------------------------------------------------------------
@@ -141,6 +166,9 @@ jobs:
- build: CPython 3.9 ARM 64 bits
python: cp39-*
arch: arm64
# - build: CPython 3.10 ARM 64 bits
# python: cp310-*
# arch: arm64
steps:
- uses: actions/checkout@v2
@@ -151,14 +179,10 @@ jobs:
python-version: '3.8'
- name: Build wheels
uses: joerick/cibuildwheel@v1.12.0
uses: pypa/cibuildwheel@v2.1.2
env:
CIBW_BUILD_VERBOSITY: 1
CIBW_BUILD: ${{ matrix.python }}
CIBW_ARCHS: ${{ matrix.arch }}
CIBW_BEFORE_BUILD: share/ci/scripts/macos/install_docs_env.sh
CIBW_TEST_REQUIRES: numpy
CIBW_TEST_COMMAND: python -m PyOpenColorIOTests.OpenColorIOTestSuite
- uses: actions/upload-artifact@v2
with:
@@ -189,6 +213,9 @@ jobs:
- build: CPython 3.9 32 bits
python: cp39-*
arch: x86
- build: CPython 3.10 32 bits
python: cp310-*
arch: x86
# -------------------------------------------------------------------
# CPython 64 bits
# -------------------------------------------------------------------
@@ -204,6 +231,9 @@ jobs:
- build: CPython 3.9 64 bits
python: cp39-*
arch: AMD64
- build: CPython 3.10 64 bits
python: cp310-*
arch: AMD64
steps:
- uses: actions/checkout@v2
@@ -214,14 +244,10 @@ jobs:
python-version: '3.8'
- name: Build wheels
uses: joerick/cibuildwheel@v1.12.0
uses: pypa/cibuildwheel@v2.1.2
env:
CIBW_BUILD_VERBOSITY: 1
CIBW_BUILD: ${{ matrix.python }}
CIBW_ARCHS: ${{ matrix.arch }}
CIBW_BEFORE_BUILD: bash -c share/ci/scripts/windows/install_docs_env.sh
CIBW_TEST_REQUIRES: numpy
CIBW_TEST_COMMAND: python -m PyOpenColorIOTests.OpenColorIOTestSuite
- uses: actions/upload-artifact@v2
with:
+18 -3
View File
@@ -28,17 +28,30 @@ endif()
# Project definition.
project(OpenColorIO
VERSION 2.1.0
VERSION 2.1.1
DESCRIPTION "OpenColorIO (OCIO) is a complete color management solution"
HOMEPAGE_URL https://github.com/AcademySoftwareFoundation/OpenColorIO
LANGUAGES CXX C)
# "dev", "beta1", rc1", etc or "" for an official release.
set(OpenColorIO_VERSION_RELEASE_TYPE "")
set(OpenColorIO_VERSION_RELEASE_TYPE "dev")
###############################################################################
# ctest
# To correctly generate the DartConfiguration.tcl, include the CTest CMake file.
# By doing so 'ctest -F memcheck' works.
include (CTest)
enable_testing()
###############################################################################
# Provides install directory variables as defined by the GNU Coding Standards.
include(GNUInstallDirs)
###############################################################################
# Forbid in-source build.
@@ -126,6 +139,8 @@ option(OCIO_BUILD_JAVA "Specify whether to build java bindings" OFF)
option(OCIO_WARNING_AS_ERROR "Set build error level for CI testing" OFF)
option(OCIO_USE_WINDOWS_UNICODE "On Windows only, compile with Unicode support" WIN32)
###############################################################################
# Optimization / internal linking preferences
@@ -259,7 +274,6 @@ if(OCIO_BUILD_DOCS)
endif()
add_subdirectory(tests)
add_subdirectory(src)
add_subdirectory(include)
add_subdirectory(ext)
@@ -315,3 +329,4 @@ install(
FILES "${OCIO_PROJECT_CONFIG}" "${OCIO_VERSION_CONFIG}"
DESTINATION "${OCIO_CONFIG_INSTALL_DIR}"
)
+2 -2
View File
@@ -61,8 +61,8 @@ else:
description = "@CMAKE_PROJECT_DESCRIPTION@"
version = "@CMAKE_PROJECT_VERSION@"
version_major = "@OpenColorIO_VERSION_MAJOR@"
version_minor = "@OpenColorIO_VERSION_MAJOR@"
version_patch = "@OpenColorIO_VERSION_MAJOR@"
version_minor = "@OpenColorIO_VERSION_MINOR@"
version_patch = "@OpenColorIO_VERSION_PATCH@"
ocio_namespace = "@OCIO_NAMESPACE@"
author = "Contributors to the {} Project".format(project)
-4
View File
@@ -1,4 +0,0 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenColorIO Project.
add_subdirectory(OpenColorIO)
-32
View File
@@ -1,32 +0,0 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenColorIO Project.
configure_file("OpenColorABI.h.in" "${CMAKE_CURRENT_BINARY_DIR}/OpenColorABI.h" @ONLY)
add_library(OpenColorIOHeaders INTERFACE)
set(BUILD_INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}/..
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/OpenColorIO
)
target_include_directories(OpenColorIOHeaders
INTERFACE
"$<BUILD_INTERFACE:${BUILD_INCLUDES}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
add_dependencies(OpenColorIOHeaders "${CMAKE_CURRENT_BINARY_DIR}/OpenColorABI.h")
# public interface
file(GLOB_RECURSE core_export_headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h")
list(APPEND core_export_headers ${CMAKE_CURRENT_BINARY_DIR}/OpenColorABI.h)
install(FILES ${core_export_headers}
DESTINATION include/OpenColorIO)
install(TARGETS OpenColorIOHeaders
EXPORT ${PROJECT_NAME}_EXPORTED_TARGETS
)
+4 -2
View File
@@ -409,7 +409,7 @@ enum BitDepth
BIT_DEPTH_UINT12,
BIT_DEPTH_UINT14,
BIT_DEPTH_UINT16,
BIT_DEPTH_UINT32,
BIT_DEPTH_UINT32, ///< Here for historical reason but that's not supported.
BIT_DEPTH_F16,
BIT_DEPTH_F32
};
@@ -446,7 +446,9 @@ enum GpuLanguage
GPU_LANGUAGE_GLSL_1_3, ///< OpenGL Shading Language
GPU_LANGUAGE_GLSL_4_0, ///< OpenGL Shading Language
GPU_LANGUAGE_HLSL_DX11, ///< DirectX Shading Language
LANGUAGE_OSL_1 ///< Open Shading Language
LANGUAGE_OSL_1, ///< Open Shading Language
GPU_LANGUAGE_GLSL_ES_1_0, ///< OpenGL ES Shading Language
GPU_LANGUAGE_GLSL_ES_3_0, ///< OpenGL ES Shading Language
};
enum EnvironmentMode
+19
View File
@@ -18,3 +18,22 @@ requires = [
"breathe"
]
build-backend = "setuptools.build_meta"
[tool.cibuildwheel]
build-verbosity = "1"
test-command = "python -m PyOpenColorIOTests.OpenColorIOTestSuite"
test-requires = ["numpy"]
manylinux-x86_64-image = "manylinux2014"
manylinux-i686-image = "manylinux2014"
manylinux-aarch64-image = "manylinux2014"
[tool.cibuildwheel.linux]
before-build = "share/ci/scripts/linux/yum/install_docs_env.sh"
[tool.cibuildwheel.macos]
before-build = "share/ci/scripts/macos/install_docs_env.sh"
[tool.cibuildwheel.windows]
before-build = "bash -c share/ci/scripts/windows/install_docs_env.sh"
-13
View File
@@ -74,19 +74,6 @@ if(OCIO_BUILD_OPENFX)
find_package(openfx 1.4 REQUIRED)
endif()
if(OCIO_BUILD_PYTHON)
# NOTE: Depending of the compiler version pybind11 2.4.3 does not compile
# with C++17 so, if you change the pybind11 version update the code to
# compile pybind11 and dependencies with C++17 or higher i.e. remove the
# cap of C++ version in FindPybind11.cmake and
# src/bindings/python/CMakeLists.txt.
# pybind11
# https://github.com/pybind/pybind11
find_package(pybind11 2.6.1 REQUIRED)
endif()
if (OCIO_PYTHON_VERSION AND NOT OCIO_BUILD_PYTHON)
message (WARNING "OCIO_PYTHON_VERSION=${OCIO_PYTHON_VERSION} but OCIO_BUILD_PYTHON is off.")
endif ()
+4
View File
@@ -203,6 +203,10 @@ if(NOT Imath_FOUND)
)
add_dependencies(Imath::Imath imath_install)
# Some Imath versions define a second target.
add_library(Imath::ImathConfig ALIAS Imath::Imath)
message(STATUS "Installing Imath: ${Imath_LIBRARY} (version \"${Imath_VERSION}\")")
endif()
endif()
+17 -9
View File
@@ -21,7 +21,6 @@
# OPENIMAGEIO_VERSION_MINOR Version minor number
# OPENIMAGEIO_VERSION_PATCH Version minor patch
# OPENIMAGEIO_VERSION_TWEAK Version minor tweak
# OIIOTOOL_BIN Path to oiiotool executable
#
# Imported targets:
# OpenImageIO::OpenImageIO The libOpenImageIO library.
@@ -59,12 +58,13 @@ find_library ( OPENIMAGEIO_LIBRARY
NAMES OpenImageIO${OIIO_LIBNAME_SUFFIX}
HINTS ${OPENIMAGEIO_ROOT_DIR}
PATH_SUFFIXES lib64 lib )
find_library ( OPENIMAGEIO_UTIL_LIBRARY
NAMES OpenImageIO_Util${OIIO_LIBNAME_SUFFIX}
HINTS ${OPENIMAGEIO_ROOT_DIR}
PATH_SUFFIXES lib64 lib )
find_path ( OPENIMAGEIO_INCLUDE_DIR
NAMES OpenImageIO/imageio.h
HINTS ${OPENIMAGEIO_ROOT_DIR} )
find_program ( OIIOTOOL_BIN
NAMES oiiotool
HINTS ${OPENIMAGEIO_ROOT_DIR} )
# Try to figure out version number
set (OIIO_VERSION_HEADER "${OPENIMAGEIO_INCLUDE_DIR}/OpenImageIO/oiioversion.h")
@@ -102,7 +102,6 @@ if (OpenImageIO_FOUND)
message ( STATUS "OpenImageIO includes = ${OPENIMAGEIO_INCLUDE_DIR}" )
message ( STATUS "OpenImageIO libraries = ${OPENIMAGEIO_LIBRARIES}" )
message ( STATUS "OpenImageIO library_dirs = ${OPENIMAGEIO_LIBRARY_DIRS}" )
message ( STATUS "OpenImageIO oiiotool = ${OIIOTOOL_BIN}" )
endif ()
if (NOT TARGET OpenImageIO::OpenImageIO)
@@ -114,10 +113,19 @@ if (OpenImageIO_FOUND)
IMPORTED_LOCATION "${OPENIMAGEIO_LIBRARIES}")
endif ()
if (NOT TARGET OpenImageIO::oiiotool AND EXISTS "${OIIOTOOL_BIN}")
add_executable(OpenImageIO::oiiotool IMPORTED)
set_target_properties(OpenImageIO::oiiotool PROPERTIES
IMPORTED_LOCATION "${OIIOTOOL_BIN}")
# Starting with OIIO v2.3, some utility classes are now only declared in OpenImageIO_Util
# (and not in both libraries like in older versions).
if (${OPENIMAGEIO_VERSION} VERSION_GREATER_EQUAL "2.3" AND NOT TARGET OpenImageIO::OpenImageIO_Util)
add_library(OpenImageIO::OpenImageIO_Util UNKNOWN IMPORTED)
set_target_properties(OpenImageIO::OpenImageIO_Util PROPERTIES
IMPORTED_LOCATION "${OPENIMAGEIO_UTIL_LIBRARY}")
target_link_libraries(OpenImageIO::OpenImageIO INTERFACE OpenImageIO::OpenImageIO_Util)
endif ()
# Starting with OIIO v2.3, OIIO needs to compile at least in C++14.
if (${OPENIMAGEIO_VERSION} VERSION_GREATER_EQUAL "2.3" AND ${CMAKE_CXX_STANDARD} LESS_EQUAL 11)
set(OpenImageIO_FOUND OFF)
message(WARNING "Need C++14 or higher to compile with OpenImageIO ${OPENIMAGEIO_VERSION}.")
endif ()
endif ()
@@ -7,22 +7,59 @@
# variable to tell CMake where to find it.
#
# TODO: OSL: Use "find_package(OSL 1.11 CONFIG)" directly instead of this file!
if(NOT TARGET osl::osl)
add_library(osl::osl UNKNOWN IMPORTED GLOBAL)
add_library(osl::osl INTERFACE IMPORTED GLOBAL)
set(OSL_FOUND OFF)
endif()
###############################################################################
### Try to find package ###
if(DEFINED OSL_ROOT)
if(NOT DEFINED OSL_ROOT)
find_package(OSL ${OpenShadingLanguage_FIND_VERSION} CONFIG)
set(OpenShadingLanguage_VERSION ${OSL_VERSION})
# TODO: No variable to have the share directory?
set(OSL_SHADERS_INCLUDE_DIR ${OSL_INCLUDE_DIR}/../share)
# Variable used by the OSL unit tests.
set(OSL_SHADERS_DIR ${OSL_SHADERS_INCLUDE_DIR}/OSL/shaders)
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (OpenShadingLanguage
FOUND_VAR OpenShadingLanguage_FOUND
REQUIRED_VARS OSL_INCLUDE_DIR OSL_LIB_DIR OpenShadingLanguage_VERSION
VERSION_VAR OpenShadingLanguage_VERSION
)
set(OSL_FOUND ${OpenShadingLanguage_FOUND})
else()
set(OSL_INCLUDE_DIR ${OSL_ROOT}/include)
if(EXISTS "${OSL_INCLUDE_DIR}/OSL/oslversion.h")
set(OSL_VERSION_HEADER "${OSL_INCLUDE_DIR}/OSL/oslversion.h")
if(EXISTS "${OSL_VERSION_HEADER}")
# Try to figure out version number
file (STRINGS "${OSL_VERSION_HEADER}" TMP REGEX "^#define OSL_LIBRARY_VERSION_MAJOR .*$")
string (REGEX MATCHALL "[0-9]+" OSL_VERSION_MAJOR ${TMP})
file (STRINGS "${OSL_VERSION_HEADER}" TMP REGEX "^#define OSL_LIBRARY_VERSION_MINOR .*$")
string (REGEX MATCHALL "[0-9]+" OSL_VERSION_MINOR ${TMP})
file (STRINGS "${OSL_VERSION_HEADER}" TMP REGEX "^#define OSL_LIBRARY_VERSION_PATCH .*$")
string (REGEX MATCHALL "[0-9]+" OSL_VERSION_PATCH ${TMP})
file (STRINGS "${OSL_VERSION_HEADER}" TMP REGEX "^#define OSL_LIBRARY_VERSION_TWEAK .*$")
if (TMP)
string (REGEX MATCHALL "[0-9]+" OSL_VERSION_TWEAK ${TMP})
else ()
set (OSL_VERSION_TWEAK 0)
endif ()
set (OpenShadingLanguage_VERSION "${OSL_VERSION_MAJOR}.${OSL_VERSION_MINOR}.${OSL_VERSION_PATCH}.${OSL_VERSION_TWEAK}")
# Find the oslcomp library.
find_library(oslcomp_LIBRARY
@@ -34,6 +71,11 @@ if(DEFINED OSL_ROOT)
lib
)
add_library(OSL::oslcomp SHARED IMPORTED)
set_target_properties(OSL::oslcomp PROPERTIES
IMPORTED_LOCATION ${oslcomp_LIBRARY}
)
# Find the oslexec library.
find_library(oslexec_LIBRARY
NAMES
@@ -44,8 +86,15 @@ if(DEFINED OSL_ROOT)
lib
)
add_library(OSL::oslexec SHARED IMPORTED)
set_target_properties(OSL::oslexec PROPERTIES
IMPORTED_LOCATION ${oslexec_LIBRARY}
)
set(OSL_SHADERS_INCLUDE_DIR ${OSL_ROOT}/share)
# Variable used by the OSL unit tests.
set(OSL_SHADERS_DIR ${OSL_ROOT}/share/OSL/shaders)
set(OSL_SHADERS_DIR ${OSL_SHADERS_INCLUDE_DIR}/OSL/shaders)
if(EXISTS "${OSL_SHADERS_DIR}")
@@ -56,6 +105,15 @@ if(DEFINED OSL_ROOT)
endif()
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (OpenShadingLanguage
FOUND_VAR OpenShadingLanguage_FOUND
REQUIRED_VARS OSL_INCLUDE_DIR oslcomp_LIBRARY oslexec_LIBRARY OpenShadingLanguage_VERSION
VERSION_VAR OpenShadingLanguage_VERSION
)
set(OSL_FOUND ${OpenShadingLanguage_FOUND})
endif()
###############################################################################
@@ -64,16 +122,21 @@ endif()
if(OSL_FOUND)
if (NOT OSL_FIND_QUIETLY)
message(STATUS "OpenShadingLanguage includes = ${OSL_INCLUDE_DIR}")
message(STATUS "OpenShadingLanguage oslcomp library = ${oslcomp_LIBRARY}")
message(STATUS "OpenShadingLanguage oslexec library = ${oslexec_LIBRARY}")
message(STATUS "OpenShadingLanguage includes = ${OSL_INCLUDE_DIR}")
message(STATUS "OpenShadingLanguage shaders = ${OSL_SHADERS_DIR}")
message(STATUS "OpenShadingLanguage library dir = ${OSL_LIB_DIR}")
endif ()
set_target_properties(osl::osl PROPERTIES
IMPORTED_LOCATION ${oslcomp_LIBRARY}
IMPORTED_LOCATION ${oslexec_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${OSL_INCLUDE_DIR}
)
list(APPEND LIB_INCLUDE_DIRS ${OSL_INCLUDE_DIR})
list(APPEND LIB_INCLUDE_DIRS ${OSL_SHADERS_INCLUDE_DIR})
target_include_directories(osl::osl INTERFACE "${LIB_INCLUDE_DIRS}")
target_link_libraries(osl::osl INTERFACE OSL::oslcomp OSL::oslexec)
if (${OpenShadingLanguage_VERSION} VERSION_GREATER_EQUAL "1.12" AND ${CMAKE_CXX_STANDARD} LESS_EQUAL 11)
set(OSL_FOUND OFF)
message(WARNING "Need C++14 or higher to compile OpenShadingLanguage. Skipping build the OSL unit tests")
endif()
mark_as_advanced(OSL_INCLUDE_DIR
oslcomp_LIBRARY oslcomp_FOUND
+33
View File
@@ -34,7 +34,40 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
endif()
if(expat_FOUND)
if (TARGET expat::libexpat)
message(STATUS "Expat ${expat_VERSION} detected, aliasing targets.")
add_library(expat::expat ALIAS expat::libexpat)
endif()
get_target_property(expat_INCLUDE_DIR expat::expat INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(expat_LIBRARY expat::expat LOCATION)
if (NOT expat_INCLUDE_DIR)
# Find include directory too, as its Config module doesn't include it
find_path(expat_INCLUDE_DIR
NAMES
expat.h
HINTS
${expat_ROOT}
${PC_expat_INCLUDE_DIRS}
PATH_SUFFIXES
include
expat/include
)
message(WARNING "Expat's include directory not specified in its Config module, patching it now to ${expat_INCLUDE_DIR}.")
if (TARGET expat::libexpat)
set_target_properties(expat::libexpat PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${expat_INCLUDE_DIR}
)
else()
set_target_properties(expat::expat PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${expat_INCLUDE_DIR}
)
endif()
endif()
set(_expat_REQUIRED_VARS ${expat_REQUIRED_VARS} expat_INCLUDE_DIR)
else()
list(APPEND _expat_REQUIRED_VARS expat_INCLUDE_DIR)
+4 -4
View File
@@ -60,19 +60,19 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
# Lib names to search for
set(_yaml-cpp_LIB_NAMES yaml-cpp)
if(WIN32 AND BUILD_TYPE_DEBUG)
if(WIN32 AND BUILD_TYPE_DEBUG AND NOT MINGW)
# Prefer Debug lib names (Windows only)
list(INSERT _yaml-cpp_LIB_NAMES 0 yaml-cppd)
endif()
if(yaml-cpp_STATIC_LIBRARY)
# Prefer static lib names
if(WIN32)
if(WIN32 AND NOT MINGW)
set(_yaml-cpp_LIB_SUFFIX "md")
endif()
set(_yaml-cpp_STATIC_LIB_NAMES
"libyaml-cpp${_yaml-cpp_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}")
if(WIN32 AND BUILD_TYPE_DEBUG)
if(WIN32 AND BUILD_TYPE_DEBUG AND NOT MINGW)
# Prefer static Debug lib names (Windows only)
list(INSERT _yaml-cpp_STATIC_LIB_NAMES 0
"libyaml-cpp${_yaml-cpp_LIB_SUFFIX}d${CMAKE_STATIC_LIBRARY_SUFFIX}")
@@ -144,7 +144,7 @@ if(NOT yaml-cpp_FOUND)
#set(yaml-cpp_INCLUDE_DIR "${_EXT_DIST_ROOT}/${CMAKE_INSTALL_INCLUDEDIR}")
# Set the expected library name
if(WIN32)
if(WIN32 AND NOT MINGW)
set(_yaml-cpp_LIB_SUFFIX "md")
if(BUILD_TYPE_DEBUG)
string(APPEND _yaml-cpp_LIB_SUFFIX "d")
+2 -2
View File
@@ -98,8 +98,8 @@ if (UNIX AND NOT CMAKE_SKIP_RPATH)
# (i.e. a binary loading a dynamic library) and then from the current directory
# (i.e. dynamic library loading another dynamic library).
if (APPLE)
set(CMAKE_INSTALL_RPATH "@loader_path/../lib;@loader_path")
set(CMAKE_INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path")
else()
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib;$ORIGIN")
set(CMAKE_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR};$ORIGIN")
endif()
endif()
+236 -214
View File
@@ -2,179 +2,177 @@
# Copyright Contributors to the OpenColorIO Project.
set(SOURCES
apphelpers/CategoryHelpers.cpp
apphelpers/ColorSpaceHelpers.cpp
apphelpers/DisplayViewHelpers.cpp
apphelpers/LegacyViewingPipeline.cpp
apphelpers/MixingHelpers.cpp
Baker.cpp
BitDepthUtils.cpp
Caching.cpp
ColorSpace.cpp
ColorSpaceSet.cpp
Config.cpp
Context.cpp
ContextVariableUtils.cpp
CPUProcessor.cpp
Display.cpp
DynamicProperty.cpp
Exception.cpp
fileformats/cdl/CDLParser.cpp
fileformats/cdl/CDLReaderHelper.cpp
fileformats/cdl/CDLWriter.cpp
fileformats/ctf/CTFReaderHelper.cpp
fileformats/ctf/CTFReaderUtils.cpp
fileformats/ctf/CTFTransform.cpp
fileformats/ctf/IndexMapping.cpp
fileformats/FileFormat3DL.cpp
fileformats/FileFormatCCC.cpp
fileformats/FileFormatCC.cpp
fileformats/FileFormatCDL.cpp
fileformats/FileFormatCSP.cpp
fileformats/FileFormatCTF.cpp
fileformats/FileFormatDiscreet1DL.cpp
fileformats/FileFormatHDL.cpp
fileformats/FileFormatICC.cpp
fileformats/FileFormatIridasCube.cpp
fileformats/FileFormatIridasItx.cpp
fileformats/FileFormatIridasLook.cpp
fileformats/FileFormatPandora.cpp
fileformats/FileFormatResolveCube.cpp
fileformats/FileFormatSpi1D.cpp
fileformats/FileFormatSpi3D.cpp
fileformats/FileFormatSpiMtx.cpp
fileformats/FileFormatTruelight.cpp
fileformats/FileFormatUtils.cpp
fileformats/FileFormatVF.cpp
fileformats/FormatMetadata.cpp
fileformats/xmlutils/XMLReaderHelper.cpp
fileformats/xmlutils/XMLReaderUtils.cpp
fileformats/xmlutils/XMLWriterUtils.cpp
FileRules.cpp
GPUProcessor.cpp
GpuShader.cpp
GpuShaderDesc.cpp
GpuShaderUtils.cpp
HashUtils.cpp
ImageDesc.cpp
ImagePacking.cpp
Logging.cpp
Look.cpp
LookParse.cpp
MathUtils.cpp
md5/md5.cpp
NamedTransform.cpp
OCIOYaml.cpp
Op.cpp
OpOptimizers.cpp
ops/allocation/AllocationOp.cpp
ops/cdl/CDLOpCPU.cpp
ops/cdl/CDLOpData.cpp
ops/cdl/CDLOpGPU.cpp
ops/cdl/CDLOp.cpp
ops/exponent/ExponentOp.cpp
ops/exposurecontrast/ExposureContrastOpCPU.cpp
ops/exposurecontrast/ExposureContrastOpData.cpp
ops/exposurecontrast/ExposureContrastOpGPU.cpp
ops/exposurecontrast/ExposureContrastOp.cpp
ops/fixedfunction/FixedFunctionOpCPU.cpp
ops/fixedfunction/FixedFunctionOpData.cpp
ops/fixedfunction/FixedFunctionOpGPU.cpp
ops/fixedfunction/FixedFunctionOp.cpp
ops/gamma/GammaOpCPU.cpp
ops/gamma/GammaOpData.cpp
ops/gamma/GammaOpGPU.cpp
ops/gamma/GammaOpUtils.cpp
ops/gamma/GammaOp.cpp
ops/gradingprimary/GradingPrimary.cpp
ops/gradingprimary/GradingPrimaryOpCPU.cpp
ops/gradingprimary/GradingPrimaryOpData.cpp
ops/gradingprimary/GradingPrimaryOpGPU.cpp
ops/gradingprimary/GradingPrimaryOp.cpp
ops/gradingrgbcurve/GradingBSplineCurve.cpp
ops/gradingrgbcurve/GradingRGBCurveOpCPU.cpp
ops/gradingrgbcurve/GradingRGBCurveOpData.cpp
ops/gradingrgbcurve/GradingRGBCurveOpGPU.cpp
ops/gradingrgbcurve/GradingRGBCurveOp.cpp
ops/gradingrgbcurve/GradingRGBCurve.cpp
ops/gradingtone/GradingTone.cpp
ops/gradingtone/GradingToneOpCPU.cpp
ops/gradingtone/GradingToneOpData.cpp
ops/gradingtone/GradingToneOpGPU.cpp
ops/gradingtone/GradingToneOp.cpp
ops/log/LogOpCPU.cpp
ops/log/LogOpData.cpp
ops/log/LogOpGPU.cpp
ops/log/LogOp.cpp
ops/log/LogUtils.cpp
ops/lut1d/Lut1DOp.cpp
ops/lut1d/Lut1DOpCPU.cpp
ops/lut1d/Lut1DOpData.cpp
ops/lut1d/Lut1DOpGPU.cpp
ops/lut3d/Lut3DOp.cpp
ops/lut3d/Lut3DOpCPU.cpp
ops/lut3d/Lut3DOpData.cpp
ops/lut3d/Lut3DOpGPU.cpp
ops/matrix/MatrixOpCPU.cpp
ops/matrix/MatrixOpData.cpp
ops/matrix/MatrixOpGPU.cpp
ops/matrix/MatrixOp.cpp
ops/noop/NoOps.cpp
ops/OpTools.cpp
ops/range/RangeOpCPU.cpp
ops/range/RangeOpData.cpp
ops/range/RangeOpGPU.cpp
ops/range/RangeOp.cpp
ops/reference/ReferenceOpData.cpp
ParseUtils.cpp
PathUtils.cpp
Platform.cpp
Processor.cpp
ScanlineHelper.cpp
Transform.cpp
transforms/AllocationTransform.cpp
transforms/builtins/ACES.cpp
transforms/builtins/BuiltinTransformRegistry.cpp
transforms/builtins/ColorMatrixHelpers.cpp
transforms/builtins/OpHelpers.cpp
transforms/builtins/ArriCameras.cpp
transforms/builtins/CanonCameras.cpp
transforms/builtins/Displays.cpp
transforms/builtins/PanasonicCameras.cpp
transforms/builtins/RedCameras.cpp
transforms/builtins/SonyCameras.cpp
transforms/BuiltinTransform.cpp
transforms/CDLTransform.cpp
transforms/ColorSpaceTransform.cpp
transforms/DisplayViewTransform.cpp
transforms/ExponentTransform.cpp
transforms/ExponentWithLinearTransform.cpp
transforms/ExposureContrastTransform.cpp
transforms/FileTransform.cpp
transforms/FixedFunctionTransform.cpp
transforms/GradingPrimaryTransform.cpp
transforms/GradingRGBCurveTransform.cpp
transforms/GradingToneTransform.cpp
transforms/GroupTransform.cpp
transforms/LogAffineTransform.cpp
transforms/LogCameraTransform.cpp
transforms/LogTransform.cpp
transforms/LookTransform.cpp
transforms/Lut1DTransform.cpp
transforms/Lut3DTransform.cpp
transforms/MatrixTransform.cpp
transforms/RangeTransform.cpp
ViewingRules.cpp
ViewTransform.cpp
SystemMonitor.cpp
apphelpers/CategoryHelpers.cpp
apphelpers/ColorSpaceHelpers.cpp
apphelpers/DisplayViewHelpers.cpp
apphelpers/LegacyViewingPipeline.cpp
apphelpers/MixingHelpers.cpp
Baker.cpp
BitDepthUtils.cpp
Caching.cpp
ColorSpace.cpp
ColorSpaceSet.cpp
Config.cpp
Context.cpp
ContextVariableUtils.cpp
CPUProcessor.cpp
Display.cpp
DynamicProperty.cpp
Exception.cpp
fileformats/cdl/CDLParser.cpp
fileformats/cdl/CDLReaderHelper.cpp
fileformats/cdl/CDLWriter.cpp
fileformats/ctf/CTFReaderHelper.cpp
fileformats/ctf/CTFReaderUtils.cpp
fileformats/ctf/CTFTransform.cpp
fileformats/ctf/IndexMapping.cpp
fileformats/FileFormat3DL.cpp
fileformats/FileFormatCCC.cpp
fileformats/FileFormatCC.cpp
fileformats/FileFormatCDL.cpp
fileformats/FileFormatCSP.cpp
fileformats/FileFormatCTF.cpp
fileformats/FileFormatDiscreet1DL.cpp
fileformats/FileFormatHDL.cpp
fileformats/FileFormatICC.cpp
fileformats/FileFormatIridasCube.cpp
fileformats/FileFormatIridasItx.cpp
fileformats/FileFormatIridasLook.cpp
fileformats/FileFormatPandora.cpp
fileformats/FileFormatResolveCube.cpp
fileformats/FileFormatSpi1D.cpp
fileformats/FileFormatSpi3D.cpp
fileformats/FileFormatSpiMtx.cpp
fileformats/FileFormatTruelight.cpp
fileformats/FileFormatUtils.cpp
fileformats/FileFormatVF.cpp
fileformats/FormatMetadata.cpp
fileformats/xmlutils/XMLReaderHelper.cpp
fileformats/xmlutils/XMLReaderUtils.cpp
fileformats/xmlutils/XMLWriterUtils.cpp
FileRules.cpp
GPUProcessor.cpp
GpuShader.cpp
GpuShaderDesc.cpp
GpuShaderUtils.cpp
HashUtils.cpp
ImageDesc.cpp
ImagePacking.cpp
Logging.cpp
Look.cpp
LookParse.cpp
MathUtils.cpp
md5/md5.cpp
NamedTransform.cpp
OCIOYaml.cpp
Op.cpp
OpOptimizers.cpp
ops/allocation/AllocationOp.cpp
ops/cdl/CDLOpCPU.cpp
ops/cdl/CDLOpData.cpp
ops/cdl/CDLOpGPU.cpp
ops/cdl/CDLOp.cpp
ops/exponent/ExponentOp.cpp
ops/exposurecontrast/ExposureContrastOpCPU.cpp
ops/exposurecontrast/ExposureContrastOpData.cpp
ops/exposurecontrast/ExposureContrastOpGPU.cpp
ops/exposurecontrast/ExposureContrastOp.cpp
ops/fixedfunction/FixedFunctionOpCPU.cpp
ops/fixedfunction/FixedFunctionOpData.cpp
ops/fixedfunction/FixedFunctionOpGPU.cpp
ops/fixedfunction/FixedFunctionOp.cpp
ops/gamma/GammaOpCPU.cpp
ops/gamma/GammaOpData.cpp
ops/gamma/GammaOpGPU.cpp
ops/gamma/GammaOpUtils.cpp
ops/gamma/GammaOp.cpp
ops/gradingprimary/GradingPrimary.cpp
ops/gradingprimary/GradingPrimaryOpCPU.cpp
ops/gradingprimary/GradingPrimaryOpData.cpp
ops/gradingprimary/GradingPrimaryOpGPU.cpp
ops/gradingprimary/GradingPrimaryOp.cpp
ops/gradingrgbcurve/GradingBSplineCurve.cpp
ops/gradingrgbcurve/GradingRGBCurveOpCPU.cpp
ops/gradingrgbcurve/GradingRGBCurveOpData.cpp
ops/gradingrgbcurve/GradingRGBCurveOpGPU.cpp
ops/gradingrgbcurve/GradingRGBCurveOp.cpp
ops/gradingrgbcurve/GradingRGBCurve.cpp
ops/gradingtone/GradingTone.cpp
ops/gradingtone/GradingToneOpCPU.cpp
ops/gradingtone/GradingToneOpData.cpp
ops/gradingtone/GradingToneOpGPU.cpp
ops/gradingtone/GradingToneOp.cpp
ops/log/LogOpCPU.cpp
ops/log/LogOpData.cpp
ops/log/LogOpGPU.cpp
ops/log/LogOp.cpp
ops/log/LogUtils.cpp
ops/lut1d/Lut1DOp.cpp
ops/lut1d/Lut1DOpCPU.cpp
ops/lut1d/Lut1DOpData.cpp
ops/lut1d/Lut1DOpGPU.cpp
ops/lut3d/Lut3DOp.cpp
ops/lut3d/Lut3DOpCPU.cpp
ops/lut3d/Lut3DOpData.cpp
ops/lut3d/Lut3DOpGPU.cpp
ops/matrix/MatrixOpCPU.cpp
ops/matrix/MatrixOpData.cpp
ops/matrix/MatrixOpGPU.cpp
ops/matrix/MatrixOp.cpp
ops/noop/NoOps.cpp
ops/OpTools.cpp
ops/range/RangeOpCPU.cpp
ops/range/RangeOpData.cpp
ops/range/RangeOpGPU.cpp
ops/range/RangeOp.cpp
ops/reference/ReferenceOpData.cpp
ParseUtils.cpp
PathUtils.cpp
Platform.cpp
Processor.cpp
ScanlineHelper.cpp
Transform.cpp
transforms/AllocationTransform.cpp
transforms/builtins/ACES.cpp
transforms/builtins/BuiltinTransformRegistry.cpp
transforms/builtins/ColorMatrixHelpers.cpp
transforms/builtins/OpHelpers.cpp
transforms/builtins/ArriCameras.cpp
transforms/builtins/CanonCameras.cpp
transforms/builtins/Displays.cpp
transforms/builtins/PanasonicCameras.cpp
transforms/builtins/RedCameras.cpp
transforms/builtins/SonyCameras.cpp
transforms/BuiltinTransform.cpp
transforms/CDLTransform.cpp
transforms/ColorSpaceTransform.cpp
transforms/DisplayViewTransform.cpp
transforms/ExponentTransform.cpp
transforms/ExponentWithLinearTransform.cpp
transforms/ExposureContrastTransform.cpp
transforms/FileTransform.cpp
transforms/FixedFunctionTransform.cpp
transforms/GradingPrimaryTransform.cpp
transforms/GradingRGBCurveTransform.cpp
transforms/GradingToneTransform.cpp
transforms/GroupTransform.cpp
transforms/LogAffineTransform.cpp
transforms/LogCameraTransform.cpp
transforms/LogTransform.cpp
transforms/LookTransform.cpp
transforms/Lut1DTransform.cpp
transforms/Lut3DTransform.cpp
transforms/MatrixTransform.cpp
transforms/RangeTransform.cpp
ViewingRules.cpp
ViewTransform.cpp
SystemMonitor.cpp
)
if(NOT WIN32)
# Install the pkg-config file.
include(GNUInstallDirs)
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix "\${prefix}")
set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
@@ -191,74 +189,87 @@ target_compile_features(OpenColorIO
)
if(BUILD_SHARED_LIBS AND WIN32)
# Impose a versioned name on Windows to avoid binary name clashes.
set(OCIO_LIBNAME_SUFFIX
${OCIO_LIBNAME_SUFFIX}_${OpenColorIO_VERSION_MAJOR}_${OpenColorIO_VERSION_MINOR}
)
set(CMAKE_SHARED_LIBRARY_SUFFIX ${OCIO_LIBNAME_SUFFIX}.dll)
# Only use the versioned name with the dynamic library.
set(CMAKE_SHARED_LIBRARY_SUFFIX _${OpenColorIO_VERSION_MAJOR}_${OpenColorIO_VERSION_MINOR}.dll)
# Create the version.rc file for the Windows DLL.
configure_file(res/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY)
set(SOURCES ${SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
endif()
set(HEADER_LOCATION "${CMAKE_SOURCE_DIR}/include/OpenColorIO")
file(GLOB_RECURSE INSTALL_HEADERS "${HEADER_LOCATION}/*.h")
# Some part of the build process expect to find the ABI header here,
# notably the documentation.
set(ABI_HEADER_LOCATION "${CMAKE_BINARY_DIR}/include/OpenColorIO")
list(APPEND INSTALL_HEADERS ${ABI_HEADER_LOCATION}/OpenColorABI.h)
configure_file("${HEADER_LOCATION}/OpenColorABI.h.in" "${ABI_HEADER_LOCATION}/OpenColorABI.h" @ONLY)
set(BUILD_INCLUDES
${HEADER_LOCATION}/..
${HEADER_LOCATION}
${CMAKE_CURRENT_SOURCE_DIR}
${ABI_HEADER_LOCATION}
)
target_include_directories(OpenColorIO
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PUBLIC
"$<BUILD_INTERFACE:${BUILD_INCLUDES}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
target_link_libraries(OpenColorIO
PUBLIC
OpenColorIOHeaders
PRIVATE
expat::expat
${OCIO_HALF_LIB}
pystring::pystring
sampleicc::sampleicc
utils::strings
yaml-cpp
PRIVATE
expat::expat
${OCIO_HALF_LIB}
pystring::pystring
sampleicc::sampleicc
utils::strings
yaml-cpp
)
if(APPLE)
target_link_libraries(OpenColorIO
PRIVATE
"-framework Carbon"
"-framework IOKit"
)
target_link_libraries(OpenColorIO
PRIVATE
"-framework Carbon"
"-framework IOKit"
)
endif()
if(NOT BUILD_SHARED_LIBS)
target_compile_definitions(OpenColorIO
PRIVATE
OpenColorIO_SKIP_IMPORTS
)
target_compile_definitions(OpenColorIO
PRIVATE
OpenColorIO_SKIP_IMPORTS
)
else()
# Only exports selected symbols.
target_compile_definitions(OpenColorIO
PRIVATE
OpenColorIO_EXPORTS
)
# Only exports selected symbols.
target_compile_definitions(OpenColorIO
PRIVATE
OpenColorIO_EXPORTS
)
endif()
if(BUILD_SHARED_LIBS OR (OCIO_BUILD_PYTHON AND UNIX))
# The Python bindings is a 'module' which is a dynamic library on Linux
# (i.e. '-fPIC' needed), but a static library on Windows.
# The Python bindings is a 'module' which is a dynamic library on Linux
# (i.e. '-fPIC' needed), but a static library on Windows.
# If supported for the target machine, emit position-independent code
# suitable for dynamic linking.
set_property(TARGET OpenColorIO PROPERTY POSITION_INDEPENDENT_CODE ON)
# If supported for the target machine, emit position-independent code
# suitable for dynamic linking.
set_property(TARGET OpenColorIO PROPERTY POSITION_INDEPENDENT_CODE ON)
endif()
if(OCIO_USE_SSE)
target_compile_definitions(OpenColorIO
PRIVATE
USE_SSE
)
target_compile_definitions(OpenColorIO
PRIVATE
USE_SSE
)
endif()
if(MSVC AND BUILD_TYPE_DEBUG AND BUILD_SHARED_LIBS)
set_target_properties(OpenColorIO PROPERTIES
PDB_NAME ${PROJECT_NAME}${OCIO_LIBNAME_SUFFIX}
PDB_NAME ${PROJECT_NAME}${OCIO_LIBNAME_SUFFIX}_${OpenColorIO_VERSION_MAJOR}_${OpenColorIO_VERSION_MINOR}
)
endif()
@@ -269,13 +280,23 @@ if(WIN32)
PRIVATE
XML_STATIC
)
if (OCIO_USE_WINDOWS_UNICODE)
# Add Unicode definitions to use Unicode functions
target_compile_definitions(OpenColorIO
PRIVATE
UNICODE
_UNICODE
)
endif()
endif()
set_target_properties(OpenColorIO PROPERTIES
OUTPUT_NAME ${PROJECT_NAME}
OUTPUT_NAME ${PROJECT_NAME}${OCIO_LIBNAME_SUFFIX}
COMPILE_FLAGS "${PLATFORM_COMPILE_FLAGS}"
VERSION ${OpenColorIO_VERSION}
SOVERSION ${SOVERSION}
PUBLIC_HEADER "${INSTALL_HEADERS}"
)
if (UNIX AND NOT APPLE)
@@ -287,13 +308,14 @@ if (UNIX AND NOT APPLE)
endif ()
if(MSVC AND BUILD_SHARED_LIBS)
# Install the pdb file if any.
install(FILES $<TARGET_PDB_FILE:${PROJECT_NAME}> DESTINATION bin OPTIONAL)
# Install the pdb file if any.
install(FILES $<TARGET_PDB_FILE:${PROJECT_NAME}> DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL)
endif()
install(TARGETS OpenColorIO
EXPORT ${PROJECT_NAME}_EXPORTED_TARGETS
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
ARCHIVE DESTINATION lib
EXPORT ${PROJECT_NAME}_EXPORTED_TARGETS
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/OpenColorIO
)
+4 -5
View File
@@ -1117,7 +1117,7 @@ ConstConfigRcPtr Config::CreateFromFile(const char * filename)
throw ExceptionMissingFile ("The config filepath is missing.");
}
std::ifstream istream(filename);
std::ifstream istream = Platform::CreateInputFileStream(filename, std::ios_base::in);
if (istream.fail())
{
std::ostringstream os;
@@ -1737,7 +1737,7 @@ void Config::validate() const
if (!path || !*path)
{
errMsg += " The search_path is empty.";
break;
continue;
}
const std::string resolvedSearchPath = getImpl()->m_context->resolveStringVar(path);
@@ -1755,17 +1755,16 @@ void Config::validate() const
}
oss << ".";
errMsg += oss.str();
break;
continue;
}
foundOne = true;
}
// After looping over all the search paths, none of them can be successfully resolved.
if (!foundOne)
{
// No valid paths were found.
getImpl()->m_validationtext = errMsg;
throw Exception(errMsg.c_str());
}
+25
View File
@@ -6,6 +6,7 @@
#include "ContextVariableUtils.h"
#include "utils/StringUtils.h"
#include "Platform.h"
#if defined(__APPLE__) && !defined(__IPHONE__)
@@ -19,6 +20,12 @@ extern char ** environ;
namespace
{
#if defined(_WIN32) && defined(UNICODE)
inline wchar_t ** GetEnviron()
{
return _wenviron;
}
#else
inline char ** GetEnviron()
{
#if __IPHONE__
@@ -30,6 +37,7 @@ inline char ** GetEnviron()
return environ;
#endif
}
#endif
} // anon.
@@ -71,11 +79,28 @@ void LoadEnvironment(EnvMap & map, bool update)
{
// First, add or update the context variables with existing env. variables.
#if defined(_WIN32) && defined(UNICODE)
if (GetEnviron() == NULL) {
// If the program starts with "main" instead of "wmain", then wenviron returns NULL until
// the first call to either wgetenv or wputenv. Calling wgetenv, even with an empty
// variable name, will populate wenviron correctly. We also use wgetenv_s (which requires
// a valid size pointer) to suppress safety warnings about wgetenv during the compile.
size_t sz;
_wgetenv_s(&sz, NULL, 0, L"");
}
for (wchar_t **env = GetEnviron(); *env != NULL; ++env)
{
// Split environment up into std::map[name] = value.
const std::string env_str = Platform::Utf16ToUtf8((wchar_t*)*env);
#else
for (char **env = GetEnviron(); *env != NULL; ++env)
{
// Split environment up into std::map[name] = value.
const std::string env_str = (char*)*env;
#endif
const int pos = static_cast<int>(env_str.find_first_of('='));
const std::string name = env_str.substr(0, pos);
+14 -9
View File
@@ -308,14 +308,15 @@ void GpuShaderCreator::finalize()
kw.newLine() << "";
kw.newLine() << "/* All the generic helper methods */";
kw.newLine() << "";
kw.newLine() << "vector4 __operator__mul__(vector4 v, matrix m)";
kw.newLine() << "vector4 __operator__mul__(matrix m, vector4 v)";
kw.newLine() << "{";
kw.indent();
kw.newLine() << "return vector4(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0], "\
"v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1], "\
"v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2], "\
"v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]);";
kw.newLine() << "return vector4(v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3], ";
kw.newLine() << " v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3], ";
kw.newLine() << " v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2] + v.w * m[2][3], ";
kw.newLine() << " v.x * m[3][0] + v.y * m[3][1] + v.z * m[3][2] + v.w * m[3][3]);";
kw.dedent();
kw.newLine() << "}";
@@ -344,28 +345,32 @@ void GpuShaderCreator::finalize()
kw.newLine() << "}";
kw.newLine() << "";
kw.newLine() << "vector4 __operator__add__(vector4 v, color4 c) {";
kw.newLine() << "vector4 __operator__add__(vector4 v, color4 c)";
kw.newLine() << "{";
kw.indent();
kw.newLine() << "return v + vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a);";
kw.dedent();
kw.newLine() << "}";
kw.newLine() << "";
kw.newLine() << "vector4 __operator__add__(color4 c, vector4 v) {";
kw.newLine() << "vector4 __operator__add__(color4 c, vector4 v)";
kw.newLine() << "{";
kw.indent();
kw.newLine() << "return vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a) + v;";
kw.dedent();
kw.newLine() << "}";
kw.newLine() << "";
kw.newLine() << "vector4 pow(color4 c, vector4 v) {";
kw.newLine() << "vector4 pow(color4 c, vector4 v)";
kw.newLine() << "{";
kw.indent();
kw.newLine() << "return pow(vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a), v);";
kw.dedent();
kw.newLine() << "}";
kw.newLine() << "";
kw.newLine() << "vector4 max(vector4 v, color4 c) {";
kw.newLine() << "vector4 max(vector4 v, color4 c)";
kw.newLine() << "{";
kw.indent();
kw.newLine() << "return max(v, vector4(c.rgb.r, c.rgb.g, c.rgb.b, c.a));";
kw.dedent();
+94 -22
View File
@@ -44,6 +44,8 @@ std::string getVecKeyword(GpuLanguage lang)
case GPU_LANGUAGE_GLSL_1_2:
case GPU_LANGUAGE_GLSL_1_3:
case GPU_LANGUAGE_GLSL_4_0:
case GPU_LANGUAGE_GLSL_ES_1_0:
case GPU_LANGUAGE_GLSL_ES_3_0:
{
kw << "vec" << N;
break;
@@ -85,6 +87,8 @@ void getTexDecl(GpuLanguage lang,
case GPU_LANGUAGE_GLSL_1_3:
case GPU_LANGUAGE_CG:
case GPU_LANGUAGE_GLSL_4_0:
case GPU_LANGUAGE_GLSL_ES_1_0:
case GPU_LANGUAGE_GLSL_ES_3_0:
{
textureDecl = "";
@@ -132,6 +136,15 @@ std::string getTexSample(GpuLanguage lang,
kw << "texture" << N << "D(" << samplerName << ", " << coords << ")";
break;
}
case GPU_LANGUAGE_GLSL_ES_1_0:
{
if (N == 1) {
throw Exception("1D textures are unsupported by OpenGL ES.");
}
kw << "texture" << N << "D(" << samplerName << ", " << coords << ")";
break;
}
case GPU_LANGUAGE_CG:
{
kw << "tex" << N << "D(" << samplerName << ", " << coords << ")";
@@ -147,6 +160,15 @@ std::string getTexSample(GpuLanguage lang,
kw << "texture(" << samplerName << ", " << coords << ")";
break;
}
case GPU_LANGUAGE_GLSL_ES_3_0:
{
if (N == 1) {
throw Exception("1D textures are unsupported by OpenGL ES.");
}
kw << "texture(" << samplerName << ", " << coords << ")";
break;
}
case LANGUAGE_OSL_1:
{
throw Exception("Unsupported by the Open Shading language (OSL) translation.");
@@ -285,12 +307,7 @@ void GpuShaderText::flushLine()
m_ossLine.clear();
}
std::string GpuShaderText::floatKeyword() const
{
return (m_lang == GPU_LANGUAGE_CG ? "half" : "float");
}
std::string GpuShaderText::floatKeywordConst() const
std::string GpuShaderText::constKeyword() const
{
std::string str;
@@ -299,6 +316,8 @@ std::string GpuShaderText::floatKeywordConst() const
case GPU_LANGUAGE_GLSL_1_2:
case GPU_LANGUAGE_GLSL_1_3:
case GPU_LANGUAGE_GLSL_4_0:
case GPU_LANGUAGE_GLSL_ES_1_0:
case GPU_LANGUAGE_GLSL_ES_3_0:
case GPU_LANGUAGE_HLSL_DX11:
{
str += "const";
@@ -310,6 +329,19 @@ std::string GpuShaderText::floatKeywordConst() const
break;
}
return str;
}
std::string GpuShaderText::floatKeyword() const
{
return (m_lang == GPU_LANGUAGE_CG ? "half" : "float");
}
std::string GpuShaderText::floatKeywordConst() const
{
std::string str;
str += constKeyword();
str += floatKeyword();
return str;
@@ -340,10 +372,20 @@ std::string GpuShaderText::colorDecl(const std::string & name) const
return (m_lang==LANGUAGE_OSL_1 ? "color" : float3Keyword()) + " " + name;
}
void GpuShaderText::declareVarConst(const std::string & name, float v)
{
newLine() << constKeyword() << declareVarStr(name, v) << ";";
}
void GpuShaderText::declareVar(const std::string & name, float v)
{
newLine() << declareVarStr(name, v) << ";";
}
// TODO: OSL: The method only solves the problem for constant float values. The code must also
// support the in-place declarations (like res = t + vec3(...) for example).
void GpuShaderText::declareVar(const std::string & name, float v)
std::string GpuShaderText::declareVarStr(const std::string & name, float v)
{
if (name.empty())
{
@@ -369,21 +411,37 @@ void GpuShaderText::declareVar(const std::string & name, float v)
oss.precision(std::numeric_limits<float>::max_digits10);
oss << newVal;
newLine() << floatDecl(name) << " = " << oss.str() << ";";
return;
return floatDecl(name) + " = " + oss.str();
}
newLine() << floatDecl(name) << " = " << getFloatString(v, m_lang) << ";";
return floatDecl(name) + " = " + getFloatString(v, m_lang);
}
void GpuShaderText::declareVarConst(const std::string & name, bool v)
{
newLine() << constKeyword() << declareVarStr(name, v) << ";";
}
void GpuShaderText::declareVar(const std::string & name, bool v)
{
newLine() << declareVarStr(name, v) << ";";
}
std::string GpuShaderText::declareVarStr(const std::string & name, bool v)
{
if (name.empty())
{
throw Exception("GPU variable name is empty.");
}
newLine() << "bool " << name << " = " << (v ? "true;" : "false;");
if (m_lang==LANGUAGE_OSL_1)
{
return intKeyword() + " " + name + " = " + (v ? "1" : "0");
}
else
{
return "bool " + name + " = " + (v ? "true" : "false");
}
}
void GpuShaderText::declareFloatArrayConst(const std::string & name, int size, const float * v)
@@ -404,6 +462,8 @@ void GpuShaderText::declareFloatArrayConst(const std::string & name, int size, c
case GPU_LANGUAGE_GLSL_1_2:
case GPU_LANGUAGE_GLSL_1_3:
case GPU_LANGUAGE_GLSL_4_0:
case GPU_LANGUAGE_GLSL_ES_1_0:
case GPU_LANGUAGE_GLSL_ES_3_0:
{
nl << floatKeywordConst() << " " << name << "[" << size << "] = ";
nl << floatKeyword() << "[" << size << "](";
@@ -455,6 +515,8 @@ void GpuShaderText::declareIntArrayConst(const std::string & name, int size, con
case GPU_LANGUAGE_GLSL_1_2:
case GPU_LANGUAGE_GLSL_1_3:
case GPU_LANGUAGE_GLSL_4_0:
case GPU_LANGUAGE_GLSL_ES_1_0:
case GPU_LANGUAGE_GLSL_ES_3_0:
{
nl << "const " << intKeyword() << " " << name << "[" << size << "] = "
<< intKeyword() << "[" << size << "](";
@@ -798,6 +860,8 @@ std::string matrix4Mul(const T * m4x4, const std::string & vecName, GpuLanguage
case GPU_LANGUAGE_GLSL_1_2:
case GPU_LANGUAGE_GLSL_1_3:
case GPU_LANGUAGE_GLSL_4_0:
case GPU_LANGUAGE_GLSL_ES_1_0:
case GPU_LANGUAGE_GLSL_ES_3_0:
{
// OpenGL shader program requests a transposed matrix
kw << "mat4("
@@ -818,12 +882,7 @@ std::string matrix4Mul(const T * m4x4, const std::string & vecName, GpuLanguage
}
case LANGUAGE_OSL_1:
{
kw << vecName << " * matrix("
<< m4x4[ 0] << ", " << m4x4[ 1] << ", " << m4x4[ 2] << ", " << m4x4[ 3] << ", "
<< m4x4[ 4] << ", " << m4x4[ 5] << ", " << m4x4[ 6] << ", " << m4x4[ 7] << ", "
<< m4x4[ 8] << ", " << m4x4[ 9] << ", " << m4x4[10] << ", " << m4x4[11] << ", "
<< m4x4[12] << ", " << m4x4[13] << ", " << m4x4[14] << ", " << m4x4[15]
<< ")";
kw << "matrix(" << getMatrixValues<T, 4>(m4x4, lang, false) << ") * " << vecName;
break;
}
@@ -858,6 +917,8 @@ std::string GpuShaderText::lerp(const std::string & x,
case GPU_LANGUAGE_GLSL_1_2:
case GPU_LANGUAGE_GLSL_1_3:
case GPU_LANGUAGE_GLSL_4_0:
case GPU_LANGUAGE_GLSL_ES_1_0:
case GPU_LANGUAGE_GLSL_ES_3_0:
{
kw << "mix(" << x << ", " << y << ", " << a << ")";
break;
@@ -886,6 +947,8 @@ std::string GpuShaderText::float3GreaterThan(const std::string & a,
case GPU_LANGUAGE_GLSL_1_2:
case GPU_LANGUAGE_GLSL_1_3:
case GPU_LANGUAGE_GLSL_4_0:
case GPU_LANGUAGE_GLSL_ES_1_0:
case GPU_LANGUAGE_GLSL_ES_3_0:
case GPU_LANGUAGE_CG:
{
kw << float3Keyword() << "(greaterThan( " << a << ", " << b << "))";
@@ -918,6 +981,8 @@ std::string GpuShaderText::float4GreaterThan(const std::string & a,
case GPU_LANGUAGE_GLSL_1_2:
case GPU_LANGUAGE_GLSL_1_3:
case GPU_LANGUAGE_GLSL_4_0:
case GPU_LANGUAGE_GLSL_ES_1_0:
case GPU_LANGUAGE_GLSL_ES_3_0:
case GPU_LANGUAGE_CG:
{
kw << float4Keyword() << "(greaterThan( " << a << ", " << b << "))";
@@ -928,7 +993,7 @@ std::string GpuShaderText::float4GreaterThan(const std::string & a,
kw << float4Keyword() << "("
<< "(" << a << "[0] > " << b << "[0]) ? 1.0 : 0.0, "
<< "(" << a << "[1] > " << b << "[1]) ? 1.0 : 0.0, "
<< "(" << a << "[2] > " << b << "[2]) ? 1.0 : 0.0) "
<< "(" << a << "[2] > " << b << "[2]) ? 1.0 : 0.0, "
<< "(" << a << "[3] > " << b << "[3]) ? 1.0 : 0.0)";
break;
}
@@ -938,7 +1003,7 @@ std::string GpuShaderText::float4GreaterThan(const std::string & a,
<< "(" << a << ".rgb.r > " << b << ".x) ? 1.0 : 0.0, "
<< "(" << a << ".rgb.g > " << b << ".y) ? 1.0 : 0.0, "
<< "(" << a << ".rgb.b > " << b << ".z) ? 1.0 : 0.0, "
<< "(" << a << ".a > " << b << ".w) ? 1.0 : 0.0)";
<< "(" << a << ".a > " << b << ".w) ? 1.0 : 0.0)";
break;
}
@@ -960,18 +1025,24 @@ std::string GpuShaderText::atan2(const std::string & y,
case GPU_LANGUAGE_GLSL_1_2:
case GPU_LANGUAGE_GLSL_1_3:
case GPU_LANGUAGE_GLSL_4_0:
case GPU_LANGUAGE_GLSL_ES_1_0:
case GPU_LANGUAGE_GLSL_ES_3_0:
{
// note: "atan" not "atan2"
kw << "atan(" << y << ", " << x << ")";
break;
}
case LANGUAGE_OSL_1:
case GPU_LANGUAGE_HLSL_DX11:
{
// note: operand order is swapped in HLSL
kw << "atan2(" << x << ", " << y << ")";
break;
}
case LANGUAGE_OSL_1:
{
kw << "atan2(" << y << ", " << x << ")";
break;
}
default:
{
@@ -990,6 +1061,8 @@ std::string GpuShaderText::sign(const std::string & v) const
case GPU_LANGUAGE_GLSL_1_2:
case GPU_LANGUAGE_GLSL_1_3:
case GPU_LANGUAGE_GLSL_4_0:
case GPU_LANGUAGE_GLSL_ES_1_0:
case GPU_LANGUAGE_GLSL_ES_3_0:
case GPU_LANGUAGE_HLSL_DX11:
{
kw << "sign(" << v << ");";
@@ -997,7 +1070,6 @@ std::string GpuShaderText::sign(const std::string & v) const
}
case LANGUAGE_OSL_1:
{
// The challenge is only to return a vector4 type instead of a color4.
kw << "sign(" << float4Const(v + ".rgb.r", v + ".rgb.g",
v + ".rgb.b", v + ".a") << ");";
break;
+9 -6
View File
@@ -67,6 +67,8 @@ public:
// Basic types.
//
std::string constKeyword() const;
std::string floatKeyword() const;
std::string floatKeywordConst() const;
std::string floatDecl(const std::string& name) const;
@@ -80,10 +82,14 @@ public:
//
// Declare a float variable.
std::string declareVarStr(const std::string & name, float v);
void declareVar(const std::string & name, float v);
void declareVarConst(const std::string & name, float v);
// Declare a bool variable.
std::string declareVarStr(const std::string & name, bool v);
void declareVar(const std::string & name, bool v);
void declareVarConst(const std::string & name, bool v);
// Declare a float array variable.
void declareFloatArrayConst(const std::string & name, int size, const float * v);
@@ -108,8 +114,7 @@ public:
std::string float3Const(float x, float y, float z) const;
std::string float3Const(double x, double y, double z) const;
// Get the string for creating constant vector with three elements
std::string float3Const(const std::string& x, const std::string& y,
const std::string& z) const;
std::string float3Const(const std::string& x, const std::string& y, const std::string& z) const;
// Get the string for creating constant vector with three elements
std::string float3Const(float v) const;
std::string float3Const(double v) const;
@@ -119,11 +124,9 @@ public:
std::string float3Decl(const std::string& name) const;
// Declare and initialize a vector with three elements
void declareFloat3(const std::string& name,
float x, float y, float z);
void declareFloat3(const std::string& name, float x, float y, float z);
void declareFloat3(const std::string& name, const Float3 & vec3);
void declareFloat3(const std::string& name,
double x, double y, double z);
void declareFloat3(const std::string& name, double x, double y, double z);
// Declare and initialize a vector with three elements
void declareFloat3(const std::string& name,
const std::string& x, const std::string& y, const std::string& z);
-9
View File
@@ -54,9 +54,6 @@ OpData & OpData::operator=(const OpData & rhs)
return *this;
}
OpData::~OpData()
{ }
OpDataRcPtr OpData::getIdentityReplacement() const
{
return std::make_shared<MatrixOpData>();
@@ -131,12 +128,6 @@ const char * GetTypeName(OpData::Type type)
throw Exception("Unexpected op type.");
}
Op::Op()
{ }
Op::~Op()
{ }
bool Op::canCombineWith(ConstOpRcPtr & /*op*/) const
{
return false;
+15 -7
View File
@@ -34,8 +34,12 @@ typedef std::vector<ConstOpCPURcPtr> ConstOpCPURcPtrVec;
class OpCPU
{
public:
OpCPU() {}
virtual ~OpCPU() {}
OpCPU() = default;
OpCPU(const OpCPU &) = delete;
OpCPU(OpCPU &&) = delete;
OpCPU & operator=(const OpCPU &) = delete;
OpCPU & operator=(OpCPU &&) = delete;
virtual ~OpCPU() = default;
// All the Ops assume float pointers (i.e. always float bit depths) except
// the 1D LUT CPU Op where the finalization depends on input and output bit depths.
@@ -114,8 +118,10 @@ public:
public:
OpData();
OpData(const OpData & rhs);
OpData(OpData && rhs) = delete;
OpData & operator=(const OpData & rhs);
virtual ~OpData();
OpData & operator=(OpData && rhs) = delete;
virtual ~OpData() = default;
const std::string & getID() const;
void setID(const std::string & id);
@@ -168,7 +174,11 @@ const char * GetTypeName(OpData::Type type);
class Op
{
public:
virtual ~Op();
Op(const Op & rhs) = delete;
Op(Op && rhs) = delete;
Op & operator=(const Op & rhs) = delete;
Op & operator=(Op && rhs) = delete;
virtual ~Op() = default;
virtual OpRcPtr clone() const = 0;
@@ -270,12 +280,10 @@ public:
ConstOpDataRcPtr data() const { return std::const_pointer_cast<const OpData>(m_data); }
protected:
Op();
Op() = default;
OpDataRcPtr & data() { return m_data; }
private:
Op(const Op &) = delete;
Op& operator= (const Op &) = delete;
// The OpData instance holds the parameters (LUT values, matrix coefs, etc.) being used.
OpDataRcPtr m_data;
+4
View File
@@ -261,6 +261,8 @@ const char * GpuLanguageToString(GpuLanguage language)
case GPU_LANGUAGE_GLSL_1_2: return "glsl_1.2";
case GPU_LANGUAGE_GLSL_1_3: return "glsl_1.3";
case GPU_LANGUAGE_GLSL_4_0: return "glsl_4.0";
case GPU_LANGUAGE_GLSL_ES_1_0: return "glsl_es_1.0";
case GPU_LANGUAGE_GLSL_ES_3_0: return "glsl_es_3.0";
case GPU_LANGUAGE_HLSL_DX11: return "hlsl_dx11";
case LANGUAGE_OSL_1: return "osl_1";
}
@@ -277,6 +279,8 @@ GpuLanguage GpuLanguageFromString(const char * s)
else if(str == "glsl_1.2") return GPU_LANGUAGE_GLSL_1_2;
else if(str == "glsl_1.3") return GPU_LANGUAGE_GLSL_1_3;
else if(str == "glsl_4.0") return GPU_LANGUAGE_GLSL_4_0;
else if(str == "glsl_es_1.0") return GPU_LANGUAGE_GLSL_ES_1_0;
else if(str == "glsl_es_3.0") return GPU_LANGUAGE_GLSL_ES_3_0;
else if(str == "hlsl_dx11") return GPU_LANGUAGE_HLSL_DX11;
else if(str == "osl_1") return LANGUAGE_OSL_1;
+3 -33
View File
@@ -4,12 +4,12 @@
#include <iostream>
#include <map>
#include <sys/stat.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Mutex.h"
#include "PathUtils.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
@@ -26,39 +26,9 @@ namespace OCIO_NAMESPACE
{
namespace
{
// Here is the explanation of the stat() method:
// https://pubs.opengroup.org/onlinepubs/009695299/basedefs/sys/stat.h.html
// "The st_ino and st_dev fields taken together uniquely identify the file within the system."
//
// However there are limitations to the stat() support on some Windows file systems:
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions?redirectedfrom=MSDN&view=vs-2019
// "The inode, and therefore st_ino, has no meaning in the FAT, HPFS, or NTFS file systems."
// That's the default hash method implementation to compute a hash key based on a file content.
std::string DefaultComputeHash(const std::string &filename)
{
struct stat fileInfo;
if (stat(filename.c_str(), &fileInfo) == 0)
{
// Treat the st_dev (i.e. device) + st_ino (i.e. inode) as a proxy for the contents.
std::ostringstream fasthash;
fasthash << fileInfo.st_dev << ":";
#ifdef _WIN32
// TODO: The hard-linked files are then not correctly supported on Windows platforms.
fasthash << std::hash<std::string>{}(filename);
#else
fasthash << fileInfo.st_ino;
#endif
return fasthash.str();
}
return "";
}
// The global variable holds the hash function to use.
// It could be changed using SetComputeHashFunction() to customize the implementation.
ComputeHashFunction g_hashFunction = DefaultComputeHash;
ComputeHashFunction g_hashFunction = Platform::CreateFileContentHash;
// We mutex both the main map and each item individually, so that
// the potentially slow stat calls dont block other lookups to already
@@ -86,7 +56,7 @@ void SetComputeHashFunction(ComputeHashFunction hashFunction)
void ResetComputeHashFunction()
{
g_hashFunction = DefaultComputeHash;
g_hashFunction = Platform::CreateFileContentHash;
}
std::string GetFastFileHash(const std::string & filename)
+138 -6
View File
@@ -1,8 +1,11 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
#include <codecvt>
#include <locale>
#include <random>
#include <sstream>
#include <sys/stat.h>
#include <vector>
#include <OpenColorIO/OpenColorIO.h>
@@ -49,12 +52,36 @@ bool Getenv(const char * name, std::string & value)
return false;
}
#ifdef _WIN32
if(uint32_t size = GetEnvironmentVariable(name, nullptr, 0))
#if defined(_WIN32)
// Define working strings, converting to UTF-16 if necessary
#ifdef UNICODE
std::wstring name_str = Utf8ToUtf16(name);
std::wstring value_str;
#else
std::string name_str = name;
std::string value_str;
#endif
if(uint32_t size = GetEnvironmentVariable(name_str.c_str(), nullptr, 0))
{
std::vector<char> buffer(size);
GetEnvironmentVariable(name, buffer.data(), size);
value = std::string(buffer.data());
value_str.resize(size);
GetEnvironmentVariable(name_str.c_str(), &value_str[0], size);
// GetEnvironmentVariable is designed for raw pointer strings and therefore requires that
// the destination buffer be long enough to place a null terminator at the end of it. Since
// we're using std::wstrings here, the null terminator is unnecessary (and causes false
// negatives in unit tests since the extra character makes it "non-equal" to normally
// defined std::wstrings). Therefore, we pop the last character off (the null terminator)
// to ensure that the string conforms to expectations.
value_str.pop_back();
// Return value, converting to UTF-8 if necessary
#ifdef UNICODE
value = Utf16ToUtf8(value_str);
#else
value = value_str;
#endif
return true;
}
else
@@ -81,7 +108,13 @@ void Setenv(const char * name, const std::string & value)
// exists. To avoid the ambiguity, use Unsetenv() when the env. variable removal if needed.
#ifdef _WIN32
#ifdef UNICODE
_wputenv_s(Utf8ToUtf16(name).c_str(), Utf8ToUtf16(value).c_str());
#else
_putenv_s(name, value.c_str());
#endif
#else
::setenv(name, value.c_str(), 1);
#endif
@@ -95,8 +128,14 @@ void Unsetenv(const char * name)
}
#ifdef _WIN32
#ifdef UNICODE
// Note that the Windows _putenv_s() removes the env. variable if the value is empty.
_wputenv_s(Utf8ToUtf16(name).c_str(), L"");
#else
_putenv_s(name, "");
#endif
#else
::unsetenv(name);
#endif
@@ -174,13 +213,21 @@ std::string CreateTempFilename(const std::string & filenameExt)
// Note: Because of security issue, tmpnam could not be used.
// Note 2: MinGW doesn't define L_tmpnam_s, we need to patch it in.
// https://www.mail-archive.com/mingw-w64-public@lists.sourceforge.net/msg17360.html
#if !defined(L_tmpnam_s)
#define L_tmpnam_s L_tmpnam
#endif
char tmpFilename[L_tmpnam_s];
if(tmpnam_s(tmpFilename))
{
throw Exception("Could not create a temporary file.");
}
filename = tmpFilename;
// Note that when a file name is pre-pended with a backslash and no path information, such as \fname21, this
// indicates that the name is valid for the current working directory.
filename = tmpFilename[0] == '\\' ? tmpFilename + 1 : tmpFilename;
#else
@@ -197,6 +244,91 @@ std::string CreateTempFilename(const std::string & filenameExt)
return filename;
}
std::ifstream CreateInputFileStream(const char * filename, std::ios_base::openmode mode)
{
#if defined(_WIN32) && defined(UNICODE)
return std::ifstream(Utf8ToUtf16(filename).c_str(), mode);
#else
return std::ifstream(filename, mode);
#endif
}
void OpenInputFileStream(std::ifstream & stream, const char * filename, std::ios_base::openmode mode)
{
#if defined(_WIN32) && defined(UNICODE)
stream.open(Utf8ToUtf16(filename).c_str(), mode);
#else
stream.open(filename, mode);
#endif
}
std::wstring Utf8ToUtf16(const std::string & str)
{
if (str.empty()) {
return std::wstring();
}
#ifdef _WIN32
int sz = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring wstr(sz, 0);
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstr[0], sz);
return wstr;
#else
throw Exception("Only supported by the Windows platform.");
#endif
}
std::string Utf16ToUtf8(const std::wstring & wstr)
{
if (wstr.empty()) {
return std::string();
}
#ifdef _WIN32
int sz = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string str(sz, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &str[0], sz, NULL, NULL);
return str;
#else
throw Exception("Only supported by the Windows platform.");
#endif
}
// Here is the explanation of the stat() method:
// https://pubs.opengroup.org/onlinepubs/009695299/basedefs/sys/stat.h.html
// "The st_ino and st_dev fields taken together uniquely identify the file within the system."
//
// However there are limitations to the stat() support on some Windows file systems:
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions?redirectedfrom=MSDN&view=vs-2019
// "The inode, and therefore st_ino, has no meaning in the FAT, HPFS, or NTFS file systems."
// That's the default hash method implementation to compute a hash key based on a file content.
std::string CreateFileContentHash(const std::string &filename)
{
#if defined(_WIN32) && defined(UNICODE)
struct _stat fileInfo;
if (_wstat(Platform::Utf8ToUtf16(filename).c_str(), &fileInfo) == 0)
#else
struct stat fileInfo;
if (stat(filename.c_str(), &fileInfo) == 0)
#endif
{
// Treat the st_dev (i.e. device) + st_ino (i.e. inode) as a proxy for the contents.
std::ostringstream fasthash;
fasthash << fileInfo.st_dev << ":";
#ifdef _WIN32
// TODO: The hard-linked files are then not correctly supported on Windows platforms.
fasthash << std::hash<std::string>{}(filename);
#else
fasthash << fileInfo.st_ino;
#endif
return fasthash.str();
}
return "";
}
} // Platform
+31
View File
@@ -20,6 +20,7 @@
#endif // _WIN32
#include <fstream>
#include <string>
@@ -28,6 +29,20 @@
#define sscanf sscanf_s
// Define std::tstring as a wstring when Unicode is enabled and a regular string otherwise
namespace std
{
#ifdef _UNICODE
typedef wstring tstring;
typedef wostringstream tostringstream;
#define LogDebugT(x) LogDebug(Platform::Utf16ToUtf8(x))
#else
typedef string tstring;
typedef ostringstream tostringstream;
#define LogDebugT(x) LogDebug(x)
#endif
}
#endif // _WIN32
@@ -71,8 +86,24 @@ void AlignedFree(void * memBlock);
// Note: Temporary files should be at some point deleted by the OS (depending of the OS
// and various platform specific settings). To be safe, add some code to remove
// the file if created.
// FIXME: Implement a function or class for temporary file creation useable by all tests.
std::string CreateTempFilename(const std::string & filenameExt);
// Create an input file stream (std::ifstream) using a UTF-8 filename on any platform.
std::ifstream CreateInputFileStream(const char * filename, std::ios_base::openmode mode);
// Open an input file stream (std::ifstream) using a UTF-8 filename on any platform.
void OpenInputFileStream(std::ifstream & stream, const char * filename, std::ios_base::openmode mode);
// Create a unique hash of a file provided as a UTF-8 filename on any platform.
std::string CreateFileContentHash(const std::string &filename);
// Convert UTF-8 string to UTF-16LE.
std::wstring Utf8ToUtf16(const std::string & str);
// Convert UTF-16LE string to UTF-8.
std::string Utf16ToUtf8(const std::wstring & str);
}
} // namespace OCIO_NAMESPACE
+17 -11
View File
@@ -12,6 +12,8 @@
#include <Logging.h>
#include "Platform.h"
namespace OCIO_NAMESPACE
{
@@ -33,7 +35,7 @@ void SystemMonitorsImpl::getAllMonitors()
DWORD dispNum = 0;
while (EnumDisplayDevices(nullptr, dispNum, &dispDevice, 0))
{
const std::string deviceName = dispDevice.DeviceName;
const std::tstring deviceName = dispDevice.DeviceName;
// Only select active monitors.
if ((dispDevice.StateFlags & DISPLAY_DEVICE_ACTIVE)
@@ -49,37 +51,41 @@ void SystemMonitorsImpl::getAllMonitors()
// monitor name for that device.
EnumDisplayDevices(deviceName.c_str(), dispNum, &dispDevice, 0);
char icmPath[MAX_PATH + 1];
TCHAR icmPath[MAX_PATH + 1];
DWORD pathLength = MAX_PATH;
// TODO: Is a monitor without ICM profile possible?
// TODO: Several ICM profiles could be associated to a single device.
const std::string displayName
= deviceName + ", " + dispDevice.DeviceString;
const std::tstring displayName
= deviceName + TEXT(", ") + dispDevice.DeviceString;
// Get the associated ICM profile path.
if (GetICMProfile(hDC, &pathLength, icmPath))
{
#ifdef _UNICODE
m_monitors.push_back({Platform::Utf16ToUtf8(displayName), Platform::Utf16ToUtf8(icmPath)});
#else
m_monitors.push_back({displayName, icmPath});
#endif
}
else
{
std::ostringstream oss;
oss << "Unable to access the ICM profile for the monitor '"
<< displayName << "'.";
std::tostringstream oss;
oss << TEXT("Unable to access the ICM profile for the monitor '")
<< displayName << TEXT("'.");
LogDebug(oss.str());
LogDebugT(oss.str());
}
DeleteDC(hDC);
}
else
{
std::ostringstream oss;
oss << "Unable to access the monitor '" << deviceName << "'.";
LogDebug(oss.str());
std::tostringstream oss;
oss << TEXT("Unable to access the monitor '") << deviceName << TEXT("'.");
LogDebugT(oss.str());
}
}
@@ -541,7 +541,7 @@ FileFormat * CreateFileFormatICC()
std::string GetProfileDescriptionFromICCProfile(const char * ICCProfileFilepath)
{
std::ifstream filestream(ICCProfileFilepath, std::ios_base::binary);
std::ifstream filestream = Platform::CreateInputFileStream(ICCProfileFilepath, std::ios_base::binary);
if (!filestream.good())
{
std::ostringstream os;
@@ -851,17 +851,17 @@ void CDLWriter::writeContent() const
oss.str("");
params = m_cdl->getSlopeParams();
oss << params[0] << ", " << params[1] << ", " << params[2];
oss << params[0] << " " << params[1] << " " << params[2];
m_formatter.writeContentTag(TAG_SLOPE, oss.str());
oss.str("");
params = m_cdl->getOffsetParams();
oss << params[0] << ", " << params[1] << ", " << params[2];
oss << params[0] << " " << params[1] << " " << params[2];
m_formatter.writeContentTag(TAG_OFFSET, oss.str());
oss.str("");
params = m_cdl->getPowerParams();
oss << params[0] << ", " << params[1] << ", " << params[2];
oss << params[0] << " " << params[1] << " " << params[2];
m_formatter.writeContentTag(TAG_POWER, oss.str());
}
m_formatter.writeEndTag(TAG_SOPNODE);
+13 -4
View File
@@ -265,14 +265,23 @@ void ExponentOp::extractGpuShaderInfo(GpuShaderCreatorRcPtr & shaderCreator) con
// outColor = pow(max(outColor, 0.), exp);
const std::string pxl(shaderCreator->getPixelName());
ss.newLine() << ss.float4Decl("res")
<< " = " << ss.float4Const(pxl + ".rgb.r",
pxl + ".rgb.g",
pxl + ".rgb.b",
pxl + ".a") << ";";
ss.newLine()
<< shaderCreator->getPixelName()
<< " = pow( "
<< "max( " << shaderCreator->getPixelName()
<< ", " << ss.float4Const(0.0f) << " )"
<< "res = pow( "
<< "max( res, " << ss.float4Const(0.0f) << " )"
<< ", " << ss.float4Const(expData()->m_exp4[0], expData()->m_exp4[1],
expData()->m_exp4[2], expData()->m_exp4[3]) << " );";
ss.newLine() << pxl << ".rgb = " << ss.float3Const("res.x", "res.y", "res.z") << ";";
ss.newLine() << pxl << ".a = res.w;";
ss.dedent();
ss.newLine() << "}";
@@ -18,8 +18,6 @@ class Renderer_ACES_RedMod03_Fwd : public OpCPU
{
public:
Renderer_ACES_RedMod03_Fwd() = delete;
Renderer_ACES_RedMod03_Fwd(const Renderer_ACES_RedMod03_Fwd &) = delete;
explicit Renderer_ACES_RedMod03_Fwd(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -29,7 +27,7 @@ protected:
float m_pivot;
float m_inv_width;
const float m_noiseLimit = 1e-2f;
static constexpr float m_noiseLimit = 1e-2f;
};
class Renderer_ACES_RedMod03_Inv : public Renderer_ACES_RedMod03_Fwd
@@ -44,8 +42,6 @@ class Renderer_ACES_RedMod10_Fwd : public OpCPU
{
public:
Renderer_ACES_RedMod10_Fwd() = delete;
Renderer_ACES_RedMod10_Fwd(const Renderer_ACES_RedMod03_Fwd &) = delete;
explicit Renderer_ACES_RedMod10_Fwd(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -55,7 +51,7 @@ protected:
float m_pivot;
float m_inv_width;
const float m_noiseLimit = 1e-2f;
static constexpr float m_noiseLimit = 1e-2f;
};
class Renderer_ACES_RedMod10_Inv : public Renderer_ACES_RedMod10_Fwd
@@ -70,24 +66,20 @@ class Renderer_ACES_Glow03_Fwd : public OpCPU
{
public:
Renderer_ACES_Glow03_Fwd() = delete;
Renderer_ACES_Glow03_Fwd(const Renderer_ACES_Glow03_Fwd &) = delete;
Renderer_ACES_Glow03_Fwd(ConstFixedFunctionOpDataRcPtr & data,
float glowGain, float glowMid);
Renderer_ACES_Glow03_Fwd(ConstFixedFunctionOpDataRcPtr & data, float glowGain, float glowMid);
void apply(const void * inImg, void * outImg, long numPixels) const override;
protected:
float m_glowGain, m_glowMid;
const float m_noiseLimit = 1e-2f;
static constexpr float m_noiseLimit = 1e-2f;
};
class Renderer_ACES_Glow03_Inv : public Renderer_ACES_Glow03_Fwd
{
public:
Renderer_ACES_Glow03_Inv(ConstFixedFunctionOpDataRcPtr & data,
float glowGain, float glowMid);
Renderer_ACES_Glow03_Inv(ConstFixedFunctionOpDataRcPtr & data, float glowGain, float glowMid);
void apply(const void * inImg, void * outImg, long numPixels) const override;
};
@@ -96,8 +88,6 @@ class Renderer_ACES_DarkToDim10_Fwd : public OpCPU
{
public:
Renderer_ACES_DarkToDim10_Fwd() = delete;
Renderer_ACES_DarkToDim10_Fwd(const Renderer_ACES_RedMod03_Fwd &) = delete;
Renderer_ACES_DarkToDim10_Fwd(ConstFixedFunctionOpDataRcPtr & data, float gamma);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -110,8 +100,6 @@ class Renderer_ACES_GamutComp13_Fwd : public OpCPU
{
public:
Renderer_ACES_GamutComp13_Fwd() = delete;
Renderer_ACES_GamutComp13_Fwd(const Renderer_ACES_GamutComp13_Fwd &) = delete;
explicit Renderer_ACES_GamutComp13_Fwd(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -142,8 +130,6 @@ class Renderer_REC2100_Surround : public OpCPU
{
public:
Renderer_REC2100_Surround() = delete;
Renderer_REC2100_Surround(const Renderer_ACES_RedMod03_Fwd &) = delete;
explicit Renderer_REC2100_Surround(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -156,8 +142,6 @@ class Renderer_RGB_TO_HSV : public OpCPU
{
public:
Renderer_RGB_TO_HSV() = delete;
Renderer_RGB_TO_HSV(const Renderer_ACES_RedMod03_Fwd &) = delete;
explicit Renderer_RGB_TO_HSV(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -167,8 +151,6 @@ class Renderer_HSV_TO_RGB : public OpCPU
{
public:
Renderer_HSV_TO_RGB() = delete;
Renderer_HSV_TO_RGB(const Renderer_ACES_RedMod03_Fwd &) = delete;
explicit Renderer_HSV_TO_RGB(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -178,8 +160,6 @@ class Renderer_XYZ_TO_xyY : public OpCPU
{
public:
Renderer_XYZ_TO_xyY() = delete;
Renderer_XYZ_TO_xyY(const Renderer_ACES_RedMod03_Fwd &) = delete;
explicit Renderer_XYZ_TO_xyY(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -189,8 +169,6 @@ class Renderer_xyY_TO_XYZ : public OpCPU
{
public:
Renderer_xyY_TO_XYZ() = delete;
Renderer_xyY_TO_XYZ(const Renderer_ACES_RedMod03_Fwd &) = delete;
explicit Renderer_xyY_TO_XYZ(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -200,8 +178,6 @@ class Renderer_XYZ_TO_uvY : public OpCPU
{
public:
Renderer_XYZ_TO_uvY() = delete;
Renderer_XYZ_TO_uvY(const Renderer_ACES_RedMod03_Fwd &) = delete;
explicit Renderer_XYZ_TO_uvY(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -211,8 +187,6 @@ class Renderer_uvY_TO_XYZ : public OpCPU
{
public:
Renderer_uvY_TO_XYZ() = delete;
Renderer_uvY_TO_XYZ(const Renderer_ACES_RedMod03_Fwd &) = delete;
explicit Renderer_uvY_TO_XYZ(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -222,8 +196,6 @@ class Renderer_XYZ_TO_LUV : public OpCPU
{
public:
Renderer_XYZ_TO_LUV() = delete;
Renderer_XYZ_TO_LUV(const Renderer_ACES_RedMod03_Fwd &) = delete;
explicit Renderer_XYZ_TO_LUV(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -233,8 +205,6 @@ class Renderer_LUV_TO_XYZ : public OpCPU
{
public:
Renderer_LUV_TO_XYZ() = delete;
Renderer_LUV_TO_XYZ(const Renderer_ACES_RedMod03_Fwd &) = delete;
explicit Renderer_LUV_TO_XYZ(ConstFixedFunctionOpDataRcPtr & data);
void apply(const void * inImg, void * outImg, long numPixels) const override;
@@ -279,10 +249,10 @@ __inline float CalcHueWeight(const float red, const float grn, const float blu,
{
// Convert RGB to Yab (luma/chroma).
const float a = 2.f * red - (grn + blu);
static const float sqrt3 = 1.7320508075688772f;
static constexpr float sqrt3 = 1.7320508075688772f;
const float b = sqrt3 * (grn - blu);
const float hue = atan2f(b, a);
const float hue = std::atan2(b, a);
// NB: The code in RedMod03 apply() assumes that in the range of the modification
// window that red will be the largest channel. The center and width must be
@@ -302,7 +272,7 @@ __inline float CalcHueWeight(const float red, const float grn, const float blu,
// These are the coefficients for a quadratic B-spline basis function.
// (All coefs taken from the ACES ctl code on github.)
static const float _M[4][4] = {
static constexpr float _M[4][4] = {
{ 0.25f, 0.00f, 0.00f, 0.00f},
{-0.75f, 0.75f, 0.75f, 0.25f},
{ 0.75f, -1.50f, 0.00f, 1.00f},
@@ -667,7 +637,7 @@ void Renderer_ACES_DarkToDim10_Fwd::apply(const void * inImg, void * outImg, lon
// With the modest 2% ACES surround, this minLum allows the min/max gain
// applied to dark colors to be about 0.6 to 1.6.
constexpr float minLum = 1e-10f;
static constexpr float minLum = 1e-10f;
// Calculate luminance assuming input is AP1 RGB.
const float Y = std::max( minLum, ( 0.27222871678091454f * red +
@@ -676,7 +646,7 @@ void Renderer_ACES_DarkToDim10_Fwd::apply(const void * inImg, void * outImg, lon
// TODO: Currently our fast approx. requires SSE registers.
// Either make this whole routine SSE or make fast scalar pow.
const float Ypow_over_Y = powf(Y, m_gamma);
const float Ypow_over_Y = std::pow(Y, m_gamma);
out[0] = red * Ypow_over_Y;
out[1] = grn * Ypow_over_Y;
+3 -3
View File
@@ -720,7 +720,7 @@ void GammaMoncurveMirrorOpCPUFwd::apply(const void * inImg, void * outImg, long
for (long idx = 0; idx<numPixels; ++idx)
{
const float sign[4] = { std::copysign(1.0f, in[0]), std::copysign(1.0f, in[1]),
std::copysign(1.0f, in[0]), std::copysign(1.0f, in[3]) };
std::copysign(1.0f, in[2]), std::copysign(1.0f, in[3]) };
const float pixel[4] = { std::fabs(in[0]), std::fabs(in[1]),
std::fabs(in[2]), std::fabs(in[3]) };
@@ -817,7 +817,7 @@ void GammaMoncurveMirrorOpCPURev::apply(const void * inImg, void * outImg, long
for (long idx = 0; idx<numPixels; ++idx)
{
const float sign[4] = { std::copysign(1.0f, in[0]), std::copysign(1.0f, in[1]),
std::copysign(1.0f, in[0]), std::copysign(1.0f, in[3]) };
std::copysign(1.0f, in[2]), std::copysign(1.0f, in[3]) };
const float pixel[4] = { std::fabs(in[0]), std::fabs(in[1]),
std::fabs(in[2]), std::fabs(in[3]) };
@@ -837,4 +837,4 @@ void GammaMoncurveMirrorOpCPURev::apply(const void * inImg, void * outImg, long
}
}
} // namespace OCIO_NAMESPACE
} // namespace OCIO_NAMESPACE
-4
View File
@@ -110,7 +110,6 @@ void AddBasicPassThruFwdShader(GpuShaderCreatorRcPtr & shaderCreator,
const double alphaGamma = gamma->getAlphaParams()[0];
const std::string pxl(shaderCreator->getPixelName());
const std::string pxlrgb(pxl + ".rgb");
ss.declareFloat4("gamma", redGamma, grnGamma, bluGamma, alphaGamma);
ss.declareFloat4("breakPnt", 0.f, 0.f, 0.f, 0.f);
@@ -139,7 +138,6 @@ void AddBasicPassThruRevShader(GpuShaderCreatorRcPtr & shaderCreator,
const double alphaGamma = 1. / gamma->getAlphaParams()[0];
const std::string pxl(shaderCreator->getPixelName());
const std::string pxlrgb(pxl + ".rgb");
ss.declareFloat4("gamma", redGamma, grnGamma, bluGamma, alphaGamma);
ss.declareFloat4("breakPnt", 0.f, 0.f, 0.f, 0.f);
@@ -171,7 +169,6 @@ void AddMoncurveFwdShader(GpuShaderCreatorRcPtr & shaderCreator,
ComputeParamsFwd(gamma->getAlphaParams(), alpha);
const std::string pxl(shaderCreator->getPixelName());
const std::string pxlrgb(pxl + ".rgb");
// Even if all components are the same, on OS X, a vec4 needs to be
// declared. This code will work in both cases.
@@ -210,7 +207,6 @@ void AddMoncurveRevShader(GpuShaderCreatorRcPtr & shaderCreator,
ComputeParamsRev(gamma->getAlphaParams(), alpha);
const std::string pxl(shaderCreator->getPixelName());
const std::string pxlrgb(pxl + ".rgb");
// Even if all components are the same, on OS X, a vec4 needs to be
// declared. This code will work in both cases.
@@ -76,12 +76,14 @@ void AddUniform(GpuShaderCreatorRcPtr & shaderCreator,
static constexpr char opPrefix[] = "grading_primary";
void AddGPLogProperties(GpuShaderCreatorRcPtr & shaderCreator, GpuShaderText & st,
void AddGPLogProperties(GpuShaderCreatorRcPtr & shaderCreator,
GpuShaderText & st,
ConstGradingPrimaryOpDataRcPtr & gpData,
GPProperties & propNames)
GPProperties & propNames,
bool dyn)
{
auto prop = gpData->getDynamicPropertyInternal();
if (gpData->isDynamic() && shaderCreator->getLanguage() != LANGUAGE_OSL_1)
if (dyn)
{
// Build names. No need to add an index to the name to avoid collisions as the dynamic
// properties are unique.
@@ -142,22 +144,12 @@ void AddGPLogProperties(GpuShaderCreatorRcPtr & shaderCreator, GpuShaderText & s
st.declareFloat3(propNames.contrast, comp.getContrast());
st.declareFloat3(propNames.gamma, comp.getGamma());
st.declareVar(propNames.pivot, static_cast<float>(comp.getPivot()));
st.declareVar(propNames.pivotBlack, static_cast<float>(value.m_pivotBlack));
st.declareVar(propNames.pivotWhite, static_cast<float>(value.m_pivotWhite));
st.declareVar(propNames.clampBlack, static_cast<float>(value.m_clampBlack));
st.declareVar(propNames.clampWhite, static_cast<float>(value.m_clampWhite));
st.declareVar(propNames.saturation, static_cast<float>(value.m_saturation));
if (shaderCreator->getLanguage() == LANGUAGE_OSL_1 && prop->isDynamic())
{
std::string msg("The dynamic properties are not yet supported by the 'Open Shading language"\
" (OSL)' translation: The '");
msg += opPrefix;
msg += "' dynamic property is replaced by a local variable.";
LogWarning(msg);
}
st.declareVarConst(propNames.pivot, static_cast<float>(comp.getPivot()));
st.declareVarConst(propNames.pivotBlack, static_cast<float>(value.m_pivotBlack));
st.declareVarConst(propNames.pivotWhite, static_cast<float>(value.m_pivotWhite));
st.declareVarConst(propNames.clampBlack, static_cast<float>(value.m_clampBlack));
st.declareVarConst(propNames.clampWhite, static_cast<float>(value.m_clampWhite));
st.declareVarConst(propNames.saturation, static_cast<float>(value.m_saturation));
}
}
@@ -235,12 +227,14 @@ void AddGPLogInverseShader(GpuShaderCreatorRcPtr & shaderCreator,
st.newLine() << pxl << ".rgb += " << props.brightness << ";";
}
void AddGPLinProperties(GpuShaderCreatorRcPtr & shaderCreator, GpuShaderText & st,
void AddGPLinProperties(GpuShaderCreatorRcPtr & shaderCreator,
GpuShaderText & st,
ConstGradingPrimaryOpDataRcPtr & gpData,
GPProperties & propNames)
GPProperties & propNames,
bool dyn)
{
auto prop = gpData->getDynamicPropertyInternal();
if (gpData->isDynamic())
if (dyn)
{
// Build names. No need to add an index to the name to avoid collisions as the dynamic
// properties are unique.
@@ -294,10 +288,10 @@ void AddGPLinProperties(GpuShaderCreatorRcPtr & shaderCreator, GpuShaderText & s
st.declareFloat3(propNames.exposure, comp.getExposure());
st.declareFloat3(propNames.contrast, comp.getContrast());
st.declareVar(propNames.pivot, static_cast<float>(comp.getPivot()));
st.declareVar(propNames.clampBlack, static_cast<float>(value.m_clampBlack));
st.declareVar(propNames.clampWhite, static_cast<float>(value.m_clampWhite));
st.declareVar(propNames.saturation, static_cast<float>(value.m_saturation));
st.declareVarConst(propNames.pivot, static_cast<float>(comp.getPivot()));
st.declareVarConst(propNames.clampBlack, static_cast<float>(value.m_clampBlack));
st.declareVarConst(propNames.clampWhite, static_cast<float>(value.m_clampWhite));
st.declareVarConst(propNames.saturation, static_cast<float>(value.m_saturation));
}
}
@@ -366,12 +360,14 @@ void AddGPLinInverseShader(GpuShaderCreatorRcPtr & shaderCreator,
st.newLine() << pxl << ".rgb += " << props.offset << ";";
}
void AddGPVideoProperties(GpuShaderCreatorRcPtr & shaderCreator, GpuShaderText & st,
void AddGPVideoProperties(GpuShaderCreatorRcPtr & shaderCreator,
GpuShaderText & st,
ConstGradingPrimaryOpDataRcPtr & gpData,
GPProperties & propNames)
GPProperties & propNames,
bool dyn)
{
auto prop = gpData->getDynamicPropertyInternal();
if (gpData->isDynamic())
if (dyn)
{
// Build names. No need to add an index to the name to avoid collisions as the dynamic
// properties are unique.
@@ -431,11 +427,11 @@ void AddGPVideoProperties(GpuShaderCreatorRcPtr & shaderCreator, GpuShaderText &
st.declareFloat3(propNames.offset, comp.getOffset());
st.declareFloat3(propNames.slope, comp.getSlope());
st.declareVar(propNames.pivotBlack, static_cast<float>(value.m_pivotBlack));
st.declareVar(propNames.pivotWhite, static_cast<float>(value.m_pivotWhite));
st.declareVar(propNames.clampBlack, static_cast<float>(value.m_clampBlack));
st.declareVar(propNames.clampWhite, static_cast<float>(value.m_clampWhite));
st.declareVar(propNames.saturation, static_cast<float>(value.m_saturation));
st.declareVarConst(propNames.pivotBlack, static_cast<float>(value.m_pivotBlack));
st.declareVarConst(propNames.pivotWhite, static_cast<float>(value.m_pivotWhite));
st.declareVarConst(propNames.clampBlack, static_cast<float>(value.m_clampBlack));
st.declareVarConst(propNames.clampWhite, static_cast<float>(value.m_clampWhite));
st.declareVarConst(propNames.saturation, static_cast<float>(value.m_saturation));
}
}
@@ -512,7 +508,7 @@ void AddGPVideoInverseShader(GpuShaderCreatorRcPtr & shaderCreator,
void GetGradingPrimaryGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
ConstGradingPrimaryOpDataRcPtr & gpData)
{
const bool dyn = gpData->isDynamic();
const bool dyn = gpData->isDynamic() && shaderCreator->getLanguage() != LANGUAGE_OSL_1;
if (!dyn)
{
auto propGP = gpData->getDynamicPropertyInternal();
@@ -522,6 +518,16 @@ void GetGradingPrimaryGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
}
}
if (gpData->isDynamic() && shaderCreator->getLanguage() == LANGUAGE_OSL_1)
{
std::string msg("The dynamic properties are not yet supported by the 'Open Shading language"\
" (OSL)' translation: The '");
msg += opPrefix;
msg += "' dynamic property is replaced by a local variable.";
LogWarning(msg);
}
const GradingStyle style = gpData->getStyle();
const TransformDirection dir = gpData->getDirection();
@@ -543,7 +549,7 @@ void GetGradingPrimaryGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
{
case GRADING_LOG:
{
AddGPLogProperties(shaderCreator, st, gpData, properties);
AddGPLogProperties(shaderCreator, st, gpData, properties, dyn);
if (dyn)
{
st.newLine() << "if (!" << properties.localBypass << ")";
@@ -570,7 +576,7 @@ void GetGradingPrimaryGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
}
case GRADING_LIN:
{
AddGPLinProperties(shaderCreator, st, gpData, properties);
AddGPLinProperties(shaderCreator, st, gpData, properties, dyn);
if (dyn)
{
st.newLine() << "if (!" << properties.localBypass << ")";
@@ -597,7 +603,7 @@ void GetGradingPrimaryGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
}
case GRADING_VIDEO:
{
AddGPVideoProperties(shaderCreator, st, gpData, properties);
AddGPVideoProperties(shaderCreator, st, gpData, properties, dyn);
if (dyn)
{
st.newLine() << "if (!" << properties.localBypass << ")";
@@ -136,11 +136,11 @@ std::string BuildResourceNameIndexed(GpuShaderCreatorRcPtr & shaderCreator, cons
return name;
}
static const std::string opPrefix{ "grading_rgbcurve" };
void SetGCProperties(GpuShaderCreatorRcPtr & shaderCreator, bool dynamic, GCProperties & propNames)
{
static const std::string opPrefix{ "grading_rgbcurve" };
if (dynamic && shaderCreator->getLanguage() != LANGUAGE_OSL_1)
if (dynamic)
{
// If there are several dynamic ops, they will use the same names for uniforms.
propNames.m_knotsOffsets = BuildResourceName(shaderCreator, opPrefix,
@@ -168,16 +168,6 @@ void SetGCProperties(GpuShaderCreatorRcPtr & shaderCreator, bool dynamic, GCProp
propNames.m_coefs, resIndex);
propNames.m_eval = BuildResourceNameIndexed(shaderCreator, opPrefix,
propNames.m_eval, resIndex);
if (shaderCreator->getLanguage() == LANGUAGE_OSL_1 && dynamic)
{
std::string msg("The dynamic properties are not yet supported by the 'Open Shading language"\
" (OSL)' translation: The '");
msg += opPrefix;
msg += "' dynamic property is replaced by a local variable.";
LogWarning(msg);
}
}
}
@@ -217,13 +207,14 @@ void AddGCPropertiesUniforms(GpuShaderCreatorRcPtr & shaderCreator,
void AddCurveEvalMethodTextToShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
ConstGradingRGBCurveOpDataRcPtr & gcData,
const GCProperties & props)
const GCProperties & props,
bool dyn)
{
GpuShaderText st(shaderCreator->getLanguage());
// Dynamic version uses uniforms declared globaly. Non-dynamic version declares local
// Dynamic version uses uniforms declared globally. Non-dynamic version declares local
// variables in the op specific helper function.
if (!gcData->isDynamic() || shaderCreator->getLanguage() == LANGUAGE_OSL_1)
if (!dyn)
{
auto propGC = gcData->getDynamicPropertyInternal();
@@ -261,7 +252,8 @@ void AddCurveEvalMethodTextToShaderProgram(GpuShaderCreatorRcPtr & shaderCreator
void AddGCForwardShader(GpuShaderCreatorRcPtr & shaderCreator,
GpuShaderText & st,
const GCProperties & props,
bool dyn, bool doLinToLog)
bool dyn,
bool doLinToLog)
{
if (dyn)
{
@@ -308,7 +300,8 @@ void AddGCForwardShader(GpuShaderCreatorRcPtr & shaderCreator,
void AddGCInverseShader(GpuShaderCreatorRcPtr & shaderCreator,
GpuShaderText & st,
const GCProperties & props,
bool dyn, bool doLinToLog)
bool dyn,
bool doLinToLog)
{
if (dyn)
{
@@ -356,7 +349,7 @@ void AddGCInverseShader(GpuShaderCreatorRcPtr & shaderCreator,
void GetGradingRGBCurveGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
ConstGradingRGBCurveOpDataRcPtr & gcData)
{
const bool dyn = gcData->isDynamic();
const bool dyn = gcData->isDynamic() && shaderCreator->getLanguage() != LANGUAGE_OSL_1;
if (!dyn)
{
auto propGC = gcData->getDynamicPropertyInternal();
@@ -366,6 +359,16 @@ void GetGradingRGBCurveGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
}
}
if (gcData->isDynamic() && shaderCreator->getLanguage() == LANGUAGE_OSL_1)
{
std::string msg("The dynamic properties are not yet supported by the 'Open Shading language"\
" (OSL)' translation: The '");
msg += opPrefix;
msg += "' dynamic property is replaced by a local variable.";
LogWarning(msg);
}
const GradingStyle style = gcData->getStyle();
const TransformDirection dir = gcData->getDirection();
@@ -397,12 +400,12 @@ void GetGradingRGBCurveGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
AddGCPropertiesUniforms(shaderCreator, shaderProp, properties);
// Add helper function plus global variables if they are not dynamic.
AddCurveEvalMethodTextToShaderProgram(shaderCreator, gcData, properties);
AddCurveEvalMethodTextToShaderProgram(shaderCreator, gcData, properties, dyn);
}
else
{
// Declare the op specific helper function.
AddCurveEvalMethodTextToShaderProgram(shaderCreator, gcData, properties);
AddCurveEvalMethodTextToShaderProgram(shaderCreator, gcData, properties, dyn);
}
const bool doLinToLog = (style == GRADING_LIN) && !gcData->getBypassLinToLog();
@@ -84,14 +84,16 @@ void AddBoolUniform(GpuShaderCreatorRcPtr & shaderCreator,
}
}
void AddGTProperties(GpuShaderCreatorRcPtr & shaderCreator, GpuShaderText & st,
ConstGradingToneOpDataRcPtr & gtData,
GTProperties & propNames)
{
static const std::string opPrefix{ "grading_tone" };
static const std::string opPrefix{ "grading_tone" };
void AddGTProperties(GpuShaderCreatorRcPtr & shaderCreator,
GpuShaderText & st,
ConstGradingToneOpDataRcPtr & gtData,
GTProperties & propNames,
bool dyn)
{
auto prop = gtData->getDynamicPropertyInternal();
if (gtData->isDynamic() && shaderCreator->getLanguage() != LANGUAGE_OSL_1)
if (dyn)
{
// Build names. No need to add an index to the name to avoid collisions as the dynamic
// properties are unique.
@@ -222,52 +224,42 @@ void AddGTProperties(GpuShaderCreatorRcPtr & shaderCreator, GpuShaderText & st,
const auto & value = prop->getValue();
const auto & compVal = prop->getComputedValue();
st.declareVar(propNames.blacksR, static_cast<float>(value.m_blacks.m_red));
st.declareVar(propNames.blacksG, static_cast<float>(value.m_blacks.m_green));
st.declareVar(propNames.blacksB, static_cast<float>(value.m_blacks.m_blue));
st.declareVar(propNames.blacksM, static_cast<float>(value.m_blacks.m_master));
st.declareVar(propNames.blacksS, static_cast<float>(compVal.m_blacksStart));
st.declareVar(propNames.blacksW, static_cast<float>(compVal.m_blacksWidth));
st.declareVarConst(propNames.blacksR, static_cast<float>(value.m_blacks.m_red));
st.declareVarConst(propNames.blacksG, static_cast<float>(value.m_blacks.m_green));
st.declareVarConst(propNames.blacksB, static_cast<float>(value.m_blacks.m_blue));
st.declareVarConst(propNames.blacksM, static_cast<float>(value.m_blacks.m_master));
st.declareVarConst(propNames.blacksS, static_cast<float>(compVal.m_blacksStart));
st.declareVarConst(propNames.blacksW, static_cast<float>(compVal.m_blacksWidth));
st.declareVar(propNames.shadowsR, static_cast<float>(value.m_shadows.m_red));
st.declareVar(propNames.shadowsG, static_cast<float>(value.m_shadows.m_green));
st.declareVar(propNames.shadowsB, static_cast<float>(value.m_shadows.m_blue));
st.declareVar(propNames.shadowsM, static_cast<float>(value.m_shadows.m_master));
st.declareVar(propNames.shadowsS, static_cast<float>(compVal.m_shadowsStart));
st.declareVar(propNames.shadowsW, static_cast<float>(compVal.m_shadowsWidth));
st.declareVarConst(propNames.shadowsR, static_cast<float>(value.m_shadows.m_red));
st.declareVarConst(propNames.shadowsG, static_cast<float>(value.m_shadows.m_green));
st.declareVarConst(propNames.shadowsB, static_cast<float>(value.m_shadows.m_blue));
st.declareVarConst(propNames.shadowsM, static_cast<float>(value.m_shadows.m_master));
st.declareVarConst(propNames.shadowsS, static_cast<float>(compVal.m_shadowsStart));
st.declareVarConst(propNames.shadowsW, static_cast<float>(compVal.m_shadowsWidth));
st.declareVar(propNames.midtonesR, static_cast<float>(value.m_midtones.m_red));
st.declareVar(propNames.midtonesG, static_cast<float>(value.m_midtones.m_green));
st.declareVar(propNames.midtonesB, static_cast<float>(value.m_midtones.m_blue));
st.declareVar(propNames.midtonesM, static_cast<float>(value.m_midtones.m_master));
st.declareVar(propNames.midtonesS, static_cast<float>(value.m_midtones.m_start));
st.declareVar(propNames.midtonesW, static_cast<float>(value.m_midtones.m_width));
st.declareVarConst(propNames.midtonesR, static_cast<float>(value.m_midtones.m_red));
st.declareVarConst(propNames.midtonesG, static_cast<float>(value.m_midtones.m_green));
st.declareVarConst(propNames.midtonesB, static_cast<float>(value.m_midtones.m_blue));
st.declareVarConst(propNames.midtonesM, static_cast<float>(value.m_midtones.m_master));
st.declareVarConst(propNames.midtonesS, static_cast<float>(value.m_midtones.m_start));
st.declareVarConst(propNames.midtonesW, static_cast<float>(value.m_midtones.m_width));
st.declareVar(propNames.highlightsR, static_cast<float>(value.m_highlights.m_red));
st.declareVar(propNames.highlightsG, static_cast<float>(value.m_highlights.m_green));
st.declareVar(propNames.highlightsB, static_cast<float>(value.m_highlights.m_blue));
st.declareVar(propNames.highlightsM, static_cast<float>(value.m_highlights.m_master));
st.declareVar(propNames.highlightsS, static_cast<float>(compVal.m_highlightsStart));
st.declareVar(propNames.highlightsW, static_cast<float>(compVal.m_highlightsWidth));
st.declareVarConst(propNames.highlightsR, static_cast<float>(value.m_highlights.m_red));
st.declareVarConst(propNames.highlightsG, static_cast<float>(value.m_highlights.m_green));
st.declareVarConst(propNames.highlightsB, static_cast<float>(value.m_highlights.m_blue));
st.declareVarConst(propNames.highlightsM, static_cast<float>(value.m_highlights.m_master));
st.declareVarConst(propNames.highlightsS, static_cast<float>(compVal.m_highlightsStart));
st.declareVarConst(propNames.highlightsW, static_cast<float>(compVal.m_highlightsWidth));
st.declareVar(propNames.whitesR, static_cast<float>(value.m_whites.m_red));
st.declareVar(propNames.whitesG, static_cast<float>(value.m_whites.m_green));
st.declareVar(propNames.whitesB, static_cast<float>(value.m_whites.m_blue));
st.declareVar(propNames.whitesM, static_cast<float>(value.m_whites.m_master));
st.declareVar(propNames.whitesS, static_cast<float>(compVal.m_whitesStart));
st.declareVar(propNames.whitesW, static_cast<float>(compVal.m_whitesWidth));
st.declareVarConst(propNames.whitesR, static_cast<float>(value.m_whites.m_red));
st.declareVarConst(propNames.whitesG, static_cast<float>(value.m_whites.m_green));
st.declareVarConst(propNames.whitesB, static_cast<float>(value.m_whites.m_blue));
st.declareVarConst(propNames.whitesM, static_cast<float>(value.m_whites.m_master));
st.declareVarConst(propNames.whitesS, static_cast<float>(compVal.m_whitesStart));
st.declareVarConst(propNames.whitesW, static_cast<float>(compVal.m_whitesWidth));
st.declareVar(propNames.sContrast, static_cast<float>(value.m_scontrast));
if (shaderCreator->getLanguage() == LANGUAGE_OSL_1 && prop->isDynamic())
{
std::string msg("The dynamic properties are not yet supported by the 'Open Shading language"\
" (OSL)' translation: The '");
msg += opPrefix;
msg += "' dynamic property is replaced by a local variable.";
LogWarning(msg);
}
st.declareVarConst(propNames.sContrast, static_cast<float>(value.m_scontrast));
}
}
@@ -542,12 +534,12 @@ void Add_MidsRev_Shader(GpuShaderCreatorRcPtr & shaderCreator,
}
else
{
st.newLine() << st.float3Decl("t") << " = " << pix << ".rgb;";
st.newLine() << st.float3Decl("outL") << ";";
st.newLine() << st.float3Decl("outM") << ";";
st.newLine() << st.float3Decl("outR") << ";";
st.newLine() << st.float3Decl("outR2") << ";";
st.newLine() << st.float3Decl("outR3") << ";";
st.newLine() << st.colorDecl("t") << " = " << pix << ".rgb;";
st.newLine() << st.colorDecl("outL") << ";";
st.newLine() << st.colorDecl("outM") << ";";
st.newLine() << st.colorDecl("outR") << ";";
st.newLine() << st.colorDecl("outR2") << ";";
st.newLine() << st.colorDecl("outR3") << ";";
// TODO: Would probably be better to call the preceding if-block 3 times
// rather than trying to do a float3 computation here. Extra computation is
@@ -603,25 +595,25 @@ void Add_MidsRev_Shader(GpuShaderCreatorRcPtr & shaderCreator,
st.dedent();
st.newLine() << "}";
st.newLine() << st.float3Decl("res") << ";";
st.newLine() << "res.x = (t.x < y1) ? outL.x : outM.x;";
st.newLine() << "res.y = (t.y < y1) ? outL.y : outM.y;";
st.newLine() << "res.z = (t.z < y1) ? outL.z : outM.z;";
st.newLine() << "res.x = (t.x > y2) ? outR.x : res.x;";
st.newLine() << "res.y = (t.y > y2) ? outR.y : res.y;";
st.newLine() << "res.z = (t.z > y2) ? outR.z : res.z;";
st.newLine() << "res.x = (t.x > y3) ? outR2.x : res.x;";
st.newLine() << "res.y = (t.y > y3) ? outR2.y : res.y;";
st.newLine() << "res.z = (t.z > y3) ? outR2.z : res.z;";
st.newLine() << "res.x = (t.x > y4) ? outR3.x : res.x;";
st.newLine() << "res.y = (t.y > y4) ? outR3.y : res.y;";
st.newLine() << "res.z = (t.z > y4) ? outR3.z : res.z;";
st.newLine() << "res.x = (t.x < y0) ? x0 + (t.x - y0) * m0 : res.x;";
st.newLine() << "res.y = (t.y < y0) ? x0 + (t.y - y0) * m0 : res.y;";
st.newLine() << "res.z = (t.z < y0) ? x0 + (t.z - y0) * m0 : res.z;";
st.newLine() << "res.x = (t.x > y5) ? x5 + (t.x - y5) * m5 : res.x;";
st.newLine() << "res.y = (t.y > y5) ? x5 + (t.y - y5) * m5 : res.y;";
st.newLine() << "res.z = (t.z > y5) ? x5 + (t.z - y5) * m5 : res.z;";
st.newLine() << st.colorDecl("res") << ";";
st.newLine() << "res.r = (t.r < y1) ? outL.r : outM.r;";
st.newLine() << "res.g = (t.g < y1) ? outL.g : outM.g;";
st.newLine() << "res.b = (t.b < y1) ? outL.b : outM.b;";
st.newLine() << "res.r = (t.r > y2) ? outR.r : res.r;";
st.newLine() << "res.g = (t.g > y2) ? outR.g : res.g;";
st.newLine() << "res.b = (t.b > y2) ? outR.b : res.b;";
st.newLine() << "res.r = (t.r > y3) ? outR2.r : res.r;";
st.newLine() << "res.g = (t.g > y3) ? outR2.g : res.g;";
st.newLine() << "res.b = (t.b > y3) ? outR2.b : res.b;";
st.newLine() << "res.r = (t.r > y4) ? outR3.r : res.r;";
st.newLine() << "res.g = (t.g > y4) ? outR3.g : res.g;";
st.newLine() << "res.b = (t.b > y4) ? outR3.b : res.b;";
st.newLine() << "res.r = (t.r < y0) ? x0 + (t.r - y0) * m0 : res.r;";
st.newLine() << "res.g = (t.g < y0) ? x0 + (t.g - y0) * m0 : res.g;";
st.newLine() << "res.b = (t.b < y0) ? x0 + (t.b - y0) * m0 : res.b;";
st.newLine() << "res.r = (t.r > y5) ? x5 + (t.r - y5) * m5 : res.r;";
st.newLine() << "res.g = (t.g > y5) ? x5 + (t.g - y5) * m5 : res.g;";
st.newLine() << "res.b = (t.b > y5) ? x5 + (t.b - y5) * m5 : res.b;";
st.newLine() << pix << ".rgb = res;";
}
@@ -707,12 +699,12 @@ void Add_FauxCubicFwdEval_Shader(GpuShaderCreatorRcPtr & shaderCreator,
}
else
{
st.newLine() << st.float3Decl("t") << " = " << pix << "." << channelSuffix << ";";
st.newLine() << st.float3Decl("res") << ";";
st.newLine() << st.float3Decl("tL") << ";";
st.newLine() << st.float3Decl("tR") << ";";
st.newLine() << st.float3Decl("fL") << ";";
st.newLine() << st.float3Decl("fR") << ";";
st.newLine() << st.colorDecl("t") << " = " << pix << "." << channelSuffix << ";";
st.newLine() << st.colorDecl("res") << ";";
st.newLine() << st.colorDecl("tL") << ";";
st.newLine() << st.colorDecl("tR") << ";";
st.newLine() << st.colorDecl("fL") << ";";
st.newLine() << st.colorDecl("fR") << ";";
}
st.newLine() << "tL = (t - x0) / (x1 - x0);";
@@ -729,15 +721,15 @@ void Add_FauxCubicFwdEval_Shader(GpuShaderCreatorRcPtr & shaderCreator,
}
else
{
st.newLine() << "res.x = (t.x < x1) ? fL.x : fR.x;";
st.newLine() << "res.y = (t.y < x1) ? fL.y : fR.y;";
st.newLine() << "res.z = (t.z < x1) ? fL.z : fR.z;";
st.newLine() << "res.x = (t.x < x0) ? y0 + (t.x - x0) * m0 : res.x;";
st.newLine() << "res.y = (t.y < x0) ? y0 + (t.y - x0) * m0 : res.y;";
st.newLine() << "res.z = (t.z < x0) ? y0 + (t.z - x0) * m0 : res.z;";
st.newLine() << "res.x = (t.x > x2) ? y2 + (t.x - x2) * m2 : res.x;";
st.newLine() << "res.y = (t.y > x2) ? y2 + (t.y - x2) * m2 : res.y;";
st.newLine() << "res.z = (t.z > x2) ? y2 + (t.z - x2) * m2 : res.z;";
st.newLine() << "res.r = (t.r < x1) ? fL.r : fR.r;";
st.newLine() << "res.g = (t.g < x1) ? fL.g : fR.g;";
st.newLine() << "res.b = (t.b < x1) ? fL.b : fR.b;";
st.newLine() << "res.r = (t.r < x0) ? y0 + (t.r - x0) * m0 : res.r;";
st.newLine() << "res.g = (t.g < x0) ? y0 + (t.g - x0) * m0 : res.g;";
st.newLine() << "res.b = (t.b < x0) ? y0 + (t.b - x0) * m0 : res.b;";
st.newLine() << "res.r = (t.r > x2) ? y2 + (t.r - x2) * m2 : res.r;";
st.newLine() << "res.g = (t.g > x2) ? y2 + (t.g - x2) * m2 : res.g;";
st.newLine() << "res.b = (t.b > x2) ? y2 + (t.b - x2) * m2 : res.b;";
}
st.newLine() << pix << "." << channelSuffix << " = res;";
}
@@ -759,14 +751,14 @@ void Add_FauxCubicRevEval_Shader(GpuShaderCreatorRcPtr & shaderCreator,
}
else
{
st.newLine() << st.float3Decl("t") << " = " << pix << "." << channelSuffix << ";";
st.newLine() << st.float3Decl("res") << ";";
st.newLine() << st.float3Decl("cL") << ";";
st.newLine() << st.float3Decl("cR") << ";";
st.newLine() << st.float3Decl("discrimL") << ";";
st.newLine() << st.float3Decl("discrimR") << ";";
st.newLine() << st.float3Decl("outL") << ";";
st.newLine() << st.float3Decl("outR") << ";";
st.newLine() << st.colorDecl("t") << " = " << pix << "." << channelSuffix << ";";
st.newLine() << st.colorDecl("res") << ";";
st.newLine() << st.colorDecl("cL") << ";";
st.newLine() << st.colorDecl("cR") << ";";
st.newLine() << st.colorDecl("discrimL") << ";";
st.newLine() << st.colorDecl("discrimR") << ";";
st.newLine() << st.colorDecl("outL") << ";";
st.newLine() << st.colorDecl("outR") << ";";
}
st.newLine() << "cL = y0 - t;";
@@ -787,15 +779,15 @@ void Add_FauxCubicRevEval_Shader(GpuShaderCreatorRcPtr & shaderCreator,
}
else
{
st.newLine() << "res.x = (t.x < y1) ? outL.x : outR.x;";
st.newLine() << "res.y = (t.y < y1) ? outL.y : outR.y;";
st.newLine() << "res.z = (t.z < y1) ? outL.z : outR.z;";
st.newLine() << "res.x = (t.x < y0) ? x0 + (t.x - y0) / m0 : res.x;";
st.newLine() << "res.y = (t.y < y0) ? x0 + (t.y - y0) / m0 : res.y;";
st.newLine() << "res.z = (t.z < y0) ? x0 + (t.z - y0) / m0 : res.z;";
st.newLine() << "res.x = (t.x > y2) ? x2 + (t.x - y2) / m2 : res.x;";
st.newLine() << "res.y = (t.y > y2) ? x2 + (t.y - y2) / m2 : res.y;";
st.newLine() << "res.z = (t.z > y2) ? x2 + (t.z - y2) / m2 : res.z;";
st.newLine() << "res.r = (t.r < y1) ? outL.r : outR.r;";
st.newLine() << "res.g = (t.g < y1) ? outL.g : outR.g;";
st.newLine() << "res.b = (t.b < y1) ? outL.b : outR.b;";
st.newLine() << "res.r = (t.r < y0) ? x0 + (t.r - y0) / m0 : res.r;";
st.newLine() << "res.g = (t.g < y0) ? x0 + (t.g - y0) / m0 : res.g;";
st.newLine() << "res.b = (t.b < y0) ? x0 + (t.b - y0) / m0 : res.b;";
st.newLine() << "res.r = (t.r > y2) ? x2 + (t.r - y2) / m2 : res.r;";
st.newLine() << "res.g = (t.g > y2) ? x2 + (t.g - y2) / m2 : res.g;";
st.newLine() << "res.b = (t.b > y2) ? x2 + (t.b - y2) / m2 : res.b;";
}
st.newLine() << pix << "." << channelSuffix << " = res;";
}
@@ -954,7 +946,7 @@ void Add_WhiteBlackPre_Shader(GpuShaderCreatorRcPtr & shaderCreator,
}
else
{
st.newLine() << st.float3Decl("t") << " = " << pix << ".rgb;";
st.newLine() << st.colorDecl("t") << " = " << pix << ".rgb;";
}
}
@@ -962,83 +954,83 @@ void Add_WBFwd_Shader(unsigned channel, bool linearExtrap, GpuShaderText & st)
{
if (channel != M)
{
st.newLine() << " float tlocal = (t - x0) / (x1 - x0);";
st.newLine() << " float res = tlocal * (x1 - x0) * ( tlocal * 0.5 * (m1 - m0) + m0 ) + y0;";
st.newLine() << " res = (t < x0) ? y0 + (t - x0) * m0 : res;";
st.newLine() << st.floatKeyword() << " tlocal = (t - x0) / (x1 - x0);";
st.newLine() << st.floatKeyword() << " res = tlocal * (x1 - x0) * ( tlocal * 0.5 * (m1 - m0) + m0 ) + y0;";
st.newLine() << "res = (t < x0) ? y0 + (t - x0) * m0 : res;";
}
else
{
st.newLine() << " " << st.float3Decl("tlocal") << " = (t - x0) / (x1 - x0);";
st.newLine() << " " << st.float3Decl("res") << " = tlocal * (x1 - x0) * ( tlocal * 0.5 * (m1 - m0) + m0 ) + y0;";
st.newLine() << " res.x = (t.x < x0) ? y0 + (t.x - x0) * m0 : res.x;";
st.newLine() << " res.y = (t.y < x0) ? y0 + (t.y - x0) * m0 : res.y;";
st.newLine() << " res.z = (t.z < x0) ? y0 + (t.z - x0) * m0 : res.z;";
st.newLine() << st.float3Decl("tlocal") << " = (t - x0) / (x1 - x0);";
st.newLine() << st.colorDecl("res") << " = tlocal * (x1 - x0) * ( tlocal * 0.5 * (m1 - m0) + m0 ) + y0;";
st.newLine() << "res.r = (t.r < x0) ? y0 + (t.r - x0) * m0 : res.r;";
st.newLine() << "res.g = (t.g < x0) ? y0 + (t.g - x0) * m0 : res.g;";
st.newLine() << "res.b = (t.b < x0) ? y0 + (t.b - x0) * m0 : res.b;";
}
if ( linearExtrap )
{
if (channel != M)
{
st.newLine() << " res = (t > x1) ? y1 + (t - x1) * m1 : res;";
st.newLine() << "res = (t > x1) ? y1 + (t - x1) * m1 : res;";
}
else
{
st.newLine() << " res.x = (t.x > x1) ? y1 + (t.x - x1) * m1 : res.x;";
st.newLine() << " res.y = (t.y > x1) ? y1 + (t.y - x1) * m1 : res.y;";
st.newLine() << " res.z = (t.z > x1) ? y1 + (t.z - x1) * m1 : res.z;";
st.newLine() << "res.r = (t.r > x1) ? y1 + (t.r - x1) * m1 : res.r;";
st.newLine() << "res.g = (t.g > x1) ? y1 + (t.g - x1) * m1 : res.g;";
st.newLine() << "res.b = (t.b > x1) ? y1 + (t.b - x1) * m1 : res.b;";
}
}
}
void Add_WBRev_Shader(unsigned channel, bool linearExtrap, GpuShaderText & st)
{
st.newLine() << " float a = 0.5 * (m1 - m0) * (x1 - x0);";
st.newLine() << " float b = m0 * (x1 - x0);";
st.newLine() << st.floatKeyword() << " a = 0.5 * (m1 - m0) * (x1 - x0);";
st.newLine() << st.floatKeyword() << " b = m0 * (x1 - x0);";
if (channel != M)
{
st.newLine() << " float c = y0 - t;";
st.newLine() << " float discrim = sqrt( b * b - 4. * a * c );";
st.newLine() << " float tmp = ( -2. * c ) / ( discrim + b );";
st.newLine() << " float res = tmp * (x1 - x0) + x0;";
st.newLine() << " res = (t < y0) ? x0 + (t - y0) / m0 : res;";
st.newLine() << st.floatKeyword() << " c = y0 - t;";
st.newLine() << st.floatKeyword() << " discrim = sqrt( b * b - 4. * a * c );";
st.newLine() << st.floatKeyword() << " tmp = ( -2. * c ) / ( discrim + b );";
st.newLine() << st.floatKeyword() << " res = tmp * (x1 - x0) + x0;";
st.newLine() << "res = (t < y0) ? x0 + (t - y0) / m0 : res;";
}
else
{
st.newLine() << " " << st.float3Decl("c") << " = y0 - t;";
st.newLine() << " " << st.float3Decl("discrim") << " = sqrt( b * b - 4. * a * c );";
st.newLine() << " " << st.float3Decl("tmp") << " = ( -2. * c ) / ( discrim + b );";
st.newLine() << " " << st.float3Decl("res") << " = tmp * (x1 - x0) + x0;";
st.newLine() << " res.x = (t.x < y0) ? x0 + (t.x - y0) / m0 : res.x;";
st.newLine() << " res.y = (t.y < y0) ? x0 + (t.y - y0) / m0 : res.y;";
st.newLine() << " res.z = (t.z < y0) ? x0 + (t.z - y0) / m0 : res.z;";
st.newLine() << st.float3Decl("c") << " = y0 - t;";
st.newLine() << st.float3Decl("discrim") << " = sqrt( b * b - 4. * a * c );";
st.newLine() << st.float3Decl("tmp") << " = ( -2. * c ) / ( discrim + b );";
st.newLine() << st.colorDecl("res") << " = tmp * (x1 - x0) + x0;";
st.newLine() << "res.r = (t.r < y0) ? x0 + (t.r - y0) / m0 : res.r;";
st.newLine() << "res.g = (t.g < y0) ? x0 + (t.g - y0) / m0 : res.g;";
st.newLine() << "res.b = (t.b < y0) ? x0 + (t.b - y0) / m0 : res.b;";
}
if ( linearExtrap )
{
if (channel != M)
{
st.newLine() << " res = (t > y1) ? x1 + (t - y1) / m1 : res;";
st.newLine() << "res = (t > y1) ? x1 + (t - y1) / m1 : res;";
}
else
{
// TODO: When m1 = 1., y1=x1, this becomes t.
st.newLine() << " res.x = (t.x > y1) ? x1 + (t.x - y1) / m1 : res.x;";
st.newLine() << " res.y = (t.y > y1) ? x1 + (t.y - y1) / m1 : res.y;";
st.newLine() << " res.z = (t.z > y1) ? x1 + (t.z - y1) / m1 : res.z;";
st.newLine() << "res.r = (t.r > y1) ? x1 + (t.r - y1) / m1 : res.r;";
st.newLine() << "res.g = (t.g > y1) ? x1 + (t.g - y1) / m1 : res.g;";
st.newLine() << "res.b = (t.b > y1) ? x1 + (t.b - y1) / m1 : res.b;";
}
}
}
void Add_WBExtrapPre_Shader(GpuShaderText & st)
{
st.newLine() << " res = (res - x0) / gain + x0;";
st.newLine() << "res = (res - x0) / gain + x0;";
// Quadratic extrapolation for better HDR control.
st.newLine() << " float new_y1 = (x1 - x0) / gain + x0;";
st.newLine() << " float xd = x0 + (x1 - x0) * 0.99;";
st.newLine() << " float md = m0 + (xd - x0) * (m1 - m0) / (x1 - x0);";
st.newLine() << " md = 1. / md;";
st.newLine() << " float aa = 0.5 * (1. / m1 - md) / (x1 - xd);";
st.newLine() << " float bb = 1. / m1 - 2. * aa * x1;";
st.newLine() << " float cc = new_y1 - bb * x1 - aa * x1 * x1;";
st.newLine() << " t = (t - x0) / gain + x0;";
st.newLine() << st.floatKeyword() << " new_y1 = (x1 - x0) / gain + x0;";
st.newLine() << st.floatKeyword() << " xd = x0 + (x1 - x0) * 0.99;";
st.newLine() << st.floatKeyword() << " md = m0 + (xd - x0) * (m1 - m0) / (x1 - x0);";
st.newLine() << "md = 1. / md;";
st.newLine() << st.floatKeyword() << " aa = 0.5 * (1. / m1 - md) / (x1 - xd);";
st.newLine() << st.floatKeyword() << " bb = 1. / m1 - 2. * aa * x1;";
st.newLine() << st.floatKeyword() << " cc = new_y1 - bb * x1 - aa * x1 * x1;";
st.newLine() << "t = (t - x0) / gain + x0;";
}
void Add_WhiteBlackFwd_Shader(GpuShaderCreatorRcPtr & shaderCreator,
@@ -1056,47 +1048,50 @@ void Add_WhiteBlackFwd_Shader(GpuShaderCreatorRcPtr & shaderCreator,
st.newLine() << "if (mtest < 1.)";
st.newLine() << "{";
st.indent();
if (!isBlack)
{
st.newLine() << " m1 = max( 0.01, m1 );";
st.newLine() << " float y1 = y0 + (m0 + m1) * (x1 - x0) * 0.5;";
st.newLine() << "m1 = max( 0.01, m1 );";
st.newLine() << st.floatKeyword() << " y1 = y0 + (m0 + m1) * (x1 - x0) * 0.5;";
}
else
{
st.newLine() << " m0 = max( 0.01, m0 );";
st.newLine() << " float y0 = y1 - (m0 + m1) * (x1 - x0) * 0.5;";
st.newLine() << "m0 = max( 0.01, m0 );";
st.newLine() << st.floatKeyword() << " y0 = y1 - (m0 + m1) * (x1 - x0) * 0.5;";
}
Add_WBFwd_Shader(channel, true, st);
if (channel != M)
{
st.newLine() << " " << pix << "." << channelSuffix << " = res;";
st.newLine() << pix << "." << channelSuffix << " = res;";
}
else
{
st.newLine() << " " << pix << ".rgb = res;";
st.newLine() << pix << ".rgb = res;";
}
st.dedent();
st.newLine() << "}";
// Slope is increasing case.
st.newLine() << "else if (mtest > 1.)";
st.newLine() << "{";
st.indent();
if (!isBlack)
{
st.newLine() << " m1 = 2. - m1;";
st.newLine() << " m1 = max( 0.01, m1 );";
st.newLine() << " float gain = (m0 + m1) * 0.5;";
st.newLine() << " t = (t - x0) * gain + x0;";
st.newLine() << "m1 = 2. - m1;";
st.newLine() << "m1 = max( 0.01, m1 );";
st.newLine() << st.floatKeyword() << " gain = (m0 + m1) * 0.5;";
st.newLine() << "t = (t - x0) * gain + x0;";
}
else
{
st.newLine() << " m0 = 2. - m0;";
st.newLine() << " m0 = max( 0.01, m0 );";
st.newLine() << " float y0 = y1 - (m0 + m1) * (x1 - x0) * 0.5;";
st.newLine() << " float gain = (m0 + m1) * 0.5;";
st.newLine() << " t = (t - x1) * gain + x1;";
st.newLine() << "m0 = 2. - m0;";
st.newLine() << "m0 = max( 0.01, m0 );";
st.newLine() << st.floatKeyword() << " y0 = y1 - (m0 + m1) * (x1 - x0) * 0.5;";
st.newLine() << st.floatKeyword() << " gain = (m0 + m1) * 0.5;";
st.newLine() << "t = (t - x1) * gain + x1;";
}
Add_WBRev_Shader(channel, isBlack, st);
@@ -1107,28 +1102,29 @@ void Add_WhiteBlackFwd_Shader(GpuShaderCreatorRcPtr & shaderCreator,
if (channel != M)
{
st.newLine() << " if (t > x1) res = (aa * t + bb) * t + cc;";
st.newLine() << "if (t > x1) res = (aa * t + bb) * t + cc;";
}
else
{
st.newLine() << " if (t.x > x1) res.x = (aa * t.x + bb) * t.x + cc;";
st.newLine() << " if (t.y > x1) res.y = (aa * t.y + bb) * t.y + cc;";
st.newLine() << " if (t.z > x1) res.z = (aa * t.z + bb) * t.z + cc;";
st.newLine() << "if (t.r > x1) res.r = (aa * t.r + bb) * t.r + cc;";
st.newLine() << "if (t.g > x1) res.g = (aa * t.g + bb) * t.g + cc;";
st.newLine() << "if (t.b > x1) res.b = (aa * t.b + bb) * t.b + cc;";
}
}
else
{
st.newLine() << " res = (res - x1) / gain + x1;";
st.newLine() << "res = (res - x1) / gain + x1;";
}
if (channel != M)
{
st.newLine() << " " << pix << "." << channelSuffix << " = res;";
st.newLine() << pix << "." << channelSuffix << " = res;";
}
else
{
st.newLine() << " " << pix << ".rgb = res;";
st.newLine() << pix << ".rgb = res;";
}
st.dedent();
st.newLine() << "}"; // else if (mtest > 1.)
st.dedent();
@@ -1148,15 +1144,16 @@ void Add_WhiteBlackRev_Shader(GpuShaderCreatorRcPtr & shaderCreator,
st.newLine() << "if (mtest < 1.)";
st.newLine() << "{";
st.indent();
if (!isBlack)
{
st.newLine() << " m1 = max( 0.01, m1 );";
st.newLine() << " float y1 = y0 + (m0 + m1) * (x1 - x0) * 0.5;";
st.newLine() << "m1 = max( 0.01, m1 );";
st.newLine() << st.floatKeyword() << " y1 = y0 + (m0 + m1) * (x1 - x0) * 0.5;";
}
else
{
st.newLine() << " m0 = max( 0.01, m0 );";
st.newLine() << " float y0 = y1 - (m0 + m1) * (x1 - x0) * 0.5;";
st.newLine() << "m0 = max( 0.01, m0 );";
st.newLine() << st.floatKeyword() << " y0 = y1 - (m0 + m1) * (x1 - x0) * 0.5;";
}
Add_WBRev_Shader(channel, true, st);
@@ -1165,32 +1162,34 @@ void Add_WhiteBlackRev_Shader(GpuShaderCreatorRcPtr & shaderCreator,
if (channel != M)
{
st.newLine() << " " << pix << "." << channelSuffix << " = res;";
st.newLine() << pix << "." << channelSuffix << " = res;";
}
else
{
st.newLine() << " " << pix << ".rgb = res;";
st.newLine() << pix << ".rgb = res;";
}
st.dedent();
st.newLine() << "}";
// Slope is increasing case.
st.newLine() << "else if (mtest > 1.)";
st.newLine() << "{";
st.indent();
if (!isBlack)
{
st.newLine() << " m1 = 2. - m1;";
st.newLine() << " m1 = max( 0.01, m1 );";
st.newLine() << " float gain = (m0 + m1) * 0.5;";
st.newLine() << " t = (t - x0) * gain + x0;";
st.newLine() << "m1 = 2. - m1;";
st.newLine() << "m1 = max( 0.01, m1 );";
st.newLine() << st.floatKeyword() << " gain = (m0 + m1) * 0.5;";
st.newLine() << "t = (t - x0) * gain + x0;";
}
else
{
st.newLine() << " m0 = 2. - m0;";
st.newLine() << " m0 = max( 0.01, m0 );";
st.newLine() << " float y0 = y1 - (m0 + m1) * (x1 - x0) * 0.5;";
st.newLine() << " float gain = (m0 + m1) * 0.5;";
st.newLine() << " t = (t - x1) * gain + x1;";
st.newLine() << "m0 = 2. - m0;";
st.newLine() << "m0 = max( 0.01, m0 );";
st.newLine() << st.floatKeyword() << " y0 = y1 - (m0 + m1) * (x1 - x0) * 0.5;";
st.newLine() << st.floatKeyword() << " gain = (m0 + m1) * 0.5;";
st.newLine() << "t = (t - x1) * gain + x1;";
}
Add_WBFwd_Shader(channel, isBlack, st);
@@ -1201,36 +1200,37 @@ void Add_WhiteBlackRev_Shader(GpuShaderCreatorRcPtr & shaderCreator,
if (channel != M)
{
st.newLine() << " float c = cc - t;";
st.newLine() << " float discrim = sqrt( bb * bb - 4. * aa * c );";
st.newLine() << " float res1 = ( -2. * c ) / ( discrim + bb );";
st.newLine() << " float brk = (aa * x1 + bb) * x1 + cc;";
st.newLine() << " res = (t < brk) ? res : res1;";
st.newLine() << st.floatKeyword() << " c = cc - t;";
st.newLine() << st.floatKeyword() << " discrim = sqrt( bb * bb - 4. * aa * c );";
st.newLine() << st.floatKeyword() << " res1 = ( -2. * c ) / ( discrim + bb );";
st.newLine() << st.floatKeyword() << " brk = (aa * x1 + bb) * x1 + cc;";
st.newLine() << "res = (t < brk) ? res : res1;";
}
else
{
st.newLine() << " " << st.float3Decl("c") << " = cc - t;";
st.newLine() << " " << st.float3Decl("discrim") << " = sqrt( bb * bb - 4. * aa * c );";
st.newLine() << " " << st.float3Decl("res1") << " = ( -2. * c ) / ( discrim + bb );";
st.newLine() << " float brk = (aa * x1 + bb) * x1 + cc;";
st.newLine() << " res.x = (t.x < brk) ? res.x : res1.x;";
st.newLine() << " res.y = (t.y < brk) ? res.y : res1.y;";
st.newLine() << " res.z = (t.z < brk) ? res.z : res1.z;";
st.newLine() << st.float3Decl("c") << " = cc - t;";
st.newLine() << st.float3Decl("discrim") << " = sqrt( bb * bb - 4. * aa * c );";
st.newLine() << st.colorDecl("res1") << " = ( -2. * c ) / ( discrim + bb );";
st.newLine() << st.floatKeyword() << " brk = (aa * x1 + bb) * x1 + cc;";
st.newLine() << "res.r = (t.r < brk) ? res.r : res1.r;";
st.newLine() << "res.g = (t.g < brk) ? res.g : res1.g;";
st.newLine() << "res.b = (t.b < brk) ? res.b : res1.b;";
}
}
else
{
st.newLine() << " res = (res - x1) / gain + x1;";
st.newLine() << "res = (res - x1) / gain + x1;";
}
if (channel != M)
{
st.newLine() << " " << pix << "." << channelSuffix << " = res;";
st.newLine() << pix << "." << channelSuffix << " = res;";
}
else
{
st.newLine() << " " << pix << ".rgb = res;";
st.newLine() << pix << ".rgb = res;";
}
st.dedent();
st.newLine() << "}"; // else if (mtest > 1.)
st.dedent();
@@ -1260,7 +1260,7 @@ void Add_SContrastTopPre_Shader(GpuShaderCreatorRcPtr & shaderCreator,
st.newLine() << st.floatKeywordConst() << " pivot = " << std::to_string(pivot) << ";";
st.newLine() << st.float3Decl("t") << " = " << pix << ".rgb;";
st.newLine() << st.colorDecl("t") << " = " << pix << ".rgb;";
// Top end
st.newLine() << "{"; // establish scope so local variable names won't conflict
@@ -1341,28 +1341,28 @@ void Add_SContrastFwd_Shader(GpuShaderCreatorRcPtr & shaderCreator,
st.newLine() << pix << ".rgb = (t - pivot) * contrast + pivot;";
st.newLine() << st.float3Decl("tR") << " = (t - x1) / (x2 - x1);";
st.newLine() << st.float3Decl("res") << " = tR * (x2 - x1) * ( tR * 0.5 * (m3 - m0) + m0 ) + y1;";
st.newLine() << st.colorDecl("res") << " = tR * (x2 - x1) * ( tR * 0.5 * (m3 - m0) + m0 ) + y1;";
st.newLine() << pix << ".rgb.r = (t.x > x1) ? res.x : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.y > x1) ? res.y : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.z > x1) ? res.z : " << pix << ".rgb.b;";
st.newLine() << pix << ".rgb.r = (t.x > x2) ? y2 + (t.x - x2) * m3 : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.y > x2) ? y2 + (t.y - x2) * m3 : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.z > x2) ? y2 + (t.z - x2) * m3 : " << pix << ".rgb.b;";
st.newLine() << pix << ".rgb.r = (t.r > x1) ? res.r : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.g > x1) ? res.g : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.b > x1) ? res.b : " << pix << ".rgb.b;";
st.newLine() << pix << ".rgb.r = (t.r > x2) ? y2 + (t.r - x2) * m3 : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.g > x2) ? y2 + (t.g - x2) * m3 : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.b > x2) ? y2 + (t.b - x2) * m3 : " << pix << ".rgb.b;";
st.dedent();
st.newLine() << "}"; // end local scope
Add_SContrastBottomPre_Shader(st, style);
st.newLine() << st.float3Decl("tR") << " = (t - x1) / (x2 - x1);";
st.newLine() << st.float3Decl("res") << " = tR * (x2 - x1) * ( tR * 0.5 * (m3 - m0) + m0 ) + y1;";
st.newLine() << st.colorDecl("res") << " = tR * (x2 - x1) * ( tR * 0.5 * (m3 - m0) + m0 ) + y1;";
st.newLine() << pix << ".rgb.r = (t.x < x2) ? res.x : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.y < x2) ? res.y : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.z < x2) ? res.z : " << pix << ".rgb.b;";
st.newLine() << pix << ".rgb.r = (t.x < x1) ? y1 + (t.x - x1) * m0 : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.y < x1) ? y1 + (t.y - x1) * m0 : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.z < x1) ? y1 + (t.z - x1) * m0 : " << pix << ".rgb.b;";
st.newLine() << pix << ".rgb.r = (t.r < x2) ? res.r : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.g < x2) ? res.g : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.b < x2) ? res.b : " << pix << ".rgb.b;";
st.newLine() << pix << ".rgb.r = (t.r < x1) ? y1 + (t.r - x1) * m0 : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.g < x1) ? y1 + (t.g - x1) * m0 : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.b < x1) ? y1 + (t.b - x1) * m0 : " << pix << ".rgb.b;";
st.dedent();
st.newLine() << "}"; // end local scope
@@ -1385,14 +1385,14 @@ void Add_SContrastRev_Shader(GpuShaderCreatorRcPtr & shaderCreator,
st.newLine() << st.floatDecl("b") << " = m0 * (x2 - x1);";
st.newLine() << st.floatDecl("a") << " = (m3 - m0) * 0.5 * (x2 - x1);";
st.newLine() << st.float3Decl("discrim") << " = sqrt( b * b - 4. * a * c );";
st.newLine() << st.float3Decl("res") << " = (x2 - x1) * (-2. * c) / ( discrim + b ) + x1;";
st.newLine() << st.colorDecl("res") << " = (x2 - x1) * (-2. * c) / ( discrim + b ) + x1;";
st.newLine() << pix << ".rgb.r = (t.x > y1) ? res.x : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.y > y1) ? res.y : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.z > y1) ? res.z : " << pix << ".rgb.b;";
st.newLine() << pix << ".rgb.r = (t.x > y2) ? x2 + (t.x - y2) / m3 : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.y > y2) ? x2 + (t.y - y2) / m3 : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.z > y2) ? x2 + (t.z - y2) / m3 : " << pix << ".rgb.b;";
st.newLine() << pix << ".rgb.r = (t.r > y1) ? res.r : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.g > y1) ? res.g : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.b > y1) ? res.b : " << pix << ".rgb.b;";
st.newLine() << pix << ".rgb.r = (t.r > y2) ? x2 + (t.r - y2) / m3 : " << pix << ".rgb.r;";
st.newLine() << pix << ".rgb.g = (t.g > y2) ? x2 + (t.g - y2) / m3 : " << pix << ".rgb.g;";
st.newLine() << pix << ".rgb.b = (t.b > y2) ? x2 + (t.b - y2) / m3 : " << pix << ".rgb.b;";
st.dedent();
st.newLine() << "}"; // end local scope
@@ -1402,14 +1402,14 @@ void Add_SContrastRev_Shader(GpuShaderCreatorRcPtr & shaderCreator,
st.newLine() << st.floatDecl("b") << " = m0 * (x2 - x1);";
st.newLine() << st.floatDecl("a") << " = (m3 - m0) * 0.5 * (x2 - x1);";
st.newLine() << st.float3Decl("discrim") << " = sqrt( b * b - 4. * a * c );";
st.newLine() << st.float3Decl("res") << " = (x2 - x1) * (-2. * c) / ( discrim + b ) + x1;";
st.newLine() << st.colorDecl("res") << " = (x2 - x1) * (-2. * c) / ( discrim + b ) + x1;";
st.newLine() << pix << ".rgb.r = (t.x > y2) ? " << pix << ".rgb.r : res.x;";
st.newLine() << pix << ".rgb.g = (t.y > y2) ? " << pix << ".rgb.g : res.y;";
st.newLine() << pix << ".rgb.b = (t.z > y2) ? " << pix << ".rgb.b : res.z;";
st.newLine() << pix << ".rgb.r = (t.x > y1) ? " << pix << ".rgb.r : x1 + (t.x - y1) / m0;";
st.newLine() << pix << ".rgb.g = (t.y > y1) ? " << pix << ".rgb.g : x1 + (t.y - y1) / m0;";
st.newLine() << pix << ".rgb.b = (t.z > y1) ? " << pix << ".rgb.b : x1 + (t.z - y1) / m0;";
st.newLine() << pix << ".rgb.r = (t.r > y2) ? " << pix << ".rgb.r : res.r;";
st.newLine() << pix << ".rgb.g = (t.g > y2) ? " << pix << ".rgb.g : res.g;";
st.newLine() << pix << ".rgb.b = (t.b > y2) ? " << pix << ".rgb.b : res.b;";
st.newLine() << pix << ".rgb.r = (t.r > y1) ? " << pix << ".rgb.r : x1 + (t.r - y1) / m0;";
st.newLine() << pix << ".rgb.g = (t.g > y1) ? " << pix << ".rgb.g : x1 + (t.g - y1) / m0;";
st.newLine() << pix << ".rgb.b = (t.b > y1) ? " << pix << ".rgb.b : x1 + (t.b - y1) / m0;";
st.dedent();
st.newLine() << "}"; // end local scope
@@ -1528,7 +1528,7 @@ void AddGTInverseShader(GpuShaderCreatorRcPtr & shaderCreator,
void GetGradingToneGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
ConstGradingToneOpDataRcPtr & gtData)
{
const bool dyn = gtData->isDynamic();
const bool dyn = gtData->isDynamic() && shaderCreator->getLanguage() != LANGUAGE_OSL_1;
if (!dyn)
{
auto propGT = gtData->getDynamicPropertyInternal();
@@ -1538,6 +1538,16 @@ void GetGradingToneGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
}
}
if (gtData->isDynamic() && shaderCreator->getLanguage() == LANGUAGE_OSL_1)
{
std::string msg("The dynamic properties are not yet supported by the 'Open Shading language"\
" (OSL)' translation: The '");
msg += opPrefix;
msg += "' dynamic property is replaced by a local variable.";
LogWarning(msg);
}
const GradingStyle style = gtData->getStyle();
const TransformDirection dir = gtData->getDirection();
@@ -1555,7 +1565,7 @@ void GetGradingToneGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
// Properties holds shader variables names and is initialized with undecorated names suitable
// for local variables.
GTProperties properties;
AddGTProperties(shaderCreator, st, gtData, properties);
AddGTProperties(shaderCreator, st, gtData, properties, dyn);
if (dyn)
{
+3 -10
View File
@@ -107,16 +107,9 @@ private:
// special case 16f/64k 1D LUT.
struct IndexPair
{
unsigned short valA;
unsigned short valB;
float fraction;
IndexPair()
{
valA = 0;
valB = 0;
fraction = 0.0f;
}
unsigned short valA = 0;
unsigned short valB = 0;
float fraction = 0.0f;
static IndexPair GetEdgeFloatValues(float fIn);
};
+8 -3
View File
@@ -201,9 +201,12 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
// Add the LUT code to the OCIO shader program.
if (height > 1 || lutData->isInputHalfDomain())
if (height > 1 || lutData->isInputHalfDomain()
|| shaderCreator->getLanguage() == GPU_LANGUAGE_GLSL_ES_1_0
|| shaderCreator->getLanguage() == GPU_LANGUAGE_GLSL_ES_3_0)
{
// In case the 1D LUT length exceeds the 1D texture maximum length
// In case the 1D LUT length exceeds the 1D texture maximum length,
// or the language doesn't support 1D textures,
// a 2D texture is used.
{
@@ -321,7 +324,9 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
ss.newLine() << "";
}
if (height > 1 || lutData->isInputHalfDomain())
if (height > 1 || lutData->isInputHalfDomain()
|| shaderCreator->getLanguage() == GPU_LANGUAGE_GLSL_ES_1_0
|| shaderCreator->getLanguage() == GPU_LANGUAGE_GLSL_ES_3_0)
{
const std::string str = name + "_computePos(" + shaderCreator->getPixelName();
+11 -8
View File
@@ -38,23 +38,26 @@ void GetMatrixGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator, ConstMatri
if (matrix->isDiagonal())
{
ss.newLine() << "res = "
<< ss.float4Const((float)values[0],
(float)values[5],
(float)values[10],
(float)values[15])
<< " * res;";
<< ss.float4Const((float)values[0],
(float)values[5],
(float)values[10],
(float)values[15])
<< " * res;";
}
else
{
ss.newLine() << "res = " << ss.mat4fMul(&values[0], "res") << ";";
// NOTE: The in-place matrix computation is not supported by OSL so,
// a temporary variable is needed.
ss.newLine() << ss.float4Decl("tmp") << " = res;";
ss.newLine() << "res = " << ss.mat4fMul(&values[0], "tmp") << ";";
}
}
if (matrix->hasOffsets())
{
ss.newLine() << "res = "
<< ss.float4Const((float)offs[0], (float)offs[1], (float)offs[2], (float)offs[3])
<< " + res;";
<< ss.float4Const((float)offs[0], (float)offs[1], (float)offs[2], (float)offs[3])
<< " + res;";
}
ss.newLine() << pxl << ".rgb = " << ss.float3Const("res.x", "res.y", "res.z") << ";";
+1 -1
View File
@@ -38,7 +38,7 @@ BEGIN
VALUE "LegalCopyright", ""
VALUE "LegalTrademarks1", ""
VALUE "LegalTrademarks2", ""
VALUE "OriginalFilename", "@PROJECT_NAME@@OCIO_LIBNAME_SUFFIX@@LIBNAME_SUFFIX@.dll"
VALUE "OriginalFilename", "@PROJECT_NAME@@OCIO_LIBNAME_SUFFIX@_@OpenColorIO_VERSION_MAJOR@_@OpenColorIO_VERSION_MINOR@@LIBNAME_SUFFIX@.dll"
VALUE "ProductName", "@PROJECT_NAME@"
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
END
+4 -2
View File
@@ -546,7 +546,8 @@ void LoadFileUncached(FileFormat * & returnFormat,
try
{
// Open the filePath
filestream.open(
Platform::OpenInputFileStream(
filestream,
filepath.c_str(),
tryFormat->isBinary()
? std::ios_base::binary : std::ios_base::in);
@@ -618,7 +619,8 @@ void LoadFileUncached(FileFormat * & returnFormat,
std::ifstream filestream;
try
{
filestream.open(filepath.c_str(), altFormat->isBinary()
Platform::OpenInputFileStream(
filestream, filepath.c_str(), altFormat->isBinary()
? std::ios_base::binary : std::ios_base::in);
if (!filestream.good())
{
+1 -1
View File
@@ -8,7 +8,7 @@ if(OCIO_BUILD_APPS)
add_subdirectory(ociomakeclf)
add_subdirectory(ociowrite)
if(TARGET OpenImageIO::OpenImageIO)
if(OpenImageIO_FOUND AND TARGET OpenImageIO::OpenImageIO)
add_subdirectory(ociolutimage)
add_subdirectory(ocioconvert)
add_subdirectory(ociodisplay)
+1 -1
View File
@@ -40,5 +40,5 @@ target_link_libraries(ociobakelut
)
install(TARGETS ociobakelut
RUNTIME DESTINATION bin
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
+1 -1
View File
@@ -28,5 +28,5 @@ target_link_libraries(ociocheck
)
install(TARGETS ociocheck
RUNTIME DESTINATION bin
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
+1 -1
View File
@@ -36,5 +36,5 @@ target_link_libraries(ociochecklut
)
install(TARGETS ociochecklut
RUNTIME DESTINATION bin
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
+1 -2
View File
@@ -27,7 +27,6 @@ set_target_properties(ocioconvert PROPERTIES
target_link_libraries(ocioconvert
PRIVATE
apputils
${OCIO_HALF_LIB}
${OCIO_GL_LIB}
oiiohelpers
OpenColorIO
@@ -35,5 +34,5 @@ target_link_libraries(ocioconvert
)
install(TARGETS ocioconvert
RUNTIME DESTINATION bin
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
+21 -1
View File
@@ -13,6 +13,16 @@ namespace OCIO = OCIO_NAMESPACE;
#include <OpenImageIO/imageio.h>
#include <OpenImageIO/typedesc.h>
// Take the half.h the same way OpenImageIO takes it i.e. do not use the Imath/OpenEXR one from
// OpenColorIO to avoid version clashes between OpenColorIO & OpenImageIO libraries. For example,
// OpenColorIO uses Imath 3.1.x but OpenImageIO (from the system) is using Imath 3.0.x which
// breaks the OpenColorIO compilation.
#if (OIIO_VERSION >= 20200)
# include <OpenImageIO/Imath.h>
#else
# include <OpenEXR/half.h>
#endif
#if (OIIO_VERSION < 10100)
namespace OIIO = OIIO_NAMESPACE;
#endif
@@ -24,7 +34,6 @@ namespace OIIO = OIIO_NAMESPACE;
#endif // OCIO_GPU_ENABLED
#include "oiiohelpers.h"
#include "utils/Half.h"
// Array of non OpenColorIO arguments.
@@ -616,6 +625,17 @@ int main(int argc, const char **argv)
exit(1);
}
if (useDisplayView)
{
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
outputcolorspace = config->getDisplayViewColorSpaceName(display, view);
}
if (outputcolorspace)
{
spec.attribute("oiio:ColorSpace", outputcolorspace);
}
f->open(outputimage, spec);
if(!f->write_image(spec.format, img.getBuffer()))
+1 -1
View File
@@ -45,5 +45,5 @@ target_link_libraries(ociodisplay
OpenImageIO::OpenImageIO
)
install(TARGETS ociodisplay
RUNTIME DESTINATION bin
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
+1 -1
View File
@@ -26,5 +26,5 @@ target_link_libraries(ociolutimage
)
install(TARGETS ociolutimage
RUNTIME DESTINATION bin
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
+1 -1
View File
@@ -29,5 +29,5 @@ target_link_libraries(ociomakeclf
)
install(TARGETS ociomakeclf
RUNTIME DESTINATION bin
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
+1 -3
View File
@@ -20,7 +20,6 @@ set_target_properties(ocioperf PROPERTIES
target_link_libraries(ocioperf
PRIVATE
apputils
${OCIO_HALF_LIB}
oiiohelpers
OpenColorIO
OpenImageIO::OpenImageIO
@@ -28,6 +27,5 @@ target_link_libraries(ocioperf
)
install(TARGETS ocioperf
RUNTIME DESTINATION bin
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
-1
View File
@@ -12,7 +12,6 @@ namespace OIIO = OIIO_NAMESPACE;
#include "apputils/argparse.h"
#include "oiiohelpers.h"
#include "utils/Half.h"
#include "utils/StringUtils.h"
+1 -2
View File
@@ -24,6 +24,5 @@ target_link_libraries(ociowrite
)
install(TARGETS ociowrite
RUNTIME DESTINATION bin
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
+38
View File
@@ -0,0 +1,38 @@
<!-- SPDX-License-Identifier: CC-BY-4.0 -->
<!-- Copyright Contributors to the OpenColorIO Project. -->
pyociodisplay
=============
**Work in progress**. Minimal image viewer implementation demonstrating use of
the OCIO GPU renderer in a Python application.
Usage
-----
1. Install dependencies on ``PYTHONPATH``
2. Run ``python pyociodisplay.py``
3. Load image with ``File/Load image...`` menu item
Dependencies
------------
* PyOpenColorIO
* [OpenImageIO (Python bindings)](https://github.com/OpenImageIO/oiio)
* [Imath (Python bindings)](https://github.com/AcademySoftwareFoundation/Imath)
* ``pip install requirements.txt``
* [numpy](https://pypi.org/project/numpy/)
* [PyOpenGL](https://pypi.org/project/PyOpenGL/)
* [PySide2](https://pypi.org/project/PySide2/)
Implementation notes
--------------------
* Assumes the ``OCIO`` environment variable is defined and pointing to a
compatible OCIO config file.
* Takes into account file and viewing rules, and may change the input color
space and/or view automatically when a new image is loaded.
* Exposure and gamma controls are dynamic parameters, driving uniforms in the
generated shader program.
* Specific channel views can be toggled with R, G, B, A keys, and the RGBA view
restored with C.
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
numpy
PyOpenGL
PySide2
+1 -1
View File
@@ -155,7 +155,7 @@ set_target_properties(OpenColorIO-JNI
# Installation
install(TARGETS OpenColorIO-JNI
DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/lib${LIB_SUFFIX}
DESTINATION ${CMAKE_INSTALL_EXEC_PREFIX}/${CMAKE_INSTALL_LIBDIR}
)
install(FILES ${JNIOCIO_JAR}
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/ocio/
+6 -6
View File
@@ -203,14 +203,14 @@ target_include_directories(PyOpenColorIO
# macOS, to prevent segfaults when potentially working with multiple Python
# installations. See note in:
# https://pybind11.readthedocs.io/en/stable/compiling.html#building-manually
set(PYOCIO_LINK_PUBLIC OpenColorIOHeaders)
if(WIN32)
list(INSERT PYOCIO_LINK_PUBLIC 0 ${Python_LIBRARIES})
if (WIN32)
set(_PublicLibs ${Python_LIBRARIES})
endif()
target_link_libraries(PyOpenColorIO
PUBLIC
${PYOCIO_LINK_PUBLIC}
${_PublicLibs}
PRIVATE
OpenColorIO
utils::strings
@@ -226,9 +226,9 @@ target_compile_definitions(PyOpenColorIO
)
if(WIN32)
set(_Python_VARIANT_PATH "lib${LIB_SUFFIX}/site-packages")
set(_Python_VARIANT_PATH "${CMAKE_INSTALL_LIBDIR}/site-packages")
else()
set(_Python_VARIANT_PATH "lib${LIB_SUFFIX}/python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/site-packages")
set(_Python_VARIANT_PATH "${CMAKE_INSTALL_LIBDIR}/python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/site-packages")
endif()
# Create an internal global variable to access it in another scope but not publicly visible
+2 -2
View File
@@ -117,7 +117,7 @@ void bindPyGpuShaderDesc(py::module & m)
const py::buffer & values)
{
py::buffer_info info = values.request();
ssize_t numChannels;
py::ssize_t numChannels;
switch (channel)
{
@@ -252,7 +252,7 @@ void bindPyGpuShaderDesc(py::module & m)
const float * values;
self.m_shaderDesc->getTextureValues(self.m_index, values);
ssize_t numChannels;
py::ssize_t numChannels;
switch (self.m_channel)
{
case GpuShaderDesc::TEXTURE_RED_CHANNEL:
+4
View File
@@ -514,6 +514,10 @@ void bindPyTypes(py::module & m)
DOC(PyOpenColorIO, GpuLanguage, GPU_LANGUAGE_GLSL_1_3))
.value("GPU_LANGUAGE_GLSL_4_0", GPU_LANGUAGE_GLSL_4_0,
DOC(PyOpenColorIO, GpuLanguage, GPU_LANGUAGE_GLSL_4_0))
.value("GPU_LANGUAGE_GLSL_ES_1_0", GPU_LANGUAGE_GLSL_ES_1_0,
DOC(PyOpenColorIO, GpuLanguage, GPU_LANGUAGE_GLSL_ES_1_0))
.value("GPU_LANGUAGE_GLSL_ES_3_0", GPU_LANGUAGE_GLSL_ES_3_0,
DOC(PyOpenColorIO, GpuLanguage, GPU_LANGUAGE_GLSL_ES_3_0))
.value("GPU_LANGUAGE_HLSL_DX11", GPU_LANGUAGE_HLSL_DX11,
DOC(PyOpenColorIO, GpuLanguage, GPU_LANGUAGE_HLSL_DX11))
.export_values();
+4 -4
View File
@@ -23,7 +23,7 @@ const std::vector<std::string> FLOAT_FORMATS = { "e", "f", "d", "g", "Ze", "Zf",
} // namespace
std::string formatCodeToDtypeName(const std::string & format, ssize_t numBits)
std::string formatCodeToDtypeName(const std::string & format, py::ssize_t numBits)
{
std::ostringstream os;
@@ -85,7 +85,7 @@ py::dtype bitDepthToDtype(BitDepth bitDepth)
return py::dtype(name);
}
ssize_t bitDepthToBytes(BitDepth bitDepth)
py::ssize_t bitDepthToBytes(BitDepth bitDepth)
{
std::string name, err;
@@ -179,7 +179,7 @@ void checkBufferType(const py::buffer_info & info, BitDepth bitDepth)
checkBufferType(info, bitDepthToDtype(bitDepth));
}
void checkBufferDivisible(const py::buffer_info & info, ssize_t numChannels)
void checkBufferDivisible(const py::buffer_info & info, py::ssize_t numChannels)
{
if (info.size % numChannels != 0)
{
@@ -190,7 +190,7 @@ void checkBufferDivisible(const py::buffer_info & info, ssize_t numChannels)
}
}
void checkBufferSize(const py::buffer_info & info, ssize_t numEntries)
void checkBufferSize(const py::buffer_info & info, py::ssize_t numEntries)
{
if (info.size != numEntries)
{
+4 -4
View File
@@ -61,11 +61,11 @@ private:
};
// Convert Python buffer protocol format code to NumPy dtype name
std::string formatCodeToDtypeName(const std::string & format, ssize_t numBits);
std::string formatCodeToDtypeName(const std::string & format, py::ssize_t numBits);
// Convert OCIO BitDepth to NumPy dtype
py::dtype bitDepthToDtype(BitDepth bitDepth);
// Convert OCIO BitDepth to data type byte count
ssize_t bitDepthToBytes(BitDepth bitDepth);
py::ssize_t bitDepthToBytes(BitDepth bitDepth);
// Convert OCIO ChannelOrdering to channel count
long chanOrderToNumChannels(ChannelOrdering chanOrder);
@@ -79,9 +79,9 @@ void checkBufferType(const py::buffer_info & info, const py::dtype & dt);
// Throw if Python buffer format is incompatible with an OCIO BitDepth
void checkBufferType(const py::buffer_info & info, BitDepth bitDepth);
// Throw if Python buffer size is not divisible by channel count
void checkBufferDivisible(const py::buffer_info & info, ssize_t numChannels);
void checkBufferDivisible(const py::buffer_info & info, py::ssize_t numChannels);
// Throw if Python buffer does not have an exact count of entries
void checkBufferSize(const py::buffer_info & info, ssize_t numEntries);
void checkBufferSize(const py::buffer_info & info, py::ssize_t numEntries);
// Calculate 3D grid size from a packed 3D LUT buffer
unsigned long getBufferLut3DGridSize(const py::buffer_info & info);
@@ -113,7 +113,7 @@ void bindPyLut1DTransform(py::module & m)
py::gil_scoped_acquire acquire;
return py::array(py::dtype("float32"),
{ static_cast<ssize_t>(values.size()) },
{ static_cast<py::ssize_t>(values.size()) },
{ sizeof(float) },
values.data());
})
@@ -128,7 +128,7 @@ void bindPyLut3DTransform(py::module & m)
py::gil_scoped_acquire acquire;
return py::array(py::dtype("float32"),
{ static_cast<ssize_t>(values.size()) },
{ static_cast<py::ssize_t>(values.size()) },
{ sizeof(float) },
values.data());
})
+3 -3
View File
@@ -90,10 +90,10 @@ if(${OCIO_EGL_HEADLESS})
endif()
install(TARGETS oglapphelpers
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(FILES ${INCLUDES}
DESTINATION include/OpenColorIO/oglapphelpers
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/OpenColorIO/oglapphelpers
)
+17 -7
View File
@@ -444,17 +444,27 @@ void OpenGLBuilder::useAllUniforms()
std::string OpenGLBuilder::getGLSLVersionString()
{
if (m_shaderDesc->getLanguage() == GPU_LANGUAGE_GLSL_1_3)
switch (m_shaderDesc->getLanguage())
{
case GPU_LANGUAGE_GLSL_1_2:
// That's the minimal version supported.
return "#version 120";
case GPU_LANGUAGE_GLSL_1_3:
return "#version 130";
}
else if (m_shaderDesc->getLanguage() == GPU_LANGUAGE_GLSL_4_0)
{
case GPU_LANGUAGE_GLSL_4_0:
return "#version 400 core";
case GPU_LANGUAGE_GLSL_ES_1_0:
return "#version 100";
case GPU_LANGUAGE_GLSL_ES_3_0:
return "#version 300 es";
case GPU_LANGUAGE_CG:
case GPU_LANGUAGE_HLSL_DX11:
case LANGUAGE_OSL_1:
default:
// These are all impossible in OpenGL contexts.
// The shader will be unusable, so let's throw
throw Exception("Invalid shader language for OpenGLBuilder");
}
// That's the minimal version supported.
return "#version 120";
}
unsigned OpenGLBuilder::buildProgram(const std::string & clientShaderProgram)
+3 -4
View File
@@ -31,15 +31,14 @@ target_link_libraries(oiiohelpers
PRIVATE
OpenColorIO
${OCIO_HALF_LIB}
utils::strings
)
install(TARGETS oiiohelpers
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/oiiohelpers.h
DESTINATION include/OpenColorIO/oiiohelpers
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/OpenColorIO/oiiohelpers
)
-1
View File
@@ -6,7 +6,6 @@
#include "oiiohelpers.h"
#include "utils/Half.h"
#include "utils/StringUtils.h"
+13 -24
View File
@@ -7,8 +7,7 @@ if(OCIO_BUILD_TESTS OR OCIO_BUILD_GPU_TESTS OR OCIO_BUILD_PYTHON)
endif()
if(OCIO_BUILD_TESTS)
# Test order is from low-level (i.e. no dependencies)
# to high-level layers.
# Test order is from low-level (i.e. no dependencies) to high-level layers.
add_subdirectory(testutils)
add_subdirectory(utils)
add_subdirectory(cpu)
@@ -19,31 +18,21 @@ if(OCIO_BUILD_GPU_TESTS)
add_subdirectory(gpu)
endif()
if(TARGET OpenImageIO::OpenImageIO)
# Running the OSL unit tests requires OSL which imposes OIIO and Imath.
# OpenShadingLanguage
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
find_package(OpenShadingLanguage 1.11)
if(NOT OSL_FOUND)
message(WARNING "Could NOT find OpenShadingLanguage. Skipping build the OSL unit tests")
endif()
if(OCIO_USE_OPENEXR_HALF)
# Imath
# https://github.com/AcademySoftwareFoundation/Imath
find_package(Imath 3)
if(NOT Imath_FOUND)
message(WARNING "Could NOT find Imath. Skipping build the OSL unit tests")
if(OpenImageIO_FOUND AND TARGET OpenImageIO::OpenImageIO)
if(TARGET Imath::Imath)
# OpenShadingLanguage
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
find_package(OpenShadingLanguage 1.11)
if(OSL_FOUND)
add_subdirectory(osl)
else()
message(WARNING "Could NOT find OpenShadingLanguage. Skipping build of the OSL unit tests")
endif()
endif()
if(OSL_FOUND AND Imath_FOUND)
add_subdirectory(osl)
else()
message(WARNING "Could NOT find Imath. Skipping build of the OSL unit tests")
endif()
else()
message(WARNING "Could NOT find OpenImageIO. Skipping build the OSL unit tests")
message(WARNING "Could NOT find OpenImageIO. Skipping build of the OSL unit tests")
endif()
if(OCIO_BUILD_JAVA)
+11 -5
View File
@@ -11,12 +11,10 @@ function(add_ocio_test NAME SOURCES PRIVATE_INCLUDES)
target_compile_definitions(${TEST_BINARY}
PRIVATE
OpenColorIO_SKIP_IMPORTS
)
target_link_libraries(${TEST_BINARY}
PUBLIC
OpenColorIOHeaders
PRIVATE
OpenColorIO
expat::expat
${OCIO_HALF_LIB}
pystring::pystring
@@ -39,7 +37,6 @@ function(add_ocio_test NAME SOURCES PRIVATE_INCLUDES)
if(PRIVATE_INCLUDES)
target_include_directories(${TEST_BINARY}
PRIVATE
"${CMAKE_SOURCE_DIR}/src/OpenColorIO"
"${CMAKE_SOURCE_DIR}/tests/cpu"
)
endif(PRIVATE_INCLUDES)
@@ -56,11 +53,20 @@ function(add_ocio_test NAME SOURCES PRIVATE_INCLUDES)
PRIVATE
XML_STATIC
)
if (OCIO_USE_WINDOWS_UNICODE)
# Add Unicode definitions to use Unicode functions
target_compile_definitions(${TEST_BINARY}
PRIVATE
UNICODE
_UNICODE
)
endif()
endif(WIN32)
set_target_properties(${TEST_BINARY} PROPERTIES
COMPILE_FLAGS "${PLATFORM_COMPILE_FLAGS}")
add_test(${TEST_NAME} ${TEST_BINARY})
add_test(NAME ${TEST_NAME} COMMAND ${TEST_BINARY})
endfunction(add_ocio_test)
# Eventually we will factor out each test into it's own executable
+161 -4
View File
@@ -1433,9 +1433,97 @@ OCIO_ADD_TEST(Config, context_variable_with_display_view)
}
}
OCIO_ADD_TEST(Config, context_variable_with_search_path)
OCIO_ADD_TEST(Config, context_variable_with_search_path_v1)
{
// Test a search_path pointing to a context variable.
// Test a search_path containing a context variable for a v1 config file.
// Note: The config validation does not check the path existence, it checks only if the path can
// be successfully resolved. But the processor creation needs to have at least one existing path.
// That's why the tests below check for the config validation and the processor creation.
static const std::string CONFIG =
"ocio_profile_version: 1\n"
"\n"
"search_path: $ENV1\n"
"\n"
"roles:\n"
" default: cs1\n"
" reference: cs1\n"
"\n"
"displays:\n"
" disp1:\n"
" - !<View> {name: view1, colorspace: cs2}\n"
"\n"
"colorspaces:\n"
" - !<ColorSpace>\n"
" name: cs1\n"
"\n"
" - !<ColorSpace>\n"
" name: cs2\n"
" from_reference: !<FileTransform> {src: lut1d_green.ctf}\n";
std::istringstream iss;
iss.str(CONFIG);
// $ENV1 is missing.
OCIO::ConfigRcPtr cfg;
OCIO_CHECK_NO_THROW(cfg = OCIO::Config::CreateFromStream(iss)->createEditableCopy());
OCIO_CHECK_THROW_WHAT(cfg->validate(), OCIO::Exception,
"The search_path '$ENV1' cannot be resolved.");
#ifdef _WIN32
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
"The specified file reference 'lut1d_green.ctf' could not be located. "
"The following attempts were made: '$ENV1\\lut1d_green.ctf'.");
#else
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
"The specified file reference 'lut1d_green.ctf' could not be located. "
"The following attempts were made: '$ENV1/lut1d_green.ctf'.");
#endif
// $ENV1 now exists.
OCIO_CHECK_NO_THROW(cfg->addEnvironmentVar("ENV1", OCIO::GetTestFilesDir().c_str()));
OCIO_CHECK_NO_THROW(cfg->validate());
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
// $ENV1 is faulty.
OCIO_CHECK_NO_THROW(cfg->addEnvironmentVar("ENV1", "faulty/path"));
OCIO_CHECK_NO_THROW(cfg->validate()); // Success because there is at least one resolved path.
#ifdef _WIN32
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
"The specified file reference 'lut1d_green.ctf' could not be located. "
"The following attempts were made: 'faulty\\path\\lut1d_green.ctf'.");
#else
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
"The specified file reference 'lut1d_green.ctf' could not be located. "
"The following attempts were made: 'faulty/path/lut1d_green.ctf'.");
#endif
OCIO_CHECK_NO_THROW(cfg->addEnvironmentVar("ENV1", nullptr));
{
// Change the search_path to have at least one successful path i.e. the first one.
const std::string searchPath = OCIO::GetTestFilesDir() + ":$ENV1";
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
OCIO_CHECK_NO_THROW(cfg->validate());
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
}
{
// Change the search_path to have at least one successful path i.e. the second one.
const std::string searchPath = "$ENV1:" + OCIO::GetTestFilesDir();
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
OCIO_CHECK_NO_THROW(cfg->validate());
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
}
}
OCIO_ADD_TEST(Config, context_variable_with_search_path_v2)
{
// Test a search_path containing a context variable for a v2 config file.
// Note: The config validation does not check the path existence, it checks only if the path can
// be successfully resolved. But the processor creation needs to have at least one existing path.
// That's why the tests below check for the config validation and the processor creation.
static const std::string CONFIG =
"ocio_profile_version: 2\n"
@@ -1463,19 +1551,88 @@ OCIO_ADD_TEST(Config, context_variable_with_search_path)
std::istringstream iss;
iss.str(CONFIG);
// $ENV1 exists in the config itself.
OCIO::ConfigRcPtr cfg;
OCIO_CHECK_NO_THROW(cfg = OCIO::Config::CreateFromStream(iss)->createEditableCopy());
OCIO_CHECK_NO_THROW(cfg->validate());
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
/// Remove the context variable.
/// Remove the context variable so, there is no more successful path.
OCIO_CHECK_NO_THROW(cfg->addEnvironmentVar("ENV1", nullptr));
OCIO_CHECK_THROW_WHAT(cfg->validate(), OCIO::Exception,
"The search_path '$ENV1' cannot be resolved.");
#ifdef _WIN32
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
"The specified file reference 'lut1d_green.ctf' could not be located. ");
"The specified file reference 'lut1d_green.ctf' could not be located. "
"The following attempts were made: '$ENV1\\lut1d_green.ctf'.");
#else
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
"The specified file reference 'lut1d_green.ctf' could not be located. "
"The following attempts were made: '$ENV1/lut1d_green.ctf'.");
#endif
// The following tests validate that in a list of search paths at least one can be resolved.
{
// Change the search_path to have at least one successful path i.e. the first one.
const std::string searchPath = OCIO::GetTestFilesDir() + ":$ENV1";
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
OCIO_CHECK_NO_THROW(cfg->validate());
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
}
{
// Change the search_path to have at least one successful path i.e. the second one.
const std::string searchPath = "$ENV1:" + OCIO::GetTestFilesDir();
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
OCIO_CHECK_NO_THROW(cfg->validate());
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
}
{
// Change the search_path to have at least one successful path i.e. the first one.
const std::string searchPath = OCIO::GetTestFilesDir() + ":";
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
OCIO_CHECK_NO_THROW(cfg->validate());
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
}
{
// Change the search_path to have at least one successful path i.e. the second one.
const std::string searchPath = ":" + OCIO::GetTestFilesDir();
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
OCIO_CHECK_NO_THROW(cfg->validate());
OCIO_CHECK_NO_THROW(cfg->getProcessor("cs1", "cs2"));
}
// The following test highlights the difference between the validation and the processor
// creation related to the search paths i.e. resolved vs. existing search paths.
{
// Change the search_path to have at least one potentially successful path
// i.e. the second one.
const std::string searchPath = "$ENV1:faulty/path";
OCIO_CHECK_NO_THROW(cfg->setSearchPath(searchPath.c_str()));
// The validation succeeds because the first path does not resolve but the second path does.
OCIO_CHECK_NO_THROW(cfg->validate());
// The first path does not resolve and the second path does resolve but it does not exist
// so the processor creation fails.
#ifdef _WIN32
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
"The specified file reference 'lut1d_green.ctf' could not be located. "
"The following attempts were made: "
"'$ENV1\\lut1d_green.ctf' : 'faulty\\path\\lut1d_green.ctf'.");
#else
OCIO_CHECK_THROW_WHAT(cfg->getProcessor("cs1", "cs2"), OCIO::Exception,
"The specified file reference 'lut1d_green.ctf' could not be located. "
"The following attempts were made: "
"'$ENV1/lut1d_green.ctf' : 'faulty/path/lut1d_green.ctf'.");
#endif
}
}
OCIO_ADD_TEST(Config, role_without_colorspace)
+95 -28
View File
@@ -17,17 +17,35 @@ OCIO_ADD_TEST(Platform, envVariable)
// Only validates the public API.
// Complete validations are done below using the private methods.
const char * path = OCIO::GetEnvVariable("PATH");
const char * path = OCIO::GetEnvVariable(u8"PATH");
OCIO_CHECK_ASSERT(path && *path);
OCIO::SetEnvVariable("MY_DUMMY_ENV", "SomeValue");
const char * value = OCIO::GetEnvVariable("MY_DUMMY_ENV");
OCIO::SetEnvVariable(u8"MY_DUMMY_ENV", u8"SomeValue");
const char * value = OCIO::GetEnvVariable(u8"MY_DUMMY_ENV");
OCIO_CHECK_ASSERT(value && *value);
OCIO_CHECK_EQUAL(std::string(value), "SomeValue");
OCIO_CHECK_EQUAL(std::string(value), u8"SomeValue");
OCIO::UnsetEnvVariable("MY_DUMMY_ENV");
value = OCIO::GetEnvVariable("MY_DUMMY_ENV");
#ifdef _WIN32
// Assert that we retrieve the correct value from the Windows API too.
uint32_t win_env_sz = GetEnvironmentVariable(TEXT("MY_DUMMY_ENV"), NULL, 0);
OCIO_CHECK_NE(win_env_sz, 0);
std::tstring win_env_value(win_env_sz, 0);
GetEnvironmentVariable(TEXT("MY_DUMMY_ENV"), &win_env_value[0], win_env_sz);
win_env_value.pop_back(); // Remove null terminator that interferes with comparison
OCIO_CHECK_ASSERT(win_env_value == TEXT("SomeValue"));
#endif
OCIO::UnsetEnvVariable(u8"MY_DUMMY_ENV");
value = OCIO::GetEnvVariable(u8"MY_DUMMY_ENV");
OCIO_CHECK_ASSERT(!value || !*value);
#ifdef _WIN32
// Assert that the variable has been unset from the Windows API too, which will result in
// GetEnvironmentVariable returning 0 and GetLastError returning ERROR_ENVVAR_NOT_FOUND.
OCIO_CHECK_EQUAL(GetEnvironmentVariable(TEXT("MY_DUMMY_ENV"), NULL, 0), 0);
OCIO_CHECK_EQUAL(GetLastError(), ERROR_ENVVAR_NOT_FOUND);
#endif
}
OCIO_ADD_TEST(Platform, getenv)
@@ -52,6 +70,32 @@ OCIO_ADD_TEST(Platform, getenv)
OCIO_CHECK_ASSERT(OCIO::Platform::Getenv("PATH", env));
OCIO_CHECK_ASSERT(!env.empty());
#ifdef _WIN32
// Assert that all results match in Windows API.
// Assert this variable doesn't exist, which will result in GetEnvironmentVariable returning
// 0 and GetLastError returning ERROR_ENVVAR_NOT_FOUND.
OCIO_CHECK_EQUAL(GetEnvironmentVariable(TEXT("NotExistingEnvVariable"), NULL, 0), 0);
OCIO_CHECK_EQUAL(GetLastError(), ERROR_ENVVAR_NOT_FOUND);
// Assert this variable does exist.
OCIO_CHECK_NE(GetEnvironmentVariable(TEXT("PATH"), NULL, 0), 0);
// Create a variable and test that it's retrievable through the Windows API.
OCIO::Platform::Setenv(u8"MY_WINDOWS_DUMMY_ENV", u8"SomeValue");
uint32_t win_env_sz = GetEnvironmentVariable(TEXT("MY_WINDOWS_DUMMY_ENV"), NULL, 0);
OCIO_CHECK_NE(win_env_sz, 0);
std::tstring win_env_value(win_env_sz, 0);
GetEnvironmentVariable(TEXT("MY_WINDOWS_DUMMY_ENV"), &win_env_value[0], win_env_sz);
win_env_value.pop_back(); // Remove null terminator that interferes with comparison
OCIO_CHECK_ASSERT(win_env_value == TEXT("SomeValue"));
OCIO::Platform::Unsetenv(u8"MY_WINDOWS_DUMMY_ENV");
OCIO_CHECK_EQUAL(GetEnvironmentVariable(TEXT("MY_WINDOWS_DUMMY_ENV"), NULL, 0), 0);
OCIO_CHECK_EQUAL(GetLastError(), ERROR_ENVVAR_NOT_FOUND);
#endif
}
OCIO_ADD_TEST(Platform, setenv)
@@ -62,61 +106,61 @@ OCIO_ADD_TEST(Platform, setenv)
Guard() = default;
~Guard()
{
OCIO::Platform::Unsetenv("MY_DUMMY_ENV");
OCIO::Platform::Unsetenv("MY_WINDOWS_DUMMY_ENV");
OCIO::Platform::Unsetenv(u8"MY_DUMMY_ENV");
OCIO::Platform::Unsetenv(u8"MY_WINDOWS_DUMMY_ENV");
}
} guard;
{
OCIO::Platform::Setenv("MY_DUMMY_ENV", "SomeValue");
OCIO::Platform::Setenv(u8"MY_DUMMY_ENV", u8"SomeValue");
std::string env;
OCIO_CHECK_ASSERT(OCIO::Platform::Getenv("MY_DUMMY_ENV", env));
OCIO_CHECK_ASSERT(OCIO::Platform::Getenv(u8"MY_DUMMY_ENV", env));
OCIO_CHECK_ASSERT(!env.empty());
OCIO_CHECK_ASSERT(0==std::strcmp("SomeValue", env.c_str()));
OCIO_CHECK_EQUAL(strlen("SomeValue"), env.size());
OCIO_CHECK_ASSERT(0==std::strcmp(u8"SomeValue", env.c_str()));
OCIO_CHECK_EQUAL(strlen(u8"SomeValue"), env.size());
}
{
OCIO::Platform::Setenv("MY_DUMMY_ENV", " ");
OCIO::Platform::Setenv(u8"MY_DUMMY_ENV", u8" ");
std::string env;
OCIO_CHECK_ASSERT(OCIO::Platform::Getenv("MY_DUMMY_ENV", env));
OCIO_CHECK_ASSERT(OCIO::Platform::Getenv(u8"MY_DUMMY_ENV", env));
OCIO_CHECK_ASSERT(!env.empty());
OCIO_CHECK_ASSERT(0==std::strcmp(" ", env.c_str()));
OCIO_CHECK_EQUAL(std::strlen(" "), env.size());
OCIO_CHECK_ASSERT(0==std::strcmp(u8" ", env.c_str()));
OCIO_CHECK_EQUAL(std::strlen(u8" "), env.size());
}
{
OCIO::Platform::Unsetenv("MY_DUMMY_ENV");
OCIO::Platform::Unsetenv(u8"MY_DUMMY_ENV");
std::string env;
OCIO_CHECK_ASSERT(!OCIO::Platform::Getenv("MY_DUMMY_ENV", env));
OCIO_CHECK_ASSERT(!OCIO::Platform::Getenv(u8"MY_DUMMY_ENV", env));
OCIO_CHECK_ASSERT(env.empty());
}
#ifdef _WIN32
{
SetEnvironmentVariable("MY_WINDOWS_DUMMY_ENV", "1");
SetEnvironmentVariable(TEXT("MY_WINDOWS_DUMMY_ENV"), TEXT("1"));
std::string env;
OCIO_CHECK_ASSERT(OCIO::Platform::Getenv("MY_WINDOWS_DUMMY_ENV", env));
OCIO_CHECK_EQUAL(env, std::string("1"));
OCIO_CHECK_ASSERT(OCIO::Platform::Getenv(u8"MY_WINDOWS_DUMMY_ENV", env));
OCIO_CHECK_EQUAL(env, std::string(u8"1"));
}
{
SetEnvironmentVariable("MY_WINDOWS_DUMMY_ENV", " ");
SetEnvironmentVariable(TEXT("MY_WINDOWS_DUMMY_ENV"), TEXT(" "));
std::string env;
OCIO_CHECK_ASSERT(OCIO::Platform::Getenv("MY_WINDOWS_DUMMY_ENV", env));
OCIO_CHECK_EQUAL(env, std::string(" "));
OCIO_CHECK_ASSERT(OCIO::Platform::Getenv(u8"MY_WINDOWS_DUMMY_ENV", env));
OCIO_CHECK_EQUAL(env, std::string(u8" "));
}
{
// Windows SetEnvironmentVariable() sets the env. variable to empty like
// the Linux ::setenv() in contradiction with the Windows _putenv_s().
SetEnvironmentVariable("MY_WINDOWS_DUMMY_ENV", "");
SetEnvironmentVariable(TEXT("MY_WINDOWS_DUMMY_ENV"), TEXT(""));
std::string env;
OCIO_CHECK_ASSERT(OCIO::Platform::Getenv("MY_WINDOWS_DUMMY_ENV", env));
OCIO_CHECK_ASSERT(OCIO::Platform::Getenv(u8"MY_WINDOWS_DUMMY_ENV", env));
OCIO_CHECK_ASSERT(env.empty());
}
{
SetEnvironmentVariable("MY_WINDOWS_DUMMY_ENV", nullptr);
SetEnvironmentVariable(TEXT("MY_WINDOWS_DUMMY_ENV"), nullptr);
std::string env;
OCIO_CHECK_ASSERT(!OCIO::Platform::Getenv("MY_WINDOWS_DUMMY_ENV", env));
OCIO_CHECK_ASSERT(!OCIO::Platform::Getenv(u8"MY_WINDOWS_DUMMY_ENV", env));
OCIO_CHECK_ASSERT(env.empty());
}
#endif
@@ -160,3 +204,26 @@ OCIO_ADD_TEST(Platform, create_temp_filename)
// Check that it only generates unique random strings.
OCIO_CHECK_EQUAL(uids.size(), TestMax);
}
OCIO_ADD_TEST(Platform, utf8_utf16_convert)
{
#ifdef _WIN32
// Define the same string in both UTF-8 and UTF-16LE encoding:
// - Hiragana letter KO: xe3, x81, x93 x3053
// - Hiragana letter N: xe3, x82, x93 x3093
// - Hiragana letter NI: xe3, x81, xab x306b
// - Hiragana letter CHI: xe3, x81, xa1 x3061
// - Hiragana letter HA/WA: xe3, x81, xaf x306f
std::string utf8_str = "\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf";
std::wstring utf16_str = L"\x3053\x3093\x306b\x3061\x306f";
// Convert each string to the other encoding and assert that the result matches the other
std::string utf16_to_utf8 = OCIO::Platform::Utf16ToUtf8(utf16_str);
std::wstring utf8_to_utf16 = OCIO::Platform::Utf8ToUtf16(utf8_str);
OCIO_CHECK_EQUAL(utf16_to_utf8, utf8_str);
// wstring can't be sent to cout, so we run an assert
OCIO_CHECK_ASSERT(wcscmp(utf8_to_utf16.c_str(), utf16_str.c_str()) == 0);
#endif
}
+2 -1
View File
@@ -11,6 +11,7 @@
#include "MathUtils.h"
#include "Op.h"
#include "Platform.h"
#include "pystring/pystring.h"
namespace OCIO_NAMESPACE
@@ -43,7 +44,7 @@ OCIO_SHARED_PTR<LocalCachedFile> LoadTestFile(
// Open the filePath
std::ifstream filestream;
filestream.open(filePath.c_str(), mode);
Platform::OpenInputFileStream(filestream, filePath.c_str(), mode);
if (!filestream.is_open())
{
+24 -6
View File
@@ -5725,9 +5725,9 @@ OCIO_ADD_TEST(CTFTransform, cdl_clf)
<SOPNode>
<Description>SOP description 1</Description>
<Description>SOP description 2</Description>
<Slope>1, 1.1, 1.2</Slope>
<Offset>0.2, 0.3, 0.4</Offset>
<Power>3.1, 3.2, 3.3</Power>
<Slope>1 1.1 1.2</Slope>
<Offset>0.2 0.3 0.4</Offset>
<Power>3.1 3.2 3.3</Power>
</SOPNode>
<SatNode>
<Description>Sat description 1</Description>
@@ -5740,6 +5740,24 @@ OCIO_ADD_TEST(CTFTransform, cdl_clf)
OCIO_CHECK_EQUAL(expected.size(), outputTransform.str().size());
OCIO_CHECK_EQUAL(expected, outputTransform.str());
// Now test if the read is working.
std::istringstream ctfStream;
ctfStream.str(expected);
std::string emptyString;
OCIO::LocalFileFormat tester;
OCIO::CachedFileRcPtr file = tester.read(ctfStream, emptyString, OCIO::INTERP_DEFAULT);
auto cachedFile = OCIO::DynamicPtrCast<OCIO::LocalCachedFile>(file);
const OCIO::ConstOpDataVec & opList = cachedFile->m_transform->getOps();
OCIO_REQUIRE_EQUAL(opList.size(), 1);
auto cdlData = std::dynamic_pointer_cast<const OCIO::CDLOpData>(opList[0]);
OCIO_REQUIRE_ASSERT(cdlData);
OCIO_CHECK_EQUAL(cdlData->getSlopeParams()[0], 1.);
OCIO_CHECK_EQUAL(cdlData->getSlopeParams()[1], 1.1);
OCIO_CHECK_EQUAL(cdlData->getSlopeParams()[2], 1.2);
}
OCIO_ADD_TEST(CTFTransform, cdl_ctf)
@@ -5768,9 +5786,9 @@ OCIO_ADD_TEST(CTFTransform, cdl_ctf)
"<ProcessList version=\"1.7\" id=\"cdl2\">\n"
" <ASC_CDL inBitDepth=\"32f\" outBitDepth=\"32f\" style=\"Fwd\">\n"
" <SOPNode>\n"
" <Slope>1, 1.1, 1.2</Slope>\n"
" <Offset>0.2, 0.3, 0.4</Offset>\n"
" <Power>3.1, 3.2, 3.3</Power>\n"
" <Slope>1 1.1 1.2</Slope>\n"
" <Offset>0.2 0.3 0.4</Offset>\n"
" <Power>3.1 3.2 3.3</Power>\n"
" </SOPNode>\n"
" <SatNode>\n"
" <Saturation>2.1</Saturation>\n"
@@ -412,3 +412,32 @@ OCIO_ADD_TEST(GradingPrimaryTransform, log_contrast_inverse_apply)
OCIO_CHECK_CLOSE(pixel[1], pixelRef[1], error);
OCIO_CHECK_CLOSE(pixel[2], pixelRef[2], error);
}
OCIO_ADD_TEST(GradingPrimaryTransform, local_bypass)
{
// Test that the GPU is empty for an identity transform.
OCIO::GradingPrimaryTransformRcPtr transform
= OCIO::GradingPrimaryTransform::Create(OCIO::GRADING_LOG);
OCIO::ConstConfigRcPtr config = OCIO::Config::CreateRaw();
OCIO::ConstProcessorRcPtr proc = config->getProcessor(transform);
OCIO::ConstGPUProcessorRcPtr gpu = proc->getOptimizedGPUProcessor(OCIO::OPTIMIZATION_NONE);
OCIO::GpuShaderDescRcPtr shaderDesc = OCIO::GpuShaderDesc::CreateShaderDesc();
OCIO_CHECK_NO_THROW(gpu->extractGpuShaderInfo(shaderDesc));
static const std::string gpuStr("\n"
"// Declaration of the OCIO shader function\n"
"\n"
"vec4 OCIOMain(vec4 inPixel)\n"
"{\n"
" vec4 outColor = inPixel;\n"
"\n"
" return outColor;\n"
"}\n");
OCIO_CHECK_EQUAL(gpuStr, std::string(shaderDesc->getShaderText()));
}
@@ -271,3 +271,32 @@ OCIO_ADD_TEST(GradingRGBCurveTransform, serialization)
}
}
OCIO_ADD_TEST(GradingRGBCurveTransform, local_bypass)
{
// Test that the GPU is empty for an identity transform.
OCIO::GradingRGBCurveTransformRcPtr transform
= OCIO::GradingRGBCurveTransform::Create(OCIO::GRADING_LOG);
OCIO::ConstConfigRcPtr config = OCIO::Config::CreateRaw();
OCIO::ConstProcessorRcPtr proc = config->getProcessor(transform);
OCIO::ConstGPUProcessorRcPtr gpu = proc->getOptimizedGPUProcessor(OCIO::OPTIMIZATION_NONE);
OCIO::GpuShaderDescRcPtr shaderDesc = OCIO::GpuShaderDesc::CreateShaderDesc();
OCIO_CHECK_NO_THROW(gpu->extractGpuShaderInfo(shaderDesc));
static const std::string gpuStr("\n"
"// Declaration of the OCIO shader function\n"
"\n"
"vec4 OCIOMain(vec4 inPixel)\n"
"{\n"
" vec4 outColor = inPixel;\n"
"\n"
" return outColor;\n"
"}\n");
OCIO_CHECK_EQUAL(gpuStr, std::string(shaderDesc->getShaderText()));
}
@@ -92,3 +92,112 @@ OCIO_ADD_TEST(GradingToneTransform, serialization)
OCIO_CHECK_EQUAL(oss.str(), GROUP_STR);
}
}
OCIO_ADD_TEST(GradingToneTransform, local_bypass)
{
// Test the local bypass behavior.
OCIO::GradingToneTransformRcPtr transform
= OCIO::GradingToneTransform::Create(OCIO::GRADING_LOG);
OCIO::ConstConfigRcPtr config = OCIO::Config::CreateRaw();
{
// Test that the GPU is empty for an identity transform.
OCIO::ConstProcessorRcPtr proc = config->getProcessor(transform);
OCIO::ConstGPUProcessorRcPtr gpu = proc->getOptimizedGPUProcessor(OCIO::OPTIMIZATION_NONE);
OCIO::GpuShaderDescRcPtr shaderDesc = OCIO::GpuShaderDesc::CreateShaderDesc();
OCIO_CHECK_NO_THROW(gpu->extractGpuShaderInfo(shaderDesc));
static const std::string gpuStr("\n"
"// Declaration of the OCIO shader function\n"
"\n"
"vec4 OCIOMain(vec4 inPixel)\n"
"{\n"
" vec4 outColor = inPixel;\n"
"\n"
" return outColor;\n"
"}\n");
OCIO_CHECK_EQUAL(gpuStr, std::string(shaderDesc->getShaderText()));
}
{
transform->makeDynamic();
const auto proc = config->getProcessor(transform);
const auto cpu = proc->getOptimizedCPUProcessor(OCIO::OPTIMIZATION_NONE);
// Values are unchanged (to within 32f precision).
float v1[3] {0.3f, 0.4f, 0.5f};
cpu->applyRGB(v1);
OCIO_CHECK_CLOSE_FROM(v1[0], 0.30000001192092896f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_CLOSE_FROM(v1[1], 0.4000000059604645f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_EQUAL(v1[2], 0.5f);
// Try a value > HalfMax = 65504, note it is not clamped. Therefore localBypass is being used.
float v2[3] {0.3f, 0.4f, 65550.0f};
cpu->applyRGB(v2);
OCIO_CHECK_CLOSE_FROM(v2[0], 0.30000001192092896f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_CLOSE_FROM(v2[1], 0.4000000059604645f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_EQUAL(v2[2], 65550.0f);
// Set the midtones control so it is no longer an identity.
auto valst = OCIO::GradingTone(OCIO::GRADING_LOG);
valst.m_midtones = OCIO::GradingRGBMSW(0.3, 1.0, 1.8, 1.2, 0.37, 0.6);
auto dp = cpu->getDynamicProperty(OCIO::DYNAMIC_PROPERTY_GRADING_TONE);
auto propGT = OCIO::DynamicPropertyValue::AsGradingTone(dp);
OCIO_CHECK_ASSERT(propGT);
OCIO_CHECK_NO_THROW(propGT->setValue(valst));
// It is affecting the midtones.
float v3[3] {0.3f, 0.4f, 0.5f};
cpu->applyRGB(v3);
OCIO_CHECK_CLOSE_FROM(v3[0], 0.20410963892936707f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_CLOSE_FROM(v3[1], 0.4343799948692322f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_CLOSE_FROM(v3[2], 0.6093657612800598f, std::numeric_limits<float>::max_digits10, __LINE__);
// The max value is now clamped, so localBypass is not being used.
float v4[3] {0.3f, 0.4f, 65550.0f};
cpu->applyRGB(v4);
OCIO_CHECK_CLOSE_FROM(v4[0], 0.20410963892936707f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_CLOSE_FROM(v4[1], 0.4343799948692322f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_EQUAL(v4[2], 65504.0f);
// The midtones control does not affect large values, so just clarify that large values
// below 65504 are not affected.
float v5[3] {0.3f, 0.4f, 65500.0f};
cpu->applyRGB(v5);
OCIO_CHECK_CLOSE_FROM(v5[0], 0.20410963892936707f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_CLOSE_FROM(v5[1], 0.4343799948692322f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_EQUAL(v5[2], 65500.0f);
// Set the midtones values back to its default.
valst.m_midtones = OCIO::GradingRGBMSW(1., 1.0, 1., 1., 0.4, 0.6);
OCIO_CHECK_NO_THROW(propGT->setValue(valst));
// The behavior is now the same as originally.
float v6[3] {0.3f, 0.4f, 0.5f};
cpu->applyRGB(v6);
OCIO_CHECK_CLOSE_FROM(v6[0], 0.30000001192092896f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_CLOSE_FROM(v6[1], 0.4000000059604645f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_EQUAL(v6[2], 0.5f);
float v7[3] {0.3f, 0.4f, 65550.0f};
cpu->applyRGB(v7);
OCIO_CHECK_CLOSE_FROM(v7[0], 0.30000001192092896f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_CLOSE_FROM(v7[1], 0.4000000059604645f, std::numeric_limits<float>::max_digits10, __LINE__);
OCIO_CHECK_EQUAL(v7[2], 65550.0f);
}
}
+3 -2
View File
@@ -147,9 +147,9 @@ OCIO_ADD_GPU_TEST(CDLOp, clamp_inv_no_clamp_v2)
namespace CDL_Data_2
{
constexpr double slope[3] = { 1.15, 1.10, 0.90 };
constexpr double slope[3] = { 1.15, 1.10, 0.90 };
constexpr double offset[3] = { 0.05, -0.02, 0.07 };
constexpr double power[3] = { 1.20, 0.95, 1.13 };
constexpr double power[3] = { 1.20, 0.95, 1.13 };
constexpr double saturation = 0.9;
};
@@ -167,6 +167,7 @@ OCIO_ADD_GPU_TEST(CDLOp, clamp_fwd_v1_legacy_shader_Data_2)
config->setMajorVersion(1);
test.setProcessor(config, cdl);
test.setLegacyShader(true);
test.setTestWideRange(true);
test.setRelativeComparison(false);
test.setErrorThreshold(1e-6f);
+1 -1
View File
@@ -50,7 +50,7 @@ target_link_libraries(test_gpu_exec
unittest_data
)
add_test(test_gpu test_gpu_exec)
add_test(NAME test_gpu COMMAND test_gpu_exec)
# Note: To avoid changing PATH from outside the cmake files.
if(MSVC AND BUILD_SHARED_LIBS)
+3 -1
View File
@@ -34,7 +34,9 @@ std::string createTempFile(const std::string& fileExt, const std::string& fileCo
throw OCIO::Exception("Could not create a temporary file");
}
filename = tmpFilename;
// Note that when a file name is pre-pended with a backslash and no path information, such as \fname21, this
// indicates that the name is valid for the current working directory.
filename = tmpFilename[0] == '\\' ? tmpFilename + 1 : tmpFilename;
filename += fileExt;
#else
+2 -1
View File
@@ -8,7 +8,8 @@
#include <string>
// FIXME: Duplicate function implemented in `src/OpenColorIO/Platform.h and cpp`.
// Implement a function or class for temporary file creation useable by all tests.
std::string createTempFile(const std::string& fileExt, const std::string& fileContent);
+5 -5
View File
@@ -124,7 +124,7 @@ OCIO_ADD_GPU_TEST(LogAffineTransform, base_inverse)
test.setProcessor(log);
test.setErrorThreshold(g_epsilon);
test.setErrorThreshold(g_epsilon); // Use the tighter tolerance than g_epsilon_inverse
test.setRelativeComparison(true);
@@ -157,7 +157,7 @@ OCIO_ADD_GPU_TEST(LogAffineTransform, linSideSlope_inverse)
test.setProcessor(log);
test.setErrorThreshold(g_epsilon);
test.setErrorThreshold(g_epsilon); // Use the tighter tolerance than g_epsilon_inverse
test.setTestNaN(false);
test.setTestInfinity(false);
@@ -188,7 +188,7 @@ OCIO_ADD_GPU_TEST(LogAffineTransform, linSideOffset_inverse)
test.setProcessor(log);
test.setErrorThreshold(g_epsilon);
test.setErrorThreshold(g_epsilon); // Use the tighter tolerance than g_epsilon_inverse
test.setTestNaN(false);
test.setTestInfinity(false);
@@ -219,7 +219,7 @@ OCIO_ADD_GPU_TEST(LogAffineTransform, logSideSlope_inverse)
test.setProcessor(log);
test.setErrorThreshold(g_epsilon);
test.setErrorThreshold(g_epsilon); // Use the tighter tolerance than g_epsilon_inverse
test.setTestNaN(false);
test.setTestInfinity(false);
@@ -250,7 +250,7 @@ OCIO_ADD_GPU_TEST(LogAffineTransform, logSideOffset_inverse)
test.setProcessor(log);
test.setErrorThreshold(g_epsilon);
test.setErrorThreshold(g_epsilon); // Use the tighter tolerance than g_epsilon_inverse
test.setTestNaN(false);
test.setTestInfinity(false);
+240
View File
@@ -0,0 +1,240 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
// NOTE:
// The file is a copy and paste from the corresponding GPU unitest i.e. []/tests/gpu/CDLOp_test.cpp.
// Keep the two files in sync. to increase the test coverage.
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
namespace CDL_Data_1
{
constexpr double slope[3] = { 1.35, 1.10, 0.71 };
constexpr double offset[3] = { 0.05, -0.23, 0.11 };
constexpr double power[3] = { 0.93, 0.81, 1.27 };
};
// Use the generic shader description with the CDL from OCIO v1 implementation.
OCIO_OSL_TEST(CDLOp, clamp_fwd_v1)
{
auto cdl = OCIO::CDLTransform::Create();
cdl->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
cdl->setSlope(CDL_Data_1::slope);
cdl->setOffset(CDL_Data_1::offset);
cdl->setPower(CDL_Data_1::power);
m_data->m_transform = cdl;
m_data->m_config->setMajorVersion(1);
m_data->m_threshold = 1e-5f; // Slight difference with the GLSL unit test i.e. 1e-6f
}
// Use the generic shader description with the CDL from OCIO v2 implementation
// (i.e. use the CDL Op with the ASC/clamping style and a forward direction).
OCIO_OSL_TEST(CDLOp, clamp_fwd_v2)
{
auto cdl = OCIO::CDLTransform::Create();
cdl->setStyle(OCIO::CDL_ASC);
cdl->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
cdl->setSlope(CDL_Data_1::slope);
cdl->setOffset(CDL_Data_1::offset);
cdl->setPower(CDL_Data_1::power);
m_data->m_transform = cdl;
m_data->m_threshold = 1e-5f;
}
OCIO_OSL_TEST(CDLOp, clamp_fwd_no_clamp_v2)
{
auto cdl = OCIO::CDLTransform::Create();
cdl->setStyle(OCIO::CDL_NO_CLAMP);
cdl->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
cdl->setSlope(CDL_Data_1::slope);
cdl->setOffset(CDL_Data_1::offset);
cdl->setPower(CDL_Data_1::power);
m_data->m_transform = cdl;
m_data->m_threshold = 5e-5f;
}
// Use the generic shader description with the CDL from OCIO v2 implementation
// (i.e. use the CDL Op with the ASC/clamping style and a inverse direction).
OCIO_OSL_TEST(CDLOp, clamp_inv_v2)
{
auto cdl = OCIO::CDLTransform::Create();
cdl->setStyle(OCIO::CDL_ASC);
cdl->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
cdl->setSlope(CDL_Data_1::slope);
cdl->setOffset(CDL_Data_1::offset);
cdl->setPower(CDL_Data_1::power);
m_data->m_transform = cdl;
m_data->m_threshold = 1e-4f;
}
OCIO_OSL_TEST(CDLOp, clamp_inv_no_clamp_v2)
{
auto cdl = OCIO::CDLTransform::Create();
cdl->setStyle(OCIO::CDL_NO_CLAMP);
cdl->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
cdl->setSlope(CDL_Data_1::slope);
cdl->setOffset(CDL_Data_1::offset);
cdl->setPower(CDL_Data_1::power);
m_data->m_transform = cdl;
m_data->m_threshold = 1e-4f;
}
namespace CDL_Data_2
{
constexpr double slope[3] = { 1.15, 1.10, 0.90 };
constexpr double offset[3] = { 0.05, -0.02, 0.07 };
constexpr double power[3] = { 1.20, 0.95, 1.13 };
constexpr double saturation = 0.9;
};
// Use the generic shader description with the CDL from OCIO v1 implementation.
OCIO_OSL_TEST(CDLOp, clamp_fwd_v1_Data_2)
{
OCIO::CDLTransformRcPtr cdl = OCIO::CDLTransform::Create();
cdl->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
cdl->setSlope(CDL_Data_2::slope);
cdl->setOffset(CDL_Data_2::offset);
cdl->setPower(CDL_Data_2::power);
cdl->setSat(CDL_Data_2::saturation);
m_data->m_transform = cdl;
m_data->m_config->setMajorVersion(1);
m_data->m_threshold = 1e-5f; // Slight difference with the GLSL unit test i.e. 1e-6f
}
// Use the generic shader description with the CDL from OCIO v2 implementation
// (i.e. use the CDL Op with the ASC/clamping style and a forward direction).
OCIO_OSL_TEST(CDLOp, clamp_fwd_v2_Data_2)
{
OCIO::CDLTransformRcPtr cdl = OCIO::CDLTransform::Create();
cdl->setStyle(OCIO::CDL_ASC);
cdl->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
cdl->setSlope(CDL_Data_2::slope);
cdl->setOffset(CDL_Data_2::offset);
cdl->setPower(CDL_Data_2::power);
cdl->setSat(CDL_Data_2::saturation);
m_data->m_transform = cdl;
m_data->m_threshold = 2e-5f;
}
OCIO_OSL_TEST(CDLOp, clamp_inv_v2_Data_2)
{
OCIO::CDLTransformRcPtr cdl = OCIO::CDLTransform::Create();
cdl->setStyle(OCIO::CDL_ASC);
cdl->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
cdl->setSlope(CDL_Data_2::slope);
cdl->setOffset(CDL_Data_2::offset);
cdl->setPower(CDL_Data_2::power);
cdl->setSat(CDL_Data_2::saturation);
m_data->m_transform = cdl;
m_data->m_threshold = 2e-5f;
}
OCIO_OSL_TEST(CDLOp, clamp_fwd_no_clamp_v2_Data_2)
{
OCIO::CDLTransformRcPtr cdl = OCIO::CDLTransform::Create();
cdl->setStyle(OCIO::CDL_NO_CLAMP);
cdl->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
cdl->setSlope(CDL_Data_2::slope);
cdl->setOffset(CDL_Data_2::offset);
cdl->setPower(CDL_Data_2::power);
cdl->setSat(CDL_Data_2::saturation);
m_data->m_transform = cdl;
m_data->m_threshold = 5e-5f;
}
OCIO_OSL_TEST(CDLOp, clamp_inv_no_clamp_v2_Data_2)
{
OCIO::CDLTransformRcPtr cdl = OCIO::CDLTransform::Create();
cdl->setStyle(OCIO::CDL_NO_CLAMP);
cdl->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
cdl->setSlope(CDL_Data_2::slope);
cdl->setOffset(CDL_Data_2::offset);
cdl->setPower(CDL_Data_2::power);
cdl->setSat(CDL_Data_2::saturation);
m_data->m_transform = cdl;
m_data->m_threshold = 5e-5f;
}
namespace CDL_Data_3
{
constexpr double slope[3] = { 3.405, 1.0, 1.0 };
constexpr double offset[3] = { -0.178, -0.178, -0.178 };
constexpr double power[3] = { 1.095, 1.095, 1.0 };
constexpr double saturation = 1.2;
};
// Use the generic shader description with the CDL from OCIO v2 implementation
// (i.e. use the CDL Op with the ASC/clamping style and a forward direction).
OCIO_OSL_TEST(CDLOp, clamp_fwd_v2_Data_3)
{
OCIO::CDLTransformRcPtr cdl = OCIO::CDLTransform::Create();
cdl->setStyle(OCIO::CDL_ASC);
cdl->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
cdl->setSlope(CDL_Data_3::slope);
cdl->setOffset(CDL_Data_3::offset);
cdl->setPower(CDL_Data_3::power);
cdl->setSat(CDL_Data_3::saturation);
m_data->m_transform = cdl;
m_data->m_threshold = 5e-5f;
}
OCIO_OSL_TEST(CDLOp, clamp_fwd_no_clamp_v2_Data_3)
{
OCIO::CDLTransformRcPtr cdl = OCIO::CDLTransform::Create();
cdl->setStyle(OCIO::CDL_NO_CLAMP);
cdl->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
cdl->setSlope(CDL_Data_3::slope);
cdl->setOffset(CDL_Data_3::offset);
cdl->setPower(CDL_Data_3::power);
cdl->setSat(CDL_Data_3::saturation);
m_data->m_transform = cdl;
m_data->m_threshold = 5e-5f;
}
OCIO_OSL_TEST(CDLOp, clamp_inv_no_clamp_v2_Data_3)
{
OCIO::CDLTransformRcPtr cdl = OCIO::CDLTransform::Create();
cdl->setStyle(OCIO::CDL_NO_CLAMP);
cdl->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
cdl->setSlope(CDL_Data_3::slope);
cdl->setOffset(CDL_Data_3::offset);
cdl->setPower(CDL_Data_3::power);
cdl->setSat(CDL_Data_3::saturation);
m_data->m_transform = cdl;
m_data->m_threshold = 5e-5f;
}
+13 -4
View File
@@ -2,11 +2,18 @@
# Copyright Contributors to the OpenColorIO Project.
set(SOURCES
ExponentOp_test.cpp
CDLOp_test.cpp
ECOp_test.cpp
FixedFunctionOp_test.cpp
GammaOp_test.cpp
GradingPrimaryOp_test.cpp
GradingRGBCurveOp_test.cpp
GradingToneOp_test.cpp
LogOp_test.cpp
MatrixOp_test.cpp
RangeOp_test.cpp
UnitTestMain.cpp
UnitTestOSL.cpp
)
add_executable(test_osl_exec ${SOURCES})
@@ -32,13 +39,15 @@ target_link_libraries(test_osl_exec
PRIVATE
OpenColorIO
osl::osl
Imath::Imath
OpenImageIO::OpenImageIO
)
add_test(test_osl test_osl_exec)
add_test(NAME test_osl COMMAND test_osl_exec)
set_tests_properties(test_osl PROPERTIES ENVIRONMENT SHADERS_DIR=${OSL_SHADERS_DIR})
list(APPEND ENVS "OSL_SHADERS_DIR=${OSL_SHADERS_DIR}")
list(APPEND ENVS "TMP_SHADERS_DIR=${CMAKE_CURRENT_BINARY_DIR}")
set_tests_properties(test_osl PROPERTIES ENVIRONMENT "${ENVS}")
# Note: To avoid changing PATH from outside the cmake files.
if(MSVC AND BUILD_SHARED_LIBS)
+179
View File
@@ -0,0 +1,179 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
// NOTE:
// The file is a copy and paste from the corresponding GPU unitest i.e. []/tests/gpu/ECOp_test.cpp.
// Keep the two files in sync. to increase the test coverage.
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
OCIO_OSL_TEST(ExposureContrast, style_linear_fwd)
{
auto ec = OCIO::ExposureContrastTransform::Create();
ec->setStyle(OCIO::EXPOSURE_CONTRAST_LINEAR);
ec->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
ec->setExposure(1.1);
ec->setContrast(0.8);
ec->setGamma(0.9);
ec->setPivot(0.22);
m_data->m_transform = ec;
m_data->m_threshold = 2e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(ExposureContrast, style_linear_rev)
{
auto ec = OCIO::ExposureContrastTransform::Create();
ec->setStyle(OCIO::EXPOSURE_CONTRAST_LINEAR);
ec->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
ec->setExposure(1.1);
ec->setContrast(0.7);
ec->setGamma(0.9);
ec->setPivot(0.22);
m_data->m_transform = ec;
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 2e-5f
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(ExposureContrast, style_video_fwd)
{
auto ec = OCIO::ExposureContrastTransform::Create();
ec->setStyle(OCIO::EXPOSURE_CONTRAST_VIDEO);
ec->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
ec->setExposure(1.1);
ec->setContrast(0.8);
ec->setGamma(0.9);
ec->setPivot(0.22);
m_data->m_transform = ec;
m_data->m_threshold = 2e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(ExposureContrast, style_video_rev)
{
auto ec = OCIO::ExposureContrastTransform::Create();
ec->setStyle(OCIO::EXPOSURE_CONTRAST_VIDEO);
ec->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
ec->setExposure(1.1);
ec->setContrast(0.7);
ec->setGamma(0.9);
ec->setPivot(0.22);
m_data->m_transform = ec;
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 2e-5f
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(ExposureContrast, style_log_fwd)
{
auto ec = OCIO::ExposureContrastTransform::Create();
ec->setStyle(OCIO::EXPOSURE_CONTRAST_LOGARITHMIC);
ec->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
ec->setExposure(1.1);
ec->setContrast(0.8);
ec->setGamma(0.9);
ec->setPivot(0.22);
m_data->m_transform = ec;
m_data->m_threshold = 1e-6f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(ExposureContrast, style_log_rev)
{
auto ec = OCIO::ExposureContrastTransform::Create();
ec->setStyle(OCIO::EXPOSURE_CONTRAST_LOGARITHMIC);
ec->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
ec->setExposure(1.1);
ec->setContrast(0.7);
ec->setGamma(0.9);
ec->setPivot(0.22);
m_data->m_transform = ec;
m_data->m_threshold = 1e-6f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(ExposureContrast, style_linear_dynamic_parameter)
{
auto ec = OCIO::ExposureContrastTransform::Create();
ec->setStyle(OCIO::EXPOSURE_CONTRAST_LINEAR);
ec->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
ec->setExposure(1.1);
ec->setContrast(0.8);
ec->setGamma(0.9);
ec->setPivot(0.22);
ec->makeExposureDynamic();
ec->makeContrastDynamic();
ec->makeGammaDynamic();
m_data->m_transform = ec;
m_data->m_threshold = 5e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
void Prepare2ECDynamic(OSLDataRcPtr & data, bool firstDyn, bool secondDyn)
{
// See also OCIO_ADD_TEST(ExposureContrastTransform, processor_several_ec).
OCIO::ExposureContrastTransformRcPtr ec1 = OCIO::ExposureContrastTransform::Create();
ec1->setStyle(OCIO::EXPOSURE_CONTRAST_LOGARITHMIC);
ec1->setExposure(0.8);
ec1->setContrast(0.5);
ec1->setGamma(1.5);
OCIO::ExposureContrastTransformRcPtr ec2 = OCIO::ExposureContrastTransform::Create();
ec2->setStyle(OCIO::EXPOSURE_CONTRAST_LOGARITHMIC);
ec2->setExposure(0.8);
ec2->setContrast(0.5);
ec2->setGamma(1.5);
if (firstDyn) ec1->makeContrastDynamic();
if (secondDyn) ec2->makeExposureDynamic();
OCIO::GroupTransformRcPtr grp = OCIO::GroupTransform::Create();
grp->appendTransform(ec1);
grp->appendTransform(ec2);
data->m_transform = grp;
data->m_threshold = 5e-5f;
data->m_expectedMinimalValue = 1.0f;
data->m_relativeComparison = true;
}
OCIO_OSL_TEST(ExposureContrast, dp_several_one_dynamic)
{
// 2 EC, first not dynamic, second dynamic.
Prepare2ECDynamic(m_data, false, true);
}
OCIO_OSL_TEST(ExposureContrast, dp_several_both_dynamic)
{
// 2 EC, both dynamic.
Prepare2ECDynamic(m_data, true, true);
}
-21
View File
@@ -1,21 +0,0 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
OCIO_OSL_TEST(Exponent, value)
{
m_data->m_inValue = OSL::Vec4(0.1, 0.3, 0.9, 0.5);
m_data->m_outValue = OSL::Vec4(0.0630957261, 0.209053621, 0.862858355, 0.353553385);
OCIO::ExponentTransformRcPtr exp = OCIO::ExponentTransform::Create();
static constexpr double expVal[4] = { 1.2, 1.3, 1.4, 1.5 };
exp->setValue(expVal);
m_data->m_transform = exp;
}
+383 -92
View File
@@ -2,177 +2,468 @@
// Copyright Contributors to the OpenColorIO Project.
// NOTE:
// The file is a copy and paste from the corresponding GPU unitest i.e. []/tests/gpu/FixedFunctionOp_test.cpp.
// Keep the two files in sync. to increase the test coverage.
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
OCIO_OSL_TEST(FixedFunction, aces_red_mod_03)
OCIO_OSL_TEST(FixedFunction, style_aces_redmod03_fwd)
{
m_data->m_inValue = OSL::Vec4(0.9, 0.05, 0.22, 0.5);
m_data->m_outValue = OSL::Vec4(0.79670035, 0.05, 0.19934007, 0.5);
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_RED_MOD_03);
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_RED_MOD_03);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
m_data->m_inputValues =
{
{ 0.90f, 0.05f, 0.22f, 0.50f },
{ 0.97f, 0.097f, 0.0097f, 1.00f },
{ 0.89f, 0.15f, 0.56f, 0.00f },
{ -1.00f, -0.001f, 1.2f, 0.00f }
};
m_data->m_threshold = 1e-6f;
}
OCIO_OSL_TEST(FixedFunction, aces_red_mod_03_inv)
OCIO_OSL_TEST(FixedFunction, style_aces_redmod03_inv)
{
m_data->m_inValue = OSL::Vec4(0.79670035, 0.05, 0.19934007, 0.5);
m_data->m_outValue = OSL::Vec4(0.9, 0.05, 0.22, 0.5);
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_RED_MOD_03);
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_RED_MOD_03);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
m_data->m_inputValues =
{
{ 0.90f, 0.05f, 0.22f, 0.50f },
{ 0.97f, 0.097f, 0.0097f, 1.00f },
{ 0.89f, 0.15f, 0.56f, 0.00f },
{ -1.0f, -0.001f, 1.2f, 0.00f }
};
m_data->m_threshold = 1e-6f;
}
OCIO_OSL_TEST(FixedFunction, aces_red_mod_10)
OCIO_OSL_TEST(FixedFunction, style_aces_redmod10_fwd)
{
m_data->m_inValue = OSL::Vec4(0.90, 0.05, 0.22, 0.5);
m_data->m_outValue = OSL::Vec4(0.77148211, 0.05, 0.22, 0.5);
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_RED_MOD_10);
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_RED_MOD_10);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
m_data->m_inputValues =
{
{ 0.90f, 0.05f, 0.22f, 0.50f },
{ 0.97f, 0.097f, 0.0097f, 1.00f },
{ 0.89f, 0.15f, 0.56f, 0.00f },
{ -1.0f, -0.001f, 1.2f, 0.00f }
};
m_data->m_threshold = 1e-5f; // Slight difference with the GLSL unit test i.e. 1e-6f
}
OCIO_OSL_TEST(FixedFunction, aces_red_mod_10_inv)
OCIO_OSL_TEST(FixedFunction, style_aces_redmod10_inv)
{
m_data->m_inValue = OSL::Vec4(0.77148211, 0.05, 0.22, 0.5);
m_data->m_outValue = OSL::Vec4(0.90, 0.05, 0.22, 0.5);
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_RED_MOD_10);
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_RED_MOD_10);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
m_data->m_inputValues =
{
{ 0.90f, 0.05f, 0.22f, 0.50f },
{ 0.97f, 0.097f, 0.0097f, 1.00f },
{ 0.89f, 0.15f, 0.56f, 0.00f },
{ -1.0f, -0.001f, 1.2f, 0.00f }
};
m_data->m_threshold = 1e-5f; // Slight difference with the GLSL unit test i.e. 1e-6f
}
OCIO_OSL_TEST(FixedFunction, aces_glow_03)
OCIO_OSL_TEST(FixedFunction, style_aces_glow03_fwd)
{
m_data->m_inValue = OSL::Vec4(0.11, 0.02, 0.0, 0.5); // YC = 0.10
m_data->m_outValue = OSL::Vec4(0.11392101, 0.02071291f, 0.0, 0.5);
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GLOW_03);
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GLOW_03);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
m_data->m_inputValues =
{
{ 0.11f, 0.02f, 0.f, 0.5f }, // YC = 0.10
{ 0.01f, 0.02f, 0.03f, 1.0f }, // YC = 0.03
{ 0.11f, 0.91f, 0.01f, 0.0f } // YC = 0.84
};
m_data->m_threshold = 1e-7f;
}
OCIO_OSL_TEST(FixedFunction, aces_glow_03_inv)
OCIO_OSL_TEST(FixedFunction, style_aces_glow03_inv)
{
m_data->m_inValue = OSL::Vec4(0.11392101, 0.02071291f, 0.0, 0.5);
m_data->m_outValue = OSL::Vec4(0.11, 0.02, 0.0, 0.5);
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GLOW_03);
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GLOW_03);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
m_data->m_inputValues =
{
{ 0.11f, 0.02f, 0.f, 0.5f }, // YC = 0.10
{ 0.01f, 0.02f, 0.03f, 1.0f }, // YC = 0.03
{ 0.11f, 0.91f, 0.01f, 0.0f } // YC = 0.84
};
m_data->m_threshold = 1e-7f;
}
OCIO_OSL_TEST(FixedFunction, aces_glow_10)
OCIO_OSL_TEST(FixedFunction, style_aces_glow10_fwd)
{
m_data->m_inValue = OSL::Vec4(0.11, 0.02, 0.0, 0.5); // YC = 0.10
m_data->m_outValue = OSL::Vec4(0.11154121, 0.02028021, 0.0, 0.5);
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GLOW_10);
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GLOW_10);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
m_data->m_inputValues =
{
{ 0.11f, 0.02f, 0.f, 0.5f }, // YC = 0.10
{ 0.01f, 0.02f, 0.03f, 1.0f }, // YC = 0.03
{ 0.11f, 0.91f, 0.01f, 0.0f } // YC = 0.84
};
m_data->m_threshold = 1e-7f;
}
OCIO_OSL_TEST(FixedFunction, aces_glow_10_inv)
OCIO_OSL_TEST(FixedFunction, style_aces_glow10_inv)
{
m_data->m_inValue = OSL::Vec4(0.11154121, 0.02028021, 0.0, 0.5);
m_data->m_outValue = OSL::Vec4(0.11, 0.02, 0.0, 0.5);
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GLOW_10);
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GLOW_10);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
m_data->m_inputValues =
{
{ 0.11f, 0.02f, 0.f, 0.5f }, // YC = 0.10
{ 0.01f, 0.02f, 0.03f, 1.0f }, // YC = 0.03
{ 0.11f, 0.91f, 0.01f, 00.f } // YC = 0.84
};
m_data->m_threshold = 1e-7f;
}
OCIO_OSL_TEST(FixedFunction, aces_dark_to_dim_10)
OCIO_OSL_TEST(FixedFunction, style_aces_gamutcomp13_fwd)
{
m_data->m_inValue = OSL::Vec4(0.11, 0.02, 0.04, 0.5);
m_data->m_outValue = OSL::Vec4(0.11661188, 0.02120216, 0.04240432, 0.5);
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_DARK_TO_DIM_10);
static constexpr double data[7] = { 1.147, 1.264, 1.312, 0.815, 0.803, 0.880, 1.2 };
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GAMUT_COMP_13, &data[0], 7);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
// See FixedFunctionOpCPU_tests.cpp for informations on the dataset
m_data->m_inputValues =
{
// ALEXA Wide Gamut
{ 0.96663409472f, 0.04819045216f, 0.00719300006f, 0.0f },
{ 0.11554181576f, 1.18493819237f, -0.06659350544f, 0.0f },
{ -0.08217582852f, -0.23312863708f, 1.05940067768f, 0.0f },
// BMD Wide Gamut
{ 0.92980366945f, 0.03025679290f, -0.02240031771f, 0.0f },
{ 0.12437260151f, 1.19238424301f, -0.08014731854f, 0.0f },
{ -0.05417707562f, -0.22264070809f, 1.10254764557f, 0.0f },
// Cinema Gamut
{ 1.10869872570f, -0.05317572504f, -0.00306261564f, 0.0f },
{ 0.00142395718f, 1.31239914894f, -0.22332298756f, 0.0f },
{ -0.11012268066f, -0.25922337174f, 1.22638559341f, 0.0f },
// REDWideGamutRGB
{ 1.14983725548f, -0.02548932098f, -0.06720325351f, 0.0f },
{ -0.06796986610f, 1.30455482006f, -0.31973674893f, 0.0f },
{ -0.08186896890f, -0.27906489372f, 1.38694024086f, 0.0f },
// S-Gamut3
{ 1.08979821205f, -0.03117186762f, -0.00326358480f, 0.0f },
{ -0.03276504576f, 1.18293666840f, -0.00156985107f, 0.0f },
{ -0.05703317001f, -0.15176482499f, 1.00483345985f, 0.0f },
// Venice S-Gamut3
{ 1.15183949471f, -0.04052511975f, -0.01231821068f, 0.0f },
{ -0.11769985408f, 1.20661473274f, 0.00725125661f, 0.0f },
{ -0.03413961083f, -0.16608965397f, 1.00506699085f, 0.0f },
// V-Gamut
{ 1.04839742184f, -0.02998665348f, -0.00313943392f, 0.0f },
{ 0.01196120959f, 1.14840388298f, -0.00963746291f, 0.0f },
{ -0.06036021933f, -0.11841656268f, 1.01277709007f, 0.0f },
// CC24 hue selective patch
{ 0.13911968470f, 0.08746965975f, 0.05927771702f, 0.0f },
{ 0.45410454273f, 0.32112336159f, 0.23821924627f, 0.0f },
{ 0.15262818336f, 0.19457373023f, 0.31270095706f, 0.0f },
{ 0.11231111735f, 0.14410330355f, 0.06487321854f, 0.0f },
{ 0.24113640189f, 0.22817260027f, 0.40912008286f, 0.0f },
{ 0.27200737596f, 0.47832396626f, 0.40502992272f, 0.0f },
{ 0.49412208796f, 0.23219805956f, 0.05947655812f, 0.0f },
{ 0.09734666348f, 0.10917002708f, 0.33662334085f, 0.0f },
{ 0.37841814756f, 0.12591768801f, 0.12897071242f, 0.0f },
{ 0.09104857594f, 0.05404697359f, 0.13533248007f, 0.0f },
{ 0.38014721870f, 0.47619381547f, 0.10615456849f, 0.0f },
{ 0.60210841894f, 0.38621774316f, 0.08225912601f, 0.0f },
{ 0.05051656812f, 0.05367648974f, 0.27239432931f, 0.0f },
{ 0.14276765287f, 0.28139206767f, 0.09023084491f, 0.0f },
{ 0.28782477975f, 0.06140174344f, 0.05256444961f, 0.0f },
{ 0.70791155100f, 0.58026152849f, 0.09300658852f, 0.0f },
{ 0.35456034541f, 0.12329842150f, 0.27530980110f, 0.0f },
{ 0.08374430984f, 0.22774916887f, 0.35839819908f, 0.0f }
};
m_data->m_threshold = 1e-6f;
}
OCIO_OSL_TEST(FixedFunction, aces_dark_to_dim_10_inv)
OCIO_OSL_TEST(FixedFunction, style_aces_gamutcomp13_inv)
{
m_data->m_inValue = OSL::Vec4(0.11661188, 0.02120216, 0.04240432, 0.5);
m_data->m_outValue = OSL::Vec4(0.11, 0.02, 0.04, 0.5);
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_DARK_TO_DIM_10);
static constexpr double data[7] = { 1.147, 1.264, 1.312, 0.815, 0.803, 0.880, 1.2 };
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GAMUT_COMP_13, &data[0], 7);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
// See FixedFunctionOpCPU_tests.cpp for informations on the dataset
m_data->m_inputValues =
{
// ALEXA Wide Gamut
{ 0.96663409472f, 0.04819045216f, 0.00719300006f, 0.0f },
{ 0.11554181576f, 1.18493819237f, -0.06659350544f, 0.0f },
{ -0.08217582852f, -0.23312863708f, 1.05940067768f, 0.0f },
// BMD Wide Gamut
{ 0.92980366945f, 0.03025679290f, -0.02240031771f, 0.0f },
{ 0.12437260151f, 1.19238424301f, -0.08014731854f, 0.0f },
{ -0.05417707562f, -0.22264070809f, 1.10254764557f, 0.0f },
// Cinema Gamut
{ 1.10869872570f, -0.05317572504f, -0.00306261564f, 0.0f },
{ 0.00142395718f, 1.31239914894f, -0.22332298756f, 0.0f },
{ -0.11012268066f, -0.25922337174f, 1.22638559341f, 0.0f },
// REDWideGamutRGB
{ 1.14983725548f, -0.02548932098f, -0.06720325351f, 0.0f },
{ -0.06796986610f, 1.30455482006f, -0.31973674893f, 0.0f },
{ -0.08186896890f, -0.27906489372f, 1.38694024086f, 0.0f },
// S-Gamut3
{ 1.08979821205f, -0.03117186762f, -0.00326358480f, 0.0f },
{ -0.03276504576f, 1.18293666840f, -0.00156985107f, 0.0f },
{ -0.05703317001f, -0.15176482499f, 1.00483345985f, 0.0f },
// Venice S-Gamut3
{ 1.15183949471f, -0.04052511975f, -0.01231821068f, 0.0f },
{ -0.11769985408f, 1.20661473274f, 0.00725125661f, 0.0f },
{ -0.03413961083f, -0.16608965397f, 1.00506699085f, 0.0f },
// V-Gamut
{ 1.04839742184f, -0.02998665348f, -0.00313943392f, 0.0f },
{ 0.01196120959f, 1.14840388298f, -0.00963746291f, 0.0f },
{ -0.06036021933f, -0.11841656268f, 1.01277709007f, 0.0f },
// CC24 hue selective patch
{ 0.13911968470f, 0.08746965975f, 0.05927771702f, 0.0f },
{ 0.45410454273f, 0.32112336159f, 0.23821924627f, 0.0f },
{ 0.15262818336f, 0.19457373023f, 0.31270095706f, 0.0f },
{ 0.11231111735f, 0.14410330355f, 0.06487321854f, 0.0f },
{ 0.24113640189f, 0.22817260027f, 0.40912008286f, 0.0f },
{ 0.27200737596f, 0.47832396626f, 0.40502992272f, 0.0f },
{ 0.49412208796f, 0.23219805956f, 0.05947655812f, 0.0f },
{ 0.09734666348f, 0.10917002708f, 0.33662334085f, 0.0f },
{ 0.37841814756f, 0.12591768801f, 0.12897071242f, 0.0f },
{ 0.09104857594f, 0.05404697359f, 0.13533248007f, 0.0f },
{ 0.38014721870f, 0.47619381547f, 0.10615456849f, 0.0f },
{ 0.60210841894f, 0.38621774316f, 0.08225912601f, 0.0f },
{ 0.05051656812f, 0.05367648974f, 0.27239432931f, 0.0f },
{ 0.14276765287f, 0.28139206767f, 0.09023084491f, 0.0f },
{ 0.28782477975f, 0.06140174344f, 0.05256444961f, 0.0f },
{ 0.70791155100f, 0.58026152849f, 0.09300658852f, 0.0f },
{ 0.35456034541f, 0.12329842150f, 0.27530980110f, 0.0f },
{ 0.08374430984f, 0.22774916887f, 0.35839819908f, 0.0f }
};
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 3e-6f
}
OCIO_OSL_TEST(FixedFunction, aces_gamut_map_13)
OCIO_OSL_TEST(FixedFunction, style_aces_darktodim10_fwd)
{
m_data->m_inValue = OSL::Vec4(0.96663409472, 0.04819045216, 0.00719300006, 0.0); // ALEXA Wide Gamut
m_data->m_outValue = OSL::Vec4(0.96663409472, 0.08610087633, 0.04698687792, 0.0);
static constexpr double params[] { 1.147, 1.264, 1.312, 0.815, 0.803, 0.880, 1.2 };
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GAMUT_COMP_13, params, 7);
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_DARK_TO_DIM_10);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
m_data->m_threshold = 1e-6f;
}
OCIO_OSL_TEST(FixedFunction, aces_gamut_map_13_inv)
OCIO_OSL_TEST(FixedFunction, style_aces_darktodim10_inv)
{
m_data->m_inValue = OSL::Vec4(0.96663409472, 0.08610087633, 0.04698687792, 0.0);
m_data->m_outValue = OSL::Vec4(0.96663409472, 0.04819045216, 0.00719300006, 0.0);
static constexpr double params[] { 1.147, 1.264, 1.312, 0.815, 0.803, 0.880, 1.2 };
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_GAMUT_COMP_13, params, 7);
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_ACES_DARK_TO_DIM_10);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
m_data->m_threshold = 1e-6f;
}
OCIO_OSL_TEST(FixedFunction, rec2100_surround)
OCIO_OSL_TEST(FixedFunction, style_rec2100_surround_fwd)
{
m_data->m_inValue = OSL::Vec4(0.11, 0.02, 0.04, 0.5);
m_data->m_outValue = OSL::Vec4(0.21779590, 0.03959925, 0.07919850, 0.5);
static constexpr double params[] { 0.78 };
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_REC2100_SURROUND, params, 1);
static constexpr double data[1] = { 0.7 };
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_REC2100_SURROUND, &data[0], 1);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
m_data->m_threshold = 1e-5f; // Slight difference with the GLSL unit test i.e. 2e-6f
}
OCIO_OSL_TEST(FixedFunction, rec2100_surround_inv)
OCIO_OSL_TEST(FixedFunction, style_rec2100_surround_inv)
{
m_data->m_inValue = OSL::Vec4(0.21779590, 0.03959925, 0.07919850, 0.5);
m_data->m_outValue = OSL::Vec4(0.11, 0.02, 0.04, 0.5);
static constexpr double params[] { 1 / 0.78 };
OCIO::FixedFunctionTransformRcPtr func
= OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_REC2100_SURROUND, params, 1);
static constexpr double data[1] = { 1. / 0.7 };
// (Since we're not calling inverse() here, set the param to be the inverse of prev test.)
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_REC2100_SURROUND, &data[0], 1);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
m_data->m_threshold = 1e-5f; // Slight difference with the GLSL unit test i.e. 2e-6f
}
OCIO_OSL_TEST(FixedFunction, style_RGB_TO_HSV_fwd)
{
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_RGB_TO_HSV);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
m_data->m_threshold = 1e-6f;
}
OCIO_OSL_TEST(FixedFunction, style_RGB_TO_HSV_fwd_custom)
{
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_RGB_TO_HSV);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
m_data->m_inputValues =
{
{ 1.500f, 2.500f, 0.500f, 0.50f },
{ 3.125f, -0.625f, 1.250f, 1.00f },
{ -5.f/3.f, -4.f/3.f, -1.f/3.f, 0.25f },
{ 0.100f, -0.800f, 0.400f, 0.25f }
};
m_data->m_threshold = 1e-6f;
}
OCIO_OSL_TEST(FixedFunction, style_RGB_TO_HSV_inv)
{
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_RGB_TO_HSV);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
m_data->m_threshold = 5e-4f;
m_data->m_relativeComparison = true;
m_data->m_expectedMinimalValue = 5e-3f;
}
OCIO_OSL_TEST(FixedFunction, style_RGB_TO_HSV_inv_custom)
{
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_RGB_TO_HSV);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
m_data->m_inputValues =
{
{ 3.f/12.f, 0.80f, 2.50f, 0.50f }, // val > 1
{ 11.f/12.f, 1.20f, 2.50f, 1.00f }, // sat > 1
{ 15.f/24.f, 0.80f, -2.00f, 0.25f }, // val < 0
{ 19.f/24.f, 1.50f, -0.40f, 0.25f }, // sat > 1, val < 0
{ -89.f/24.f, 0.50f, 0.40f, 2.00f }, // under-range hue
{ 81.f/24.f, 1.50f, -0.40f, -0.25f }, // over-range hue, sat > 1, val < 0
{ 81.f/24.f, -0.50f, 0.40f, 0.00f }, // sat < 0
{ 0.5000f, 2.50f, 0.04f, 0.00f } // sat > 2
};
m_data->m_threshold = 1e-6f;
}
OCIO_OSL_TEST(FixedFunction, style_XYZ_TO_xyY_fwd)
{
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_XYZ_TO_xyY);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
m_data->m_threshold = 1e-6f;
}
OCIO_OSL_TEST(FixedFunction, style_XYZ_TO_xyY_inv)
{
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_XYZ_TO_xyY);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
m_data->m_threshold = 1e-6f;
}
OCIO_OSL_TEST(FixedFunction, style_XYZ_TO_uvY_fwd)
{
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_XYZ_TO_uvY);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
m_data->m_threshold = 1e-6f;
}
OCIO_OSL_TEST(FixedFunction, style_XYZ_TO_uvY_inv)
{
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_XYZ_TO_uvY);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
m_data->m_threshold = 1e-5f;
}
OCIO_OSL_TEST(FixedFunction, style_XYZ_TO_LUV_fwd)
{
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_XYZ_TO_LUV);
func->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
m_data->m_transform = func;
m_data->m_threshold = 1e-5f;
}
OCIO_OSL_TEST(FixedFunction, style_XYZ_TO_LUV_inv)
{
OCIO::FixedFunctionTransformRcPtr func =
OCIO::FixedFunctionTransform::Create(OCIO::FIXED_FUNCTION_XYZ_TO_LUV);
func->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = func;
m_data->m_threshold = 1e-5f;
}
+167
View File
@@ -0,0 +1,167 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
// NOTE:
// The file is a copy and paste from the corresponding GPU unitest i.e. []/tests/gpu/GammaOp_test.cpp.
// Keep the two files in sync. to increase the test coverage.
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
namespace
{
// Helper method to build unit tests
OCIO::ExponentTransformRcPtr AddExponent(OCIO::TransformDirection direction,
const double(&gamma)[4],
OCIO::NegativeStyle style)
{
OCIO::ExponentTransformRcPtr exp = OCIO::ExponentTransform::Create();
exp->setNegativeStyle(style);
exp->setDirection(direction);
exp->setValue(gamma);
return exp;
}
// Helper method to build unit tests
OCIO::ExponentWithLinearTransformRcPtr AddExponentWithLinear(OCIO::TransformDirection direction,
const double(&gamma)[4],
const double(&offset)[4],
OCIO::NegativeStyle style)
{
OCIO::ExponentWithLinearTransformRcPtr exp = OCIO::ExponentWithLinearTransform::Create();
exp->setDirection(direction);
exp->setGamma(gamma);
exp->setOffset(offset);
exp->setNegativeStyle(style);
return exp;
}
} // anon. namespace
OCIO_OSL_TEST(ExponentOp, forward_v1)
{
static constexpr double exp[4] = { 2.6, 1.0, 1.8, 1.1 };
m_data->m_transform
= AddExponent(OCIO::TRANSFORM_DIR_FORWARD, exp, OCIO::NEGATIVE_CLAMP);
m_data->m_config->setMajorVersion(1);
m_data->m_threshold = 1e-5f;
}
OCIO_OSL_TEST(ExponentOp, forward)
{
static constexpr double exp[4] = { 2.6, 1.0, 1.8, 1.1 };
m_data->m_transform
= AddExponent(OCIO::TRANSFORM_DIR_FORWARD, exp, OCIO::NEGATIVE_CLAMP);
m_data->m_threshold = 1e-5f;
}
OCIO_OSL_TEST(ExponentOp, forward_mirror)
{
static constexpr double exp[4] = { 2.6, 1.0, 1.8, 1.1 };
m_data->m_transform
= AddExponent(OCIO::TRANSFORM_DIR_FORWARD, exp, OCIO::NEGATIVE_MIRROR);
m_data->m_threshold = 1e-5f;
}
OCIO_OSL_TEST(ExponentOp, forward_pass_thru)
{
static constexpr double exp[4] = { 2.6, 1.0, 1.8, 1.1 };
m_data->m_transform
= AddExponent(OCIO::TRANSFORM_DIR_FORWARD, exp, OCIO::NEGATIVE_PASS_THRU);
m_data->m_threshold = 1e-5f;
}
OCIO_OSL_TEST(ExponentOp, inverse_v1)
{
static constexpr double exp[4] = { 2.6, 1.0, 1.8, 1.1 };
m_data->m_transform
= AddExponent(OCIO::TRANSFORM_DIR_INVERSE, exp, OCIO::NEGATIVE_CLAMP);
m_data->m_config->setMajorVersion(1);
m_data->m_threshold = 1e-5f; // Slight difference with the GLSL unit test i.e. g_epsilon
}
OCIO_OSL_TEST(ExponentOp, inverse)
{
static constexpr double exp[4] = { 2.6, 1.0, 1.8, 1.1 };
m_data->m_transform
= AddExponent(OCIO::TRANSFORM_DIR_INVERSE, exp, OCIO::NEGATIVE_CLAMP);
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 1e-6f
}
OCIO_OSL_TEST(ExponentOp, inverse_mirror)
{
static constexpr double exp[4] = { 2.6, 1.0, 1.8, 1.1 };
m_data->m_transform
= AddExponent(OCIO::TRANSFORM_DIR_INVERSE, exp, OCIO::NEGATIVE_MIRROR);
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 1e-6f
}
OCIO_OSL_TEST(ExponentOp, inverse_pass_thru)
{
static constexpr double exp[4] = { 2.6, 1.0, 1.8, 1.1 };
m_data->m_transform
= AddExponent(OCIO::TRANSFORM_DIR_INVERSE, exp, OCIO::NEGATIVE_PASS_THRU);
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 1e-6f
}
static constexpr double gammaVals[4] = { 2.1, 1.0, 2.3, 1.5 };
static constexpr double offsetVals[4] = { .01, 0., .03, .05 };
OCIO_OSL_TEST(ExponentWithLinearOp, forward)
{
m_data->m_transform
= AddExponentWithLinear(OCIO::TRANSFORM_DIR_FORWARD, gammaVals, offsetVals, OCIO::NEGATIVE_LINEAR);
m_data->m_threshold = 1e-5f; // Slight difference with the GLSL unit test i.e. 5e-6f
}
OCIO_OSL_TEST(ExponentWithLinearOp, mirror_forward)
{
m_data->m_transform
= AddExponentWithLinear(OCIO::TRANSFORM_DIR_FORWARD, gammaVals, offsetVals, OCIO::NEGATIVE_MIRROR);
m_data->m_threshold = 1e-5f; // Slight difference with the GLSL unit test i.e. 5e-6f
}
OCIO_OSL_TEST(ExponentWithLinearOp, inverse)
{
m_data->m_transform
= AddExponentWithLinear(OCIO::TRANSFORM_DIR_INVERSE, gammaVals, offsetVals, OCIO::NEGATIVE_LINEAR);
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 5e-7f
}
OCIO_OSL_TEST(ExponentWithLinearOp, mirror_inverse)
{
m_data->m_transform
= AddExponentWithLinear(OCIO::TRANSFORM_DIR_INVERSE, gammaVals, offsetVals, OCIO::NEGATIVE_MIRROR);
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 5e-7f
}
+275
View File
@@ -0,0 +1,275 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
// NOTE:
// The file is a copy and paste from the corresponding GPU unitest i.e. []/tests/gpu/GradingPrimaryOp_test.cpp.
// Keep the two files in sync. to increase the test coverage.
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
namespace GPTest1
{
static constexpr OCIO::GradingStyle style = OCIO::GRADING_LOG;
static const OCIO::GradingRGBM brightness{ -10., 45., -5., 50. };
static const OCIO::GradingRGBM contrast{ 0.9, 1.4, 0.7, 0.75 };
static const OCIO::GradingRGBM gamma{ 1.1, 0.7, 1.05, 1.15 };
static constexpr double saturation = 1.21;
static constexpr double pivot = -0.3;
static constexpr double pivotBlack = 0.05;
static constexpr double pivotWhite = 0.9;
static constexpr double clampBlack = -0.05;
static constexpr double clampWhite = 1.50;
}
OCIO::GradingPrimaryTransformRcPtr GradingPrimaryLog(OCIO::TransformDirection dir, bool dynamic)
{
auto gp = OCIO::GradingPrimaryTransform::Create(GPTest1::style);
gp->setDirection(dir);
if (dynamic)
{
gp->makeDynamic();
}
OCIO::GradingPrimary gplog{ GPTest1::style };
gplog.m_brightness = GPTest1::brightness;
gplog.m_contrast = GPTest1::contrast;
gplog.m_gamma = GPTest1::gamma;
gplog.m_saturation = GPTest1::saturation;
gplog.m_pivot = GPTest1::pivot;
gplog.m_pivotBlack = GPTest1::pivotBlack;
gplog.m_pivotWhite = GPTest1::pivotWhite;
gplog.m_clampBlack = GPTest1::clampBlack;
gplog.m_clampWhite = GPTest1::clampWhite;
gp->setValue(gplog);
return gp;
}
OCIO_OSL_TEST(GradingPrimary, style_log_fwd)
{
m_data->m_transform = GradingPrimaryLog(OCIO::TRANSFORM_DIR_FORWARD, false);
m_data->m_threshold = 2e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingPrimary, style_log_fwd_dynamic)
{
m_data->m_transform = GradingPrimaryLog(OCIO::TRANSFORM_DIR_FORWARD, true);
m_data->m_threshold = 2e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingPrimary, style_log_rev)
{
m_data->m_transform = GradingPrimaryLog(OCIO::TRANSFORM_DIR_INVERSE, false);
m_data->m_threshold = 5e-4f; // Slight difference with the GLSL unit test i.e. 2e-5f
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingPrimary, style_log_rev_dynamic)
{
m_data->m_transform = GradingPrimaryLog(OCIO::TRANSFORM_DIR_INVERSE, true);
m_data->m_threshold = 5e-4f; // Slight difference with the GLSL unit test i.e. 2e-5f
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
namespace GPTest2
{
static constexpr OCIO::GradingStyle style = OCIO::GRADING_LIN;
static const OCIO::GradingRGBM exposure{ 0.5, -0.2, 0.4, -0.25 };
static const OCIO::GradingRGBM offset{ -0.03, 0.02, 0.1, -0.1 };
static const OCIO::GradingRGBM contrast{ 0.9, 1.4, 0.7, 0.75 };
static constexpr double saturation = 1.33;
static constexpr double pivot = 0.5;
static constexpr double clampBlack = -0.40;
static constexpr double clampWhite = 1.05;
}
OCIO::GradingPrimaryTransformRcPtr GradingPrimaryLin(OCIO::TransformDirection dir, bool dynamic)
{
auto gp = OCIO::GradingPrimaryTransform::Create(GPTest2::style);
gp->setDirection(dir);
if (dynamic)
{
gp->makeDynamic();
}
OCIO::GradingPrimary gplin{ GPTest2::style };
gplin.m_exposure = GPTest2::exposure;
gplin.m_contrast = GPTest2::contrast;
gplin.m_offset = GPTest2::offset;
gplin.m_pivot = GPTest2::pivot;
gplin.m_saturation = GPTest2::saturation;
gplin.m_clampBlack = GPTest2::clampBlack;
gplin.m_clampWhite = GPTest2::clampWhite;
gp->setValue(gplin);
return gp;
}
OCIO_OSL_TEST(GradingPrimary, style_lin_fwd)
{
m_data->m_transform = GradingPrimaryLin(OCIO::TRANSFORM_DIR_FORWARD, false);
m_data->m_threshold = 2e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingPrimary, style_lin_fwd_dynamic)
{
m_data->m_transform = GradingPrimaryLin(OCIO::TRANSFORM_DIR_FORWARD, true);
m_data->m_threshold = 2e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingPrimary, style_lin_rev)
{
m_data->m_transform = GradingPrimaryLin(OCIO::TRANSFORM_DIR_INVERSE, false);
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 2e-5f
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingPrimary, style_lin_rev_dynamic)
{
m_data->m_transform = GradingPrimaryLin(OCIO::TRANSFORM_DIR_INVERSE, true);
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 2e-5f
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
namespace GPTest3
{
static constexpr OCIO::GradingStyle style = OCIO::GRADING_LIN;
static const OCIO::GradingRGBM lift{ 0.05, -0.04, 0.02, 0.05 };
static const OCIO::GradingRGBM gamma{ 0.9, 1.4, 0.7, 0.75 };
static const OCIO::GradingRGBM gain{ 1.2, 1.1, 1.25, 0.8 };
static const OCIO::GradingRGBM offset{ -0.03, 0.02, 0.1, -0.1 };
static constexpr double saturation = 1.2;
static constexpr double pivotBlack = 0.05;
static constexpr double pivotWhite = 0.9;
static constexpr double clampBlack = -0.15;
static constexpr double clampWhite = 1.50;
}
void GradingPrimaryVideo(OSLDataRcPtr & data, OCIO::TransformDirection dir, bool dynamic)
{
auto gp = OCIO::GradingPrimaryTransform::Create(GPTest3::style);
gp->setDirection(dir);
if (dynamic)
{
gp->makeDynamic();
}
OCIO::GradingPrimary gpvideo{ GPTest3::style };
gpvideo.m_lift = GPTest3::lift;
gpvideo.m_gamma = GPTest3::gamma;
gpvideo.m_gain = GPTest3::gain;
gpvideo.m_offset = GPTest3::offset;
gpvideo.m_saturation = GPTest3::saturation;
gpvideo.m_clampBlack = GPTest3::clampBlack;
gpvideo.m_clampWhite = GPTest3::clampWhite;
gpvideo.m_pivotBlack = GPTest3::pivotBlack;
gpvideo.m_pivotWhite = GPTest3::pivotWhite;
gp->setValue(gpvideo);
data->m_threshold = 3e-5f;
data->m_expectedMinimalValue = 1.0f;
data->m_relativeComparison = true;
data->m_transform = gp;
}
OCIO_OSL_TEST(GradingPrimary, style_video_fwd)
{
GradingPrimaryVideo(m_data, OCIO::TRANSFORM_DIR_FORWARD, false);
}
OCIO_OSL_TEST(GradingPrimary, style_video_fwd_dynamic)
{
GradingPrimaryVideo(m_data, OCIO::TRANSFORM_DIR_FORWARD, true);
}
OCIO_OSL_TEST(GradingPrimary, style_video_rev)
{
GradingPrimaryVideo(m_data, OCIO::TRANSFORM_DIR_INVERSE, false);
}
OCIO_OSL_TEST(GradingPrimary, style_video_rev_dynamic)
{
GradingPrimaryVideo(m_data, OCIO::TRANSFORM_DIR_INVERSE, true);
}
OCIO_OSL_TEST(GradingPrimary, style_log_dynamic_retests)
{
auto gp = OCIO::GradingPrimaryTransform::Create(GPTest1::style);
gp->makeDynamic();
OCIO::GradingPrimary gplog{ GPTest1::style };
gplog.m_brightness = GPTest1::brightness;
gplog.m_contrast = GPTest1::contrast;
gplog.m_gamma = GPTest1::gamma;
gplog.m_saturation = GPTest1::saturation;
gplog.m_pivot = GPTest1::pivot;
gp->setValue(gplog);
m_data->m_transform = gp;
m_data->m_threshold = 5e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingPrimary, two_transforms_retests)
{
auto gpDyn = OCIO::GradingPrimaryTransform::Create(GPTest1::style);
gpDyn->makeDynamic();
OCIO::GradingPrimary gplog{ GPTest1::style };
gplog.m_brightness = GPTest1::brightness;
gplog.m_contrast = GPTest1::contrast;
gplog.m_gamma = GPTest1::gamma;
gplog.m_saturation = GPTest1::saturation;
gplog.m_pivot = GPTest1::pivot;
gpDyn->setValue(gplog);
auto gpNonDyn = OCIO::GradingPrimaryTransform::Create(GPTest2::style);
OCIO::GradingPrimary gplin{ GPTest2::style };
gplin.m_exposure = GPTest2::exposure;
gplin.m_contrast = GPTest2::contrast;
gplin.m_offset = GPTest2::offset;
gplin.m_pivot = GPTest2::pivot;
gplin.m_saturation = GPTest2::saturation;
gplin.m_clampBlack = GPTest2::clampBlack;
gplin.m_clampWhite = GPTest2::clampWhite;
gpNonDyn->setValue(gplin);
auto group = OCIO::GroupTransform::Create();
group->appendTransform(gpDyn);
group->appendTransform(gpNonDyn);
m_data->m_transform = group;
m_data->m_threshold = 1e-4f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
+182
View File
@@ -0,0 +1,182 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
// NOTE:
// The file is a copy and paste from the corresponding GPU unitest i.e. []/tests/gpu/GradingRGBCurveOp_test.cpp.
// Keep the two files in sync. to increase the test coverage.
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
void GradingRGBCurveLog(OSLDataRcPtr & data, OCIO::TransformDirection dir, bool dynamic)
{
auto r = OCIO::GradingBSplineCurve::Create({ { 0.0f, 0.0f }, { 0.785f, 0.231f },
{ 0.809f, 0.631f },{ 0.948f, 0.704f },
{ 1.0f, 1.0f } });
auto g = OCIO::GradingBSplineCurve::Create({ { 0.1f, 0.15f }, { 0.55f, 0.35f },{ 0.9f, 1.1f } });
auto b = OCIO::GradingBSplineCurve::Create({ { -6.f, -8.f }, { -2.f, -5.f },
{ 2.f, 4.f }, { 5.f, 6.f } });
auto m = OCIO::GradingBSplineCurve::Create({ { -0.1f, 0.1f },{ 1.1f, 1.3f } });
OCIO::ConstGradingRGBCurveRcPtr curves = OCIO::GradingRGBCurve::Create(r, g, b, m);
auto gc = OCIO::GradingRGBCurveTransform::Create(OCIO::GRADING_LOG);
gc->setValue(curves);
gc->setDirection(dir);
if (dynamic)
{
gc->makeDynamic();
}
data->m_transform = gc;
data->m_threshold = 2e-5f;
data->m_expectedMinimalValue = 1.0f;
data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingRGBCurve, style_log_fwd)
{
GradingRGBCurveLog(m_data, OCIO::TRANSFORM_DIR_FORWARD, false);
}
OCIO_OSL_TEST(GradingRGBCurve, style_log_fwd_dynamic)
{
GradingRGBCurveLog(m_data, OCIO::TRANSFORM_DIR_FORWARD, true);
}
OCIO_OSL_TEST(GradingRGBCurve, style_log_rev)
{
GradingRGBCurveLog(m_data, OCIO::TRANSFORM_DIR_INVERSE, false);
}
OCIO_OSL_TEST(GradingRGBCurve, style_log_rev_dynamic)
{
GradingRGBCurveLog(m_data, OCIO::TRANSFORM_DIR_INVERSE, true);
}
void GradingRGBCurveLin(OSLDataRcPtr & data, OCIO::TransformDirection dir, bool dynamic)
{
auto r = OCIO::GradingBSplineCurve::Create({ { 0.0f, 0.0f },{ 0.785f, 0.231f },
{ 0.809f, 0.631f },{ 0.948f, 0.704f },
{ 1.0f, 1.0f } });
auto g = OCIO::GradingBSplineCurve::Create({ { 0.1f, 0.15f },{ 0.55f, 0.35f },{ 0.9f, 0.8f } });
auto b = OCIO::GradingBSplineCurve::Create({ { -6.f, -4.f },{ -2.f, -1.f },
{ 2.f, 2.f },{ 5.f, 4.f } });
auto m = OCIO::GradingBSplineCurve::Create({ { -0.1f, 0.1f },{ 1.1f, 0.9f } });
OCIO::ConstGradingRGBCurveRcPtr curves = OCIO::GradingRGBCurve::Create(r, g, b, m);
auto gc = OCIO::GradingRGBCurveTransform::Create(OCIO::GRADING_LIN);
gc->setValue(curves);
gc->setDirection(dir);
if (dynamic)
{
gc->makeDynamic();
}
data->m_transform = gc;
data->m_threshold = 1.5e-4f;
data->m_expectedMinimalValue = 1.0f;
data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingRGBCurve, style_lin_fwd)
{
GradingRGBCurveLin(m_data, OCIO::TRANSFORM_DIR_FORWARD, false);
}
OCIO_OSL_TEST(GradingRGBCurve, style_lin_fwd_dynamic)
{
GradingRGBCurveLin(m_data, OCIO::TRANSFORM_DIR_FORWARD, true);
}
OCIO_OSL_TEST(GradingRGBCurve, style_lin_rev)
{
GradingRGBCurveLin(m_data, OCIO::TRANSFORM_DIR_INVERSE, false);
}
OCIO_OSL_TEST(GradingRGBCurve, style_lin_rev_dynamic)
{
GradingRGBCurveLin(m_data, OCIO::TRANSFORM_DIR_INVERSE, true);
}
OCIO_OSL_TEST(GradingRGBCurve, style_log_dynamic_retests)
{
auto gc = OCIO::GradingRGBCurveTransform::Create(OCIO::GRADING_LOG);
gc->makeDynamic();
auto rnc = OCIO::GradingBSplineCurve::Create({ { 0.0f, 0.0f },{ 0.785f, 0.231f },
{ 0.809f, 0.631f },{ 0.948f, 0.704f },
{ 1.0f, 1.0f } });
auto gnc = OCIO::GradingBSplineCurve::Create({ { 0.1f, 0.15f },{ 0.55f, 0.35f },{ 0.9f, 1.1f } });
auto bnc = OCIO::GradingBSplineCurve::Create({ { -6.f, -8.f },{ -2.f, -5.f },
{ 2.f, 4.f },{ 5.f, 6.f } });
auto mnc = OCIO::GradingBSplineCurve::Create({ { -0.1f, 0.1f },{ 1.1f, 1.3f } });
OCIO::ConstGradingBSplineCurveRcPtr r = rnc;
OCIO::ConstGradingBSplineCurveRcPtr g = gnc;
OCIO::ConstGradingBSplineCurveRcPtr b = bnc;
OCIO::ConstGradingBSplineCurveRcPtr m = mnc;
OCIO::ConstGradingRGBCurveRcPtr curves = OCIO::GradingRGBCurve::Create(r, g, b, m);
gc->setValue(curves);
m_data->m_transform = gc;
m_data->m_threshold = 5e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingRGBCurve, two_transforms_retests)
{
auto gcDyn = OCIO::GradingRGBCurveTransform::Create(OCIO::GRADING_LOG);
gcDyn->makeDynamic();
auto rnc = OCIO::GradingBSplineCurve::Create({ { 0.0f, 0.0f }, { 0.785f, 0.231f },
{ 0.809f, 0.631f }, { 0.948f, 0.704f },
{ 1.0f, 1.0f } });
auto gnc = OCIO::GradingBSplineCurve::Create({ { 0.1f, 0.15f }, { 0.55f, 0.35f }, { 0.9f, 1.1f } });
auto bnc = OCIO::GradingBSplineCurve::Create({ { -6.f, -8.f }, { -2.f, -5.f },
{ 2.f, 4.f }, { 5.f, 6.f } });
auto mnc = OCIO::GradingBSplineCurve::Create({ { -0.1f, 0.1f }, { 1.1f, 1.3f } });
OCIO::ConstGradingBSplineCurveRcPtr r = rnc;
OCIO::ConstGradingBSplineCurveRcPtr g = gnc;
OCIO::ConstGradingBSplineCurveRcPtr b = bnc;
OCIO::ConstGradingBSplineCurveRcPtr m = mnc;
OCIO::ConstGradingRGBCurveRcPtr curves = OCIO::GradingRGBCurve::Create(r, g, b, m);
gcDyn->setValue(curves);
auto c1 = OCIO::GradingBSplineCurve::Create({ { 0.0f, 0.0f },{ 0.2f, 0.2f },
{ 0.5f, 0.7f },{ 1.0f, 1.0f } });
auto c2 = OCIO::GradingBSplineCurve::Create({ { 0.0f, 0.5f },{ 0.3f, 0.7f },
{ 0.5f, 1.1f },{ 1.0f, 1.5f } });
auto c3 = OCIO::GradingBSplineCurve::Create({ { 0.0f, -0.5f },{ 0.2f, -0.4f },
{ 0.3f, 0.1f },{ 0.5f, 0.4f },
{ 0.7f, 0.9f },{ 1.0f, 1.1f } });
auto c4 = OCIO::GradingBSplineCurve::Create({ { -1.0f, 0.0f },{ 0.2f, 0.2f },
{ 0.8f, 0.8f },{ 2.0f, 1.0f } });
OCIO::ConstGradingRGBCurveRcPtr curves2 = OCIO::GradingRGBCurve::Create(c1, c2, c3, c4);
auto gcNonDyn = OCIO::GradingRGBCurveTransform::Create(OCIO::GRADING_LIN);
gcNonDyn->setValue(curves2);
auto group = OCIO::GroupTransform::Create();
group->appendTransform(gcDyn);
group->appendTransform(gcNonDyn);
m_data->m_transform = group;
m_data->m_threshold = 5e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
+408
View File
@@ -0,0 +1,408 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
// NOTE:
// The file is a copy and paste from the corresponding GPU unitest i.e. []/tests/gpu/GradingToneOp_test.cpp.
// Keep the two files in sync. to increase the test coverage.
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
namespace GTTest1
{
static constexpr OCIO::GradingStyle style = OCIO::GRADING_LOG;
// These are {R, G, B, master, center, width};
static const OCIO::GradingRGBMSW midtones{ 0.3, 1.0, 1.8, 1.2, 0.47, 0.6 };
}
void GradingToneLogMidtones(OSLDataRcPtr & data, OCIO::TransformDirection dir, bool dynamic)
{
auto gt = OCIO::GradingToneTransform::Create(GTTest1::style);
gt->setDirection(dir);
if (dynamic)
{
gt->makeDynamic();
}
OCIO::GradingTone tone(GTTest1::style);
tone.m_midtones = GTTest1::midtones;
gt->setValue(tone);
data->m_transform = gt;
data->m_threshold = 2e-5f;
data->m_expectedMinimalValue = 1.0f;
data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingTone, style_log_midtones_fwd)
{
GradingToneLogMidtones(m_data, OCIO::TRANSFORM_DIR_FORWARD, false);
}
OCIO_OSL_TEST(GradingTone, style_log_midtones_fwd_dynamic)
{
GradingToneLogMidtones(m_data, OCIO::TRANSFORM_DIR_FORWARD, true);
}
OCIO_OSL_TEST(GradingTone, style_log_midtones_rev)
{
GradingToneLogMidtones(m_data, OCIO::TRANSFORM_DIR_INVERSE, false);
}
OCIO_OSL_TEST(GradingTone, style_log_midtones_rev_dynamic)
{
GradingToneLogMidtones(m_data, OCIO::TRANSFORM_DIR_INVERSE, true);
}
namespace GTTest2
{
static constexpr OCIO::GradingStyle style = OCIO::GRADING_LOG;
// These are {R, G, B, master, start, pivot};
static const OCIO::GradingRGBMSW highlights{ 0.3, 1.0, 1.8, 1.4, -0.1, 0.9 };
}
void GradingToneLogHighlights(OSLDataRcPtr & data, OCIO::TransformDirection dir, bool dynamic)
{
auto gt = OCIO::GradingToneTransform::Create(GTTest2::style);
gt->setDirection(dir);
if (dynamic)
{
gt->makeDynamic();
}
OCIO::GradingTone tone(GTTest2::style);
tone.m_highlights = GTTest2::highlights;
gt->setValue(tone);
data->m_transform = gt;
data->m_threshold = 2e-5f;
data->m_expectedMinimalValue = 1.0f;
data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingTone, style_log_highlights_fwd)
{
GradingToneLogHighlights(m_data, OCIO::TRANSFORM_DIR_FORWARD, false);
}
OCIO_OSL_TEST(GradingTone, style_log_highlights_fwd_dynamic)
{
GradingToneLogHighlights(m_data, OCIO::TRANSFORM_DIR_FORWARD, true);
}
OCIO_OSL_TEST(GradingTone, style_log_highlights_rev)
{
GradingToneLogHighlights(m_data, OCIO::TRANSFORM_DIR_INVERSE, false);
}
OCIO_OSL_TEST(GradingTone, style_log_highlights_rev_dynamic)
{
GradingToneLogHighlights(m_data, OCIO::TRANSFORM_DIR_INVERSE, true);
}
namespace GTTest3
{
static constexpr OCIO::GradingStyle style = OCIO::GRADING_VIDEO;
// These are {R, G, B, master, start, pivot};
static const OCIO::GradingRGBMSW shadows{ 0.3, 1., 1.79, 0.6, 0.8, -0.1 };
}
void GradingToneVideoShadows(OSLDataRcPtr & data, OCIO::TransformDirection dir, bool dynamic)
{
auto gt = OCIO::GradingToneTransform::Create(GTTest3::style);
gt->setDirection(dir);
if (dynamic)
{
gt->makeDynamic();
}
OCIO::GradingTone tone(GTTest3::style);
tone.m_shadows = GTTest3::shadows;
gt->setValue(tone);
data->m_transform = gt;
data->m_threshold = 3e-5f;
data->m_expectedMinimalValue = 1.0f;
data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingTone, style_video_shadows_fwd)
{
GradingToneVideoShadows(m_data, OCIO::TRANSFORM_DIR_FORWARD, false);
}
OCIO_OSL_TEST(GradingTone, style_video_shadows_fwd_dynamic)
{
GradingToneVideoShadows(m_data, OCIO::TRANSFORM_DIR_FORWARD, true);
}
OCIO_OSL_TEST(GradingTone, style_video_shadows_rev)
{
GradingToneVideoShadows(m_data, OCIO::TRANSFORM_DIR_INVERSE, false);
}
OCIO_OSL_TEST(GradingTone, style_video_shadows_rev_dynamic)
{
GradingToneVideoShadows(m_data, OCIO::TRANSFORM_DIR_INVERSE, true);
}
namespace GTTest4
{
static constexpr OCIO::GradingStyle style = OCIO::GRADING_VIDEO;
// These are {R, G, B, master, start, width};
static const OCIO::GradingRGBMSW whites{ 0.3, 1., 1.9, 0.6, -0.2, 1.4 };
}
void GradingToneVideoWhites(OSLDataRcPtr & data, OCIO::TransformDirection dir, bool dynamic)
{
auto gt = OCIO::GradingToneTransform::Create(GTTest4::style);
gt->setDirection(dir);
if (dynamic)
{
gt->makeDynamic();
}
OCIO::GradingTone tone(GTTest4::style);
tone.m_whites = GTTest4::whites;
gt->setValue(tone);
data->m_transform = gt;
data->m_threshold = 3e-5f;
data->m_expectedMinimalValue = 1.0f;
data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingTone, style_video_white_detail_fwd)
{
GradingToneVideoWhites(m_data, OCIO::TRANSFORM_DIR_FORWARD, false);
}
OCIO_OSL_TEST(GradingTone, style_video_white_detail_fwd_dynamic)
{
GradingToneVideoWhites(m_data, OCIO::TRANSFORM_DIR_FORWARD, true);
}
OCIO_OSL_TEST(GradingTone, style_video_white_detail_rev)
{
GradingToneVideoWhites(m_data, OCIO::TRANSFORM_DIR_INVERSE, false);
}
OCIO_OSL_TEST(GradingTone, style_video_white_detail_rev_dynamic)
{
GradingToneVideoWhites(m_data, OCIO::TRANSFORM_DIR_INVERSE, true);
}
namespace GTTest5
{
static constexpr OCIO::GradingStyle style = OCIO::GRADING_LOG;
// These are {R, G, B, master, start, width};
static const OCIO::GradingRGBMSW blacks{ 0.3, 1., 1.9, 0.6, 0.8, 0.9 };
}
void GradingToneLogBlacks(OSLDataRcPtr & data, OCIO::TransformDirection dir, bool dynamic)
{
auto gt = OCIO::GradingToneTransform::Create(GTTest5::style);
gt->setDirection(dir);
if (dynamic)
{
gt->makeDynamic();
}
OCIO::GradingTone tone(GTTest5::style);
tone.m_blacks = GTTest5::blacks;
gt->setValue(tone);
data->m_transform = gt;
data->m_threshold = 3e-5f;
data->m_expectedMinimalValue = 1.0f;
data->m_relativeComparison = true;}
OCIO_OSL_TEST(GradingTone, style_log_black_detail_fwd)
{
GradingToneLogBlacks(m_data, OCIO::TRANSFORM_DIR_FORWARD, false);
}
OCIO_OSL_TEST(GradingTone, style_log_black_detail_fwd_dynamic)
{
GradingToneLogBlacks(m_data, OCIO::TRANSFORM_DIR_FORWARD, true);
}
OCIO_OSL_TEST(GradingTone, style_log_black_detail_rev)
{
GradingToneLogBlacks(m_data, OCIO::TRANSFORM_DIR_INVERSE, false);
}
OCIO_OSL_TEST(GradingTone, style_log_black_detail_rev_dynamic)
{
GradingToneLogBlacks(m_data, OCIO::TRANSFORM_DIR_INVERSE, true);
}
namespace GTTest6
{
static constexpr OCIO::GradingStyle style = OCIO::GRADING_LOG;
static constexpr double scontrast = 1.8;
static constexpr double scontrast2 = 0.3;
}
void GradingToneLogSContrast(OSLDataRcPtr & data,
OCIO::TransformDirection dir,
bool dynamic,
double scontrast)
{
auto gt = OCIO::GradingToneTransform::Create(GTTest6::style);
gt->setDirection(dir);
if (dynamic)
{
gt->makeDynamic();
}
OCIO::GradingTone tone(GTTest6::style);
tone.m_scontrast = scontrast;
gt->setValue(tone);
data->m_transform = gt;
data->m_threshold = 3e-5f;
data->m_expectedMinimalValue = 1.0f;
data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingTone, style_log_scontrast_fwd)
{
GradingToneLogSContrast(m_data, OCIO::TRANSFORM_DIR_FORWARD, false, GTTest6::scontrast);
}
OCIO_OSL_TEST(GradingTone, style_log_scontrast_fwd_dynamic)
{
GradingToneLogSContrast(m_data, OCIO::TRANSFORM_DIR_FORWARD, true, GTTest6::scontrast);
}
OCIO_OSL_TEST(GradingTone, style_log_scontrast2_fwd)
{
GradingToneLogSContrast(m_data, OCIO::TRANSFORM_DIR_FORWARD, false, GTTest6::scontrast2);
}
OCIO_OSL_TEST(GradingTone, style_log_scontrast2_fwd_dynamic)
{
GradingToneLogSContrast(m_data, OCIO::TRANSFORM_DIR_FORWARD, true, GTTest6::scontrast2);
}
OCIO_OSL_TEST(GradingTone, style_log_scontrast_rev)
{
GradingToneLogSContrast(m_data, OCIO::TRANSFORM_DIR_INVERSE, false, GTTest6::scontrast);
}
OCIO_OSL_TEST(GradingTone, style_log_scontrast_rev_dynamic)
{
GradingToneLogSContrast(m_data, OCIO::TRANSFORM_DIR_INVERSE, true, GTTest6::scontrast);
}
OCIO_OSL_TEST(GradingTone, style_log_scontrast2_rev)
{
GradingToneLogSContrast(m_data, OCIO::TRANSFORM_DIR_INVERSE, false, GTTest6::scontrast2);
}
OCIO_OSL_TEST(GradingTone, style_log_scontrast2_rev_dynamic)
{
GradingToneLogSContrast(m_data, OCIO::TRANSFORM_DIR_INVERSE, true, GTTest6::scontrast2);
}
namespace GTTest7
{
static constexpr OCIO::GradingStyle style = OCIO::GRADING_LIN;
// These are {R, G, B, master, center, width};
const OCIO::GradingRGBMSW midtones{ 0.3, 1.4, 1.8, 1., 1., 8. };
}
void GradingToneLinMidtones(OSLDataRcPtr & data, OCIO::TransformDirection dir, bool dynamic)
{
auto gt = OCIO::GradingToneTransform::Create(GTTest7::style);
gt->setDirection(dir);
if (dynamic)
{
gt->makeDynamic();
}
OCIO::GradingTone tone(GTTest7::style);
tone.m_midtones = GTTest7::midtones;
gt->setValue(tone);
data->m_transform = gt;
data->m_threshold = 5e-5f;
data->m_expectedMinimalValue = 1.0f;
data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingTone, style_lin_midtones_fwd)
{
GradingToneLinMidtones(m_data, OCIO::TRANSFORM_DIR_FORWARD, false);
}
OCIO_OSL_TEST(GradingTone, style_lin_midtones_fwd_dynamic)
{
GradingToneLinMidtones(m_data, OCIO::TRANSFORM_DIR_FORWARD, true);
}
OCIO_OSL_TEST(GradingTone, style_lin_midtones_rev)
{
GradingToneLinMidtones(m_data, OCIO::TRANSFORM_DIR_INVERSE, false);
}
OCIO_OSL_TEST(GradingTone, style_lin_midtones_rev_dynamic)
{
GradingToneLinMidtones(m_data, OCIO::TRANSFORM_DIR_INVERSE, true);
}
OCIO_OSL_TEST(GradingTone, style_log_dynamic_retests)
{
auto gt = OCIO::GradingToneTransform::Create(OCIO::GRADING_LOG);
gt->makeDynamic();
OCIO::GradingTone gtlog{ OCIO::GRADING_LOG };
gt->setValue(gtlog);
m_data->m_transform = gt;
m_data->m_threshold = 5e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
OCIO_OSL_TEST(GradingTone, two_transforms_retests)
{
auto gtDyn = OCIO::GradingToneTransform::Create(OCIO::GRADING_LOG);
gtDyn->makeDynamic();
OCIO::GradingTone gtlog{ OCIO::GRADING_LOG };
gtDyn->setValue(gtlog);
auto gtNonDyn = OCIO::GradingToneTransform::Create(GTTest6::style);
OCIO::GradingTone tone{ OCIO::GRADING_LIN };
tone.m_scontrast = 1.8;
tone.m_midtones = OCIO::GradingRGBMSW(0.3, 1.4, 1.8, 1., 1., 8.);
gtNonDyn->setValue(tone);
auto group = OCIO::GroupTransform::Create();
group->appendTransform(gtDyn);
group->appendTransform(gtNonDyn);
m_data->m_transform = group;
m_data->m_threshold = 5e-5f;
m_data->m_expectedMinimalValue = 1.0f;
m_data->m_relativeComparison = true;
}
+274
View File
@@ -0,0 +1,274 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
// NOTE:
// The file is a copy and paste from the corresponding GPU unitest i.e. []/tests/gpu/LogOp_test.cpp.
// Keep the two files in sync. to increase the test coverage.
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
static constexpr float g_epsilon = 1e-5f;
static constexpr float g_epsilon_inverse = 1e-4f;
static constexpr float base10 = 10.0f;
static const float eulerConstant = expf(1.0f);
OCIO_OSL_TEST(LogTransform, LogBase_10_generic_shader)
{
OCIO::LogTransformRcPtr log = OCIO::LogTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
log->setBase(base10);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon;
}
OCIO_OSL_TEST(LogTransform, LogBase_10_inverse_generic_shader)
{
OCIO::LogTransformRcPtr log = OCIO::LogTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
log->setBase(base10);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon_inverse;
}
OCIO_OSL_TEST(LogTransform, LogBase_euler_generic_shader)
{
OCIO::LogTransformRcPtr log = OCIO::LogTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
log->setBase(eulerConstant);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon;
}
OCIO_OSL_TEST(LogTransform, LogBase_euler_inverse_generic_shader)
{
OCIO::LogTransformRcPtr log = OCIO::LogTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
log->setBase(eulerConstant);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon_inverse;
}
OCIO_OSL_TEST(LogAffineTransform, base)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
log->setBase(base10);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon;
}
OCIO_OSL_TEST(LogAffineTransform, base_inverse)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
log->setBase(base10);
m_data->m_transform = log;
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 1e-5f
}
OCIO_OSL_TEST(LogAffineTransform, linSideSlope)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
static constexpr double linSideSlope[3] = {2.0, 0.5, 3.0};
log->setLinSideSlopeValue(linSideSlope);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon;
}
OCIO_OSL_TEST(LogAffineTransform, linSideSlope_inverse)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
static constexpr double linSideSlope[3] = { 2.0, 0.5, 3.0 };
log->setLinSideSlopeValue(linSideSlope);
m_data->m_transform = log;
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 1e-5f
}
OCIO_OSL_TEST(LogAffineTransform, linSideOffset)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
static constexpr double linSideOffset[3] = { 0.1, 0.2, 0.3 };
log->setLinSideOffsetValue(linSideOffset);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon;
}
OCIO_OSL_TEST(LogAffineTransform, linSideOffset_inverse)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
static constexpr double linSideOffset[3] = { 0.1, 0.2, 0.3 };
log->setLinSideOffsetValue(linSideOffset);
m_data->m_transform = log;
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 1e-5f
}
OCIO_OSL_TEST(LogAffineTransform, logSideSlope)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
static constexpr double logSideSlope[3] = { 2.0, 0.5, 3.0 };
log->setLogSideSlopeValue(logSideSlope);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon * 0.5f;
}
OCIO_OSL_TEST(LogAffineTransform, logSideSlope_inverse)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
static constexpr double logSideSlope[3] = { 2.0, 0.5, 3.0 };
log->setLogSideSlopeValue(logSideSlope);
m_data->m_transform = log;
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 1e-5f
}
OCIO_OSL_TEST(LogAffineTransform, logSideOffset)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
static constexpr double logSideOffset[3] = { 0.1, 0.2, 0.3 };
log->setLogSideOffsetValue(logSideOffset);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon;
}
OCIO_OSL_TEST(LogAffineTransform, logSideOffset_inverse)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
static constexpr double logSideOffset[3] = { 0.1, 0.2, 0.3 };
log->setLogSideOffsetValue(logSideOffset);
m_data->m_transform = log;
m_data->m_threshold = 5e-5f; // Slight difference with the GLSL unit test i.e. 1e-5f
}
OCIO_OSL_TEST(LogAffineTransform, lin2log)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
static constexpr double logSideSlope[3] = { 0.2, 0.4, 0.25 };
log->setLogSideSlopeValue(logSideSlope);
static constexpr double logSideOffset[3] = { 0.14, 0.13, 0.12 };
log->setLogSideOffsetValue(logSideOffset);
static constexpr double linSideSlope[3] = { 1.5, 1.8, 1.2 };
log->setLinSideSlopeValue(linSideSlope);
static constexpr double linSideOffset[3] = { 0.05, 0.1, 0.15 };
log->setLinSideOffsetValue(linSideOffset);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon * 0.5f;
}
OCIO_OSL_TEST(LogAffineTransform, log2lin)
{
OCIO::LogAffineTransformRcPtr log = OCIO::LogAffineTransform::Create();
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
static constexpr double logSideSlope[3] = { 0.21, 0.2, 0.19 };
log->setLogSideSlopeValue(logSideSlope);
static constexpr double logSideOffset[3] = { 0.61, 0.6, 0.59 };
log->setLogSideOffsetValue(logSideOffset);
static constexpr double linSideSlope[3] = { 1.11, 1.1, 1.12 };
log->setLinSideSlopeValue(linSideSlope);
static constexpr double linSideOffset[3] = { 0.051, 0.05, 0.052 };
log->setLinSideOffsetValue(linSideOffset);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon_inverse;
}
OCIO_OSL_TEST(LogCameraTransform, camera_lin2log)
{
static constexpr double linSideBreak[3] = { 0.12, 0.13, 0.15 };
OCIO::LogCameraTransformRcPtr log = OCIO::LogCameraTransform::Create(linSideBreak);
log->setDirection(OCIO::TRANSFORM_DIR_FORWARD);
static constexpr double logSideSlope[3] = { 0.2, 0.3, 0.4 };
log->setLogSideSlopeValue(logSideSlope);
static constexpr double logSideOffset[3] = { 0.7, 0.6, 0.5 };
log->setLogSideOffsetValue(logSideOffset);
static constexpr double linSideSlope[3] = { 1.4, 1.1, 1.2 };
log->setLinSideSlopeValue(linSideSlope);
static constexpr double linSideOffset[3] = { 0.15, 0.16, 0.25 };
log->setLinSideOffsetValue(linSideOffset);
static constexpr double linearSlope[3] = { 1.22, 1.33, 1.44 };
log->setLinearSlopeValue(linearSlope);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon;
}
OCIO_OSL_TEST(LogCameraTransform, camera_log2lin)
{
static constexpr double linSideBreak[3] = { 0.12, 0.13, 0.14 };
OCIO::LogCameraTransformRcPtr log = OCIO::LogCameraTransform::Create(linSideBreak);
log->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
static constexpr double logSideSlope[3] = { 0.21, 0.22, 0.23 };
log->setLogSideSlopeValue(logSideSlope);
static constexpr double logSideOffset[3] = { 0.6, 0.7, 0.8 };
log->setLogSideOffsetValue(logSideOffset);
static constexpr double linSideSlope[3] = { 1.1, 1.2, 1.3 };
log->setLinSideSlopeValue(linSideSlope);
static constexpr double linSideOffset[3] = { 0.051, 0.052, 0.053 };
log->setLinSideOffsetValue(linSideOffset);
static constexpr double linearSlope[3] = { 1.25, 1.23, 1.22 };
log->setLinearSlopeValue(linearSlope);
m_data->m_transform = log;
m_data->m_threshold = g_epsilon_inverse;
}
+143 -15
View File
@@ -2,35 +2,163 @@
// Copyright Contributors to the OpenColorIO Project.
// NOTE:
// The file is a copy and paste from the corresponding GPU unitest i.e. []/tests/gpu/MatrixOp_test.cpp.
// Keep the two files in sync. to increase the test coverage.
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
OCIO_OSL_TEST(Matrix, offset_only)
OCIO_OSL_TEST(MatrixOps, matrix)
{
m_data->m_inValue = OSL::Vec4(0.1, 0.2, 0.6, 0.0);
m_data->m_outValue = OSL::Vec4(0.2, 0.4, 1.0, 0.0);
static constexpr double m[16] = { 1.1, 0.2, 0.3, 0.4,
0.5, 1.6, 0.7, 0.8,
0.2, 0.1, 1.1, 0.2,
0.3, 0.4, 0.5, 1.6 };
OCIO::MatrixTransformRcPtr matrix = OCIO::MatrixTransform::Create();
auto matrix = OCIO::MatrixTransform::Create();
matrix->setMatrix(m);
static constexpr double offsets[4]{0.1, 0.2, 0.4, 0.0};
matrix->setOffset(offsets);
m_data->m_transform = matrix;
}
OCIO_OSL_TEST(Matrix, diagonal)
OCIO_OSL_TEST(MatrixOps, scale)
{
m_data->m_inValue = OSL::Vec4(0.1, 0.2, 0.6, 1.0);
m_data->m_outValue = OSL::Vec4(0.1, 0.4, 1.8, 1.0);
static constexpr double m[16] = { 1.0, 0.0, 0.0, 0.0,
0.0, -0.3, 0.0, 0.0,
0.0, 0.0, 0.6, 0.0,
0.0, 0.0, 0.0, 1.0 };
OCIO::MatrixTransformRcPtr matrix = OCIO::MatrixTransform::Create();
auto matrix = OCIO::MatrixTransform::Create();
matrix->setMatrix(m);
m_data->m_transform = matrix;
}
OCIO_OSL_TEST(MatrixOps, offset)
{
static constexpr double o[4] = { -0.5, +0.25, -0.25, 0.0 };
auto matrix = OCIO::MatrixTransform::Create();
matrix->setOffset(o);
m_data->m_transform = matrix;
}
OCIO_OSL_TEST(MatrixOps, matrix_offset)
{
static constexpr double m[16] = { 1.1, 0.2, 0.3, 0.4,
0.5, 1.6, 0.7, 0.8,
0.2, 0.1, 1.1, 0.2,
0.3, 0.4, 0.5, 1.6 };
static constexpr double o[4] = { -0.5, -0.25, 0.25, 0.0 };
auto matrix = OCIO::MatrixTransform::Create();
matrix->setMatrix(m);
matrix->setOffset(o);
m_data->m_transform = matrix;
}
OCIO_OSL_TEST(MatrixOps, matrix_inverse)
{
static constexpr double m[16] = { 1.1, 0.2, 0.3, 0.4,
0.5, 1.6, 0.7, 0.8,
0.2, 0.1, 1.1, 0.2,
0.3, 0.4, 0.5, 1.6 };
auto matrix = OCIO::MatrixTransform::Create();
matrix->setMatrix(m);
matrix->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = matrix;
}
OCIO_OSL_TEST(MatrixOps, scale_inverse)
{
static constexpr double m[16] = { 1.0, 0.0, 0.0, 0.0,
0.0, -0.3, 0.0, 0.0,
0.0, 0.0, 0.6, 0.0,
0.0, 0.0, 0.0, 1.0 };
auto matrix = OCIO::MatrixTransform::Create();
matrix->setMatrix(m);
matrix->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = matrix;
}
OCIO_OSL_TEST(MatrixOps, offset_inverse)
{
static constexpr double o[4] = { -0.5, +0.25, -0.25, 0.0 };
auto matrix = OCIO::MatrixTransform::Create();
matrix->setOffset(o);
matrix->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = matrix;
}
OCIO_OSL_TEST(MatrixOps, matrix_offset_inverse)
{
static constexpr double m[16] = { 1.1, 0.2, 0.3, 0.4,
0.5, 1.6, 0.7, 0.8,
0.2, 0.1, 1.1, 0.2,
0.3, 0.4, 0.5, 1.6 };
static constexpr double o[4] = { -0.5, -0.25, 0.25, 0.0 };
auto matrix = OCIO::MatrixTransform::Create();
matrix->setMatrix(m);
matrix->setOffset(o);
matrix->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
m_data->m_transform = matrix;
}
OCIO_OSL_TEST(MatrixOps, matrix_offset_generic_shader)
{
static constexpr double m[16] = { 1.1, 0.2, 0.3, 0.4,
0.5, 1.6, 0.7, 0.8,
0.2, 0.1, 1.1, 0.2,
0.3, 0.4, 0.5, 1.6 };
static constexpr double o[4] = { -0., -0.25, 0.25, 0.0 };
auto matrix = OCIO::MatrixTransform::Create();
matrix->setMatrix(m);
matrix->setOffset(o);
m_data->m_transform = matrix;
}
OCIO_OSL_TEST(MatrixOps, matrix_offset_inverse_generic_shader)
{
static constexpr double m[16] = { 1.1, 0.2, 0.3, 0.4,
0.5, 1.6, 0.7, 0.8,
0.2, 0.1, 1.1, 0.2,
0.3, 0.4, 0.5, 1.6 };
static constexpr double o[4] = { -0.5, -0.25, 0.25, 0.0 };
auto matrix = OCIO::MatrixTransform::Create();
matrix->setMatrix(m);
matrix->setOffset(o);
matrix->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
static constexpr double values[16]{1.0, 0.0, 0.0, 0.0,
0.0, 2.0, 0.0, 0.0,
0.0, 0.0, 3.0, 0.0,
0.0, 0.0, 0.0, 1.0};
matrix->setMatrix(values);
m_data->m_transform = matrix;
}
+74 -22
View File
@@ -2,48 +2,100 @@
// Copyright Contributors to the OpenColorIO Project.
// NOTE:
// The file is a copy and paste from the corresponding GPU unitest i.e. []/tests/gpu/RangeOp_test.cpp.
// Keep the two files in sync. to increase the test coverage.
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
OCIO_OSL_TEST(Range, identity)
OCIO_OSL_TEST(RangeOp, scale_with_low_and_high_clippings)
{
m_data->m_inValue = OSL::Vec4(0.1, 0.2, 0.6, 0.0);
m_data->m_outValue = OSL::Vec4(0.1, 0.2, 0.6, 0.0);
OCIO::RangeTransformRcPtr range = OCIO::RangeTransform::Create();
range->setMinInValue(0.);
range->setMinOutValue(0.);
range->setMinInValue(0.1f);
range->setMaxInValue(1.1f);
range->setMinOutValue(0.5f);
range->setMaxOutValue(1.5f);
m_data->m_transform = range;
}
OCIO_OSL_TEST(Range, scale)
OCIO_OSL_TEST(RangeOp, scale_with_low_clipping)
{
m_data->m_inValue = OSL::Vec4(0.1, 0.2, 0.6, 0.0);
m_data->m_outValue = OSL::Vec4(0.3, 0.4, 0.8, 0.0);
OCIO::RangeTransformRcPtr range = OCIO::RangeTransform::Create();
range->setMinInValue(0.);
range->setMaxInValue(1.);
range->setMinOutValue(0.2);
range->setMaxOutValue(1.2);
range->setMinInValue(0.2f);
range->setMinOutValue(0.2f);
m_data->m_transform = range;
}
OCIO_OSL_TEST(Range, scale_and_clamp)
OCIO_OSL_TEST(RangeOp, scale_with_high_clipping)
{
m_data->m_inValue = OSL::Vec4(-0.1, 0.2, 1.6, 0.0);
m_data->m_outValue = OSL::Vec4( 0.2, 0.4, 1.2, 0.0);
OCIO::RangeTransformRcPtr range = OCIO::RangeTransform::Create();
range->setMinInValue(0.);
range->setMaxInValue(1.);
range->setMinOutValue(0.2);
range->setMaxOutValue(1.2);
range->setMaxInValue(0.9f);
range->setMaxOutValue(0.9f);
m_data->m_transform = range;
}
OCIO_OSL_TEST(RangeOp, scale_with_low_and_high_clippings_2)
{
// The similar test above is only an offset, this test is a scale & offset.
OCIO::RangeTransformRcPtr range = OCIO::RangeTransform::Create();
range->setMinInValue(0.1f);
range->setMaxInValue(1.1f);
range->setMinOutValue(-0.5f);
range->setMaxOutValue(1.5f);
m_data->m_transform = range;
}
OCIO_OSL_TEST(RangeOp, arbitrary_1)
{
OCIO::RangeTransformRcPtr range = OCIO::RangeTransform::Create();
range->setMinInValue (0.4000202f);
range->setMaxInValue (0.6000502f);
range->setMinOutValue(0.4000601f);
range->setMaxOutValue(0.6000801f);
m_data->m_transform = range;
}
OCIO_OSL_TEST(RangeOp, arbitrary_1_no_clamp)
{
OCIO::RangeTransformRcPtr range = OCIO::RangeTransform::Create();
range->setStyle(OCIO::RANGE_NO_CLAMP);
range->setMinInValue (0.4000202f);
range->setMaxInValue (0.6000502f);
range->setMinOutValue(0.4000601f);
range->setMaxOutValue(0.6000801f);
m_data->m_transform = range;
}
OCIO_OSL_TEST(RangeOp, arbitrary_2)
{
OCIO::RangeTransformRcPtr range = OCIO::RangeTransform::Create();
range->setMinInValue(-0.010201f);
range->setMaxInValue (0.601102f);
range->setMinOutValue(0.209803f);
range->setMaxOutValue(1.600208f);
m_data->m_transform = range;
}
OCIO_OSL_TEST(RangeOp, arbitrary_2_no_clamp)
{
OCIO::RangeTransformRcPtr range = OCIO::RangeTransform::Create();
range->setStyle(OCIO::RANGE_NO_CLAMP);
range->setMinInValue(-0.010201f);
range->setMaxInValue (0.601102f);
range->setMinOutValue(0.209803f);
range->setMaxOutValue(1.600208f);
m_data->m_transform = range;
}
+102 -93
View File
@@ -2,23 +2,23 @@
// Copyright Contributors to the OpenColorIO Project.
#include <OSL/oslcomp.h>
#include <OSL/oslexec.h>
#include <OSL/rendererservices.h>
#include <fstream>
#include <memory>
#include <vector>
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include "UnitTestMain.h"
#include "UnitTestOSL.h"
#include <memory>
#include <vector>
#include <OSL/oslcomp.h>
namespace
{
class MyOSLShaderCreator : public OCIO::GpuShaderCreator
class MyOSLShaderCreator final : public OCIO::GpuShaderCreator
{
public:
static OCIO::GpuShaderCreatorRcPtr Create(const OSLDataRcPtr & test)
@@ -32,8 +32,6 @@ public:
OCIO::GpuShaderCreatorRcPtr clone() const override { return OCIO::GpuShaderCreatorRcPtr(); }
// TODO: OSL: Throw when unexpected methods are used.
void setTextureMaxWidth(unsigned /*maxWidth*/) override {}
unsigned getTextureMaxWidth() const noexcept override { return 0; }
@@ -110,37 +108,6 @@ private:
std::string m_shaderCode;
};
class ErrorRecorder final : public OIIO::ErrorHandler
{
public:
ErrorRecorder() : ErrorHandler() {}
virtual void operator()(int errcode, const std::string& msg)
{
if (errcode >= EH_ERROR) {
if (m_errormessage.size()
&& m_errormessage[m_errormessage.length() - 1] != '\n')
m_errormessage += '\n';
m_errormessage += msg;
}
}
bool haserror() const { return m_errormessage.size(); }
std::string geterror(bool erase = true)
{
std::string s;
if (erase)
std::swap(s, m_errormessage);
else
s = m_errormessage;
return s;
}
private:
std::string m_errormessage;
} g_errhandler;
typedef std::vector<OSLDataRcPtr> UnitTests;
@@ -156,7 +123,12 @@ void AddUnitTest(const OSLDataRcPtr & test)
GetUnitTests().push_back(test);
}
} //anon namespace
void logFunction(const char *)
{
// Mute all messages, warnings, etc.
}
} // anon. namespace
OSLDataRcPtr OSLData::Create()
@@ -168,15 +140,20 @@ OSLDataRcPtr OSLData::Create()
int main(int, const char **)
{
const std::string shaders{OCIO::GetEnvVariable("SHADERS_DIR")};
const std::string optionShaders{"-I" + shaders};
const std::vector<std::string> options{ optionShaders, "-Werror" };
const std::string oslShaderPath{OCIO::GetEnvVariable("OSL_SHADERS_DIR")};
const std::string newShaderPath{OCIO::GetEnvVariable("TMP_SHADERS_DIR")};
const std::string shaderName{"OSL_OCIOMain"};
const std::string oslShaderOption{"-I" + oslShaderPath};
const std::vector<std::string> options{ oslShaderOption, "-Werror" };
size_t failures = 0;
size_t noTest = 0;
std::cerr << "\n OpenColorIO_Core_OSL_Unit_Tests\n\n";
OCIO::SetLoggingFunction(logFunction);
for (const auto & test : GetUnitTests())
{
constexpr size_t maxCharToDisplay = 59;
@@ -192,94 +169,126 @@ int main(int, const char **)
<< test->m_name
<< "] - ";
OSL::RendererServices * renderer = new OSL::RendererServices();
OIIO::TextureSystem * texturesys = OIIO::TextureSystem::create();
OSL::ShadingSystem * shadingsys = new OSL::ShadingSystem(renderer, texturesys);
OSL::ShaderGroupRef shadergroup = shadingsys->ShaderGroupBegin();
// TODO: OSL: Create the OSL group!
std::string oslShaderString;
try
{
OCIO::ConstConfigRcPtr config = OCIO::Config::CreateRaw();
OCIO::ConstProcessorRcPtr processor = config->getProcessor(test->m_transform);
OCIO::ConstGPUProcessorRcPtr gpu = processor->getOptimizedGPUProcessor(OCIO::OPTIMIZATION_NONE);
// Create the OSL shader.
OCIO::ConstProcessorRcPtr processor
= test->m_config->getProcessor(test->m_transform);
OCIO::ConstCPUProcessorRcPtr cpu
= processor->getOptimizedCPUProcessor(OCIO::OPTIMIZATION_NONE);
OCIO::ConstGPUProcessorRcPtr gpu
= processor->getOptimizedGPUProcessor(OCIO::OPTIMIZATION_NONE);
OCIO::GpuShaderCreatorRcPtr shaderDesc = MyOSLShaderCreator::Create(test);
gpu->extractGpuShaderInfo(shaderDesc);
OSL::OSLCompiler compiler(&g_errhandler);
const std::string oslBuffer
= dynamic_cast<MyOSLShaderCreator*>(shaderDesc.get())->getShaderCode();
std::string osoBuffer;
oslShaderString = dynamic_cast<MyOSLShaderCreator*>(shaderDesc.get())->getShaderCode();
if (!compiler.compile_buffer(oslBuffer, osoBuffer, options))
// Compute the expected output values for the following input values.
static const Image g_inValues{
{ 0.00f, 0.02f, 0.04f, 0.06f},
{ 0.08f, 0.10f, 0.12f, 0.14f},
{ 0.16f, 0.18f, 0.20f, 0.22f},
{ 0.24f, 0.26f, 0.28f, 0.30f},
{ 0.32f, 0.34f, 0.36f, 0.38f},
{ 0.40f, 0.42f, 0.44f, 0.46f},
{ 0.48f, 0.50f, 0.52f, 0.54f},
{ 0.56f, 0.58f, 0.60f, 0.62f},
{ 0.64f, 0.66f, 0.68f, 0.70f},
{ 0.72f, 0.74f, 0.76f, 0.78f},
{ 0.80f, 0.82f, 0.84f, 0.86f},
{ 0.90f, 0.92f, 0.94f, 0.96f},
{ 0.00f, 0.00f, 0.00f, 0.00f},
{ 1.10f, 1.10f, 1.10f, 1.00f},
{ 0.50f, 0.40f, 0.30f, 0.00f},
{ 1.00f, 0.00f, 0.00f, 1.00f},
{ 0.90f, 0.10f, 0.20f, 0.00f},
{-0.10f, -0.10f, -0.10f, 0.00f},
{-0.10f, 0.40f, 1.10f, 1.00f}
};
// Used the custom input values if any.
const Image inValues = test->m_inputValues.empty() ? g_inValues : test->m_inputValues;
Image outValues = inValues;
for (size_t idx = 0; idx < inValues.size(); ++idx)
{
failures++;
std::cerr << "FAILED\n";
cpu->applyRGBA((float *)&outValues[idx]);
}
// Compile the OSL shader i.e. no need to execute if the compilation fails.
ErrorRecorder msg;
OSL::OSLCompiler compiler(&msg);
std::string osoShaderBuffer;
if (!compiler.compile_buffer(oslShaderString, osoShaderBuffer, options))
{
std::string errormessage;
if (g_errhandler.haserror())
if (msg.haserror())
{
errormessage = g_errhandler.geterror();
errormessage = msg.geterror();
}
else
{
errormessage = "OSL: Could not compile the shader";
}
std::cerr << errormessage << std::endl;
continue;
throw std::runtime_error(errormessage);
}
if (!shadingsys->LoadMemoryCompiledShader("shadername", osoBuffer))
// Save the OSL shader (use the compiled version as it's now available).
{
failures++;
std::cerr << "FAILED\n";
std::string errormessage;
if (g_errhandler.haserror())
{
errormessage = g_errhandler.geterror();
}
else
{
errormessage = "OSL: Could not load the shader";
}
std::cerr << errormessage << std::endl;
continue;
std::string filepath{newShaderPath};
filepath += "/";
filepath += shaderName;
filepath += ".oso";
std::ofstream out(filepath);
out << osoShaderBuffer;
}
// Excecute in-memory the OSL shader.
// TODO: OSL: Add the CPU execution of the shader to validate the processing.
ExecuteOSLShader(shaderName,
inValues,
outValues,
test->m_threshold,
test->m_expectedMinimalValue,
test->m_relativeComparison);
std::cerr << "PASSED\n";
std::cerr << "PASSED" << std::endl;
}
catch(std::exception & ex)
{
failures++;
std::cerr << "FAILED\n";
std::cerr << "FAILED" << std::endl;
std::cerr << ex.what() << std::endl;
std::cerr << "\n***********\n";
std::cerr << oslShaderString;
std::cerr << "\n***********\n";
}
catch(...)
{
failures++;
std::cerr << "FAILED\n";
std::cerr << "FAILED" << std::endl;
std::cerr << "Unexpected exception!" << std::endl;
std::cerr << "\n***********\n";
std::cerr << oslShaderString;
std::cerr << "\n***********\n";
}
shadergroup.reset();
delete shadingsys;
delete renderer;
noTest++;
}
+20 -7
View File
@@ -5,40 +5,53 @@
#ifndef OPENCOLORIO_OSL_UNITTEST_H
#define OPENCOLORIO_OSL_UNITTEST_H
#include <OSL/wide.h>
#include "UnitTestTypes.h"
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE;
#include <string>
#include <OSL/wide.h>
struct OSLData;
typedef std::shared_ptr<OSLData> OSLDataRcPtr;
// Defined the unit test data.
struct OSLData
{
static OSLDataRcPtr Create();
// It contains the color to process.
OSL::Vec4 m_inValue;
// It contains the expected color.
OSL::Vec4 m_outValue;
OCIO::ConfigRcPtr m_config;
OCIO::ConstTransformRcPtr m_transform;
// Use these values for the processing instead of the default ones.
Image m_inputValues;
float m_threshold{ 1e-6f };
float m_expectedMinimalValue{ 1e-6f };
bool m_relativeComparison{ false };
std::string m_name;
OSLData() : m_config(OCIO::Config::CreateRaw()->createEditableCopy()) {}
};
// Defines the unit test to be executed.
class UnitTest
{
public:
UnitTest() : m_data(OSLData::Create()) {}
// Implement the method to define a specific unit test.
virtual void create() = 0;
// The data of the unit test.
OSLDataRcPtr m_data;
};
// Helper macro.
#ifdef FIELD_STR
@@ -57,7 +70,7 @@ public:
#define OCIO_OSL_TEST(group, name) \
class UnitTest_##group##_##name : public UnitTest \
class UnitTest_##group##_##name final : public UnitTest \
{ \
public: \
UnitTest_##group##_##name() : UnitTest() \
+213
View File
@@ -0,0 +1,213 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
#include "UnitTestOSL.h"
#include <OSL/oslexec.h>
#include <OSL/rendererservices.h>
namespace
{
// Define a userdata structure that holds any varying per-point values that
// might be retrieved by shader.
struct MyUserData
{
OSL::Vec3 inColor_rgb{0.0f, 0.0f, 0.0f};
float inColor_a{1.0f};
MyUserData() = delete;
MyUserData(const Vec4 & c)
: inColor_rgb(c[0], c[1], c[2])
, inColor_a(c[3])
{
}
// Make a retrieve-by-name function.
bool retrieve(OSL::ustring name, OSL::TypeDesc type, void * val, bool /*derivatives*/)
{
static const OSL::ustring ucolor_rgb("inColor.rgb");
if (name == ucolor_rgb && type == OIIO::TypeColor)
{
((float*)val)[0] = inColor_rgb[0];
((float*)val)[1] = inColor_rgb[1];
((float*)val)[2] = inColor_rgb[2];
return true;
}
static const OSL::ustring ucolor_a("inColor.a");
if (name == ucolor_a && type == OIIO::TypeFloat)
{
((float*)val)[0] = inColor_a;
return true;
}
// Not a named value we know about, so just return false.
return false;
}
};
// RendererServices is the interface through which OSL requests things back
// from the app (called a "renderer", but it doesn't have to literally be
// one). The important feature we are concerned about here is that this is
// how "userdata" is retrieved. We set up a subclass that overloads
// get_userdata() to retrieve it from a per-point MyUserData that whose
// pointer is stored in shaderglobals.renderstate.
class MyRendererServices final : public OSL::RendererServices
{
public:
virtual bool get_userdata(bool derivatives, OSL::ustring name,
OSL::TypeDesc type, OSL::ShaderGlobals * sg,
void * val)
{
// In this case, our implementation of get_userdata just requests
// it from the MyUserData, which we have arranged is pointed to
// by shaderglobals.renderstate.
MyUserData * userdata = (MyUserData *)sg->renderstate;
return userdata ? userdata->retrieve(name, type, val, derivatives)
: false;
}
};
inline bool AbsoluteDifference(float x1, float x2, float diff)
{
const float thisDiff = fabs(x2 - x1);
if (thisDiff > diff)
{
diff = thisDiff;
return true;
}
return false;
}
inline bool RelativeDifference(float x1, float x2, float min_x1, float diff)
{
const float absx1 = fabs(x1);
float div = std::max(absx1, min_x1);
const float thisDiff = fabs(x1 - x2) / div;
if (thisDiff > diff)
{
diff = thisDiff;
return true;
}
return false;
}
// Return true if diff has been updated.
inline bool ComputeDiff(float x1, float x2, bool rel, float min_x1, float diff)
{
if (rel)
{
return RelativeDifference(x1, x2, min_x1, diff);
}
else
{
return AbsoluteDifference(x1, x2, diff);
}
}
} // anon.
void ExecuteOSLShader(const std::string & shaderName,
const Image & inValues,
const Image & outValues,
float threshold,
float minValue,
bool relativeComparison)
{
MyRendererServices renderer;
ErrorRecorder msg;
std::unique_ptr<OSL::ShadingSystem> shadsys(new OSL::ShadingSystem(&renderer, nullptr, &msg));
OSL::ShaderGroupRef mygroup = shadsys->ShaderGroupBegin("my_color_mgt");
shadsys->Parameter(*mygroup, "inColor.rgb", 1.0f, /*lockgeom=*/false);
shadsys->Parameter(*mygroup, "inColor.a", 1.0f, /*lockgeom=*/false);
shadsys->Shader(*mygroup, "shader", shaderName, "layer1");
shadsys->ShaderGroupEnd(*mygroup);
const std::vector<OSL::ustring> output_names{ OSL::ustring("outColor.rgb"), OSL::ustring("outColor.a") };
shadsys->attribute (mygroup.get(), "renderer_outputs",
OSL::TypeDesc(OSL::TypeDesc::STRING, output_names.size()),
output_names.data());
// Now we want to create a context in which we can execute the shader.
// We need one context per thread.
OSL::PerThreadInfo * perthread = shadsys->create_thread_info();
OSL::ShadingContext * ctx = shadsys->get_context(perthread);
// The group must already be optimized before we call find_symbol,
// so we force that to happen now.
shadsys->optimize_group(mygroup.get(), ctx);
// Get a ShaderSymbol* handle to the final output we care about. This
// will greatly speed up retrieving the value later, rather than by
// looking it up by name on every shade.
const OSL::ShaderSymbol * outsymRGB
= shadsys->find_symbol(*mygroup.get(), OSL::ustring("layer1"), OSL::ustring("outColor.rgb"));
OSL_ASSERT(outsymRGB);
const OSL::ShaderSymbol * outsymA
= shadsys->find_symbol(*mygroup.get(), OSL::ustring("layer1"), OSL::ustring("outColor.a"));
OSL_ASSERT(outsymA);
for (size_t idx = 0; idx < inValues.size(); ++idx)
{
OSL::ShaderGlobals shaderglobals;
// Make a userdata record. Make sure the shaderglobals points to it.
MyUserData userdata(inValues[idx]);
shaderglobals.renderstate = &userdata;
// Run the shader (will automagically optimize and JIT the first time it executes).
if (!shadsys->execute(*ctx, *mygroup.get(), shaderglobals))
{
std::string errormessage;
if (msg.haserror())
{
errormessage = msg.geterror();
}
else
{
errormessage = "OSL: Could not compile the shader";
}
throw std::runtime_error(errormessage);
}
const OSL::Vec3 outRGB = *(OSL::Vec3 *)shadsys->symbol_address(*ctx, outsymRGB);
const float outA = *(float *)shadsys->symbol_address(*ctx, outsymA);
// Check the result.
if ( ComputeDiff(outValues[idx][0], outRGB[0], relativeComparison, minValue, threshold)
|| ComputeDiff(outValues[idx][1], outRGB[1], relativeComparison, minValue, threshold)
|| ComputeDiff(outValues[idx][2], outRGB[2], relativeComparison, minValue, threshold)
|| ComputeDiff(outValues[idx][3], outA, relativeComparison, minValue, threshold))
{
std::stringstream str;
str << "Values from ["
<< inValues[idx][0] << ", " << inValues[idx][1] << ", "
<< inValues[idx][2] << ", " << inValues[idx][3]
<< "] to ["
<< outValues[idx][0] << ", " << outValues[idx][1] << ", "
<< outValues[idx][2] << ", " << outValues[idx][3]
<< "], but OSL computed values are ["
<< outRGB[0] << ", " << outRGB[1] << ", " << outRGB[2] << ", " << outA << "].";
throw std::runtime_error(str.str());
}
}
// All done. Release the contexts and threadinfo for each thread:
shadsys->release_context(ctx);
shadsys->destroy_thread_info(perthread);
}
+64
View File
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
#ifndef OPENCOLORIO_OSL_UNITTEST_OSL_H
#define OPENCOLORIO_OSL_UNITTEST_OSL_H
#include "UnitTestTypes.h"
#include <OpenImageIO/errorhandler.h>
#include <string>
// Trap the OSL messages in case of error.
class ErrorRecorder final : public OIIO::ErrorHandler
{
public:
ErrorRecorder() : ErrorHandler() {}
virtual void operator()(int errcode, const std::string & msg)
{
if (errcode >= EH_ERROR)
{
if (m_errormessage.size()
&& m_errormessage[m_errormessage.length() - 1] != '\n')
{
m_errormessage += '\n';
}
m_errormessage += msg;
}
}
inline bool haserror() const { return m_errormessage.size(); }
std::string geterror(bool erase = true)
{
std::string s;
if (erase)
{
std::swap(s, m_errormessage);
}
else
{
s = m_errormessage;
}
return s;
}
private:
std::string m_errormessage;
};
// Excecute in-memory the OSL shader.
void ExecuteOSLShader(const std::string & shaderName,
const Image & inValues,
const Image & outValues,
float threshold,
float minValue,
bool relativecomparison);
#endif /* OPENCOLORIO_OSL_UNITTEST_OSL_H */

Some files were not shown because too many files have changed in this diff Show More