Skip to content

Add support for the lj2k and zstd compression modes. - #5495

Open
QuantaDude wants to merge 8 commits into
AcademySoftwareFoundation:mainfrom
QuantaDude:openexr-3.5-compression
Open

QuantaDude wants to merge 8 commits into
AcademySoftwareFoundation:mainfrom
QuantaDude:openexr-3.5-compression

Conversation

@QuantaDude

@QuantaDude QuantaDude commented Sep 24, 2026 •

Copy link
Copy Markdown

Description

closes #5482

  • lj2k and zstd compression mapping in the OpenEXR C++ and OpenEXR Core input paths.

  • lj2k and zstd compression selection in the OpenEXR output path.

  • LJ2K quality handling with the OpenEXR-supported range of 1 to 150, defaulting to 110.

  • ZSTD compression-level handling with the OpenEXR-supported range of 1 to 22, defaulting to 5.

  • Regression coverage for both compression modes in the openexr-compression tests, including the OpenEXR Core path.

  • Reference EXR files and expected output for the new test cases.

  • Bumped OpenEXR version in src/build-scripts/build_openexr from v3.4.15 to v3.5.0

  • Updated the compression attributes documentation in src/doc/builtinplugins.md

Tests

abhirup@abhirup-artix …/OpenImageIO on  openexr-3.5-compression via △ v4.4.2 via 🐍 v3.14.7 
 &  cmake -S . -B build \
            -DCMAKE_BUILD_TYPE=Release \
            -DCMAKE_INSTALL_PREFIX="$PWD/dist" \
            -DOIIO_BUILD_TESTS=ON \
            -DBUILD_TESTING=ON \
            -DOIIO_DOWNLOAD_MISSING_TESTDATA=ON \
            -DUSE_OPENCV=OFF \
            -DUSE_QT=OFF \
            -DUSE_FFMPEG=OFF \
            -DUSE_PYTHON=ON \
            -DUSE_OPENVDB=OFF \
            -DUSE_PTEX=OFF \
            -DUSE_DCMTK=OFF \
            -DUSE_LIBUHDR=OFF
  
  abhirup@abhirup-artix …/OpenImageIO on  openexr-3.5-compression via △ v4.4.2 via 🐍 v3.14.7 
 &   ctest --test-dir build -R '^openexr-compression' --output-on-failure

output

abhirup@abhirup-artix …/OpenImageIO on  openexr-3.5-compression via △ v4.4.2 via 🐍 v3.14.7 took 16s 
 &  ctest --test-dir build -R '^openexr-compression' --output-on-failure
Test project /home/abhirup/OSS/OpenImageIO/build
    Start 152: openexr-compression
1/2 Test #152: openexr-compression ..............   Passed    3.11 sec
    Start 166: openexr-compression.core
2/2 Test #166: openexr-compression.core .........   Passed    3.09 sec

100% tests passed out of 2

Total Test time (real) =   6.21 sec

Checklist:

  • I have read the guidelines on contributions and code review procedures.
  • I have read the Policy on AI Coding Assistants
    and if I used AI coding assistants, I have an Assisted-by: TOOL / MODEL
    line in the pull request description above. => I have only used ChatGPT for researching, clarifying a few things.
  • I have updated the documentation if my PR adds features or changes
    behavior.
  • I am sure that this PR's changes are tested in the testsuite.
  • I have run and passed the testsuite in CI before submitting the
    PR, by pushing the changes to my fork and seeing that the automated CI
    passed there. (Exceptions: If most tests pass and you can't figure out why
    the remaining ones fail, it's ok to submit the PR and ask for help. Or if
    any failures seem entirely unrelated to your change; sometimes things break
    on the GitHub runners.)
  • My code follows the prevailing code style of this project and I
    fixed any problems reported by the clang-format CI test.
  • If I added or modified a public C++ API call, I have also amended the
    corresponding Python bindings. If altering ImageBufAlgo functions, I also
    exposed the new functionality as oiiotool options. => No new APIs, just added two new compression modes for OpenEXR.

@linux-foundation-easycla

linux-foundation-easycla Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: QuantaDude / name: Abhirup Bhattacharyya (67ad861)

Comment thread src/cmake/testing.cmake Outdated
Comment on lines +9 to +11
set (_openexr_new_compression "1")
else ()
set (_openexr_new_compression "0")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name is likely to seem dated in two years when zstd isn't "new" and something else implemented in 2027 is added.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my bad, I'll name it more specific.

