Compare commits

...
3 Commits
Author SHA1 Message Date
fa521922c9 Create RB-2.3.2 release (#1940)
* Fix ssse3 detection typo (#1929)

Signed-off-by: Mark Reid <mindmark@gmail.com>
(cherry picked from commit 003b6a19e6)
Signed-off-by: Doug Walker <doug.walker@autodesk.com>

* fix: use system `include pystring.h` for `ConfigUtils.cpp` (#1921)

Signed-off-by: Rui Chen <rui@chenrui.dev>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit e747e9c0bd)
Signed-off-by: Doug Walker <doug.walker@autodesk.com>

* Fix narrowing conversion error on riscv64 (#1924)

Signed-off-by: phancb <nxhsdu@qq.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit a95febc70e)
Signed-off-by: Doug Walker <doug.walker@autodesk.com>

* Add manylinux_2_28 Python wheels (#1933)

Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Michael Dolan <michdolan@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit f9250992eb)
Signed-off-by: Doug Walker <doug.walker@autodesk.com>

* Enhance ociochecklut to print the output after each step in a multi-t… (#1925)

* Enhance ociochecklut to print the output after each step in a multi-transform LUT

Signed-off-by: pylee <penne.y.lee@intel.com>

* Review feedback to enable printe of transforms list when using -s flag.

Signed-off-by: pylee <penne.y.lee@intel.com>

* Print transform description for each step instead.

Signed-off-by: pylee <penne.y.lee@intel.com>

---------

Signed-off-by: pylee <penne.y.lee@intel.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit aadf595946)
Signed-off-by: Doug Walker <doug.walker@autodesk.com>

* Fix AVX instructions used on CPUs that don't support them (#1935)

* Fix AVX instructions used on CPUs that don't support them

It's supposed to check all bits are enabled, not just one of them.
This causes a crash using OpenColorIO on older CPUs.

Thanks to Ray Molenkamp for help tracking this down.

Signed-off-by: Brecht Van Lommel <brecht@blender.org>

* Fix another case pointed out in review

Signed-off-by: Brecht Van Lommel <brecht@blender.org>

---------

Signed-off-by: Brecht Van Lommel <brecht@blender.org>
(cherry picked from commit 0c90ded166)
Signed-off-by: Doug Walker <doug.walker@autodesk.com>

* Increment library version to 2.3.2

Signed-off-by: Doug Walker <doug.walker@autodesk.com>

---------

Signed-off-by: Mark Reid <mindmark@gmail.com>
Signed-off-by: Doug Walker <doug.walker@autodesk.com>
Signed-off-by: Rui Chen <rui@chenrui.dev>
Signed-off-by: phancb <nxhsdu@qq.com>
Signed-off-by: Rémi Achard <remiachard@gmail.com>
Signed-off-by: pylee <penne.y.lee@intel.com>
Signed-off-by: Brecht Van Lommel <brecht@blender.org>
Co-authored-by: Mark Reid <mindmark@gmail.com>
Co-authored-by: Rui Chen <rui@chenrui.dev>
Co-authored-by: phanium <91544758+phanen@users.noreply.github.com>
Co-authored-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Michael Dolan <michdolan@gmail.com>
Co-authored-by: PenneLee <penne.y.lee@intel.com>
Co-authored-by: Brecht Van Lommel <brecht@blender.org>
2024-01-30 02:11:35 -05:00
+3 92db29b9e7 Integrate main into RB-2.3 branch and update library version (#1918)
* Fix support for X86 32-bit (#1842)

Signed-off-by: Mark Reid <mindmark@gmail.com>
(cherry picked from commit 16b3157f2e)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Add some small arm neon optimizations (#1847)

* Remove unused includes

Signed-off-by: Mark Reid <mindmark@gmail.com>

* Use neon hardware support for f16 conversions

Signed-off-by: Mark Reid <mindmark@gmail.com>

* Add some small neon optimizations
use blendv,floor and fma intrinsics were possible

Signed-off-by: Mark Reid <mindmark@gmail.com>

---------

Signed-off-by: Mark Reid <mindmark@gmail.com>
(cherry picked from commit 14f0afa2d8)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Add links to new release notes documentation (#1848)

Signed-off-by: Kevin Wheatley <kevin.wheatley@framestore.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 87126fad7f)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Changing version to 2.4.0 (#1852)

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 381d1fc371)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Correctly recover CXX_FLAGS in CheckSupportSSE2.cmake (#1861)

Signed-off-by: Chongyun Lee <uchkks@protonmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit c429400170)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix regression in cccid handling when no value is supplied (#1855)

In v1 of OCIO FileTransforms are able to load .cc files
without specifying a cccid. In v2 this broke causing an
exception to be raised instead of using the first cc found
in the file.

Signed-off-by: Kevin Wheatley <kevin.wheatley@framestore.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit c7ad35340a)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix missing cache id reset on look update. (#1873)

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>
(cherry picked from commit dddbee023d)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* ocioview: Curve Inspector improvements (#1845)

* Curve inspector improvements

- Move README to root app folder
- Change curve inspector grid to always render as a square with 10 segments.
- Add transform init callback to set new transform subscriptions to the current viewer if set to passthrough.

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

* Improve log range calculation

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

* Improve channel sample comparison

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

* Update src/apps/ocioview/ocioview/inspect/curve_inspector.py

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

Co-authored-by: Doug Walker <doug.walker@autodesk.com>
Signed-off-by: Michael Dolan <michdolan@gmail.com>

---------

Signed-off-by: Michael Dolan <michdolan@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 8add374dad)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix missing Default View Transform on equal operator (#1886)

Add the missing assignment of the the default view transform when a config is copied using the equal operator

Signed-off-by: Michael De Caria <decariamichael@gmail.com>
Signed-off-by: Doug Walker <doug.walker@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit bc8569b2db)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Remove circular import caused by typing annotations. (#1882)

Signed-off-by: Thomas Mansencal <thomas.mansencal@gmail.com>
Signed-off-by: Doug Walker <doug.walker@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 1fad4666c3)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* fix(grammatical): Spelling mistakes (#1892)

Signed-off-by: AbhineshJha <abhinesh_223002@saitm.org>
Signed-off-by: Doug Walker <doug.walker@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 0d00b2c538)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Improve ocioview mac support and simplify dependencies (#1853)

* PySide 6, remove imath, add imageio support

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

Remove Imath

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

Support imageio as fallback for openimageio

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

Further adjustments following latest updates

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

Fix pixel probe

Signed-off-by: Remi Achard <remiachard@gmail.com>

Add OpenColorIO to requirements

Signed-off-by: Remi Achard <remiachard@gmail.com>

* Fix rebase issue

Signed-off-by: Remi Achard <remiachard@gmail.com>

---------

Signed-off-by: Remi Achard <remiachard@gmail.com>
Signed-off-by: Thomas Mansencal <thomas.mansencal@gmail.com>
Signed-off-by: Michael Dolan <michdolan@gmail.com>
Co-authored-by: Thomas Mansencal <thomas.mansencal@gmail.com>
Co-authored-by: Michael Dolan <michdolan@gmail.com>
(cherry picked from commit 45544ce667)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Issue #1874 Cast to unsigned char for isspace. (#1888)

* Issue #1874 Cast to unsigned char for isspace.

Signed-off-by: pylee <penne.y.lee@intel.com>

* Add unit test.

Signed-off-by: pylee <penne.y.lee@intel.com>

* Add test comment as suggested in code review.

Signed-off-by: pylee <penne.y.lee@intel.com>

---------

Signed-off-by: pylee <penne.y.lee@intel.com>
Signed-off-by: Doug Walker <doug.walker@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit ed852073f2)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Tentative fix for the doxygen installation in the CI (Windows) (#1890)

Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit b94a184e4b)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Simplify the Findyaml-cpp module (#1891)

This fixes compatibility with yaml-cpp 0.8, which previously failed
because of a `get_property` call with the wrong target name.
I took the liberty to add a few simplifications along the way.

Signed-off-by: Tobias Mayer <tobim@fastmail.fm>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 1d3b69502e)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Skip processor concatenation if the display color space is also data. (#1896)

* Skip processor concatenation if the display view transform is also data.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

* Moved missing display color space exception before processor creation.

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>

---------

Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 52b496528c)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Restore GPU workflow and minor updates to CI (#1899)

* Restore GPU workflow runs

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

* Enable undefined behaviour sanitizer

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

* Fix SIMD option for platform_latest

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

* Fix install_docs_env on CI workflow (not used at the moment)

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

* Fix OpenEXR build flag

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

---------

Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 382dcb6ce7)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Improve handling of pystring include dir (#1901)

Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 9078753990)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Improve compatibility with minizip-ng COMPAT mode (#1902)

Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit ffd0f70ad5)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix NamedTransform context var issue (#1905)

Signed-off-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 4d64b32bc7)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix env serialization for v1 configs (#1904)

Signed-off-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 4f4f30e1d3)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix yaml-cpp build issues (#1907)

Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit 41441bb2e6)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Adsk Contrib - Improve heuristics for finding known color spaces (#1913)

* Improve heuristics

Signed-off-by: Doug Walker <doug.walker@autodesk.com>

* Add some comments

Signed-off-by: Doug Walker <doug.walker@autodesk.com>

---------

Signed-off-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit d8852b5d6c)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Add Python 3.12 wheels (#1898)

Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit f2cfec330e)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Increment library version to 2.3.1

Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

* Fix wrong RPATH being injected into Python bindings DSO (#1849)

Signed-off-by: Kevin Wheatley <kevin.wheatley@framestore.com>
Co-authored-by: Doug Walker <doug.walker@autodesk.com>
(cherry picked from commit ba2b41e309)
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>

---------

Signed-off-by: Mark Reid <mindmark@gmail.com>
Signed-off-by: Doug Walker <Doug.Walker@autodesk.com>
Signed-off-by: Kevin Wheatley <kevin.wheatley@framestore.com>
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
Signed-off-by: Chongyun Lee <uchkks@protonmail.com>
Signed-off-by: Eric Renaud-Houde <eric.renaud.houde@gmail.com>
Signed-off-by: Michael Dolan <michdolan@gmail.com>
Signed-off-by: Michael De Caria <decariamichael@gmail.com>
Signed-off-by: Doug Walker <doug.walker@autodesk.com>
Signed-off-by: Thomas Mansencal <thomas.mansencal@gmail.com>
Signed-off-by: AbhineshJha <abhinesh_223002@saitm.org>
Signed-off-by: Remi Achard <remiachard@gmail.com>
Signed-off-by: pylee <penne.y.lee@intel.com>
Signed-off-by: Tobias Mayer <tobim@fastmail.fm>
Signed-off-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: Mark Reid <mindmark@gmail.com>
Co-authored-by: Kevin Wheatley <kevin.wheatley@framestore.com>
Co-authored-by: Cédrik Fuoco <105517825+cedrik-fuoco-adsk@users.noreply.github.com>
Co-authored-by: Uchiha Kakashi <45286352+licy183@users.noreply.github.com>
Co-authored-by: Éric Renaud-Houde <eric.renaud.houde@gmail.com>
Co-authored-by: Michael Dolan <michdolan@gmail.com>
Co-authored-by: Michael De Caria <decariamichael@gmail.com>
Co-authored-by: Thomas Mansencal <thomas.mansencal@gmail.com>
Co-authored-by: Abhinesh <142514166+AbhineshJha@users.noreply.github.com>
Co-authored-by: Rémi Achard <remiachard@gmail.com>
Co-authored-by: PenneLee <pennelee@gmail.com>
Co-authored-by: tobim <tobim+github@fastmail.fm>
2023-12-07 20:02:08 -05:00
Cédrik Fuoco b35fb73b86 Update release type (#1839)
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
2023-08-31 21:38:17 -04:00
145 changed files with 5811 additions and 726 deletions
+17 -2
View File
@@ -77,6 +77,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2023
install-ext-packages: MISSING
- build: 11
build-type: Release
build-shared: 'ON'
@@ -89,6 +90,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2023
install-ext-packages: ALL
- build: 10
build-type: Release
build-shared: 'OFF'
@@ -101,6 +103,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2023
install-ext-packages: ALL
# -------------------------------------------------------------------
# VFX CY2022 (Python 3.9)
# -------------------------------------------------------------------
@@ -116,6 +119,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2022
install-ext-packages: ALL
- build: 8
build-type: Release
build-shared: 'ON'
@@ -128,6 +132,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2022
install-ext-packages: MISSING
- build: 7
build-type: Release
build-shared: 'OFF'
@@ -140,6 +145,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2022
install-ext-packages: ALL
# -------------------------------------------------------------------
# VFX CY2021 (Python 3.7)
# -------------------------------------------------------------------
@@ -155,6 +161,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2021
install-ext-packages: MISSING
- build: 5
build-type: Release
build-shared: 'OFF'
@@ -167,6 +174,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2021
install-ext-packages: ALL
- build: 4
build-type: Debug
build-shared: 'ON'
@@ -179,6 +187,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2021
install-ext-packages: ALL
# -------------------------------------------------------------------
# VFX CY2020 (Python 3.7)
# -------------------------------------------------------------------
@@ -194,6 +203,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2020
install-ext-packages: MISSING
- build: 2
build-type: Debug
build-shared: 'OFF'
@@ -206,6 +216,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2020
install-ext-packages: ALL
- build: 1
build-type: Release
build-shared: 'ON'
@@ -218,6 +229,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2020
install-ext-packages: ALL
env:
CXX: ${{ matrix.cxx-compiler }}
CC: ${{ matrix.cc-compiler }}
@@ -245,7 +257,7 @@ jobs:
-DOCIO_BUILD_GPU_TESTS=OFF \
-DOCIO_USE_SIMD=${{ matrix.use-simd }} \
-DOCIO_USE_OIIO_FOR_APPS=${{ matrix.use-oiio }} \
-DOCIO_INSTALL_EXT_PACKAGES=ALL \
-DOCIO_INSTALL_EXT_PACKAGES=${{ matrix.install-ext-packages }} \
-DOCIO_WARNING_AS_ERROR=ON \
-DPython_EXECUTABLE=$(which python)
working-directory: _build
@@ -527,7 +539,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
- name: Install docs env
run: share/ci/scripts/windows/install_docs_env.sh
run: |
DOXYGEN_PATH=$GITHUB_WORKSPACE/doxygen
share/ci/scripts/windows/install_docs_env.sh "$DOXYGEN_PATH"
echo "$DOXYGEN_PATH" >> $GITHUB_PATH
shell: bash
if: matrix.build-docs == 'ON'
- name: Install tests env
+15 -4
View File
@@ -54,6 +54,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2022
use-oiio: 'ON'
- build: 2
build-docs: 'OFF'
build-openfx: 'OFF'
@@ -62,6 +63,7 @@ jobs:
cc-compiler: gcc
compiler-desc: GCC
vfx-cy: 2021
use-oiio: 'OFF'
# -------------------------------------------------------------------
# Clang
# -------------------------------------------------------------------
@@ -73,6 +75,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2022
use-oiio: 'OFF'
- build: 4
build-docs: 'ON'
build-openfx: 'ON'
@@ -81,6 +84,7 @@ jobs:
cc-compiler: clang
compiler-desc: Clang
vfx-cy: 2021
use-oiio: 'ON'
env:
CXX: ${{ matrix.cxx-compiler }}
CC: ${{ matrix.cc-compiler }}
@@ -132,7 +136,7 @@ jobs:
-DOCIO_INSTALL_EXT_PACKAGES=NONE \
-DOCIO_WARNING_AS_ERROR=OFF \
-DPython_EXECUTABLE=$(which python) \
-DOCIO_USE_OIIO_CMAKE_CONFIG=ON
-DOCIO_USE_OIIO_FOR_APPS=${{ matrix.use-oiio }}
working-directory: _build
- name: Build
run: |
@@ -176,11 +180,13 @@ jobs:
build-openfx: 'ON'
cxx-standard: 17
python-version: '3.11'
use-oiio: 'ON'
- build: 2
build-docs: 'ON'
build-openfx: 'ON'
cxx-standard: 14
python-version: '3.9'
use-oiio: 'OFF'
steps:
- name: Setup Python
uses: actions/setup-python@v4
@@ -235,7 +241,7 @@ jobs:
-DOCIO_INSTALL_EXT_PACKAGES=NONE \
-DOCIO_WARNING_AS_ERROR=OFF \
-DPython_EXECUTABLE=$(which python) \
-DOCIO_USE_OIIO_CMAKE_CONFIG=ON
-DOCIO_USE_OIIO_FOR_APPS=${{ matrix.use-oiio }}
working-directory: _build
- name: Build
run: |
@@ -279,11 +285,13 @@ jobs:
build-openfx: 'ON'
cxx-standard: 17
python-version: '3.11'
use-oiio: 'ON'
- build: 2
build-docs: 'ON'
build-openfx: 'ON'
cxx-standard: 14
python-version: '3.9'
use-oiio: 'OFF'
steps:
- name: Setup Python
uses: actions/setup-python@v4
@@ -292,7 +300,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
- name: Install docs env
run: share/ci/scripts/windows/install_docs_env.sh
run: |
DOXYGEN_PATH=$GITHUB_WORKSPACE/doxygen
share/ci/scripts/windows/install_docs_env.sh "$DOXYGEN_PATH"
echo "$DOXYGEN_PATH" >> $GITHUB_PATH
shell: bash
if: matrix.build-docs == 'ON'
- name: Install tests env
@@ -359,7 +370,7 @@ jobs:
-DOCIO_WARNING_AS_ERROR=OFF \
-DPython_EXECUTABLE=$(which python) \
-DOCIO_BUILD_PYTHON=OFF \
-DOCIO_USE_OIIO_CMAKE_CONFIG=ON
-DOCIO_USE_OIIO_FOR_APPS=${{ matrix.use-oiio }}
shell: bash
working-directory: _build
- name: Build
-2
View File
@@ -16,8 +16,6 @@ on:
tags-ignore:
- v0.*
- v1.*
paths:
- .github/workflows/gpu_workflow.yml
jobs:
# ---------------------------------------------------------------------------
+3 -3
View File
@@ -104,7 +104,7 @@ jobs:
-DOCIO_BUILD_OPENFX=ON \
-DOCIO_BUILD_GPU_TESTS=OFF \
-DOCIO_BUILD_PYTHON=${{ matrix.build-python}} \
-DOCIO_USE_SSE=ON \
-DOCIO_USE_SIMD=ON \
-DOCIO_USE_OIIO_FOR_APPS=OFF \
-DOCIO_INSTALL_EXT_PACKAGES=ALL \
-DOCIO_WARNING_AS_ERROR=ON \
@@ -219,7 +219,7 @@ jobs:
-DOCIO_BUILD_OPENFX=ON \
-DOCIO_BUILD_GPU_TESTS=OFF \
-DOCIO_BUILD_PYTHON=${{ matrix.build-python}} \
-DOCIO_USE_SSE=ON \
-DOCIO_USE_SIMD=ON \
-DOCIO_USE_OIIO_FOR_APPS=OFF \
-DOCIO_INSTALL_EXT_PACKAGES=ALL \
-DOCIO_WARNING_AS_ERROR=ON \
@@ -333,7 +333,7 @@ jobs:
-DOCIO_BUILD_OPENFX=ON \
-DOCIO_BUILD_GPU_TESTS=OFF \
-DOCIO_BUILD_PYTHON=${{ matrix.build-python}} \
-DOCIO_USE_SSE=ON \
-DOCIO_USE_SIMD=ON \
-DOCIO_USE_OIIO_FOR_APPS=OFF \
-DOCIO_INSTALL_EXT_PACKAGES=ALL \
-DOCIO_WARNING_AS_ERROR=ON \
+73 -17
View File
@@ -78,41 +78,86 @@ jobs:
matrix:
include:
# -------------------------------------------------------------------
# CPython 64 bits
# CPython 64 bits manylinux_2_28
# -------------------------------------------------------------------
- build: CPython 3.7 64 bits
- build: CPython 3.7 64 bits manylinux_2_28
manylinux: manylinux_2_28
python: cp37-manylinux*
arch: x86_64
- build: CPython 3.8 64 bits
- build: CPython 3.8 64 bits manylinux_2_28
manylinux: manylinux_2_28
python: cp38-manylinux*
arch: x86_64
- build: CPython 3.9 64 bits
- build: CPython 3.9 64 bits manylinux_2_28
manylinux: manylinux_2_28
python: cp39-manylinux*
arch: x86_64
- build: CPython 3.10 64 bits
- build: CPython 3.10 64 bits manylinux_2_28
manylinux: manylinux_2_28
python: cp310-manylinux*
arch: x86_64
- build: CPython 3.11 64 bits
- build: CPython 3.11 64 bits manylinux_2_28
manylinux: manylinux_2_28
python: cp311-manylinux*
arch: x86_64
- build: CPython 3.12 64 bits manylinux_2_28
manylinux: manylinux_2_28
python: cp312-manylinux*
arch: x86_64
# -------------------------------------------------------------------
# CPython ARM 64 bits
# CPython 64 bits manylinux2014
# -------------------------------------------------------------------
- build: CPython 3.7 ARM 64 bits
- build: CPython 3.7 64 bits manylinux2014
manylinux: manylinux2014
python: cp37-manylinux*
arch: x86_64
- build: CPython 3.8 64 bits manylinux2014
manylinux: manylinux2014
python: cp38-manylinux*
arch: x86_64
- build: CPython 3.9 64 bits manylinux2014
manylinux: manylinux2014
python: cp39-manylinux*
arch: x86_64
- build: CPython 3.10 64 bits manylinux2014
manylinux: manylinux2014
python: cp310-manylinux*
arch: x86_64
- build: CPython 3.11 64 bits manylinux2014
manylinux: manylinux2014
python: cp311-manylinux*
arch: x86_64
- build: CPython 3.12 64 bits manylinux2014
manylinux: manylinux2014
python: cp312-manylinux*
arch: x86_64
# -------------------------------------------------------------------
# CPython ARM 64 bits manylinux2014
# -------------------------------------------------------------------
- build: CPython 3.7 ARM 64 bits manylinux2014
manylinux: manylinux2014
python: cp37-manylinux*
arch: aarch64
- build: CPython 3.8 ARM 64 bits
- build: CPython 3.8 ARM 64 bits manylinux2014
manylinux: manylinux2014
python: cp38-manylinux*
arch: aarch64
- build: CPython 3.9 ARM 64 bits
- build: CPython 3.9 ARM 64 bits manylinux2014
manylinux: manylinux2014
python: cp39-manylinux*
arch: aarch64
- build: CPython 3.10 ARM 64 bits
- build: CPython 3.10 ARM 64 bits manylinux2014
manylinux: manylinux2014
python: cp310-manylinux*
arch: aarch64
- build: CPython 3.11 ARM 64 bits
- build: CPython 3.11 ARM 64 bits manylinux2014
manylinux: manylinux2014
python: cp311-manylinux*
arch: aarch64
- build: CPython 3.12 ARM 64 bits manylinux2014
manylinux: manylinux2014
python: cp312-manylinux*
arch: aarch64
steps:
- uses: actions/checkout@v3
@@ -128,10 +173,12 @@ jobs:
platforms: all
- name: Build wheels
uses: pypa/cibuildwheel@v2.13.1
uses: pypa/cibuildwheel@v2.16.2
env:
CIBW_BUILD: ${{ matrix.python }}
CIBW_ARCHS: ${{ matrix.arch }}
CIBW_MANYLINUX_X86_64_IMAGE: ${{ matrix.manylinux }}
CIBW_MANYLINUX_AARCH64_IMAGE: ${{ matrix.manylinux }}
- uses: actions/upload-artifact@v3
with:
@@ -143,7 +190,7 @@ jobs:
macos:
name: Build wheels on macOS
runs-on: macos-11
runs-on: macos-12
# Don't run on OCIO forks
if: |
github.event_name != 'schedule' ||
@@ -169,6 +216,9 @@ jobs:
- build: CPython 3.11 64 bits
python: cp311-*
arch: x86_64
- build: CPython 3.12 64 bits
python: cp312-*
arch: x86_64
# -------------------------------------------------------------------
# CPython ARM 64 bits
# -------------------------------------------------------------------
@@ -184,6 +234,9 @@ jobs:
- build: CPython 3.11 ARM 64 bits
python: cp311-*
arch: arm64
- build: CPython 3.12 ARM 64 bits
python: cp312-*
arch: arm64
steps:
- uses: actions/checkout@v3
@@ -194,7 +247,7 @@ jobs:
python-version: '3.8'
- name: Build wheels
uses: pypa/cibuildwheel@v2.13.1
uses: pypa/cibuildwheel@v2.16.2
env:
CIBW_BUILD: ${{ matrix.python }}
CIBW_ARCHS: ${{ matrix.arch }}
@@ -209,7 +262,7 @@ jobs:
windows:
name: Build wheels on Windows
runs-on: windows-2019
runs-on: windows-2022
# Don't run on OCIO forks
if: |
github.event_name != 'schedule' ||
@@ -235,6 +288,9 @@ jobs:
- build: CPython 3.11 64 bits
python: cp311-*
arch: AMD64
- build: CPython 3.12 64 bits
python: cp312-*
arch: AMD64
steps:
- uses: actions/checkout@v3
@@ -245,7 +301,7 @@ jobs:
python-version: '3.8'
- name: Build wheels
uses: pypa/cibuildwheel@v2.13.1
uses: pypa/cibuildwheel@v2.16.2
env:
CIBW_BUILD: ${{ matrix.python }}
CIBW_ARCHS: ${{ matrix.arch }}
+5
View File
@@ -3,8 +3,13 @@
This file documents releases up to 1.1.1. For a description of version 2.0 and later
please refer to the Releases page on GitHub:
https://github.com/AcademySoftwareFoundation/OpenColorIO/releases
and for more details please see the release notes in latest documentation pages:
https://opencolorio.readthedocs.io/en/latest/releases/_index.html#releases
**Version 1.1.1 (April 2 2019):**
* Added optional compatibility for building apps with OpenImageIO 1.9+
* Added USE_SSE checks to fix Linux build failure
+6 -3
View File
@@ -29,13 +29,13 @@ endif()
# Project definition.
project(OpenColorIO
VERSION 2.3.0
VERSION 2.3.2
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 "dev")
set(OpenColorIO_VERSION_RELEASE_TYPE "")
###############################################################################
@@ -180,8 +180,11 @@ option(OCIO_USE_OIIO_FOR_APPS "Request OIIO to build apps (ociolutimage, ociocon
if (NOT APPLE)
if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(AMD64|IA64|EM64T|X86|x86_64|i386|i686)")
if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(AMD64|IA64|EM64T|x86_64|X86|i386|i686)")
# Intel-based architecture (not APPLE)
if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(X86|i386|i686)")
set(OCIO_ARCH_X86_32 1)
endif()
set(OCIO_ARCH_X86 1)
set(OCIO_BUILD_ENABLE_OPTIMIZATIONS_SSE ON)
set(OCIO_BUILD_ENABLE_OPTIMIZATIONS_AVX ON)
+1 -1
View File
@@ -243,7 +243,7 @@ expected to validate the behavior of every part of OCIO:
* Any change to existing functionality should have tests added if they
don't already exist.
The test should should be run, via ``ctest``, before submitting a pull request.
The test should be run, via ``ctest``, before submitting a pull request.
## Versioning Policy
+10 -4
View File
@@ -38,7 +38,7 @@ Houdini, Silhouette FX, and
[others](https://opencolorio.org/#supported_apps).
OpenColorIO is free and open source software ([LICENSE](LICENSE)), and
one of several projects actvively sponsored by the ASWF
one of several projects actively sponsored by the ASWF
([Academy Software Foundation](https://www.aswf.io/)).
OpenColorIO Project Mission
@@ -50,12 +50,12 @@ content creation applications and pipelines.
OpenColorIO aims to:
* be stable, secure, and thouroughly tested on Linux, macOS, and Windows
* be stable, secure, and thoroughly tested on Linux, macOS, and Windows
* be performant on modern CPUs and GPUs
* be simple, scalable, and well documented
* be compatible with critical color and imaging standards
* provide lossless color processing wherever possible
* maintain config backwards compatability across major versions
* maintain config backwards compatibility across major versions
* have every new feature carefully reviewed by leaders from the motion picture,
VFX, animation, and video game industries
* have a healthy and active community
@@ -65,13 +65,14 @@ OpenColorIO Project Governance
------------------------------
OpenColorIO is governed by the Academy Software Foundation (ASWF). See
[GOVERNANCE.md](GOVERNANCE.md) for detailed infomation about how the project
[GOVERNANCE.md](GOVERNANCE.md) for detailed information about how the project
operates.
Web Resources
-------------
* Website: <http://opencolorio.org>
* Documentation: <https://opencolorio.readthedocs.io/en/latest/>
* Mailing lists:
* Developer: <ocio-dev@lists.aswf.io>
* User: <ocio-user@lists.aswf.io>
@@ -99,6 +100,11 @@ The following reference implementations are provided:
* Other
* nuke-default
Sources for the newer builtin ACES configuration files can be found in the releases section of the
[OpenColorIO-Config-ACES](https://github.com/AcademySoftwareFoundation/OpenColorIO-Config-ACES)
repository.
Acknowledgements
----------------
+4
View File
@@ -2456,6 +2456,10 @@ public:
*/
bool hasChannelCrosstalk() const;
/**
* Returns a hash string generated by hashing the cachedIDs of the (unoptimized) list of ops
* contained in the Processor. (This forms part of the key used by the config's processor cache.)
*/
const char * getCacheID() const;
/**
+1 -1
View File
@@ -760,7 +760,7 @@ extern OCIOEXPORT const char * OCIO_INACTIVE_COLORSPACES_ENVVAR;
* The envvar 'OCIO_OPTIMIZATION_FLAGS' provides a way to force a given optimization level.
* Remove the variable or set the value to empty to not use it. Set the value of the variable
* to the desired optimization level as either an integer or hexadecimal value.
* Ex: OCIO_OPTIMIZATION_FLAGS="20479" or "0x4FFF" for OPTIMIZATION_LOSSLESS.
* Ex: OCIO_OPTIMIZATION_FLAGS="144457667" or "0x89c3fc3" for OPTIMIZATION_LOSSLESS.
*/
extern OCIOEXPORT const char * OCIO_OPTIMIZATION_FLAGS_ENVVAR;
+6 -6
View File
@@ -4,7 +4,10 @@ requires = [
"wheel",
"cmake>=3.13",
"ninja; sys_platform != 'win32' and platform_machine != 'arm64'",
# Documentation requirements
# Documentation requirements (see docs/requirements.txt for details)
"urllib3<2",
"docutils>=0.18.1",
"sphinx<=7.1.2",
"six",
"testresources",
"recommonmark",
@@ -23,10 +26,6 @@ test-command = [
"ociocheck"
]
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"
@@ -34,4 +33,5 @@ before-build = "share/ci/scripts/linux/yum/install_docs_env.sh"
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"
environment = { PATH="$GITHUB_WORKSPACE/doxygen;$PATH" }
before-build = 'bash -c "share/ci/scripts/windows/install_docs_env.sh $GITHUB_WORKSPACE/doxygen"'
+1
View File
@@ -12,6 +12,7 @@ classifiers =
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: Implementation :: CPython
Programming Language :: C++
description = OpenColorIO (OCIO) is a complete color management solution geared towards motion picture production with an emphasis on visual effects and computer animation.
+2 -1
View File
@@ -5,6 +5,7 @@
set -ex
HERE=$(dirname $0)
DOXYGEN_LOCATION="$1"
bash $HERE/install_doxygen.sh latest
bash $HERE/install_doxygen.sh "$DOXYGEN_LOCATION"
pip install -r $HERE/../../../../docs/requirements.txt
+14 -6
View File
@@ -4,10 +4,18 @@
set -ex
DOXYGEN_VERSION="$1"
DOXYGEN_LOCATION="$1"
if [ "$DOXYGEN_VERSION" == "latest" ]; then
choco install doxygen.install
else
choco install doxygen.install --version=${DOXYGEN_VERSION}
fi
# Utility to parse JSON object.
choco install jq
# Get the URL of the latest zip package for Doxygen.
url=$(curl -s 'https://api.github.com/repos/doxygen/doxygen/releases/latest' | jq -r '.assets[] | select(.name | test("doxygen-.*windows.x64.bin.zip")) | .browser_download_url')
# Download the zip.
mkdir $DOXYGEN_LOCATION
cd $DOXYGEN_LOCATION
powershell 'iwr -URI '$url' -OutFile doxygen.zip'
# Unzip the file into $DOXYGEN_LOCATION.
unzip -o doxygen.zip
@@ -216,7 +216,7 @@ macro (ocio_handle_dependency dep_name)
endif()
if(ocio_dep_REQUIRED)
if(NOT ${dep_name}_FOUND AND NOT ocio_dep_VERSION)
if(NOT ${dep_name}_FOUND)
message(SEND_ERROR "${ColorError}${dep_name} is required, will abort at the end.${ColorReset}")
endif()
endif()
+16 -1
View File
@@ -8,6 +8,7 @@
# minizip-ng_LIBRARY - minizip-ng library to link to
# minizip-ng_INCLUDE_DIR - Where to find mz.h and other headers
# minizip-ng_VERSION - The version of the library
# minizip-ng_COMPAT - Whether minizip-ng MZ_COMPAT was used or not
#
# Global targets defined by this module:
# MINIZIP::minizip-ng - IMPORTED target, if found
@@ -114,7 +115,9 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
PATH_SUFFIXES
include
include/minizip-ng
include/minizip
minizip-ng/include
minizip/include
)
# Minizip-ng uses prefix "lib" on all platform by default.
@@ -202,4 +205,16 @@ if(_minizip-ng_TARGET_CREATE)
mark_as_advanced(minizip-ng_INCLUDE_DIR minizip-ng_LIBRARY minizip-ng_VERSION)
target_link_libraries(MINIZIP::minizip-ng INTERFACE ZLIB::ZLIB)
endif()
endif()
###############################################################################
### Detect compatibility mode ###
set(minizip-ng_COMPAT FALSE)
if(minizip-ng_INCLUDE_DIR)
list(GET minizip-ng_INCLUDE_DIR 0 _minizip-ng_INCLUDE_DIR)
if(EXISTS "${_minizip-ng_INCLUDE_DIR}/mz_compat.h")
set(minizip-ng_COMPAT TRUE)
endif()
endif()
mark_as_advanced(minizip-ng_COMPAT)
+2 -1
View File
@@ -28,11 +28,12 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
# Find include directory
find_path(pystring_INCLUDE_DIR
NAMES
pystring/pystring.h
pystring.h
HINTS
${pystring_ROOT}
PATH_SUFFIXES
include
include/pystring
pystring/include
)
+41 -37
View File
@@ -10,10 +10,9 @@
# yaml-cpp_VERSION - Library's version
#
# Global targets defined by this module:
# yaml-cpp
# yaml-cpp::yaml-cpp
#
# For compatibility with the upstream CMake package, the following variables and targets are defined:
# yaml-cpp::yaml-cpp - Alias of the yaml-cpp target
# YAML_CPP_LIBRARIES - Libraries to link against yaml-cpp
# YAML_CPP_INCLUDE_DIR - Include directory
#
@@ -41,16 +40,26 @@ if(CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
set(BUILD_TYPE_DEBUG ON)
endif()
if(yaml-cpp_FIND_QUIETLY)
set(quiet QUIET)
endif()
if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
set(_yaml-cpp_REQUIRED_VARS yaml-cpp_LIBRARY)
# Search for yaml-cpp-config.cmake
if(NOT DEFINED yaml-cpp_ROOT)
# Search for yaml-cpp-config.cmake
find_package(yaml-cpp ${yaml-cpp_FIND_VERSION} CONFIG QUIET)
find_package(yaml-cpp ${yaml-cpp_FIND_VERSION} CONFIG ${quiet})
endif()
if(yaml-cpp_FOUND)
get_target_property(yaml-cpp_LIBRARY yaml-cpp LOCATION)
# Alias target for yaml-cpp < 0.8 compatibility
if(TARGET yaml-cpp AND NOT TARGET yaml-cpp::yaml-cpp)
add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp)
endif()
get_target_property(yaml-cpp_INCLUDE_DIR yaml-cpp::yaml-cpp INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(yaml-cpp_LIBRARY yaml-cpp::yaml-cpp LOCATION)
else()
# As yaml-cpp-config.cmake search fails, search an installed library
@@ -59,14 +68,14 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
list(APPEND _yaml-cpp_REQUIRED_VARS yaml-cpp_INCLUDE_DIR yaml-cpp_VERSION)
# Search for yaml-cpp.pc
find_package(PkgConfig QUIET)
pkg_check_modules(PC_yaml-cpp QUIET "yaml-cpp>=${yaml-cpp_FIND_VERSION}")
find_package(PkgConfig ${quiet})
pkg_check_modules(PC_yaml-cpp ${quiet} "yaml-cpp>=${yaml-cpp_FIND_VERSION}")
# Try to detect the version installed, if any.
if(NOT PC_yaml-cpp_FOUND)
pkg_search_module(PC_yaml-cpp QUIET "yaml-cpp")
pkg_search_module(PC_yaml-cpp ${quiet} "yaml-cpp")
endif()
# Find include directory
find_path(yaml-cpp_INCLUDE_DIR
NAMES
@@ -91,7 +100,7 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
# Prefer static lib names
set(_yaml-cpp_STATIC_LIB_NAMES
"${CMAKE_STATIC_LIBRARY_PREFIX}yaml-cpp${CMAKE_STATIC_LIBRARY_SUFFIX}")
# Starting from 0.7.0, all platforms uses the suffix "d" for debug.
# See https://github.com/jbeder/yaml-cpp/blob/master/CMakeLists.txt#L141
if(BUILD_TYPE_DEBUG)
@@ -127,42 +136,37 @@ if(NOT OCIO_INSTALL_EXT_PACKAGES STREQUAL ALL)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(yaml-cpp
REQUIRED_VARS
REQUIRED_VARS
${_yaml-cpp_REQUIRED_VARS}
VERSION_VAR
yaml-cpp_VERSION
)
endif()
###############################################################################
### Create target
if(yaml-cpp_FOUND AND NOT TARGET yaml-cpp)
add_library(yaml-cpp UNKNOWN IMPORTED GLOBAL)
set(_yaml-cpp_TARGET_CREATE TRUE)
endif()
###############################################################################
### Configure target ###
if(_yaml-cpp_TARGET_CREATE)
set_target_properties(yaml-cpp PROPERTIES
IMPORTED_LOCATION ${yaml-cpp_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${yaml-cpp_INCLUDE_DIR}
)
mark_as_advanced(yaml-cpp_INCLUDE_DIR yaml-cpp_LIBRARY yaml-cpp_VERSION)
endif()
###############################################################################
### Set variables for compatibility ###
### Create target
if(TARGET yaml-cpp AND NOT TARGET yaml-cpp::yaml-cpp)
add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp)
endif()
if (yaml-cpp_FOUND AND NOT TARGET yaml-cpp::yaml-cpp)
add_library(yaml-cpp::yaml-cpp UNKNOWN IMPORTED GLOBAL)
set_target_properties(yaml-cpp::yaml-cpp PROPERTIES
IMPORTED_LOCATION ${yaml-cpp_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${yaml-cpp_INCLUDE_DIR}
)
if(yaml-cpp_INCLUDE_DIR)
set(YAML_CPP_INCLUDE_DIR "${yaml-cpp_INCLUDE_DIR}")
endif()
# Required because Installyaml-cpp.cmake creates `yaml-cpp::yaml-cpp`
# as an alias, and aliases get resolved in exported targets, causing the
# find_dependency(yaml-cpp) call in OpenColorIOConfig.cmake to fail.
# This can be removed once Installyaml-cpp.cmake targets yaml-cpp 0.8.
if (NOT TARGET yaml-cpp)
add_library(yaml-cpp ALIAS yaml-cpp::yaml-cpp)
endif ()
endif ()
set(YAML_CPP_LIBRARIES yaml-cpp::yaml-cpp)
if (yaml-cpp_FOUND)
# TODO: Remove this variable and use the `yaml-cpp::yaml-cpp` target
# directly when the minimum version of yaml-cpp is updated to 0.8.
get_target_property(YAML_CPP_INCLUDE_DIR yaml-cpp::yaml-cpp INCLUDE_DIRECTORIES)
set(YAML_CPP_LIBRARIES yaml-cpp::yaml-cpp)
endif ()
@@ -110,7 +110,7 @@ if(NOT OpenEXR_FOUND AND OCIO_INSTALL_EXT_PACKAGES AND NOT OCIO_INSTALL_EXT_PACK
-DBUILD_SHARED_LIBS=OFF
-DBUILD_TESTING=OFF
-DOPENEXR_INSTALL_EXAMPLES=OFF
-DOPENEXR_INSTALL_TOOLS=OFF
-DOPENEXR_BUILD_TOOLS=OFF
# Try to use in-source built Imath first, if available.
-DCMAKE_PREFIX_PATH=${_EXT_DIST_ROOT}
)
@@ -38,7 +38,7 @@ if(NOT pystring_FOUND AND OCIO_INSTALL_EXT_PACKAGES AND NOT OCIO_INSTALL_EXT_PAC
else()
set(pystring_VERSION ${pystring_FIND_VERSION})
endif()
set(pystring_INCLUDE_DIR "${_EXT_DIST_ROOT}/${CMAKE_INSTALL_INCLUDEDIR}")
set(pystring_INCLUDE_DIR "${_EXT_DIST_ROOT}/${CMAKE_INSTALL_INCLUDEDIR}/pystring")
set(pystring_LIBRARY
"${_EXT_DIST_ROOT}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}pystring${CMAKE_STATIC_LIBRARY_SUFFIX}")
@@ -21,8 +21,8 @@
###############################################################################
### Create target (if previous 'find_package' call hasn't) ###
if(NOT TARGET yaml-cpp)
add_library(yaml-cpp UNKNOWN IMPORTED GLOBAL)
if(NOT TARGET yaml-cpp::yaml-cpp)
add_library(yaml-cpp::yaml-cpp UNKNOWN IMPORTED GLOBAL)
set(_yaml-cpp_TARGET_CREATE TRUE)
endif()
@@ -138,7 +138,7 @@ if(NOT yaml-cpp_FOUND AND OCIO_INSTALL_EXT_PACKAGES AND NOT OCIO_INSTALL_EXT_PAC
--parallel
)
add_dependencies(yaml-cpp yaml-cpp_install)
add_dependencies(yaml-cpp::yaml-cpp yaml-cpp_install)
if(OCIO_VERBOSE)
message(STATUS "Installing yaml-cpp: ${yaml-cpp_LIBRARY} (version \"${yaml-cpp_VERSION}\")")
endif()
@@ -149,7 +149,7 @@ endif()
### Configure target ###
if(_yaml-cpp_TARGET_CREATE)
set_target_properties(yaml-cpp PROPERTIES
set_target_properties(yaml-cpp::yaml-cpp PROPERTIES
IMPORTED_LOCATION ${yaml-cpp_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${yaml-cpp_INCLUDE_DIR}
)
@@ -157,15 +157,5 @@ if(_yaml-cpp_TARGET_CREATE)
mark_as_advanced(yaml-cpp_INCLUDE_DIR yaml-cpp_LIBRARY yaml-cpp_VERSION)
endif()
###############################################################################
### Set variables for compatibility ###
if(TARGET yaml-cpp AND NOT TARGET yaml-cpp::yaml-cpp)
add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp)
endif()
if(yaml-cpp_INCLUDE_DIR)
set(YAML_CPP_INCLUDE_DIR "${yaml-cpp_INCLUDE_DIR}")
endif()
set(YAML_CPP_INCLUDE_DIR "${yaml-cpp_INCLUDE_DIR}")
set(YAML_CPP_LIBRARIES yaml-cpp::yaml-cpp)
+1 -1
View File
@@ -59,7 +59,7 @@ else()
message(STATUS "Performing Test COMPILER_SUPPORTS_SSE2 - Failed")
endif()
set(CMAKE_REQUIRED_FLAGS "${_cmake_cxx_flags_orig}")
set(CMAKE_CXX_FLAGS "${_cmake_cxx_flags_orig}")
unset(_cmake_cxx_flags_orig)
if(__universal_build)
+1 -1
View File
@@ -13,7 +13,7 @@ endif()
# MSVC doesn't have flags
if(USE_GCC OR USE_CLANG)
set(CMAKE_CXX_FLAGS "-w -msse3")
set(CMAKE_CXX_FLAGS "-w -mssse3")
endif()
if (APPLE AND __universal_build)
+2 -2
View File
@@ -107,8 +107,8 @@ if(USE_GCC OR USE_CLANG)
endif()
if(OCIO_ENABLE_SANITIZER)
set(PLATFORM_COMPILE_OPTIONS "${PLATFORM_COMPILE_OPTIONS};-fno-omit-frame-pointer;-fsanitize=address")
set(PLATFORM_LINK_OPTIONS "${PLATFORM_LINK_OPTIONS};-fsanitize=address")
set(PLATFORM_COMPILE_OPTIONS "${PLATFORM_COMPILE_OPTIONS};-fno-omit-frame-pointer;-fsanitize=address;-fsanitize=undefined")
set(PLATFORM_LINK_OPTIONS "${PLATFORM_LINK_OPTIONS};-fsanitize=address;-fsanitize=undefined")
endif()
endif()
-1
View File
@@ -9,7 +9,6 @@
#if OCIO_USE_AVX
#include <immintrin.h>
#include <stdio.h>
#include <OpenColorIO/OpenColorIO.h>
#include "BitDepthUtils.h"
-1
View File
@@ -9,7 +9,6 @@
#if OCIO_USE_AVX2
#include <immintrin.h>
#include <stdio.h>
#include <OpenColorIO/OpenColorIO.h>
#include "BitDepthUtils.h"
+1 -1
View File
@@ -389,7 +389,7 @@ elseif(APPLE)
# Check for minizip first since our Findminizip module sets minizip-ng_LIBRARY.
if (minizip_LIBRARY)
if (minizip_LIBRARY OR minizip-ng_COMPAT)
get_filename_component(_minizip-ng_LIBDIR "${minizip_LIBRARY}" DIRECTORY)
set(_minizip-ng_NAME "minizip")
elseif(minizip-ng_LIBRARY)
+10 -3
View File
@@ -50,6 +50,13 @@ static inline void cpuid(int index, int *data)
{
#if _MSC_VER
__cpuid(data, index);
#elif OCIO_ARCH_X86_32
__asm__ volatile (
"mov %%ebx, %%esi \n\t"
"cpuid \n\t"
"xchg %%ebx, %%esi"
: "=a" (data[0]), "=S" (data[1]), "=c" (data[2]), "=d" (data[3])
: "0" (index), "2"(0));
#else
__asm__ volatile (
"mov %%rbx, %%rsi \n\t"
@@ -100,10 +107,10 @@ CPUInfo::CPUInfo()
flags |= X86_CPU_FLAG_SSE42;
/* Check OSXSAVE and AVX bits */
if (info.reg.ecx & 0x18000000)
if ((info.reg.ecx & 0x18000000) == 0x18000000)
{
xcr = xgetbv();
if(xcr & 0x6) {
if((xcr & 0x6) == 0x6) {
flags |= X86_CPU_FLAG_AVX;
if(info.reg.ecx & 0x20000000) {
@@ -122,7 +129,7 @@ CPUInfo::CPUInfo()
/* OPMASK/ZMM state */
if ((xcr & 0xe0) == 0xe0) {
if ((flags & X86_CPU_FLAG_AVX2) && (info.reg.ebx & 0xd0030000))
if ((flags & X86_CPU_FLAG_AVX2) && ((info.reg.ebx & 0xd0030000) == 0xd0030000))
flags |= X86_CPU_FLAG_AVX512;
}
}
+3
View File
@@ -3,10 +3,13 @@
#cmakedefine01 OCIO_ARCH_X86
#cmakedefine01 OCIO_ARCH_X86_32
// Relevant only for arm64 architecture.
#if defined(__aarch64__)
#cmakedefine01 OCIO_USE_SSE2NEON
#else
#define OCIO_USE_SSE2NEON 0
#endif
// On the Apple platform, a universal build is created for both x86_64 and arm64 architectures.
+36 -5
View File
@@ -12,6 +12,8 @@
#include <regex>
#include <functional>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "builtinconfigs/BuiltinConfigRegistry.h"
@@ -34,7 +36,6 @@
#include "Platform.h"
#include "PrivateTypes.h"
#include "Processor.h"
#include "pystring/pystring.h"
#include "transforms/FileTransform.h"
#include "utils/StringUtils.h"
#include "ViewingRules.h"
@@ -435,7 +436,7 @@ public:
{
m_viewTransforms.push_back(vt->createEditableCopy());
}
m_defaultViewTransform = rhs.m_defaultViewTransform;
m_defaultLumaCoefs = rhs.m_defaultLumaCoefs;
m_strictParsing = rhs.m_strictParsing;
@@ -2821,6 +2822,23 @@ bool Config::isColorSpaceLinear(const char * colorSpace, ReferenceSpaceType refe
auto procToReference = config.getImpl()->getProcessorWithoutCaching(
config, t, TRANSFORM_DIR_FORWARD
);
// TODO: It could be useful to try and avoid evaluating points through ops that are
// expensive but highly unlikely to be linear (with inverse Lut3D being the prime example).
// There are some heuristics that are used in ConfigUtils.cpp that are intended to filter
// out color spaces from consideration before a processor is even calculated. However,
// those are not entirely appropriate here since one could imagine wanting to know if a
// color space involving a FileTransform (an ASC CDL being a good example) is linear.
// Likewise, one might want to know whether a color space involving a Look or ColorSpace
// Transform is linear (both of those are filtered out by the ConfigUtils heuristics).
// It seems like the right approach here is to go ahead and build the processor and
// thereby convert File/Look/ColorSpace Transforms into ops. But currently there is
// no method on the Processor class to know if it contains a Lut3D. There is the
// ProcessorMetadata files list, though that is not as precise. For example, it would
// not say if a CLF or CTF file contains a Lut3D or just a matrix. Probably the best
// solution would be to have each op sub-class provide an isLinear method and then
// surface that on the Processor class, iterating over each op in the Processor.
auto optCPUProc = procToReference->getOptimizedCPUProcessor(OPTIMIZATION_NONE);
optCPUProc->apply(desc, descDst);
@@ -4100,6 +4118,10 @@ void Config::addLook(const ConstLookRcPtr & look)
if(StringUtils::Lower(getImpl()->m_looksList[i]->getName()) == namelower)
{
getImpl()->m_looksList[i] = look->createEditableCopy();
AutoMutex lock(getImpl()->m_cacheidMutex);
getImpl()->resetCacheIDs();
return;
}
}
@@ -4715,20 +4737,29 @@ ConstProcessorRcPtr Config::GetProcessorFromConfigs(const ConstContextRcPtr & sr
"the source color space.");
}
const char* csName = dstConfig->getDisplayViewColorSpaceName(dstDisplay, dstView);
const char* displayColorSpaceName = View::UseDisplayName(csName) ? dstDisplay : csName;
ConstColorSpaceRcPtr displayColorSpace = dstConfig->getColorSpace(displayColorSpaceName);
if (!displayColorSpace)
{
throw Exception("Can't create the processor for the destination config: "
"display color space not found.");
}
auto p2 = dstConfig->getProcessor(dstContext, dstInterchangeName, dstDisplay, dstView, direction);
if (!p2)
{
throw Exception("Can't create the processor for the destination config "
"and the destination color space.");
"and the destination display view transform.");
}
ProcessorRcPtr processor = Processor::Create();
processor->getImpl()->setProcessorCacheFlags(srcConfig->getImpl()->m_cacheFlags);
// If the source color spaces is a data space, its corresponding processor
// If either of the color spaces are data spaces, its corresponding processor
// will be empty, but need to make sure the entire result is also empty to
// better match the semantics of how data spaces are handled.
if (!srcColorSpace->isData())
if (!srcColorSpace->isData() && !displayColorSpace->isData())
{
if (direction == TRANSFORM_DIR_INVERSE)
{
+203 -37
View File
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenColorIO Project.
#include <pystring.h>
#include "ConfigUtils.h"
#include "MathUtils.h"
#include "utils/StringUtils.h"
@@ -165,7 +167,7 @@ bool GetInterchangeRolesForColorSpaceConversion(const char ** srcInterchangeCSNa
// Return true if the color space name or its aliases contains sRGB (case-insensitive).
//
bool containsSRGB(ConstColorSpaceRcPtr & cs)
bool containsSRGB(const ConstColorSpaceRcPtr & cs)
{
std::string name = StringUtils::Lower(cs->getName());
if (StringUtils::Find(name, "srgb") != std::string::npos)
@@ -223,10 +225,31 @@ const char * getRefSpaceName(const ConstConfigRcPtr & cfg)
return "";
}
// Find the first scene-referred color space with isdata: true.
//
const char * getDataSpaceName(const ConstConfigRcPtr & cfg)
{
int nbCs = cfg->getNumColorSpaces(SEARCH_REFERENCE_SPACE_SCENE, COLORSPACE_ALL);
for (int i = 0; i < nbCs; i++)
{
const char * csname = cfg->getColorSpaceNameByIndex(SEARCH_REFERENCE_SPACE_SCENE,
COLORSPACE_ALL,
i);
ConstColorSpaceRcPtr cs = cfg->getColorSpace(csname);
if (cs->isData())
{
return csname;
}
}
return "";
}
// Return false if the supplied Processor modifies any of the supplied float values
// by more than the supplied absolute tolerance amount.
//
bool isIdentityTransform(ConstProcessorRcPtr proc,
bool isIdentityTransform(const ConstProcessorRcPtr & proc,
std::vector<float> & RGBAvals,
float absTolerance)
{
@@ -249,28 +272,143 @@ bool isIdentityTransform(ConstProcessorRcPtr proc,
return true;
}
// Helper to avoid color spaces that are without transforms or are data spaces.
// Determine whether a Processor contains a MatrixTransform with off-diagonal coefficients.
//
bool hasNoTransform(const ConstColorSpaceRcPtr & cs)
bool hasNonTrivialMatrixTransform(const ConstProcessorRcPtr & proc)
{
GroupTransformRcPtr gt = proc->createGroupTransform();
// The result of createGroupTransform only contains transforms that correspond to ops,
// in other words, there are no complex transforms such as File, Builtin, or ColorSpace,
// and the only GroupTransform is the enclosing one.
for (int i = 0; i < gt->getNumTransforms(); ++i)
{
ConstTransformRcPtr transform = gt->getTransform(i);
if (transform->getTransformType() == TRANSFORM_TYPE_MATRIX)
{
// Check that there is a significant off-diagonal coefficient in the matrix.
// This is to avoid matrices that are not actual color primary conversions,
// for example, the scale and offset that are sometimes prepended to a Lut1D.
ConstMatrixTransformRcPtr mtx = DynamicPtrCast<const MatrixTransform>(transform);
double values[16];
mtx->getMatrix(values);
for (int j = 0; j < 3 ; ++j) // only checking rgb, not alpha
{
for (int k = 0; k < 3 ; ++k) // only checking rgb, not alpha
{
if (j != k)
{
if (std::abs(values[j * 4 + k]) > 0.1)
{
return true;
}
}
}
}
}
}
return false;
}
// Determine if the transform contains a type that is inappropriate for the heuristics.
//
bool containsBlockedTransform(const ConstTransformRcPtr & transform)
{
// If it's a GroupTransform, need to recurse into it to check the contents.
if (transform->getTransformType() == TRANSFORM_TYPE_GROUP)
{
ConstGroupTransformRcPtr gt = DynamicPtrCast<const GroupTransform>(transform);
for (int i = 0; i < gt->getNumTransforms(); ++i)
{
ConstTransformRcPtr tr = gt->getTransform(i);
if (containsBlockedTransform(tr))
{
return true;
}
}
}
// Prevent FileTransforms from being used, except for spi1d and spimtx since these
// may be used with OCIO v1 configs to implement the type of color spaces the heuristics
// are designed to look for. (E.g. The sRGB Texture space in the legacy ACES configs.)
else if (transform->getTransformType() == TRANSFORM_TYPE_FILE)
{
ConstFileTransformRcPtr ft = DynamicPtrCast<const FileTransform>(transform);
std::string filepath = ft->getSrc();
std::string root, extension;
pystring::os::path::splitext(root, extension, filepath);
extension = StringUtils::Lower(extension);
if (extension != ".spi1d" && extension != ".spimtx")
{
return true;
}
}
// Prevent transforms that may be hiding a FileTransform.
else if (transform->getTransformType() == TRANSFORM_TYPE_COLORSPACE
|| transform->getTransformType() == TRANSFORM_TYPE_DISPLAY_VIEW
|| transform->getTransformType() == TRANSFORM_TYPE_LOOK)
{
return true;
}
// Putting this here since Lut3D is the main type of transform to avoid,
// however given that the input transform comes directly from a color space
// and has not been converted to a processor yet, it should never actually
// have a transform of this type (it would still be a FileTransform).
else if (transform->getTransformType() == TRANSFORM_TYPE_LUT3D)
{
return true;
}
return false;
}
// Look at the to_ref/from_ref transforms in the color space and exclude color spaces
// that are probably not what the heuristics are looking for and could be prohibitively
// expensive to fully check.
//
// Because this check is done before a processor is built, it is inexpensive but it may
// be inaccurate. In other words, it's possible that this check will exclude some
// reasonable color spaces, but that's better than trying to invert 3d-LUTs, etc.
//
// cs -- Color space object to check.
// refSpaceType -- Exclude if the color space is not of the same reference space type.
// blockRefSpaces -- Exclude the color space if it does not have any transforms.
//
bool excludeColorSpaceFromHeuristics(const ConstColorSpaceRcPtr & cs,
ReferenceSpaceType refSpaceType,
bool blockRefSpaces)
{
if (cs->isData())
{
return true;
}
ConstTransformRcPtr srcTransform = cs->getTransform(COLORSPACE_DIR_TO_REFERENCE);
if (!srcTransform)
if (cs->getReferenceSpaceType() != refSpaceType)
{
srcTransform = cs->getTransform(COLORSPACE_DIR_FROM_REFERENCE);
if (srcTransform)
{
return false;
}
else
{
return true;
}
return true;
}
ConstTransformRcPtr transform = cs->getTransform(COLORSPACE_DIR_TO_REFERENCE);
if (transform)
{
// The to_ref transform is what the heuristics try to use first, so if that
// does not contain problematic transforms, it's ok to proceed without checking
// the from_ref transform.
return containsBlockedTransform(transform);
}
// There is no to_ref transform, check if the from_ref is present.
transform = cs->getTransform(COLORSPACE_DIR_FROM_REFERENCE);
if (transform)
{
return containsBlockedTransform(transform);
}
// Color space contains no transforms (it's a reference space).
else
{
return blockRefSpaces;
}
return false;
}
// Test the supplied color space against a set of color spaces in the built-in config.
@@ -288,17 +426,6 @@ int getReferenceSpaceFromLinearSpace(const ConstConfigRcPtr & srcConfig,
const ConstColorSpaceRcPtr & cs,
const ConstConfigRcPtr & builtinConfig)
{
// Currently only handling scene-referred spaces in the heuristics.
if (cs->getReferenceSpaceType() == REFERENCE_SPACE_DISPLAY)
{
return -1;
}
// Don't check spaces without transforms / data spaces.
if (hasNoTransform(cs))
{
return -1;
}
// Define a set of (somewhat arbitrary) RGB values to test whether the combined transform is
// enough of an identity.
std::vector<float> vals = { 0.7f, 0.4f, 0.02f, 0.f,
@@ -353,14 +480,9 @@ int getReferenceSpaceFromLinearSpace(const ConstConfigRcPtr & srcConfig,
//
int getReferenceSpaceFromSRGBSpace(const ConstConfigRcPtr & srcConfig,
const char * srcRefName,
const ConstColorSpaceRcPtr cs,
const ConstColorSpaceRcPtr & cs,
const ConstConfigRcPtr & builtinConfig)
{
// Currently only handling scene-referred spaces in the heuristics.
if (cs->getReferenceSpaceType() == REFERENCE_SPACE_DISPLAY)
{
return -1;
}
// Get a transform in the to-reference direction.
ConstTransformRcPtr toRefTransform;
ConstTransformRcPtr ctransform = cs->getTransform(COLORSPACE_DIR_TO_REFERENCE);
@@ -405,6 +527,18 @@ int getReferenceSpaceFromSRGBSpace(const ConstConfigRcPtr & srcConfig,
ConstProcessorRcPtr proc = srcConfig->getProcessor(toRefTransform, TRANSFORM_DIR_FORWARD);
// Ensure that the color space is not only an sRGB curve, it needs to have a color matrix
// too or else the last step below could succeed by pairing the built-in sRGB space with
// a linear space that cancels out the matrix in the built-in sRGB space.
// NB: This is being done after the getProcessor call rather than simply looking at
// the raw color space transform contents since once it becomes a processor, the complex
// transforms (e.g. File, ColorSpace, Builtins) that could be hiding a matrix are
// converted into ops.
if (!hasNonTrivialMatrixTransform(proc))
{
return -1;
}
ConstCPUProcessorRcPtr cpu = proc->getOptimizedCPUProcessor(OPTIMIZATION_NONE);
// Convert the non-linear values to linear.
cpu->apply(desc, descDst);
@@ -422,6 +556,7 @@ int getReferenceSpaceFromSRGBSpace(const ConstConfigRcPtr & srcConfig,
out[i] = 1.055f * std::pow(out[i], 1.f / 2.4f) - 0.055f;
}
// Compare against the original source values.
// (This assumes equal channel sRGB values remain so in the reference space of src config.)
if (!EqualWithAbsError(vals[i], out[i], 1e-3f))
{
return -1;
@@ -442,6 +577,8 @@ int getReferenceSpaceFromSRGBSpace(const ConstConfigRcPtr & srcConfig,
// sRGB texture space. If the result is an identity, then that tells what the source config
// reference space is.
// At this point, cs has the expected non-linearity and a non-trivial matrix to its reference space.
// Now try to identify the matrix.
for (int i = 0; i < getNumberOfbuiltinLinearSpaces(); i++)
{
ConstProcessorRcPtr proc = Config::GetProcessorFromConfigs(srcConfig,
@@ -511,7 +648,7 @@ void IdentifyInterchangeSpace(const char ** srcInterchange,
// Identify the name of a reference space in the source config.
*srcInterchange = getRefSpaceName(srcConfig);
if (!*srcInterchange)
if (!**srcInterchange)
{
std::ostringstream os;
os << "The supplied config does not have a color space for the reference.";
@@ -531,8 +668,16 @@ void IdentifyInterchangeSpace(const char ** srcInterchange,
for (int i = 0; i < nbCs; i++)
{
ConstColorSpaceRcPtr cs = srcConfig->getColorSpace(srcConfig->getColorSpaceNameByIndex(i));
if (containsSRGB(cs))
{
// Exclude color spaces that may be too expensive to test or otherwise inappropriate.
// Currently only handling scene-referred spaces in the heuristics.
if (excludeColorSpaceFromHeuristics(cs, REFERENCE_SPACE_SCENE, true))
{
continue;
}
refColorSpacePrimsIndex = getReferenceSpaceFromSRGBSpace(srcConfig,
*srcInterchange,
cs,
@@ -549,6 +694,14 @@ void IdentifyInterchangeSpace(const char ** srcInterchange,
for (int i = 0; i < nbCs; i++)
{
ConstColorSpaceRcPtr cs = srcConfig->getColorSpace(srcConfig->getColorSpaceNameByIndex(i));
// Exclude color spaces that may be too expensive to test or otherwise inappropriate.
// Currently only handling scene-referred spaces in the heuristics.
if (excludeColorSpaceFromHeuristics(cs, REFERENCE_SPACE_SCENE, true))
{
continue;
}
if (srcConfig->isColorSpaceLinear(cs->getName(), REFERENCE_SPACE_SCENE))
{
refColorSpacePrimsIndex = getReferenceSpaceFromLinearSpace(srcConfig,
@@ -602,6 +755,18 @@ const char * IdentifyBuiltinColorSpace(const ConstConfigRcPtr & srcConfig,
throw Exception(os.str().c_str());
}
if (builtinColorSpace->isData())
{
const char * dataName = getDataSpaceName(srcConfig);
if (!*dataName)
{
std::ostringstream os;
os << "The requested space is a data space but the supplied config does not have a data space.";
throw Exception(os.str().c_str());
}
return dataName;
}
ReferenceSpaceType builtinRefSpaceType = builtinColorSpace->getReferenceSpaceType();
// Identify interchange spaces. Passing an empty string for the source color space
@@ -633,8 +798,8 @@ const char * IdentifyBuiltinColorSpace(const ConstConfigRcPtr & srcConfig,
0.f, 0.f, 0.f, 0.f,
1.f, 1.f, 1.f, 0.f };
// Loop over each non-data color space in the source config and test if the conversion to
// the specified space in the built-in config is an identity.
// Loop over the active, non-excluded, color spaces in the source config and test if the
// conversion to the specified space in the built-in config is an identity.
//
// Note that there is a possibility that both the source and built-in sides of the
// transform could be an identity (e.g., if the user asks for ACES2065-1 and that is
@@ -646,7 +811,8 @@ const char * IdentifyBuiltinColorSpace(const ConstConfigRcPtr & srcConfig,
for (int i = 0; i < nbCs; i++)
{
ConstColorSpaceRcPtr cs = srcConfig->getColorSpace(srcConfig->getColorSpaceNameByIndex(i));
if (cs->isData() || (cs->getReferenceSpaceType() != builtinRefSpaceType))
if (excludeColorSpaceFromHeuristics(cs, builtinRefSpaceType, false))
{
continue;
}
+2 -1
View File
@@ -7,6 +7,8 @@
#include <sstream>
#include <string>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "ContextVariableUtils.h"
@@ -15,7 +17,6 @@
#include "OCIOZArchive.h"
#include "PathUtils.h"
#include "PrivateTypes.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
namespace OCIO_NAMESPACE
+4 -3
View File
@@ -4,6 +4,8 @@
#include <cstring>
#include <unordered_set>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Display.h"
@@ -19,7 +21,6 @@
#include "ParseUtils.h"
#include "PathUtils.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
#include "ViewingRules.h"
#include "yaml-cpp/yaml.h"
@@ -4737,9 +4738,9 @@ inline void save(YAML::Emitter & out, const Config & config)
out << YAML::Newline;
out << YAML::Newline;
if (configMajorVersion >= 2)
if (configMajorVersion >= 2 || config.getNumEnvironmentVars() > 0)
{
// Print the environment even if empty.
// For v2 configs, write the environment section, even if empty.
out << YAML::Key << "environment";
out << YAML::Value << YAML::BeginMap;
for(int i = 0; i < config.getNumEnvironmentVars(); ++i)
+3 -2
View File
@@ -8,10 +8,12 @@
#include <set>
#include <limits>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Mutex.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
#include "transforms/FileTransform.h"
@@ -24,7 +26,6 @@
#include "mz_strm_mem.h"
#include "mz_strm_os.h"
#include "mz_strm_split.h"
#include "mz_strm_zlib.h"
#include "mz_zip.h"
#include "mz_zip_rw.h"
+2 -1
View File
@@ -4,6 +4,8 @@
#include <cstring>
#include <sstream>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Logging.h"
@@ -20,7 +22,6 @@
#include "ops/lut1d/Lut1DOp.h"
#include "ops/lut3d/Lut3DOp.h"
#include "ops/range/RangeOp.h"
#include "pystring/pystring.h"
namespace OCIO_NAMESPACE
{
+2 -2
View File
@@ -5,12 +5,13 @@
#include <iostream>
#include <map>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Mutex.h"
#include "PathUtils.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
#include "OCIOZArchive.h"
@@ -218,4 +219,3 @@ int ParseColorSpaceFromString(const Config & config, const char * str)
}
} // namespace OCIO_NAMESPACE
+35 -5
View File
@@ -18,8 +18,6 @@
#endif
#endif
#include <stdio.h>
#include <OpenColorIO/OpenColorIO.h>
#include "BitDepthUtils.h"
@@ -76,6 +74,8 @@ static inline void sse2RGBATranspose_4x4(__m128 row0, __m128 row1, __m128 row2,
out_a = _mm_movehl_ps(tmp3, tmp1);
}
#if !OCIO_USE_SSE2NEON
static inline __m128i sse2_blendv(__m128i a, __m128i b, __m128i mask)
{
return _mm_xor_si128(_mm_and_si128(_mm_xor_si128(a, b), mask), a);
@@ -164,6 +164,8 @@ static inline __m128 sse2_cvtph_ps(__m128i a)
return _mm_or_ps(o, sign);
}
#endif
// Note Packing functions perform no 0.0 - 1.0 normalization
// but perform 0 - max value clamping for integer formats
template<BitDepth BD> struct SSE2RGBAPack {};
@@ -290,21 +292,48 @@ struct SSE2RGBAPack<BIT_DEPTH_F16>
__m128i rgba_00_01 = _mm_loadu_si128((const __m128i*)(in + 0));
__m128i rgba_02_03 = _mm_loadu_si128((const __m128i*)(in + 8));
#if OCIO_USE_SSE2NEON
// use neon hardware support for f16 to f32
__m128 rgba0 = vreinterpretq_m128_f32(
vcvt_f32_f16(vget_low_f16(vreinterpretq_f16_s64(vreinterpretq_s64_m128i(rgba_00_01))))
);
__m128 rgba1 = vreinterpretq_m128_f32(
vcvt_f32_f16(vget_high_f16(vreinterpretq_f16_s64(vreinterpretq_s64_m128i(rgba_00_01))))
);
__m128 rgba2 = vreinterpretq_m128_f32(
vcvt_f32_f16(vget_low_f16(vreinterpretq_f16_s64(vreinterpretq_s64_m128i(rgba_02_03))))
);
__m128 rgba3 = vreinterpretq_m128_f32(
vcvt_f32_f16(vget_high_f16(vreinterpretq_f16_s64(vreinterpretq_s64_m128i(rgba_02_03))))
);
#else
__m128 rgba0 = sse2_cvtph_ps(rgba_00_01);
__m128 rgba1 = sse2_cvtph_ps(_mm_shuffle_epi32(rgba_00_01, _MM_SHUFFLE(1,0,3,2)));
__m128 rgba2 = sse2_cvtph_ps(rgba_02_03);
__m128 rgba3 = sse2_cvtph_ps(_mm_shuffle_epi32(rgba_02_03, _MM_SHUFFLE(1,0,3,2)));
#endif
sse2RGBATranspose_4x4(rgba0, rgba1, rgba2, rgba3, r, g, b, a);
}
static inline void Store(half *out, __m128 r, __m128 g, __m128 b, __m128 a)
{
__m128 rgba0, rgba1, rgba2, rgba3;
__m128i rgba;
sse2RGBATranspose_4x4(r, g, b, a, rgba0, rgba1, rgba2, rgba3);
#if OCIO_USE_SSE2NEON
// use neon hardware support for f32 to f16
float16x8_t rgba;
float16x4_t rgba00_01 = vcvt_f16_f32(vreinterpretq_f32_m128(rgba0));
float16x4_t rgba03_03 = vcvt_f16_f32(vreinterpretq_f32_m128(rgba1));
float16x4_t rgba04_05 = vcvt_f16_f32(vreinterpretq_f32_m128(rgba2));
float16x4_t rgba06_07 = vcvt_f16_f32(vreinterpretq_f32_m128(rgba3));
rgba = vcombine_f16(rgba00_01, rgba03_03);
vst1q_f16((float16_t *)(out+0), rgba);
rgba = vcombine_f16(rgba04_05, rgba06_07);
vst1q_f16((float16_t *)(out+8), rgba);
#else
__m128i rgba;
__m128i rgba00_01 = sse2_cvtps_ph(rgba0);
__m128i rgba02_03 = sse2_cvtps_ph(rgba1);
__m128i rgba04_05 = sse2_cvtps_ph(rgba2);
@@ -315,6 +344,7 @@ struct SSE2RGBAPack<BIT_DEPTH_F16>
rgba = _mm_xor_si128(rgba04_05, _mm_shuffle_epi32(rgba06_07, _MM_SHUFFLE(1,0,3,2)));
_mm_storeu_si128((__m128i*)(out+8), rgba);
#endif
}
};
@@ -217,7 +217,7 @@ void LocalFileFormat::buildFileOps(OpRcPtrVec & ops,
{
// Use 0 for empty string.
int cccindex=0;
if (StringToInt(&cccindex, cccid.c_str(), true))
if (cccid.empty() || StringToInt(&cccindex, cccid.c_str(), true))
{
int maxindex = ((int)cachedFile->m_transformVec.size())-1;
if (cccindex<0 || cccindex>maxindex)
@@ -247,7 +247,7 @@ LocalFileFormat::buildFileOps(OpRcPtrVec & ops,
{
// Use 0 for empty string.
int cccindex=0;
if (StringToInt(&cccindex, cccid.c_str(), true))
if (cccid.empty() || StringToInt(&cccindex, cccid.c_str(), true))
{
int maxindex = ((int)cachedFile->m_transformVec.size())-1;
if (cccindex<0 || cccindex>maxindex)
@@ -274,7 +274,7 @@ LocalFileFormat::buildFileOps(OpRcPtrVec & ops,
if (!success)
{
std::ostringstream os;
os << "You must specify a valid cccid to load from the ccc file";
os << "You must specify a valid cccid to load from the cdl file";
os << " (either by name or index). id='" << cccid << "' ";
os << "is not found in the file, and is not parsable as an ";
os << "integer index.";
@@ -6,6 +6,8 @@
#include <fstream>
#include <sstream>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "expat.h"
@@ -23,7 +25,6 @@
#include "OpBuilders.h"
#include "ops/noop/NoOps.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "TransformBuilder.h"
#include "transforms/FileTransform.h"
#include "utils/StringUtils.h"
@@ -8,6 +8,8 @@
#include <sstream>
#include <iostream>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "BitDepthUtils.h"
@@ -16,7 +18,6 @@
#include "ops/lut1d/Lut1DOp.h"
#include "ops/lut3d/Lut3DOp.h"
#include "ParseUtils.h"
#include "pystring/pystring.h"
#include "Platform.h"
#include "transforms/FileTransform.h"
#include "utils/StringUtils.h"
@@ -771,4 +772,3 @@ FileFormat * CreateFileFormatDiscreet1DL()
}
} // namespace OCIO_NAMESPACE
@@ -5,6 +5,8 @@
#include <sstream>
#include <fstream>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Logging.h"
@@ -15,7 +17,6 @@
#include "ops/matrix/MatrixOp.h"
#include "ops/range/RangeOp.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "transforms/FileTransform.h"
@@ -5,6 +5,8 @@
#include <cstring>
#include <iterator>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "expat.h"
@@ -13,7 +15,6 @@
#include "ops/lut3d/Lut3DOp.h"
#include "ParseUtils.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "transforms/FileTransform.h"
#include "utils/StringUtils.h"
#include "utils/NumberUtils.h"
@@ -579,4 +580,3 @@ FileFormat * CreateFileFormatIridasLook()
}
} // namespace OCIO_NAMESPACE
@@ -24,13 +24,23 @@ namespace {
static inline __m128 fmadd_ps_sse2(__m128 a, __m128 b, __m128 c)
{
#if OCIO_USE_SSE2NEON
return vreinterpretq_m128_f32(
vfmaq_f32(vreinterpretq_f32_m128(c), vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))
);
#else
return _mm_add_ps(_mm_mul_ps(a, b), c);
#endif
}
static inline __m128 floor_ps_sse2(__m128 v)
{
#if OCIO_USE_SSE2NEON
return _mm_floor_ps(v);
#else
// NOTE: using truncate cvtt
return _mm_cvtepi32_ps(_mm_cvttps_epi32(v));
#endif
}
@@ -38,18 +38,32 @@ struct rgbavec_sse2 {
static inline __m128 floor_ps_sse2(__m128 v)
{
#if OCIO_USE_SSE2NEON
return _mm_floor_ps(v);
#else
// NOTE: using truncate cvtt
return _mm_cvtepi32_ps(_mm_cvttps_epi32(v));
#endif
}
static inline __m128 blendv_ps_sse2(__m128 a, __m128 b, __m128 mask)
{
#if OCIO_USE_SSE2NEON
return _mm_blendv_ps(a, b, mask);
#else
return _mm_xor_ps(_mm_and_ps(_mm_xor_ps(a, b), mask), a);
#endif
}
static inline __m128 fmadd_ps_sse2(__m128 a, __m128 b, __m128 c)
{
#if OCIO_USE_SSE2NEON
return vreinterpretq_m128_f32(
vfmaq_f32(vreinterpretq_f32_m128(c), vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))
);
#else
return _mm_add_ps(_mm_mul_ps(a, b), c);
#endif
}
static inline rgbavec_sse2 interp_tetrahedral_sse2(const Lut3DContextSSE2 &ctx, __m128 r, __m128 g, __m128 b, __m128 a)
@@ -184,7 +184,7 @@ void BuildColorSpaceOps(OpRcPtrVec & ops,
if (!src)
{
srcNamedTransform = config.getNamedTransform(srcName.c_str());
srcNamedTransform = config.getNamedTransform( context->resolveStringVar(srcName.c_str()) );
if (!srcNamedTransform)
{
ThrowMissingCS(srcName.c_str());
@@ -192,7 +192,7 @@ void BuildColorSpaceOps(OpRcPtrVec & ops,
}
if (!dst)
{
dstNamedTransform = config.getNamedTransform(dstName.c_str());
dstNamedTransform = config.getNamedTransform( context->resolveStringVar(dstName.c_str()) );
if (!dstNamedTransform)
{
ThrowMissingCS(dstName.c_str());
@@ -393,6 +393,31 @@ void BuildReferenceConversionOps(OpRcPtrVec & ops,
}
}
bool CollectContextVariables(const Config & config,
const Context & context,
ConstNamedTransformRcPtr & nt,
ContextRcPtr & usedContextVars)
{
bool foundContextVars = false;
if (nt)
{
ConstTransformRcPtr to = nt->getTransform(TRANSFORM_DIR_FORWARD);
if (to && CollectContextVariables(config, context, to, usedContextVars))
{
foundContextVars = true;
}
ConstTransformRcPtr from = nt->getTransform(TRANSFORM_DIR_INVERSE);
if (from && CollectContextVariables(config, context, from, usedContextVars))
{
foundContextVars = true;
}
}
return foundContextVars;
}
bool CollectContextVariables(const Config & config,
const Context & context,
ConstColorSpaceRcPtr & cs,
@@ -441,15 +466,37 @@ bool CollectContextVariables(const Config & config,
}
ConstColorSpaceRcPtr src = config.getColorSpace(srcName.c_str());
if (CollectContextVariables(config, context, src, usedContextVars))
if (src)
{
foundContextVars = true;
if (CollectContextVariables(config, context, src, usedContextVars))
{
foundContextVars = true;
}
}
else
{
ConstNamedTransformRcPtr nt_src = config.getNamedTransform(srcName.c_str());
if (CollectContextVariables(config, context, nt_src, usedContextVars))
{
foundContextVars = true;
}
}
ConstColorSpaceRcPtr dst = config.getColorSpace(dstName.c_str());
if (CollectContextVariables(config, context, dst, usedContextVars))
if (dst)
{
foundContextVars = true;
if (CollectContextVariables(config, context, dst, usedContextVars))
{
foundContextVars = true;
}
}
else
{
ConstNamedTransformRcPtr nt_dst = config.getNamedTransform(dstName.c_str());
if (CollectContextVariables(config, context, nt_dst, usedContextVars))
{
foundContextVars = true;
}
}
return foundContextVars;
+2 -1
View File
@@ -9,6 +9,8 @@
#include <iostream>
#include <iterator>
#include <pystring.h>
#include <OpenColorIO/OpenColorIO.h>
#include "Caching.h"
@@ -19,7 +21,6 @@
#include "ops/noop/NoOps.h"
#include "PathUtils.h"
#include "Platform.h"
#include "pystring/pystring.h"
#include "utils/StringUtils.h"
namespace OCIO_NAMESPACE
+134 -47
View File
@@ -50,12 +50,16 @@ public:
void setGPU(OCIO::ConstGPUProcessorRcPtr gpu)
{
m_gpu = gpu;
m_oglApp = OCIO::OglApp::CreateOglApp("ociochecklut", 256, 20);
if (m_verbose)
if (!m_oglApp)
{
m_oglApp->printGLInfo();
m_oglApp = OCIO::OglApp::CreateOglApp("ociochecklut", 256, 20);
if (m_verbose)
{
m_oglApp->printGLInfo();
}
}
m_oglApp->setPrintShader(m_verbose);
float image[4]{ 0.f, 0.f, 0.f, 0.f };
m_oglApp->initImage(1, 1, OCIO::OglApp::COMPONENTS_RGBA, image);
@@ -191,6 +195,7 @@ int main (int argc, const char* argv[])
bool usegpu = false;
bool usegpuLegacy = false;
bool outputgpuInfo = false;
bool stepInfo = false;
ArgParse ap;
ap.options("ociochecklut -- check any LUT file and optionally convert a pixel\n\n"
@@ -199,6 +204,7 @@ int main (int argc, const char* argv[])
"<SEPARATOR>", "Options:",
"-t", &test, "Test a set a predefined RGB values",
"-v", &verbose, "Verbose",
"-s", &stepInfo, "Print the output after each step in a multi - transform LUT",
"--help", &help, "Print help message",
"--inv", &invlut, "Apply LUT in inverse direction",
"--gpu", &usegpu, "Use GPU instead of CPU",
@@ -346,7 +352,7 @@ int main (int argc, const char* argv[])
0.f, 1.f, 0.f,
0.f, 0.f, 1.f };
if (verbose)
if (verbose || stepInfo)
{
std::cout << std::endl;
}
@@ -357,59 +363,140 @@ int main (int argc, const char* argv[])
{
std::vector<float> pixel = { input[curPix], input[curPix+1], input[curPix+2],
comp == 3 ? 0.0f : input[curPix + 3] };
try
{
proc.apply(pixel);
}
catch (const OCIO::Exception & e)
{
std::cerr << "ERROR: Processing pixel: " << e.what() << std::endl;
return 1;
}
catch (...)
{
std::cerr << "ERROR: Unknown error encountered while processing pixel." << std::endl;
return 1;
}
// Print to string so that in & out values can be aligned if needed.
std::vector<std::string> out;
ToString(out, pixel, 0, comp);
if (verbose)
if (stepInfo)
{
std::vector<std::string> in;
ToString(in, input, curPix, comp);
std::cout << "Input [R G B";
if (comp == 4)
// Process each step in a multi - transform LUT
try
{
std::cout << " A";
}
std::cout << "]: [";
PrintAlignedVec(in, out, comp);
std::cout << "]" << std::endl;
// Create GroupTransform so that each can be processed one at a time.
auto processor = config->getProcessor(t);
auto transform = processor->createGroupTransform();
std::vector<float> inputPixel = pixel;
std::vector<float> outputPixel = pixel;
const auto numTransforms = transform->getNumTransforms();
std::cout << std::endl;
std::cout << "Output [R G B";
if (comp == 4)
{
std::cout << " A";
for (int i = 0; i < numTransforms; ++i)
{
auto transformStep = transform->getTransform(i);
auto processorStep = config->getProcessor(transformStep);
if (usegpu || usegpuLegacy)
{
proc.setGPU(usegpuLegacy ? processorStep->getOptimizedLegacyGPUProcessor(OCIO::OPTIMIZATION_DEFAULT, 32)
: processorStep->getDefaultGPUProcessor());
}
else
{
proc.setCPU(processorStep->getDefaultCPUProcessor());
}
// Process the pixel
proc.apply(outputPixel);
// Print the input/output pixel
std::vector<std::string> in;
ToString(in, inputPixel, 0, comp);
std::vector<std::string> out;
ToString(out, outputPixel, 0, comp);
std::cout << "\n" << *(transform->getTransform(i)) << std::endl;
std::cout << "Input [R G B";
if (comp == 4)
{
std::cout << " A";
}
std::cout << "]: [";
PrintAlignedVec(in, out, comp);
std::cout << "]" << std::endl;
std::cout << "Output [R G B";
if (comp == 4)
{
std::cout << " A";
}
std::cout << "]: [";
PrintAlignedVec(out, in, comp);
std::cout << "]" << std::endl;
inputPixel = outputPixel;
}
}
std::cout << "]: [";
PrintAlignedVec(out, in, comp);
std::cout << "]" << std::endl;
catch (const OCIO::Exception& exception)
{
std::cerr << "ERROR: " << exception.what() << std::endl;
return 1;
}
catch (...)
{
std::cerr << "ERROR: Unknown error encountered while processing single step operator." << std::endl;
return 1;
}
curPix += comp;
}
else
{
std::cout << out[0] << " " << out[1] << " " << out[2];
if (comp == 4)
// Process in a single step
try
{
std::cout << " " << out[3];
proc.apply(pixel);
}
catch (const OCIO::Exception& e)
{
std::cerr << "ERROR: Processing pixel: " << e.what() << std::endl;
return 1;
}
catch (...)
{
std::cerr << "ERROR: Unknown error encountered while processing pixel." << std::endl;
return 1;
}
// Print to string so that in & out values can be aligned if needed.
std::vector<std::string> out;
ToString(out, pixel, 0, comp);
std::cout << std::endl;
}
curPix += comp;
if (verbose)
{
std::vector<std::string> in;
ToString(in, input, curPix, comp);
std::cout << "Input [R G B";
if (comp == 4)
{
std::cout << " A";
}
std::cout << "]: [";
PrintAlignedVec(in, out, comp);
std::cout << "]" << std::endl;
std::cout << "Output [R G B";
if (comp == 4)
{
std::cout << " A";
}
std::cout << "]: [";
PrintAlignedVec(out, in, comp);
std::cout << "]" << std::endl;
}
else
{
std::cout << out[0] << " " << out[1] << " " << out[2];
if (comp == 4)
{
std::cout << " " << out[3];
}
std::cout << std::endl;
}
curPix += comp;
}
}
else if (test)
{
@@ -41,10 +41,10 @@ Dependencies
* PyOpenColorIO
* [OpenImageIO (Python bindings)](https://github.com/OpenImageIO/oiio)
* [Imath (Python bindings)](https://github.com/AcademySoftwareFoundation/Imath)
* ``pip install -r requirements.txt``
* [numpy](https://pypi.org/project/numpy/)
* [Pygments](https://pypi.org/project/Pygments/)
* [PyOpenGL](https://pypi.org/project/PyOpenGL/)
* [PySide2](https://pypi.org/project/PySide2/)
* [PySide6](https://pypi.org/project/PySide6/)
* [QtAwesome](https://pypi.org/project/QtAwesome/)
* [imageio](https://pypi.org/project/imageio/)
+4 -5
View File
@@ -7,7 +7,7 @@ import sys
from pathlib import Path
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets, QtOpenGL
from PySide6 import QtCore, QtGui, QtWidgets, QtOpenGL
import ocioview.log_handlers # Import to initialize logging
from ocioview.main_window import OCIOView
@@ -30,12 +30,11 @@ if __name__ == "__main__":
sys.excepthook = excepthook
# OpenGL core profile needed on macOS to access programmatic pipeline
gl_format = QtOpenGL.QGLFormat()
gl_format.setProfile(QtOpenGL.QGLFormat.CoreProfile)
gl_format.setSampleBuffers(True)
gl_format = QtGui.QSurfaceFormat()
gl_format.setProfile(QtGui.QSurfaceFormat.CoreProfile)
gl_format.setSwapInterval(1)
gl_format.setVersion(4, 0)
QtOpenGL.QGLFormat.setDefaultFormat(gl_format)
QtGui.QSurfaceFormat.setDefaultFormat(gl_format)
# Create app
app = QtWidgets.QApplication(sys.argv)
+1 -1
View File
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from .items import (
ColorSpaceEdit,
+1 -1
View File
@@ -3,7 +3,7 @@
from pathlib import Path
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
# Root application directory
@@ -6,7 +6,7 @@ from typing import Optional
import PyOpenColorIO as ocio
from pygments.formatters import HtmlFormatter
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..message_router import MessageRouter
from ..utils import get_glyph_icon, processor_to_shader_html
@@ -40,9 +40,9 @@ class CodeInspector(QtWidgets.QWidget):
html_css = HtmlFormatter(style="material").get_style_defs()
# Update line number colors to match palette
html_css = html_css.replace("#263238", palette.color(palette.Base).name())
html_css = html_css.replace("#263238", palette.color(palette.ColorRole.Base).name())
html_css = html_css.replace(
"#37474F", palette.color(palette.Text).darker(150).name()
"#37474F", palette.color(palette.ColorRole.Text).darker(150).name()
)
# Widgets
@@ -8,7 +8,7 @@ from typing import Optional
import numpy as np
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..constants import R_COLOR, G_COLOR, B_COLOR, GRAY_COLOR
from ..message_router import MessageRouter
@@ -17,11 +17,22 @@ from ..widgets import EnumComboBox, FloatEditArray, IntEdit
class SampleType(enum.Enum):
"""Enum of curve sampling types for representing OCIO transforms."""
LINEAR = "linear"
"""Linear scale."""
LOG = "log"
"""Log scale with a user-defined base."""
class CurveInspector(QtWidgets.QWidget):
"""
Widget for inspecting OCIO transform tone curves, which updates
asynchronously when visible, to reduce unnecessary background
processing.
"""
@classmethod
def label(cls) -> str:
return "Curve"
@@ -43,11 +54,11 @@ class CurveInspector(QtWidgets.QWidget):
self.input_range_edit.setToolTip(self.input_range_label.toolTip())
self.input_range_edit.value_changed.connect(self._on_input_range_changed)
self.sample_size_label = get_glyph_icon("ph.line-segments", as_widget=True)
self.sample_size_label.setToolTip("Sample size")
self.sample_size_edit = IntEdit(default=CurveView.SAMPLE_SIZE_DEFAULT)
self.sample_size_edit.setToolTip(self.sample_size_label.toolTip())
self.sample_size_edit.value_changed.connect(self._on_sample_size_changed)
self.sample_count_label = get_glyph_icon("ph.line-segments", as_widget=True)
self.sample_count_label.setToolTip("Sample count")
self.sample_count_edit = IntEdit(default=CurveView.SAMPLE_COUNT_DEFAULT)
self.sample_count_edit.setToolTip(self.sample_count_label.toolTip())
self.sample_count_edit.value_changed.connect(self._on_sample_count_changed)
self.sample_type_label = get_glyph_icon("mdi6.function-variant", as_widget=True)
self.sample_type_label.setToolTip("Sample type")
@@ -70,16 +81,16 @@ class CurveInspector(QtWidgets.QWidget):
option_layout = QtWidgets.QHBoxLayout()
option_layout.addWidget(self.input_range_label)
option_layout.addWidget(self.input_range_edit)
option_layout.setStretch(1, 2)
option_layout.addWidget(self.sample_size_label)
option_layout.addWidget(self.sample_size_edit)
option_layout.setStretch(3, 1)
option_layout.setStretch(1, 3)
option_layout.addWidget(self.sample_count_label)
option_layout.addWidget(self.sample_count_edit)
option_layout.setStretch(3, 2)
option_layout.addWidget(self.sample_type_label)
option_layout.addWidget(self.sample_type_combo)
option_layout.setStretch(5, 1)
option_layout.setStretch(5, 3)
option_layout.addWidget(self.log_base_label)
option_layout.addWidget(self.log_base_edit)
option_layout.setStretch(7, 1)
option_layout.setStretch(7, 2)
layout = QtWidgets.QVBoxLayout()
layout.addLayout(option_layout)
@@ -88,83 +99,137 @@ class CurveInspector(QtWidgets.QWidget):
self.setLayout(layout)
def reset(self) -> None:
"""Clear rendered curves."""
self.view.reset()
@QtCore.Slot(str, float)
def _on_input_range_changed(self, label: str, value: float) -> None:
"""
Triggered when the user changes the input range, which defines
the input values to be sampled through the transform.
:param label: Float edit label
:param value: Float edit value
"""
self.view.set_input_range(
self.input_range_edit.component_value("min"),
self.input_range_edit.component_value("max"),
)
@QtCore.Slot(int)
def _on_sample_size_changed(self, sample_size: int) -> None:
if sample_size >= CurveView.SAMPLE_SIZE_MIN:
self.view.set_sample_size(sample_size)
def _on_sample_count_changed(self, sample_count: int) -> None:
"""
Triggered when the user changes the number of samples to be
processed within the input range through the transform.
:param sample_count: Number of samples. Typically, a power of 2
number.
"""
if sample_count >= CurveView.SAMPLE_COUNT_MIN:
self.view.set_sample_count(sample_count)
else:
with SignalsBlocked(self.sample_size_edit):
self.sample_size_edit.set_value(CurveView.SAMPLE_SIZE_MIN)
self.view.set_sample_size(CurveView.SAMPLE_SIZE_MIN)
with SignalsBlocked(self.sample_count_edit):
self.sample_count_edit.set_value(CurveView.SAMPLE_COUNT_MIN)
self.view.set_sample_count(CurveView.SAMPLE_COUNT_MIN)
@QtCore.Slot(int)
def _on_sample_type_changed(self, index: int) -> None:
"""
Triggered when the user changes the sample type, which defines
how samples are distributed within the input range.
:param index: Curve type index
"""
sample_type = self.sample_type_combo.member()
self.log_base_edit.setEnabled(sample_type == SampleType.LOG)
self.view.set_sample_type(sample_type)
@QtCore.Slot(int)
def _on_log_base_changed(self, log_base: int) -> None:
"""
Triggered when the user changes the base for the log sample
type.
:param log_base: Log scale base
"""
self.view.set_log_base(log_base)
class CurveView(QtWidgets.QGraphicsView):
"""
Widget for rendering OCIO transform tone curves.
"""
SAMPLE_SIZE_MIN = 2**8
SAMPLE_SIZE_DEFAULT = 2**10
SAMPLE_COUNT_MIN = 2**8
SAMPLE_COUNT_DEFAULT = 2**10
INPUT_MIN_DEFAULT = 0.0
INPUT_MAX_DEFAULT = 1.0
LOG_BASE_DEFAULT = 2
CURVE_SCALE = 100
FONT_HEIGHT = 4
# The curve viewer only shows 5 digit decimal precision, so this should work fine
# as a minimum when input min is 0.
LOG_EPSILON = 1e-5
LOG_BASE_DEFAULT = 2
EPSILON = 1e-5
def __init__(
self,
input_min: float = INPUT_MIN_DEFAULT,
input_max: float = INPUT_MAX_DEFAULT,
sample_size: int = SAMPLE_SIZE_DEFAULT,
sample_count: int = SAMPLE_COUNT_DEFAULT,
sample_type: SampleType = SampleType.LINEAR,
log_base: int = LOG_BASE_DEFAULT,
parent: Optional[QtWidgets.QWidget] = None,
):
"""
:param input_min: Input range minimum value
:param input_max: Input range maximum value
:param sample_count: Number of samples in the input range,
which will typically be a power of 2 value.
:param sample_type: Sample scale/distribution type
:param log_base: Log scale base when sample_type is
`SampleType.LOG`.
"""
super().__init__(parent=parent)
self.setRenderHint(QtGui.QPainter.Antialiasing, True)
self.setViewportUpdateMode(QtWidgets.QGraphicsView.FullViewportUpdate)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setMouseTracking(True)
self.scale(1, -1)
self.scale(1, -1) # Flip to make origin the bottom-left corner
# Input range
if input_max <= input_min:
input_min = self.INPUT_MIN_DEFAULT
input_max = self.INPUT_MAX_DEFAULT
self._log_base = max(2, log_base)
self._input_min = input_min
self._input_max = input_max
self._sample_size = max(self.SAMPLE_SIZE_MIN, sample_size)
# Sample characteristics
self._sample_count = max(self.SAMPLE_COUNT_MIN, sample_count)
self._sample_type = sample_type
self._log_base = max(2, log_base)
# Cached sample data
self._sample_ellipse: Optional[QtWidgets.QGraphicsEllipseItem] = None
self._sample_text: Optional[QtWidgets.QGraphicsTextItem] = None
self._sample_rect: Optional[QtCore.QRectF] = None
self._samples_x_lin: np.ndarray = None
self._samples_x_log: np.ndarray = None
self._sample_y_min: float = self._input_min
self._sample_y_max: float = self._input_max
self._samples: dict[str, np.ndarray] = {}
self._nearest_samples: dict[str, tuple[float, float, float]] = {}
self._x_lin: np.ndarray = np.array([], dtype=np.float32)
self._x_log: np.ndarray = np.array([], dtype=np.float32)
self._x_min: float = self._input_min
self._x_max: float = self._input_max
self._y_min: float = self._input_min
self._y_max: float = self._input_max
# Cached curve data
self._curve_init = False
self._curve_tf = QtGui.QTransform()
self._curve_tf_inv = QtGui.QTransform()
self._curve_paths: dict[str, QtGui.QPainterPath] = {}
self._curve_items: dict[str, QtWidgets.QGraphicsPathItem] = {}
self._curve_rect = QtCore.QRectF(
@@ -173,10 +238,11 @@ class CurveView(QtWidgets.QGraphicsView):
self._input_max - self._input_min,
self._input_max - self._input_min,
)
self._nearest_samples: dict[str, tuple[float, float, float]] = {}
self._prev_cpu_proc = None
self._curve_init = False
# Cached processor from which the OCIO transform is derived
self._prev_cpu_proc = None
# Graphics scene
self._scene = QtWidgets.QGraphicsScene()
self.setScene(self._scene)
@@ -200,8 +266,8 @@ class CurveView(QtWidgets.QGraphicsView):
msg_router.set_cpu_processor_updates_allowed(False)
def resizeEvent(self, event: QtGui.QResizeEvent) -> None:
"""Re-fit graph on resize, to always be centered."""
super().resizeEvent(event)
self._fit()
def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
@@ -213,37 +279,52 @@ class CurveView(QtWidgets.QGraphicsView):
self._nearest_samples.clear()
pos = self.mapToScene(event.pos()) / self.CURVE_SCALE
pos = self._curve_tf_inv.map(self.mapToScene(event.pos()))
pos_arr = np.array([pos.x(), pos.y()], dtype=np.float32)
for color_name, samples in self._samples.items():
all_dist = np.linalg.norm(samples - pos_arr, axis=2)
all_dist = np.linalg.norm(samples - pos_arr, axis=1)
nearest_dist_index = np.argmin(all_dist)
self._nearest_samples[color_name] = (
(
self._samples_x_lin[nearest_dist_index]
self._x_lin[nearest_dist_index]
if self._sample_type == SampleType.LINEAR
else self._samples_x_log[nearest_dist_index]
else self._x_log[nearest_dist_index]
),
samples[0][nearest_dist_index][0],
samples[0][nearest_dist_index][1],
samples[nearest_dist_index][0],
samples[nearest_dist_index][1],
)
self._invalidate()
def wheelEvent(self, event: QtGui.QWheelEvent) -> None:
"""
Ignore wheel events to prevent scrolling around graphics scene.
"""
event.ignore()
def reset(self) -> None:
"""Clear all curves."""
self._samples.clear()
self._curve_items.clear()
self._curve_paths.clear()
self._nearest_samples.clear()
self._prev_cpu_proc = None
self._curve_init = False
self._curve_paths.clear()
self._curve_items.clear()
self._prev_cpu_proc = None
self._scene.clear()
self._invalidate()
def set_input_range(self, input_min: float, input_max: float) -> None:
"""
Set the input range, which defines the input values to be
sampled through the transform.
:param input_min: Input range minimum value
:param input_max: Input range maximum value
"""
if (
input_min != self._input_min or input_max != self._input_max
) and input_max > input_min:
@@ -252,31 +333,62 @@ class CurveView(QtWidgets.QGraphicsView):
self._update_curves()
def set_input_min(self, input_min: float) -> None:
"""
Set the input minimum, which defines the lowest value to be
sampled through the transform.
:param input_min: Input range minimum value
"""
if input_min != self._input_min and input_min < self._input_max:
self._input_min = input_min
self._update_curves()
def set_input_max(self, input_max: float) -> None:
"""
Set the input maximum, which defines the highest value to be
sampled through the transform.
:param input_max: Input range minimum value
"""
if input_max != self._input_max and input_max > self._input_min:
self._input_max = input_max
self._update_curves()
def set_sample_size(self, sample_size: int) -> None:
if sample_size != self._sample_size and sample_size >= self.SAMPLE_SIZE_MIN:
self._sample_size = sample_size
def set_sample_count(self, sample_count: int) -> None:
"""
Set the number of samples to be processed within the input
range through the transform.
:param sample_count: Number of samples. Typically, a power of 2
number.
"""
if sample_count != self._sample_count and sample_count >= self.SAMPLE_COUNT_MIN:
self._sample_count = sample_count
self._update_curves()
def set_sample_type(self, sample_type: SampleType) -> None:
"""
Set the sample type, which defines how samples are distributed
within the input range.
:param sample_type: Curve type index
"""
if sample_type != self._sample_type:
self._sample_type = sample_type
self._update_curves()
def set_log_base(self, log_base: int) -> None:
"""
Set the base for the log sample type.
:param log_base: Log scale base
"""
if log_base != self._log_base and log_base >= 2:
self._log_base = log_base
self._update_curves()
def drawBackground(self, painter: QtGui.QPainter, rect: QtCore.QRectF) -> None:
"""Draw curve grid and axis values."""
# Flood fill background
painter.setPen(QtCore.Qt.NoPen)
painter.setBrush(QtCore.Qt.black)
@@ -285,101 +397,41 @@ class CurveView(QtWidgets.QGraphicsView):
if not self._curve_init:
return
# Calculate grid rect
curve_t, curve_b, curve_l, curve_r = (
self._curve_rect.top(),
self._curve_rect.bottom(),
self._curve_rect.left(),
self._curve_rect.right(),
)
# Round to nearest 10 for grid bounds
grid_t = curve_t // 10 * 10
if grid_t > math.ceil(curve_t):
grid_t -= 10
grid_b = curve_b // 10 * 10
if grid_b < math.floor(curve_b):
grid_b += 10
grid_l = curve_l // 10 * 10
if grid_l > math.ceil(curve_l):
grid_l -= 10
grid_r = curve_r // 10 * 10
if grid_r < math.floor(curve_r):
grid_r += 10
font = painter.font()
font.setPixelSize(self.FONT_HEIGHT)
painter.setFont(font)
text_pen = QtGui.QPen(GRAY_COLOR)
grid_pen = QtGui.QPen(GRAY_COLOR.darker(200))
grid_pen.setWidthF(0)
font = painter.font()
font.setPixelSize(self.FONT_HEIGHT)
painter.setPen(grid_pen)
painter.setBrush(QtCore.Qt.NoBrush)
painter.setFont(font)
# Calculate samples to display
sample_step = math.ceil(self._sample_size / 10.0)
min_x = max_x = min_y = max_y = None
if self._sample_type == SampleType.LINEAR:
sample_x_values = self._samples_x_lin
else: # SampleType.LOG
sample_x_values = self._samples_x_log
sample_y_data = []
for i, sample_y in enumerate(
np.linspace(self._sample_y_min, self._sample_y_max, 11, dtype=np.float32)
):
pos_y = sample_y * self.CURVE_SCALE
sample_y_data.append((pos_y, sample_y))
if min_y is None or pos_y < min_y:
min_y = pos_y
if max_y is None or pos_y > max_y:
max_y = pos_y
sample_x_data = []
for i, sample_x in enumerate(sample_x_values):
if not (i % sample_step == 0 or i == self._sample_size - 1):
continue
pos_x = self._samples_x_lin[i] * self.CURVE_SCALE
sample_x_data.append((pos_x, sample_x))
if min_x is None or pos_x < min_x:
min_x = pos_x
if max_x is None or pos_x > max_x:
max_x = pos_x
if min_x is None:
min_x = grid_l
if max_x is None:
max_x = grid_r
if min_y is None:
min_y = grid_t
if max_x is None:
max_y = grid_b
self._sample_rect = QtCore.QRectF(
max_x + 5, min_y, 40, len(self._curve_items) * 20
)
# Draw grid border
painter.drawRect(self._curve_rect)
# Draw grid rows
y_text_origin = QtGui.QTextOption(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
y_text_origin.setWrapMode(QtGui.QTextOption.NoWrap)
for pos_y, sample_y in sample_y_data:
painter.setPen(grid_pen)
painter.drawLine(QtCore.QLineF(min_x, pos_y, max_x, pos_y))
for i, y in enumerate(
np.linspace(self._y_min, self._y_max, 11, dtype=np.float32)
):
p1 = self._curve_tf.map(QtCore.QPointF(self._x_min, y))
p2 = self._curve_tf.map(QtCore.QPointF(self._x_max, y))
if pos_y > grid_t:
label_value = round(sample_y, 2)
if self._y_min < y < self._y_max:
painter.setPen(grid_pen)
painter.drawLine(QtCore.QLineF(p1, p2))
if y > self._y_min:
label_value = round(y, 2)
if label_value == 0.0:
label_value = abs(label_value)
painter.save()
painter.translate(QtCore.QPointF(min_x, pos_y))
painter.translate(p1)
painter.scale(1, -1)
painter.setPen(text_pen)
painter.drawText(
@@ -391,28 +443,39 @@ class CurveView(QtWidgets.QGraphicsView):
x_text_origin = QtGui.QTextOption(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
x_text_origin.setWrapMode(QtGui.QTextOption.NoWrap)
for pos_x, sample_x in sample_x_data:
painter.setPen(grid_pen)
painter.drawLine(QtCore.QLineF(pos_x, min_y, pos_x, max_y))
sample_step = math.ceil(self._sample_count / 10.0)
if pos_x > grid_l:
for i, x in enumerate(self._x_lin):
if not (i % sample_step == 0 or i == self._sample_count - 1):
continue
p1 = self._curve_tf.map(QtCore.QPointF(x, self._y_min))
p2 = self._curve_tf.map(QtCore.QPointF(x, self._y_max))
if self._x_min < x < self._x_max:
painter.setPen(grid_pen)
painter.drawLine(QtCore.QLineF(p1, p2))
if x > self._x_min:
label_value = round(
sample_x, 5 if self._sample_type == SampleType.LOG else 2
x if self._sample_type == SampleType.LINEAR else self._x_log[i],
2 if self._sample_type == SampleType.LINEAR else 5,
)
if label_value == 0.0:
label_value = abs(label_value)
painter.save()
painter.translate(QtCore.QPointF(pos_x, min_y))
painter.translate(p1)
painter.scale(1, -1)
painter.rotate(90)
painter.setPen(text_pen)
painter.drawText(
QtCore.QRect(2.5 + 1, -10, 40, 20), str(label_value), x_text_origin
QtCore.QRectF(2.5 + 1, -10, 40, 20), str(label_value), x_text_origin
)
painter.restore()
def drawForeground(self, painter: QtGui.QPainter, rect: QtCore.QRectF) -> None:
"""Draw nearest sample point and coordinates."""
if not self._curve_init:
return
@@ -436,16 +499,18 @@ class CurveView(QtWidgets.QGraphicsView):
painter.setBrush(QtGui.QColor(color_name))
painter.drawEllipse(
QtCore.QPointF(
nearest_sample[1] * self.CURVE_SCALE,
nearest_sample[2] * self.CURVE_SCALE,
self._curve_tf.map(
QtCore.QPointF(
nearest_sample[1],
nearest_sample[2],
)
),
1.25,
1.25,
1.5,
1.5,
)
# Draw sample values
if sample_l is not None:
# Draw sample values
painter.setBrush(QtCore.Qt.NoBrush)
x_label_value = f"{nearest_sample[0]:.05f}"
@@ -461,27 +526,56 @@ class CurveView(QtWidgets.QGraphicsView):
if color_name == GRAY_COLOR.name():
palette = self.palette()
painter.setPen(palette.color(palette.Text))
painter.setPen(palette.color(palette.ColorRole.Text))
else:
painter.setPen(QtGui.QColor(color_name))
painter.drawText(
QtCore.QRectF(5, -20, 35, 10), x_label_value, text_origin
)
painter.drawText(
QtCore.QRectF(5, -10, 35, 10), y_label_value, text_origin
)
painter.restore()
def _invalidate(self) -> None:
"""Force repaint of visible region of graphics scene."""
self._scene.invalidate(QtCore.QRectF(self.visibleRegion().boundingRect()))
def _update_curves(self) -> None:
"""
Update X-axis samples and rebuild curves from any cached
processor.
"""
self._update_x_samples()
if self._prev_cpu_proc is not None:
self._on_cpu_processor_ready(self._prev_cpu_proc)
def _update_x_samples(self):
"""
Update linear and log X-axis samples from input and sample
parameters.
"""
self._x_lin = np.linspace(
self._input_min, self._input_max, self._sample_count, dtype=np.float32
)
log_min = math.log(max(self.EPSILON, self._input_min))
log_max = max(log_min + 0.00001, math.log(self._input_max, self._log_base))
self._x_log = np.logspace(
log_min, log_max, self._sample_count, base=self._log_base, dtype=np.float32
)
self._x_min = self._x_lin.min()
self._x_max = self._x_lin.max()
def _fit(self) -> None:
"""Fit and center graph."""
if not self._curve_init:
return
# Use font metrics to calculate text padding, based on estimated maximum
# number lengths.
font = self.font()
font.setPixelSize(self.FONT_HEIGHT)
fm = QtGui.QFontMetrics(font)
@@ -503,29 +597,15 @@ class CurveView(QtWidgets.QGraphicsView):
fit_rect = self._curve_rect.adjusted(-pad_l, -pad_t, pad_r, pad_b)
# Fit and center on calculated rectangle
self.fitInView(fit_rect, QtCore.Qt.KeepAspectRatio)
self.centerOn(fit_rect.center())
self.update()
def _invalidate(self) -> None:
self._scene.invalidate(QtCore.QRectF(self.visibleRegion().boundingRect()))
def _update_x_samples(self):
self._samples_x_lin = np.linspace(
self._input_min, self._input_max, self._sample_size, dtype=np.float32
)
self._samples_x_log = np.logspace(
math.log(max(self.LOG_EPSILON, self._input_min)),
math.log(max(self.LOG_EPSILON, self._input_max)),
self._sample_size,
base=self._log_base,
dtype=np.float32,
)
@QtCore.Slot(ocio.CPUProcessor)
def _on_cpu_processor_ready(self, cpu_proc: ocio.CPUProcessor) -> None:
"""
Update curves from OCIO CPU processor.
Update curves from sampled OCIO CPU processor.
:param cpu_proc: CPU processor of currently viewed transform
"""
@@ -535,12 +615,12 @@ class CurveView(QtWidgets.QGraphicsView):
# Get input samples
if self._sample_type == SampleType.LOG:
samples = self._samples_x_log
x_samples = self._x_log
else: # LINEAR
samples = self._samples_x_lin
x_samples = self._x_lin
# Interleave samples per channel
rgb_samples = np.repeat(samples, 3)
rgb_samples = np.repeat(x_samples, 3)
# Apply processor to samples
cpu_proc.applyRGB(rgb_samples)
@@ -550,28 +630,21 @@ class CurveView(QtWidgets.QGraphicsView):
g_samples = rgb_samples[1::3]
b_samples = rgb_samples[2::3]
# Build painter path from sample data
if np.array_equal(r_samples, g_samples) and np.array_equal(
r_samples, b_samples
# Collect sample pairs and min/max Y sample values
if np.allclose(r_samples, g_samples, atol=self.EPSILON) and np.allclose(
r_samples, b_samples, atol=self.EPSILON
):
palette = self.palette()
color_name = palette.color(palette.Text).name()
color_name = palette.color(palette.ColorRole.Text).name()
self._samples[color_name] = np.dstack((self._samples_x_lin, r_samples))
self._sample_y_min = r_samples.min()
self._sample_y_max = r_samples.max()
self._samples[color_name] = np.stack((self._x_lin, r_samples), axis=-1)
curve = QtGui.QPainterPath(
QtCore.QPointF(self._samples_x_lin[0], r_samples[0])
)
curve.reserve(samples.size)
for i in range(1, samples.size):
curve.lineTo(QtCore.QPointF(self._samples_x_lin[i], r_samples[i]))
self._curve_paths[color_name] = curve
self._y_min = r_samples.min()
self._y_max = r_samples.max()
else:
sample_y_min = None
sample_y_max = None
y_min = None
y_max = None
for i, (color, channel_samples) in enumerate(
[
@@ -582,43 +655,71 @@ class CurveView(QtWidgets.QGraphicsView):
):
color_name = color.name()
self._samples[color_name] = np.dstack(
(self._samples_x_lin, channel_samples)
self._samples[color_name] = np.stack(
(self._x_lin, channel_samples), axis=-1
)
channel_sample_y_min = channel_samples.min()
if sample_y_min is None or channel_sample_y_min < sample_y_min:
sample_y_min = channel_sample_y_min
channel_sample_y_max = channel_samples.max()
if sample_y_max is None or channel_sample_y_max > sample_y_max:
sample_y_max = channel_sample_y_max
channel_y_min = channel_samples.min()
if y_min is None or channel_y_min < y_min:
y_min = channel_y_min
channel_y_max = channel_samples.max()
if y_max is None or channel_y_max > y_max:
y_max = channel_y_max
curve = QtGui.QPainterPath(
QtCore.QPointF(self._samples_x_lin[0], channel_samples[0])
self._y_min = y_min
self._y_max = y_max
# Transform to scale/translate curve so that it fits in a square and
# has its origin at (0, 0).
curve_tf = QtGui.QTransform()
curve_tf.translate(-self._x_min, -self._y_min)
curve_tf.scale(
self.CURVE_SCALE / (self._x_max - self._x_min),
self.CURVE_SCALE / (self._y_max - self._y_min),
)
self._curve_tf = curve_tf
self._curve_tf_inv, ok = curve_tf.inverted()
# Curve square
self._curve_rect = QtCore.QRectF(
self._curve_tf.map(QtCore.QPointF(self._x_min, self._y_min)),
self._curve_tf.map(QtCore.QPointF(self._x_max, self._y_max)),
)
# Sample box rect
self._sample_rect = QtCore.QRectF(
self._curve_rect.right() + 5,
self._curve_rect.top(),
40,
len(self._samples) * 20,
)
# Build painter paths that fit in square from sample data
for color_name, channel_samples in self._samples.items():
curve = QtGui.QPainterPath(
self._curve_tf.map(
QtCore.QPointF(channel_samples[0][0], channel_samples[0][1])
)
curve.reserve(samples.size)
for j in range(1, samples.size):
curve.lineTo(
QtCore.QPointF(self._samples_x_lin[j], channel_samples[j])
)
curve.reserve(channel_samples.shape[0])
for i in range(1, channel_samples.shape[0]):
curve.lineTo(
self._curve_tf.map(
QtCore.QPointF(channel_samples[i][0], channel_samples[i][1])
)
self._curve_paths[color_name] = curve
self._sample_y_min = sample_y_min
self._sample_y_max = sample_y_max
)
self._curve_paths[color_name] = curve
# Add curve(s) to scene
self._curve_rect = QtCore.QRectF()
for color_name, curve in self._curve_paths.items():
pen = QtGui.QPen()
pen.setColor(QtGui.QColor(color_name))
pen.setWidthF(0)
pen.setWidthF(0.5)
curve_item = self._scene.addPath(
curve, pen, QtGui.QBrush(QtCore.Qt.NoBrush)
)
curve_item.setScale(self.CURVE_SCALE)
self._curve_items[color_name] = curve_item
self._curve_rect = self._curve_rect.united(curve_item.sceneBoundingRect())
self._curve_init = True
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..log_handlers import set_logging_level
from ..message_router import MessageRouter
+1 -1
View File
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from .inspect.curve_inspector import CurveInspector
from .inspect import LogInspector, CodeInspector
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..widgets import ItemModelListWidget
from ..utils import get_glyph_icon
@@ -5,7 +5,7 @@ from dataclasses import dataclass
from typing import Any, Callable, Optional, Type
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..undo import ConfigSnapshotUndoCommand
@@ -87,7 +87,7 @@ class BaseActiveDisplayViewModel(BaseConfigItemModel):
def _get_undo_command_type(
self, column_desc: ColumnDesc
) -> Type[QtWidgets.QUndoCommand]:
) -> Type[QtGui.QUndoCommand]:
if column_desc == self.ACTIVE:
# Changing check state of the ACTIVE column has side effects related to
# display/view order, so a config snapshot is needed to revert the change.
@@ -4,7 +4,7 @@
from functools import partial
from typing import Optional
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
import PyOpenColorIO as ocio
from ..config_cache import ConfigCache
@@ -5,7 +5,7 @@ import copy
from typing import Any, Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..ref_space_manager import ReferenceSpaceManager
@@ -4,7 +4,7 @@
from functools import partial
from typing import Optional
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..constants import MARGIN_WIDTH
from ..transform_manager import TransformManager
@@ -47,7 +47,7 @@ class BaseConfigItemParamEdit(QtWidgets.QWidget):
if self.__has_transforms__:
self.__has_tabs__ = True
no_tf_color = palette.color(palette.Disabled, palette.Text)
no_tf_color = palette.color(palette.ColorGroup.Disabled, palette.ColorRole.Text)
self._from_ref_icon = get_glyph_icon("mdi6.layers-plus")
self._no_from_ref_icon = get_glyph_icon(
"mdi6.layers-plus", color=no_tf_color
@@ -6,7 +6,7 @@ from dataclasses import dataclass
from typing import Any, Optional, Type, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..config_cache import ConfigCache
from ..transform_manager import TransformManager, TransformAgent
@@ -587,7 +587,7 @@ class BaseConfigItemModel(QtCore.QAbstractTableModel):
def _get_undo_command_type(
self, column_desc: ColumnDesc
) -> Type[QtWidgets.QUndoCommand]:
) -> Type[QtGui.QUndoCommand]:
"""
Support overriding the undo command type used to
track data changes, per column.
@@ -5,7 +5,7 @@ from pathlib import Path
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtWidgets
from PySide6 import QtWidgets
from ..constants import RGB
from ..widgets import (
@@ -5,7 +5,7 @@ import logging
from pathlib import Path
from typing import Any, Optional
from PySide2 import QtCore
from PySide6 import QtCore
import PyOpenColorIO as ocio
from .config_item_model import ColumnDesc, BaseConfigItemModel
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..config_cache import ConfigCache
from ..widgets import CallbackComboBox
@@ -34,7 +34,6 @@ class ColorSpaceDelegate(QtWidgets.QStyledItemDelegate):
editor = CallbackComboBox(
get_items=ConfigCache.get_color_space_names, editable=True, parent=parent
)
editor.setAutoCompletion(True)
editor.completer().setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
return editor
@@ -119,7 +118,6 @@ class RoleDelegate(QtWidgets.QStyledItemDelegate):
raise NotImplementedError
widget = CallbackComboBox(get_items=get_items, editable=True, parent=parent)
widget.setAutoCompletion(True)
widget.completer().setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
return widget
@@ -5,7 +5,7 @@ from dataclasses import dataclass, field
from typing import Any, Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..config_cache import ConfigCache
from ..utils import next_name
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..utils import get_glyph_icon
from .active_display_view_edit import ActiveDisplayViewEdit
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..config_cache import ConfigCache
from ..utils import get_glyph_icon
@@ -6,7 +6,7 @@ from dataclasses import dataclass, field
from typing import Any, Optional, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..undo import ConfigSnapshotUndoCommand
@@ -5,7 +5,7 @@ from functools import partial
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtWidgets
from PySide6 import QtWidgets
from ..config_cache import ConfigCache
from ..widgets import CallbackComboBox, TextEdit
@@ -5,7 +5,7 @@ import copy
from typing import Any, Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..ref_space_manager import ReferenceSpaceManager
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtWidgets
from PySide6 import QtWidgets
from ..config_cache import ConfigCache
from ..utils import get_glyph_icon
@@ -5,7 +5,7 @@ import copy
from typing import Any, Optional, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..utils import get_glyph_icon
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtGui, QtWidgets
from PySide6 import QtGui, QtWidgets
from ..widgets import ItemModelTableWidget
from .delegates import RoleDelegate
@@ -5,7 +5,7 @@ from dataclasses import dataclass
from typing import Any
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..config_cache import ConfigCache
from .config_item_model import ColumnDesc, BaseConfigItemModel
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from ..utils import get_glyph_icon
from .file_rule_edit import FileRuleEdit
@@ -5,7 +5,7 @@ from functools import partial
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtWidgets
from PySide6 import QtWidgets
from ..config_cache import ConfigCache
from ..widgets import CallbackComboBox, LineEdit
@@ -6,7 +6,7 @@ from dataclasses import dataclass, field
from typing import Any, Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from .config_item_model import ColumnDesc, BaseConfigItemModel
@@ -5,7 +5,7 @@ from functools import partial
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..config_cache import ConfigCache
from ..transform_manager import TransformManager
@@ -4,7 +4,7 @@
from typing import Any, Optional, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..ref_space_manager import ReferenceSpaceManager
@@ -4,7 +4,7 @@
from functools import partial
from typing import Optional
from PySide2 import QtWidgets
from PySide6 import QtWidgets
import PyOpenColorIO as ocio
from ..config_cache import ConfigCache
@@ -5,7 +5,7 @@ import copy
from typing import Any, Optional, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..utils import get_enum_member, get_glyph_icon
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..config_cache import ConfigCache
from ..utils import get_glyph_icon
@@ -7,7 +7,7 @@ from dataclasses import dataclass, field
from typing import Any, Optional, Union
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from ..config_cache import ConfigCache
from ..undo import ConfigSnapshotUndoCommand
+1 -1
View File
@@ -7,7 +7,7 @@ from pathlib import Path
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from .config_cache import ConfigCache
from .config_dock import ConfigDock
+1 -1
View File
@@ -10,7 +10,7 @@ from typing import Any, Optional
from queue import Empty, SimpleQueue
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui, QtWidgets
from PySide6 import QtCore, QtGui, QtWidgets
from .utils import config_to_html, processor_to_ctf_html, processor_to_shader_html
+1 -1
View File
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenColorIO Project.
from PySide2 import QtCore
from PySide6 import QtCore
settings = QtCore.QSettings(
+1 -1
View File
@@ -3,7 +3,7 @@
from typing import Optional
from PySide2 import QtGui, QtWidgets
from PySide6 import QtGui, QtWidgets
from .constants import (
BORDER_COLOR_ROLE,
@@ -7,7 +7,7 @@ from functools import partial
from typing import Callable, Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtGui
from PySide6 import QtCore, QtGui
from .utils import get_glyph_icon
@@ -99,12 +99,15 @@ class TransformManager:
tf_agent.item_tf_changed.connect(partial(cls._on_item_tf_changed, slot))
cls._tf_subscriptions[slot] = tf_subscription
# Trigger immediate update to subscribers
# Inform menu subscribers of the menu change
cls._update_menu_items()
cls._on_item_tf_changed(
slot,
*item_model.get_item_transforms(item_name),
)
# Inform init subscribers of the new subscription
for init_callback in cls._tf_subscribers.get(-1, []):
init_callback(slot)
# Trigger immediate update to subscribers of this slot
cls._on_item_tf_changed(slot, *item_model.get_item_transforms(item_name))
# Repaint views for previous and new model
if prev_item_model is not None:
@@ -206,10 +209,27 @@ class TransformManager:
menu_callback(cls.get_subscription_menu_items())
@classmethod
def subscribe_to_transforms(cls, slot: int, tf_callback: Callable) -> None:
def subscribe_to_transform_subscription_init(cls, init_callback: Callable) -> None:
"""
Subscribe to transform and item name updates at the given slot
number.
Subscribe to transform subscription initialization on all slots.
:param init_callback: Transform subscription initialization
callback, which will be called whenever a new transform
subscription is initialized with the subscription slot
number.
"""
cls._tf_subscribers[-1].append(init_callback)
# Trigger immediate update to init subscriber if a transform subscription
# exists.
for slot, tf_subscription in cls._tf_subscriptions.items():
init_callback(slot)
break
@classmethod
def subscribe_to_transforms_at(cls, slot: int, tf_callback: Callable) -> None:
"""
Subscribe to transform updates at the given slot number.
:param slot: Subscription slot number
:param tf_callback: Transform callback, which will be called
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..widgets import EnumComboBox, FloatEdit, FloatEditArray
from .transform_edit import BaseTransformEdit
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..widgets import ComboBox
from .transform_edit import BaseTransformEdit
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..constants import RGB
from ..widgets import EnumComboBox, FloatEdit, FloatEditArray
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..config_cache import ConfigCache
from ..widgets import CheckBox, CallbackComboBox
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..config_cache import ConfigCache
from ..utils import SignalsBlocked
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..constants import RGBA
from ..widgets import EnumComboBox, FloatEditArray
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..constants import RGBA
from ..widgets import EnumComboBox, FloatEditArray
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..widgets import EnumComboBox, FloatEdit
from .transform_edit import BaseTransformEdit
@@ -5,7 +5,7 @@ import os
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore
from PySide6 import QtCore
from ..widgets import EnumComboBox, LineEdit
from .transform_edit import BaseTransformEdit
@@ -4,7 +4,7 @@
from typing import Optional
import PyOpenColorIO as ocio
from PySide2 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets
from ..widgets import EnumComboBox, FloatEditArray, ExpandingStackedWidget
from .transform_edit import BaseTransformEdit

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