Comment thread src/cmake/testing.cmake Outdated
URL http://github.com/AcademySoftwareFoundation/openexr-images)
# For OpenEXR >= 3.1, be sure to test with the core option on

if (OpenEXR_VERSION VERSION_GREATER_EQUAL 3.1.10)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 3.1.10? Isn't this a feature of 3.5?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The diff seems messy, I set a conditional variable in the cmake checking if the openEXR version is 3.5.0 or above and then I simply passed it as a env variable to the compression tests. I had to duplicate this existing if block two times.
Anyway, now I've a better way to deal with this using set_property()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the newer commit, I now append the OIIO_OPENEXR_LJ2K_ZSTD_SUPPORT environment variable to the openexr-compression test when openexr version is at least 3.5.0.

Comment thread src/cmake/testing.cmake Outdated
endif ()

if (OpenEXR_VERSION VERSION_GREATER_EQUAL 3.1)
# For OpenEXR >= 3.5 we need to add the new compression tests, with the core library

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment doesn't match the if. Which version are we talking about here?

Comment thread src/cmake/testing.cmake Outdated
Comment on lines +494 to +496
# For OpenEXR >= 3.5
if (OpenEXR_VERSION VERSION_GREATER_EQUAL 3.1.10)
oiio_add_tests (openexr-compression

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment doesn't match the condition

Comment thread src/build-scripts/build_openexr.bash

@QuantaDude QuantaDude left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I improved testing.cmake, changed the env variable, simplified how it's set and bumped OpenEXR_BUILD_VERSION in build_OpenEXR.cmake.

I have also created a new reference out-legacy.txt file for the test to pass on older OpenEXR versions.

Does openexr_ver in ci.yml need to be set to v3.5.0 as well?

Comment thread src/build-scripts/build_openexr.bash
Comment thread src/cmake/testing.cmake Outdated
URL http://github.com/AcademySoftwareFoundation/openexr-images)
# For OpenEXR >= 3.1, be sure to test with the core option on

if (OpenEXR_VERSION VERSION_GREATER_EQUAL 3.1.10)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the newer commit, I now append the OIIO_OPENEXR_LJ2K_ZSTD_SUPPORT environment variable to the openexr-compression test when openexr version is at least 3.5.0.

@lgritz

lgritz commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

Does openexr_ver in ci.yml need to be set to v3.5.0 as well?

It should be for the "latest releases" jobs, but NOT for any of the other jobs, which are intentionally sampling building against a variety of OpenEXR versions.

@QuantaDude

Copy link
Copy Markdown
Author

@lgritz I updated the git commit hash for the local, latest builds for OpenEXR and fixed clang-format CI errors.

Not sure why the openexr-compression test is failing, it passes on my machine with openexr 3.14.15

Comment thread src/doc/builtinplugins.md Outdated
- float
- aperture
* - ``compression``
* - ``compression``

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line seems to have changed for no reason

Comment thread src/openexr.imageio/exrinput_c.cpp
Comment thread testsuite/openexr-compression/ref/out-exr3.4.txt
Comment thread testsuite/openexr-compression/ref/out-zstd.exr Outdated
@lgritz

lgritz commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

Some of the CI failures you're getting revealed a separate problem with OpenEXR and zstd and static libraries. I have an OIIO-side fix here: #5498

And an OpenEXR side here: AcademySoftwareFoundation/openexr#2673

- `lj2k` and `zstd` compression mapping in the OpenEXR C++ and OpenEXR Core input paths.

- `lj2k` and `zstd` compression selection in the OpenEXR output path.

- LJ2K quality handling with the OpenEXR-supported range of `1` to `150`, defaulting to `110`.

- ZSTD compression-level handling with the OpenEXR-supported range of `1` to `22`, defaulting to `5`.

- Regression coverage for both compression modes in the `openexr-compression` tests, including the OpenEXR Core path.

- Reference EXR files and expected output for the new test cases.

- Bumped OpenEXR version in `src/build-scripts/build_openexr` from `v3.4.15` to `v3.5.0`

- Updated the compression attributes documentation in `src/doc/builtinplugins.md`

Signed-off-by: Abhirup Bhattacharyya <abhirup27022001@outlook.com>
Signed-off-by: Abhirup Bhattacharyya <abhirup27022001@outlook.com>
Raise the local build OpenEXR default to 3.5.0 in build_OpenEXR.cmake,
matching the version already bumped in the build shell script.

Rename the OIIO_OPENEXR_NEW_COMPRESSION environment variable to
OIIO_OPENEXR_LJ2K_ZSTD_SUPPORT, old env variable would have read oddly
once something else lands in a future OpenEXR release.

The lj2k/zstd env var is now added via
set_property(TEST ... APPEND PROPERTY ENVIRONMENT ...) once
OpenEXR_VERSION >= 3.5.0, after both the base and .core test
variants already exist, rather than being threaded through
ENVIRONMENT arguments on a separate set of oiio_add_tests() calls.

Add testsuite/openexr-compression/ref/out-legacy.txt so the test
still passes on OpenEXR < 3.5.0, where lj2k/zstd aren't compiled in.

Signed-off-by: Abhirup Bhattacharyya <abhirup27022001@outlook.com>
Signed-off-by: Abhirup Bhattacharyya <abhirup27022001@outlook.com>
Signed-off-by: Abhirup Bhattacharyya <abhirup27022001@outlook.com>
…x docs indent

- Added a guard in testing.cmake before setting the
  `OIIO_OPENEXR_LJ2K_ZSTD_SUPPORT` env variable property for the
  `openexr-compression` test. To fix openImageIO from not being able to
  configure and build when the `BUILD_TESTING`, `OIIO_BUILD_TESTS` flag
  options were not set to `ON`.

Signed-off-by: Abhirup Bhattacharyya <abhirup27022001@outlook.com>
@QuantaDude
QuantaDude force-pushed the openexr-3.5-compression branch from be1d0db to dcc7927 Compare September 26, 2026 02:07
Signed-off-by: Abhirup Bhattacharyya <abhirup27022001@outlook.com>
@lgritz

lgritz commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator

It's looking like the lj2k.exr is such a close match that it, too, is getting mixed up with zip.exr and leading to failures because it's nondeterministic which of the two matching files it will find first.

Hmmm... Maybe you can intentionally choose a lower quality "lj2k" compression to force it to be distinct from the lossless compression? (And to prove to ourselves that there is not some bug that is forcing lj2k to always be equivalent to htj2k and not actually be lossy?)

@lgritz

lgritz commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator

Oh, also, we should be testing htj2k as well as lj2k, obviously.

@QuantaDude

Copy link
Copy Markdown
Author

@lgritz It's only failing in the bleeding edge build. I checked the bleeding edge's CI (which build on OpenEXR's main branch) CI's build log says openexr is version 4.0.0.
It's giving garbage values:

 Comparing "out-lj2k.exr" and "ref/out-lj2k.exr"
-128 x 96, 3 channels
-  Mean error = nan
-  RMS error = nan
-  Peak SNR = nan
-  Max error  = inf @ (71, 95, R)  values are -1.3589859e-05, 0.027938843, 0.15246582 vs -nan, 6.341934e-05, 0.00015449524
-  12118 pixels (98.6%) over 0.016
-  12263 pixels (99.8%) over 0.008
-FAILURE

I'll commit again with a new exr reference.

@lgritz

lgritz commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator

Max error = inf @ (71, 95, R) values are -1.3589859e-05, 0.027938843, 0.15246582 vs -nan, 6.341934e-05, 0.00015449524

Well, that's not good -- a NaN is creeping in somewhere! Maybe a problem in OpenEXR main?

@QuantaDude

Copy link
Copy Markdown
Author

yes, I can confirm. The main branch's LJ2K compression is producing corrupted output.

@lgritz

lgritz commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator

D'oh! We were so close to having this wrapped up!

@QuantaDude

Copy link
Copy Markdown
Author

@lgritz I opened an OpenEXR issue regarding this.

@lgritz

lgritz commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator

Hopefully, with a straightforward repro case, somebody can fix the problem in OpenEXR right away.

In the mean time, would you like to add a htj2k to this test as well?

Added HTJ2K compression tests when OpenEXR 3.4.0 or newer is
available, and add expected output for the `htj2k32` and `htj2k256`
compression modes.

Created a new reference file `out-exr3.1.txt` for idiff when OpenEXR
version is older than `3.4.0`.

Signed-off-by: Abhirup Bhattacharyya <abhirup27022001@outlook.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EXR New compression

2 participants