From 949ae1b364d8b3d9a135cafb89335aa4ad371d9b Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 13 Dec 2024 04:29:44 +0000
Subject: [PATCH 1/7] Bump actions/upload-artifact from 3 to 4
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)
---
updated-dependencies:
- dependency-name: actions/upload-artifact
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
.github/workflows/ci_steps.yml | 2 +-
.github/workflows/ossfuzz_workflow.yml | 2 +-
.github/workflows/python-wheels-publish-test.yml | 2 +-
.github/workflows/python-wheels-publish.yml | 2 +-
.github/workflows/python-wheels.yml | 2 +-
.github/workflows/scorecard.yml | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/ci_steps.yml b/.github/workflows/ci_steps.yml
index f4b9f727a5..9bd1a8c34e 100644
--- a/.github/workflows/ci_steps.yml
+++ b/.github/workflows/ci_steps.yml
@@ -154,7 +154,7 @@ jobs:
- name: Upload install_manifest.txt
# Upload the manifest to make it possible to download for inspection and debugging
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: install_manifest
path: _build/${{ env.INSTALL_MANIFEST }}
diff --git a/.github/workflows/ossfuzz_workflow.yml b/.github/workflows/ossfuzz_workflow.yml
index 4dbc1c9f3f..d0d7e7b998 100644
--- a/.github/workflows/ossfuzz_workflow.yml
+++ b/.github/workflows/ossfuzz_workflow.yml
@@ -48,7 +48,7 @@ jobs:
dry-run: false
language: c++
- name: Upload Crash
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
+ uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3.2.1
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
diff --git a/.github/workflows/python-wheels-publish-test.yml b/.github/workflows/python-wheels-publish-test.yml
index 897f7dcae9..755a1b4514 100644
--- a/.github/workflows/python-wheels-publish-test.yml
+++ b/.github/workflows/python-wheels-publish-test.yml
@@ -64,7 +64,7 @@ jobs:
CIBW_ENVIRONMENT: OPENEXR_RELEASE_CANDIDATE_TAG="${{ github.ref_name }}"
- name: Upload artifact
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
+ uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3.2.1
with:
name: wheels-${{ matrix.os }}
path: |
diff --git a/.github/workflows/python-wheels-publish.yml b/.github/workflows/python-wheels-publish.yml
index a5ce3f2082..08a1959178 100644
--- a/.github/workflows/python-wheels-publish.yml
+++ b/.github/workflows/python-wheels-publish.yml
@@ -57,7 +57,7 @@ jobs:
CIBW_TEST_SKIP: "*arm64"
- name: Upload artifact
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
+ uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3.2.1
with:
name: wheels-${{ matrix.os }}
path: |
diff --git a/.github/workflows/python-wheels.yml b/.github/workflows/python-wheels.yml
index 06e2a51675..3d16e1f143 100644
--- a/.github/workflows/python-wheels.yml
+++ b/.github/workflows/python-wheels.yml
@@ -70,7 +70,7 @@ jobs:
OPENEXR_TEST_IMAGE_REPO: "https://raw.githubusercontent.com/AcademySoftwareFoundation/openexr-images/main"
- name: Upload artifact
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
+ uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3.2.1
with:
name: wheels-${{ matrix.os }}
path: |
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 6af412face..3fb0340eba 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -43,7 +43,7 @@ jobs:
# Upload the results as artifacts (optional)
- name: "Upload artifact"
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
+ uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3.2.1
with:
name: SARIF file
path: results.sarif
From d8c96a061fd920955c2be7cb9a28206c3fce1b66 Mon Sep 17 00:00:00 2001
From: Cary Phillips
Date: Fri, 31 Jan 2025 15:27:39 -0800
Subject: [PATCH 2/7] Update actions/upload-artifact to @v4 (#1969)
This requires all artifacts to have unique names, so the
install_manifest.txt files need to uploaded with the name that
includes the os and build number.
Signed-off-by: Cary Phillips
---
.github/workflows/ci_steps.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ci_steps.yml b/.github/workflows/ci_steps.yml
index 9bd1a8c34e..9d83bbee89 100644
--- a/.github/workflows/ci_steps.yml
+++ b/.github/workflows/ci_steps.yml
@@ -156,7 +156,7 @@ jobs:
# Upload the manifest to make it possible to download for inspection and debugging
uses: actions/upload-artifact@v4
with:
- name: install_manifest
+ name: ${{ env.INSTALL_MANIFEST }}
path: _build/${{ env.INSTALL_MANIFEST }}
- name: Validate install
From c8a670e11800667d4ac9b192ae3bf73b4f9dd583 Mon Sep 17 00:00:00 2001
From: Pierre-Anthony Lemieux
Date: Sun, 2 Feb 2025 11:55:28 -0800
Subject: [PATCH 3/7] Add HT256 compressor
Signed-off-by: Pierre-Anthony Lemieux
---
.github/workflows/ci_steps.yml | 11 +-
.github/workflows/ci_workflow.yml | 6 +
.github/workflows/ossfuzz_workflow.yml | 2 +-
.../workflows/python-wheels-publish-test.yml | 2 +-
.github/workflows/python-wheels-publish.yml | 2 +-
.github/workflows/python-wheels.yml | 4 +-
.github/workflows/scorecard.yml | 2 +-
BUILD.bazel | 7 +
MODULE.bazel | 11 +
bazel/openjph_add_build_file.patch | 119 ++++++
bazel/openjph_module_dot_bazel.patch | 11 +
cmake/LibraryDefine.cmake | 4 +-
cmake/OpenEXRSetup.cmake | 62 ++++
.../install_manifest.macos.1.txt | 1 +
.../install_manifest.macos.2.txt | 1 +
.../install_manifest.macos.3.txt | 1 +
.../install_manifest.macos.4.txt | 1 +
.../install_manifest.macos.5.txt | 18 +
.../install_manifest.macos.6.txt | 1 +
.../install_manifest.macos.7.txt | 5 +
.../install_manifest.ubuntu.1.txt | 1 +
.../install_manifest.ubuntu.10.txt | 1 +
.../install_manifest.ubuntu.2.txt | 1 +
.../install_manifest.ubuntu.3.txt | 1 +
.../install_manifest.ubuntu.4.txt | 1 +
.../install_manifest.ubuntu.5.txt | 18 +
.../install_manifest.ubuntu.6.txt | 1 +
.../install_manifest.ubuntu.7.txt | 1 +
.../install_manifest.ubuntu.8.txt | 1 +
.../install_manifest.ubuntu.9.txt | 1 +
.../install_manifest.windows.1.txt | 1 +
.../install_manifest.windows.2.txt | 1 +
.../install_manifest.windows.3.txt | 1 +
.../install_manifest.windows.4.txt | 1 +
.../install_manifest.windows.5.txt | 17 +
.../install_manifest.windows.6.txt | 1 +
share/ci/scripts/install_openjph.sh | 28 ++
src/lib/OpenEXR/CMakeLists.txt | 2 +
src/lib/OpenEXR/ImfCRgbaFile.h | 3 +-
src/lib/OpenEXR/ImfCompression.cpp | 7 +
src/lib/OpenEXR/ImfCompression.h | 4 +-
src/lib/OpenEXR/ImfCompressor.cpp | 5 +
src/lib/OpenEXR/ImfHTCompressor.cpp | 47 +++
src/lib/OpenEXR/ImfHTCompressor.h | 40 ++
src/lib/OpenEXRCore/CMakeLists.txt | 2 +
src/lib/OpenEXRCore/compression.c | 7 +
src/lib/OpenEXRCore/internal_compress.h | 8 +
src/lib/OpenEXRCore/internal_decompress.h | 13 +
src/lib/OpenEXRCore/internal_ht.cpp | 343 ++++++++++++++++++
src/lib/OpenEXRCore/internal_ht_common.cpp | 72 ++++
src/lib/OpenEXRCore/internal_ht_common.h | 22 ++
src/lib/OpenEXRCore/openexr_attr.h | 1 +
src/test/OpenEXRTest/testCompressionApi.cpp | 4 +-
src/wrappers/python/Imath.py | 3 +-
src/wrappers/python/PyOpenEXR.cpp | 4 +-
website/OpenEXRFileLayout.rst | 3 +
website/ReadingAndWritingImageFiles.rst | 7 +-
website/StandardAttributes.rst | 1 +
website/python.rst | 1 +
59 files changed, 931 insertions(+), 16 deletions(-)
create mode 100644 bazel/openjph_add_build_file.patch
create mode 100644 bazel/openjph_module_dot_bazel.patch
create mode 100755 share/ci/scripts/install_openjph.sh
create mode 100644 src/lib/OpenEXR/ImfHTCompressor.cpp
create mode 100644 src/lib/OpenEXR/ImfHTCompressor.h
create mode 100644 src/lib/OpenEXRCore/internal_ht.cpp
create mode 100644 src/lib/OpenEXRCore/internal_ht_common.cpp
create mode 100644 src/lib/OpenEXRCore/internal_ht_common.h
diff --git a/.github/workflows/ci_steps.yml b/.github/workflows/ci_steps.yml
index 9d83bbee89..57eb6b4af3 100644
--- a/.github/workflows/ci_steps.yml
+++ b/.github/workflows/ci_steps.yml
@@ -47,6 +47,8 @@ on:
type: string
OPENEXR_FORCE_INTERNAL_DEFLATE:
type: string
+ OPENEXR_FORCE_INTERNAL_OPENJPH:
+ type: string
BUILD_TESTING:
type: string
namespace:
@@ -84,6 +86,12 @@ jobs:
run: share/ci/scripts/install_libdeflate.sh master
shell: bash
+ - name: Install OpenJPH
+ # Pre-install OpenJPH so the builds validate finding the external installation
+ if: ${{ inputs.OPENEXR_FORCE_INTERNAL_OPENJPH == 'OFF' }}
+ run: share/ci/scripts/install_openjph.sh master
+ shell: bash
+
- name: Install help2man
# TODO: this could go in the ASWF Linux docker
# container. Also, it doesn't currently work for Windows, so
@@ -113,6 +121,7 @@ jobs:
-DOPENEXR_BUILD_TOOLS=${{ inputs.OPENEXR_BUILD_TOOLS }} \
-DOPENEXR_FORCE_INTERNAL_IMATH=${{ inputs.OPENEXR_FORCE_INTERNAL_IMATH }} \
-DOPENEXR_FORCE_INTERNAL_DEFLATE=${{ inputs.OPENEXR_FORCE_INTERNAL_DEFLATE }} \
+ -DOPENEXR_FORCE_INTERNAL_OPENJPH=${{ inputs.OPENEXR_FORCE_INTERNAL_OPENJPH }} \
-DBUILD_TESTING=${{ inputs.BUILD_TESTING }} \
-DOPENEXR_RUN_FUZZ_TESTS=OFF \
-DCMAKE_VERBOSE_MAKEFILE=ON"
@@ -170,7 +179,7 @@ jobs:
# When building against external Imath/libdeflate shared objects, the tests need PATH to include the dll's.
if: contains(inputs.os, 'windows')
run: |
- echo "$PATH;C:/Program Files (x86)/Imath/bin;C:/Program Files (x86)/Imath/lib;C:/Program Files (x86)/libdeflate/bin;C:/Program Files (x86)/libdeflate/lib" >> $GITHUB_PATH
+ echo "$PATH;C:/Program Files (x86)/openjph/lib/;C:/Program Files (x86)/openjph/bin;C:/Program Files (x86)/Imath/bin;C:/Program Files (x86)/Imath/lib;C:/Program Files (x86)/libdeflate/bin;C:/Program Files (x86)/libdeflate/lib" >> $GITHUB_PATH
shell: bash
- name: Test
diff --git a/.github/workflows/ci_workflow.yml b/.github/workflows/ci_workflow.yml
index f87dec6f6b..5afbb601ae 100644
--- a/.github/workflows/ci_workflow.yml
+++ b/.github/workflows/ci_workflow.yml
@@ -77,6 +77,7 @@ jobs:
OPENEXR_BUILD_TOOLS: ${{ matrix.OPENEXR_BUILD_TOOLS || 'ON' }}
OPENEXR_FORCE_INTERNAL_IMATH: ${{ matrix.OPENEXR_FORCE_INTERNAL_IMATH || 'OFF' }}
OPENEXR_FORCE_INTERNAL_DEFLATE: ${{ matrix.OPENEXR_FORCE_INTERNAL_DEFLATE || 'OFF' }}
+ OPENEXR_FORCE_INTERNAL_OPENJPH: ${{ matrix.OPENEXR_FORCE_INTERNAL_OPENJPH || 'OFF' }}
BUILD_TESTING: ${{ matrix.BUILD_TESTING || 'ON' }}
namespace: ${{ matrix.namespace }}
validate_install: ${{ matrix.validate_install || 'ON' }}
@@ -107,6 +108,7 @@ jobs:
OPENEXR_BUILD_TOOLS: 'OFF'
OPENEXR_FORCE_INTERNAL_IMATH: 'ON'
OPENEXR_FORCE_INTERNAL_DEFLATE: 'ON'
+ OPENEXR_FORCE_INTERNAL_OPENJPH: 'ON'
BUILD_TESTING: 'OFF'
- build: 6
@@ -141,6 +143,7 @@ jobs:
OPENEXR_BUILD_TOOLS: ${{ matrix.OPENEXR_BUILD_TOOLS || 'ON' }}
OPENEXR_FORCE_INTERNAL_IMATH: ${{ matrix.OPENEXR_FORCE_INTERNAL_IMATH || 'OFF' }}
OPENEXR_FORCE_INTERNAL_DEFLATE: ${{ matrix.OPENEXR_FORCE_INTERNAL_DEFLATE || 'OFF' }}
+ OPENEXR_FORCE_INTERNAL_OPENJPH: ${{ matrix.OPENEXR_FORCE_INTERNAL_OPENJPH || 'OFF' }}
BUILD_TESTING: ${{ matrix.BUILD_TESTING || 'ON' }}
validate_install: ${{ matrix.validate_install || 'ON' }}
strategy:
@@ -170,6 +173,7 @@ jobs:
OPENEXR_BUILD_TOOLS: 'OFF'
OPENEXR_FORCE_INTERNAL_IMATH: 'ON'
OPENEXR_FORCE_INTERNAL_DEFLATE: 'ON'
+ OPENEXR_FORCE_INTERNAL_OPENJPH: 'ON'
BUILD_TESTING: 'OFF'
- build: 6
@@ -195,6 +199,7 @@ jobs:
OPENEXR_BUILD_TOOLS: ${{ matrix.OPENEXR_BUILD_TOOLS || 'ON' }}
OPENEXR_FORCE_INTERNAL_IMATH: ${{ matrix.OPENEXR_FORCE_INTERNAL_IMATH || 'OFF' }}
OPENEXR_FORCE_INTERNAL_DEFLATE: ${{ matrix.OPENEXR_FORCE_INTERNAL_DEFLATE || 'OFF' }}
+ OPENEXR_FORCE_INTERNAL_OPENJPH: ${{ matrix.OPENEXR_FORCE_INTERNAL_OPENJPH || 'OFF' }}
BUILD_TESTING: ${{ matrix.BUILD_TESTING || 'ON' }}
validate_install: ${{ matrix.validate_install || 'ON' }}
strategy:
@@ -224,6 +229,7 @@ jobs:
OPENEXR_BUILD_TOOLS: 'OFF'
OPENEXR_FORCE_INTERNAL_IMATH: 'ON'
OPENEXR_FORCE_INTERNAL_DEFLATE: 'ON'
+ OPENEXR_FORCE_INTERNAL_OPENJPH: 'ON'
BUILD_TESTING: 'OFF'
- build: 6
diff --git a/.github/workflows/ossfuzz_workflow.yml b/.github/workflows/ossfuzz_workflow.yml
index d0d7e7b998..e3d4ed6c50 100644
--- a/.github/workflows/ossfuzz_workflow.yml
+++ b/.github/workflows/ossfuzz_workflow.yml
@@ -48,7 +48,7 @@ jobs:
dry-run: false
language: c++
- name: Upload Crash
- uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3.2.1
+ uses: actions/upload-artifact@v4
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
diff --git a/.github/workflows/python-wheels-publish-test.yml b/.github/workflows/python-wheels-publish-test.yml
index 755a1b4514..1913f25f82 100644
--- a/.github/workflows/python-wheels-publish-test.yml
+++ b/.github/workflows/python-wheels-publish-test.yml
@@ -64,7 +64,7 @@ jobs:
CIBW_ENVIRONMENT: OPENEXR_RELEASE_CANDIDATE_TAG="${{ github.ref_name }}"
- name: Upload artifact
- uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3.2.1
+ uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: |
diff --git a/.github/workflows/python-wheels-publish.yml b/.github/workflows/python-wheels-publish.yml
index 08a1959178..f1cbd19f6b 100644
--- a/.github/workflows/python-wheels-publish.yml
+++ b/.github/workflows/python-wheels-publish.yml
@@ -57,7 +57,7 @@ jobs:
CIBW_TEST_SKIP: "*arm64"
- name: Upload artifact
- uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3.2.1
+ uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: |
diff --git a/.github/workflows/python-wheels.yml b/.github/workflows/python-wheels.yml
index 3d16e1f143..b114a998d4 100644
--- a/.github/workflows/python-wheels.yml
+++ b/.github/workflows/python-wheels.yml
@@ -70,9 +70,9 @@ jobs:
OPENEXR_TEST_IMAGE_REPO: "https://raw.githubusercontent.com/AcademySoftwareFoundation/openexr-images/main"
- name: Upload artifact
- uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3.2.1
+ uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: |
./wheelhouse/*.whl
- ./wheelhouse/*.tar.gz
+ ./wheelhouse/*.tar.gz
\ No newline at end of file
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 3fb0340eba..252fc91648 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -43,7 +43,7 @@ jobs:
# Upload the results as artifacts (optional)
- name: "Upload artifact"
- uses: actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3.2.1
+ uses: actions/upload-artifact@v4
with:
name: SARIF file
path: results.sarif
diff --git a/BUILD.bazel b/BUILD.bazel
index e29bd10dc7..67c94305ae 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -189,6 +189,9 @@ cc_library(
"src/lib/OpenEXRCore/internal_dwa_simd.h",
"src/lib/OpenEXRCore/internal_file.h",
"src/lib/OpenEXRCore/internal_float_vector.h",
+ "src/lib/OpenEXRCore/internal_ht.cpp",
+ "src/lib/OpenEXRCore/internal_ht_common.h",
+ "src/lib/OpenEXRCore/internal_ht_common.cpp",
"src/lib/OpenEXRCore/internal_huf.c",
"src/lib/OpenEXRCore/internal_huf.h",
"src/lib/OpenEXRCore/internal_memory.h",
@@ -262,6 +265,7 @@ cc_library(
visibility = ["//visibility:public"],
deps = [
"@imath",
+ "@openjph",
"@libdeflate//:deflate",
],
)
@@ -308,6 +312,7 @@ cc_library(
"src/lib/OpenEXR/ImfGenericInputFile.cpp",
"src/lib/OpenEXR/ImfGenericOutputFile.cpp",
"src/lib/OpenEXR/ImfHeader.cpp",
+ "src/lib/OpenEXR/ImfHTCompressor.cpp",
"src/lib/OpenEXR/ImfHuf.cpp",
"src/lib/OpenEXR/ImfIDManifest.cpp",
"src/lib/OpenEXR/ImfIDManifestAttribute.cpp",
@@ -413,6 +418,7 @@ cc_library(
"src/lib/OpenEXR/ImfGenericInputFile.h",
"src/lib/OpenEXR/ImfGenericOutputFile.h",
"src/lib/OpenEXR/ImfHeader.h",
+ "src/lib/OpenEXR/ImfHTCompressor.h",
"src/lib/OpenEXR/ImfHuf.h",
"src/lib/OpenEXR/ImfIDManifest.h",
"src/lib/OpenEXR/ImfIDManifestAttribute.h",
@@ -504,6 +510,7 @@ cc_library(
":IlmThread",
":OpenEXRCore",
"@imath",
+ "@openjph"
],
)
diff --git a/MODULE.bazel b/MODULE.bazel
index f6e9677995..5dd63a6b49 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -8,6 +8,7 @@ module(
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "imath")
+bazel_dep(name = "openjph")
bazel_dep(name = "libdeflate")
bazel_dep(name = "platforms", version = "0.0.10")
@@ -30,3 +31,13 @@ archive_override(
strip_prefix = "libdeflate-master",
urls = ["https://github.com/ebiggers/libdeflate/archive/refs/heads/master.zip"],
)
+
+archive_override(
+ module_name = "openjph",
+ patches = [
+ "//bazel:openjph_add_build_file.patch",
+ "//bazel:openjph_module_dot_bazel.patch",
+ ],
+ strip_prefix = "OpenJPH-add-export",
+ urls = ["https://github.com/palemieux/OpenJPH/archive/refs/heads/add-export.zip"],
+)
diff --git a/bazel/openjph_add_build_file.patch b/bazel/openjph_add_build_file.patch
new file mode 100644
index 0000000000..1be2311131
--- /dev/null
+++ b/bazel/openjph_add_build_file.patch
@@ -0,0 +1,119 @@
+--- /dev/null
++++ BUILD.bazel
+@@ -0,0 +1,116 @@
++load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
++load("@rules_license//rules:license.bzl", "license")
++
++package(
++ default_applicable_licenses = [":license"],
++)
++
++exports_files([
++ "LICENSE",
++])
++
++license(
++ name = "license",
++ license_kinds = ["@rules_license//licenses/spdx:BSD-2-Clause"],
++ license_text = "LICENSE",
++)
++
++cc_binary(
++ name = "ojph_compress",
++ srcs = ["src/apps/ojph_compress/ojph_compress.cpp"],
++ visibility = ["//visibility:public"],
++ deps = [":ojph_expand"],
++)
++
++cc_library(
++ name = "ojph_expand",
++ srcs = [
++ "src/apps/ojph_expand/ojph_expand.cpp",
++ "src/apps/others/ojph_img_io.cpp",
++ ],
++ hdrs = [
++ "src/apps/common/ojph_img_io.h",
++ ],
++ includes = [
++ "src/apps/common",
++ ],
++ visibility = ["//visibility:public"],
++ deps = [":openjph"],
++)
++
++cc_library(
++ name = "openjph",
++ srcs = [
++ "src/core/codestream/ojph_bitbuffer_read.h",
++ "src/core/codestream/ojph_bitbuffer_write.h",
++ "src/core/codestream/ojph_codeblock.cpp",
++ "src/core/codestream/ojph_codeblock.h",
++ "src/core/codestream/ojph_codeblock_fun.cpp",
++ "src/core/codestream/ojph_codeblock_fun.h",
++ "src/core/codestream/ojph_codestream.cpp",
++ "src/core/codestream/ojph_codestream_gen.cpp",
++ "src/core/codestream/ojph_codestream_local.cpp",
++ "src/core/codestream/ojph_codestream_local.h",
++ "src/core/codestream/ojph_params.cpp",
++ "src/core/codestream/ojph_params_local.h",
++ "src/core/codestream/ojph_precinct.cpp",
++ "src/core/codestream/ojph_precinct.h",
++ "src/core/codestream/ojph_resolution.cpp",
++ "src/core/codestream/ojph_resolution.h",
++ "src/core/codestream/ojph_subband.cpp",
++ "src/core/codestream/ojph_subband.h",
++ "src/core/codestream/ojph_tile.cpp",
++ "src/core/codestream/ojph_tile.h",
++ "src/core/codestream/ojph_tile_comp.cpp",
++ "src/core/codestream/ojph_tile_comp.h",
++ "src/core/coding/ojph_block_common.cpp",
++ "src/core/coding/ojph_block_common.h",
++ "src/core/coding/ojph_block_decoder.h",
++ "src/core/coding/ojph_block_decoder32.cpp",
++ "src/core/coding/ojph_block_decoder64.cpp",
++ "src/core/coding/ojph_block_encoder.cpp",
++ "src/core/coding/ojph_block_encoder.h",
++ "src/core/coding/table0.h",
++ "src/core/coding/table1.h",
++ "src/core/common/ojph_arch.h",
++ "src/core/common/ojph_base.h",
++ "src/core/common/ojph_codestream.h",
++ "src/core/common/ojph_defs.h",
++ "src/core/common/ojph_file.h",
++ "src/core/common/ojph_message.h",
++ "src/core/common/ojph_params.h",
++ "src/core/common/ojph_version.h",
++ "src/core/others/ojph_arch.cpp",
++ "src/core/others/ojph_file.cpp",
++ "src/core/others/ojph_mem.cpp",
++ "src/core/others/ojph_message.cpp",
++ "src/core/transform/ojph_colour.cpp",
++ "src/core/transform/ojph_colour.h",
++ "src/core/transform/ojph_colour_local.h",
++ "src/core/transform/ojph_transform.cpp",
++ "src/core/transform/ojph_transform.h",
++ "src/core/transform/ojph_transform_local.h",
++ ],
++ hdrs = [
++ "src/core/common/ojph_arg.h",
++ "src/core/common/ojph_mem.h",
++ ],
++ defines = [
++ "OJPH_DISABLE_SIMD",
++ #"OJPH_DISABLE_SSE2",
++ #"OJPH_DISABLE_SSSE3",
++ #"OJPH_DISABLE_SSE4",
++ #"OJPH_DISABLE_AVX",
++ #"OJPH_DISABLE_AVX2",
++ #"OJPH_DISABLE_AVX512",
++ #"OJPH_DISABLE_NEON",
++ ],
++ includes = [
++ "src/core/codestream",
++ "src/core/coding",
++ "src/core/common",
++ "src/core/others",
++ "src/core/transform",
++ ],
++ visibility = ["//visibility:public"],
++)
\ No newline at end of file
diff --git a/bazel/openjph_module_dot_bazel.patch b/bazel/openjph_module_dot_bazel.patch
new file mode 100644
index 0000000000..e68e24e9a1
--- /dev/null
+++ b/bazel/openjph_module_dot_bazel.patch
@@ -0,0 +1,11 @@
+--- MODULE.bazel
++++ MODULE.bazel
+@@ -0,0 +1,8 @@
++module(
++ name = "openjph",
++ version = "0.20.0",
++ compatibility_level = 1,
++)
++
++bazel_dep(name = "rules_cc", version = "0.1.0")
++bazel_dep(name = "rules_license", version = "1.0.0")
\ No newline at end of file
diff --git a/cmake/LibraryDefine.cmake b/cmake/LibraryDefine.cmake
index 6e8c424fc9..7c3462e064 100644
--- a/cmake/LibraryDefine.cmake
+++ b/cmake/LibraryDefine.cmake
@@ -24,7 +24,7 @@ function(OPENEXR_DEFINE_LIBRARY libname)
PRIVATE cxx_std_${OPENEXR_CXX_STANDARD}
INTERFACE cxx_std_17 )
- # we are embedding libdeflate
+ # we are embedding libdeflate
target_include_directories(${objlib} PRIVATE ${EXR_DEFLATE_INCLUDE_DIR})
if(OPENEXR_CURLIB_PRIV_EXPORT AND BUILD_SHARED_LIBS)
@@ -40,7 +40,7 @@ function(OPENEXR_DEFINE_LIBRARY libname)
if(OPENEXR_CURLIB_CURBINDIR)
target_include_directories(${objlib} PRIVATE $)
endif()
- target_link_libraries(${objlib} PUBLIC ${PROJECT_NAME}::Config ${OPENEXR_CURLIB_DEPENDENCIES})
+ target_link_libraries(${objlib} PUBLIC ${PROJECT_NAME}::Config ${OPENEXR_CURLIB_DEPENDENCIES} ${CMAKE_DL_LIBS} ${EXR_OPENJPH_LIB})
if(OPENEXR_CURLIB_PRIVATE_DEPS)
target_link_libraries(${objlib} PRIVATE ${OPENEXR_CURLIB_PRIVATE_DEPS})
endif()
diff --git a/cmake/OpenEXRSetup.cmake b/cmake/OpenEXRSetup.cmake
index 4fdce34622..22f4553be4 100644
--- a/cmake/OpenEXRSetup.cmake
+++ b/cmake/OpenEXRSetup.cmake
@@ -297,6 +297,68 @@ else()
set(EXR_DEFLATE_LIB)
endif()
+
+#######################################
+# Find or download OpenJPH
+#######################################
+
+message(STATUS "Locating OpenJPH")
+
+option(OPENEXR_FORCE_INTERNAL_OPENJPH "Force downloading OpenJPH from a git repo" OFF)
+
+set(OPENEXR_OJPH_REPO "https://github.com/palemieux/OpenJPH.git" CACHE STRING "OpenJPH Git repo URI")
+set(OPENEXR_OJPH_TAG "add-export" CACHE STRING "OpenJPH Git repo tag")
+
+if (NOT OPENEXR_FORCE_INTERNAL_OPENJPH)
+ find_package(openjph 0.20 QUIET)
+
+ if(openjph_FOUND)
+ message(STATUS "Found OpenJPH using find_package.")
+ set(EXR_OPENJPH_LIB openjph)
+ else()
+ # If not found, try pkgconfig
+ find_package(PkgConfig)
+ if(PKG_CONFIG_FOUND)
+ include(FindPkgConfig)
+ pkg_check_modules(openjph IMPORTED_TARGET GLOBAL openjph=0.20)
+ if(openjph_FOUND)
+ set(EXR_OPENJPH_LIB PkgConfig::openjph)
+ message(STATUS "Found OpenJPH using PkgConfig at ${deflate_LINK_LIBRARIES}")
+ endif()
+ endif()
+ endif()
+endif()
+
+if(NOT EXR_OPENJPH_LIB)
+ include(FetchContent)
+ FetchContent_Declare(
+ openjph
+ GIT_REPOSITORY ${OPENEXR_OJPH_REPO}
+ GIT_TAG ${OPENEXR_OJPH_TAG}
+ )
+
+ set(OJPH_BUILD_TESTS OFF CACHE BOOL "" FORCE)
+ set(OJPH_ENABLE_TIFF_SUPPORT OFF CACHE BOOL "" FORCE)
+ set(OJPH_BUILD_EXECUTABLES OFF CACHE BOOL "" FORCE)
+ FetchContent_MakeAvailable(openjph)
+ install(
+ TARGETS openjph
+ EXPORT ${PROJECT_NAME}
+ )
+ set_target_properties(openjph PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
+ )
+ include_directories("${openjph_SOURCE_DIR}/src/core/common")
+
+ set(EXR_OPENJPH_LIB openjph)
+
+ message(STATUS "Building OpenJPH from ${OPENEXR_OJPH_REPO}.")
+endif()
+
+if (NOT EXR_OPENJPH_LIB)
+ message(ERROR "Failed to find OpenJPH.")
+endif()
+
#######################################
# Find or install Imath
#######################################
diff --git a/share/ci/install_manifest/install_manifest.macos.1.txt b/share/ci/install_manifest/install_manifest.macos.1.txt
index 0f76c3365b..37cb08afe3 100644
--- a/share/ci/install_manifest/install_manifest.macos.1.txt
+++ b/share/ci/install_manifest/install_manifest.macos.1.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/cmake/OpenEXR/OpenEXRConfig.cmake
lib/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.macos.2.txt b/share/ci/install_manifest/install_manifest.macos.2.txt
index 15c0837e7c..4e007dbe44 100644
--- a/share/ci/install_manifest/install_manifest.macos.2.txt
+++ b/share/ci/install_manifest/install_manifest.macos.2.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/cmake/OpenEXR/OpenEXRConfig.cmake
lib/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib/cmake/OpenEXR/OpenEXRTargets-debug.cmake
diff --git a/share/ci/install_manifest/install_manifest.macos.3.txt b/share/ci/install_manifest/install_manifest.macos.3.txt
index 8a2e321951..a1e649463b 100644
--- a/share/ci/install_manifest/install_manifest.macos.3.txt
+++ b/share/ci/install_manifest/install_manifest.macos.3.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/cmake/OpenEXR/OpenEXRConfig.cmake
lib/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.macos.4.txt b/share/ci/install_manifest/install_manifest.macos.4.txt
index c263380c4b..db3593cf88 100644
--- a/share/ci/install_manifest/install_manifest.macos.4.txt
+++ b/share/ci/install_manifest/install_manifest.macos.4.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/cmake/OpenEXR/OpenEXRConfig.cmake
lib/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.macos.5.txt b/share/ci/install_manifest/install_manifest.macos.5.txt
index 01fc2bd872..3f51a0c6e1 100644
--- a/share/ci/install_manifest/install_manifest.macos.5.txt
+++ b/share/ci/install_manifest/install_manifest.macos.5.txt
@@ -180,6 +180,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/cmake/Imath/ImathConfig.cmake
lib/cmake/Imath/ImathConfigVersion.cmake
lib/cmake/Imath/ImathTargets-release.cmake
@@ -213,3 +214,20 @@ lib/libOpenEXRUtil-$MAJOR_$MINOR.$SOVERSION.dylib
lib/libOpenEXRUtil-$MAJOR_$MINOR.dylib
lib/libOpenEXRUtil.dylib
lib/pkgconfig/Imath.pc
+include/openjph/ojph_arch.h
+include/openjph/ojph_arg.h
+include/openjph/ojph_base.h
+include/openjph/ojph_codestream.h
+include/openjph/ojph_defs.h
+include/openjph/ojph_file.h
+include/openjph/ojph_mem.h
+include/openjph/ojph_message.h
+include/openjph/ojph_params.h
+include/openjph/ojph_version.h
+lib/cmake/openjph/openjph-config-release.cmake
+lib/cmake/openjph/openjph-config.cmake
+lib/cmake/openjph/openjph-configVersion.cmake
+lib/libopenjph.0.20.0.dylib
+lib/libopenjph.0.20.dylib
+lib/libopenjph.dylib
+lib/pkgconfig/openjph.pc
\ No newline at end of file
diff --git a/share/ci/install_manifest/install_manifest.macos.6.txt b/share/ci/install_manifest/install_manifest.macos.6.txt
index 0f76c3365b..37cb08afe3 100644
--- a/share/ci/install_manifest/install_manifest.macos.6.txt
+++ b/share/ci/install_manifest/install_manifest.macos.6.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/cmake/OpenEXR/OpenEXRConfig.cmake
lib/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.macos.7.txt b/share/ci/install_manifest/install_manifest.macos.7.txt
index 0f76c3365b..9063f25c40 100644
--- a/share/ci/install_manifest/install_manifest.macos.7.txt
+++ b/share/ci/install_manifest/install_manifest.macos.7.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/cmake/OpenEXR/OpenEXRConfig.cmake
lib/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib/cmake/OpenEXR/OpenEXRTargets-release.cmake
@@ -181,6 +182,10 @@ lib/libOpenEXRUtil-$MAJOR_$MINOR.$SOVERSION.dylib
lib/libOpenEXRUtil-$MAJOR_$MINOR.dylib
lib/libOpenEXRUtil.dylib
lib/pkgconfig/OpenEXR.pc
+lib/libopenjph.0.20.0.dylib
+lib/libopenjph.0.20.dylib
+lib/libopenjph.dylib
+lib/pkgconfig/openjph.pc
share/doc/OpenEXR/examples/deepExamples.cpp
share/doc/OpenEXR/examples/deepExamples.h
share/doc/OpenEXR/examples/deepTiledExamples.cpp
diff --git a/share/ci/install_manifest/install_manifest.ubuntu.1.txt b/share/ci/install_manifest/install_manifest.ubuntu.1.txt
index 669a1cdafa..9ef1a42478 100644
--- a/share/ci/install_manifest/install_manifest.ubuntu.1.txt
+++ b/share/ci/install_manifest/install_manifest.ubuntu.1.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib64/cmake/OpenEXR/OpenEXRConfig.cmake
lib64/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib64/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.ubuntu.10.txt b/share/ci/install_manifest/install_manifest.ubuntu.10.txt
index 669a1cdafa..9ef1a42478 100644
--- a/share/ci/install_manifest/install_manifest.ubuntu.10.txt
+++ b/share/ci/install_manifest/install_manifest.ubuntu.10.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib64/cmake/OpenEXR/OpenEXRConfig.cmake
lib64/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib64/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.ubuntu.2.txt b/share/ci/install_manifest/install_manifest.ubuntu.2.txt
index 2e8a401d7d..43b5b26bd6 100644
--- a/share/ci/install_manifest/install_manifest.ubuntu.2.txt
+++ b/share/ci/install_manifest/install_manifest.ubuntu.2.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib64/cmake/OpenEXR/OpenEXRConfig.cmake
lib64/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib64/cmake/OpenEXR/OpenEXRTargets-debug.cmake
diff --git a/share/ci/install_manifest/install_manifest.ubuntu.3.txt b/share/ci/install_manifest/install_manifest.ubuntu.3.txt
index f2e6b5e8b5..888428c04c 100644
--- a/share/ci/install_manifest/install_manifest.ubuntu.3.txt
+++ b/share/ci/install_manifest/install_manifest.ubuntu.3.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib64/cmake/OpenEXR/OpenEXRConfig.cmake
lib64/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib64/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.ubuntu.4.txt b/share/ci/install_manifest/install_manifest.ubuntu.4.txt
index 78b49be7ff..ea171071e9 100644
--- a/share/ci/install_manifest/install_manifest.ubuntu.4.txt
+++ b/share/ci/install_manifest/install_manifest.ubuntu.4.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib64/cmake/OpenEXR/OpenEXRConfig.cmake
lib64/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib64/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.ubuntu.5.txt b/share/ci/install_manifest/install_manifest.ubuntu.5.txt
index c44e7a1b68..870eea544b 100644
--- a/share/ci/install_manifest/install_manifest.ubuntu.5.txt
+++ b/share/ci/install_manifest/install_manifest.ubuntu.5.txt
@@ -180,6 +180,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib64/cmake/Imath/ImathConfig.cmake
lib64/cmake/Imath/ImathConfigVersion.cmake
lib64/cmake/Imath/ImathTargets-release.cmake
@@ -213,3 +214,20 @@ lib64/libOpenEXRUtil-$MAJOR_$MINOR.so.$SOVERSION
lib64/libOpenEXRUtil-$MAJOR_$MINOR.so.$SOVERSION.$MAJOR.$MINOR.0
lib64/libOpenEXRUtil.so
lib64/pkgconfig/Imath.pc
+include/openjph/ojph_arch.h
+include/openjph/ojph_arg.h
+include/openjph/ojph_base.h
+include/openjph/ojph_codestream.h
+include/openjph/ojph_defs.h
+include/openjph/ojph_file.h
+include/openjph/ojph_mem.h
+include/openjph/ojph_message.h
+include/openjph/ojph_params.h
+include/openjph/ojph_version.h
+lib64/cmake/openjph/openjph-config-release.cmake
+lib64/cmake/openjph/openjph-config.cmake
+lib64/cmake/openjph/openjph-configVersion.cmake
+lib64/libopenjph.so
+lib64/libopenjph.so.0.20
+lib64/libopenjph.so.0.20.0
+lib64/pkgconfig/openjph.pc
\ No newline at end of file
diff --git a/share/ci/install_manifest/install_manifest.ubuntu.6.txt b/share/ci/install_manifest/install_manifest.ubuntu.6.txt
index 8d7f85e748..1098520f3b 100644
--- a/share/ci/install_manifest/install_manifest.ubuntu.6.txt
+++ b/share/ci/install_manifest/install_manifest.ubuntu.6.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib64/cmake/OpenEXR/OpenEXRConfig.cmake
lib64/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib64/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.ubuntu.7.txt b/share/ci/install_manifest/install_manifest.ubuntu.7.txt
index 2f1285e001..beaa47db4a 100644
--- a/share/ci/install_manifest/install_manifest.ubuntu.7.txt
+++ b/share/ci/install_manifest/install_manifest.ubuntu.7.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib64/cmake/OpenEXR/OpenEXRConfig.cmake
lib64/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib64/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.ubuntu.8.txt b/share/ci/install_manifest/install_manifest.ubuntu.8.txt
index 669a1cdafa..9ef1a42478 100644
--- a/share/ci/install_manifest/install_manifest.ubuntu.8.txt
+++ b/share/ci/install_manifest/install_manifest.ubuntu.8.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib64/cmake/OpenEXR/OpenEXRConfig.cmake
lib64/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib64/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.ubuntu.9.txt b/share/ci/install_manifest/install_manifest.ubuntu.9.txt
index 669a1cdafa..9ef1a42478 100644
--- a/share/ci/install_manifest/install_manifest.ubuntu.9.txt
+++ b/share/ci/install_manifest/install_manifest.ubuntu.9.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib64/cmake/OpenEXR/OpenEXRConfig.cmake
lib64/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib64/cmake/OpenEXR/OpenEXRTargets-release.cmake
diff --git a/share/ci/install_manifest/install_manifest.windows.1.txt b/share/ci/install_manifest/install_manifest.windows.1.txt
index b71d2e9f13..cdebeb0653 100644
--- a/share/ci/install_manifest/install_manifest.windows.1.txt
+++ b/share/ci/install_manifest/install_manifest.windows.1.txt
@@ -161,6 +161,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/Iex-$MAJOR_$MINOR.lib
lib/IlmThread-$MAJOR_$MINOR.lib
lib/OpenEXR-$MAJOR_$MINOR.lib
diff --git a/share/ci/install_manifest/install_manifest.windows.2.txt b/share/ci/install_manifest/install_manifest.windows.2.txt
index d87af55e00..25bec4b554 100644
--- a/share/ci/install_manifest/install_manifest.windows.2.txt
+++ b/share/ci/install_manifest/install_manifest.windows.2.txt
@@ -161,6 +161,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/Iex-$MAJOR_$MINOR_d.lib
lib/IlmThread-$MAJOR_$MINOR_d.lib
lib/OpenEXR-$MAJOR_$MINOR_d.lib
diff --git a/share/ci/install_manifest/install_manifest.windows.3.txt b/share/ci/install_manifest/install_manifest.windows.3.txt
index 76dc51a25c..3b5ed0156c 100644
--- a/share/ci/install_manifest/install_manifest.windows.3.txt
+++ b/share/ci/install_manifest/install_manifest.windows.3.txt
@@ -156,6 +156,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/Iex-$MAJOR_$MINOR.lib
lib/IlmThread-$MAJOR_$MINOR.lib
lib/OpenEXR-$MAJOR_$MINOR.lib
diff --git a/share/ci/install_manifest/install_manifest.windows.4.txt b/share/ci/install_manifest/install_manifest.windows.4.txt
index b71d2e9f13..cdebeb0653 100644
--- a/share/ci/install_manifest/install_manifest.windows.4.txt
+++ b/share/ci/install_manifest/install_manifest.windows.4.txt
@@ -161,6 +161,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/Iex-$MAJOR_$MINOR.lib
lib/IlmThread-$MAJOR_$MINOR.lib
lib/OpenEXR-$MAJOR_$MINOR.lib
diff --git a/share/ci/install_manifest/install_manifest.windows.5.txt b/share/ci/install_manifest/install_manifest.windows.5.txt
index 09e3f282ed..aa3ab1430f 100644
--- a/share/ci/install_manifest/install_manifest.windows.5.txt
+++ b/share/ci/install_manifest/install_manifest.windows.5.txt
@@ -186,6 +186,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/Iex-$MAJOR_$MINOR.lib
lib/IlmThread-$MAJOR_$MINOR.lib
lib/Imath-3_2.lib
@@ -201,3 +202,19 @@ lib/cmake/OpenEXR/OpenEXRConfigVersion.cmake
lib/cmake/OpenEXR/OpenEXRTargets-release.cmake
lib/cmake/OpenEXR/OpenEXRTargets.cmake
lib/pkgconfig/Imath.pc
+bin/openjph.0.20.dll
+include/openjph/ojph_arch.h
+include/openjph/ojph_arg.h
+include/openjph/ojph_base.h
+include/openjph/ojph_codestream.h
+include/openjph/ojph_defs.h
+include/openjph/ojph_file.h
+include/openjph/ojph_mem.h
+include/openjph/ojph_message.h
+include/openjph/ojph_params.h
+include/openjph/ojph_version.h
+lib/cmake/openjph/openjph-config-release.cmake
+lib/cmake/openjph/openjph-config.cmake
+lib/cmake/openjph/openjph-configVersion.cmake
+lib/openjph.0.20.lib
+lib/pkgconfig/openjph.pc
\ No newline at end of file
diff --git a/share/ci/install_manifest/install_manifest.windows.6.txt b/share/ci/install_manifest/install_manifest.windows.6.txt
index b71d2e9f13..cdebeb0653 100644
--- a/share/ci/install_manifest/install_manifest.windows.6.txt
+++ b/share/ci/install_manifest/install_manifest.windows.6.txt
@@ -161,6 +161,7 @@ include/OpenEXR/openexr_errors.h
include/OpenEXR/openexr_part.h
include/OpenEXR/openexr_std_attr.h
include/OpenEXR/openexr_version.h
+include/OpenEXR/ImfHTCompressor.h
lib/Iex-$MAJOR_$MINOR.lib
lib/IlmThread-$MAJOR_$MINOR.lib
lib/OpenEXR-$MAJOR_$MINOR.lib
diff --git a/share/ci/scripts/install_openjph.sh b/share/ci/scripts/install_openjph.sh
new file mode 100755
index 0000000000..f2526fa806
--- /dev/null
+++ b/share/ci/scripts/install_openjph.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright Contributors to the OpenColorIO Project.
+
+set -ex
+
+TAG="$1"
+
+if [[ $OSTYPE == "msys" ]]; then
+ SUDO=""
+else
+ SUDO="sudo"
+fi
+
+git clone -b add-export https://github.com/palemieux/OpenJPH.git
+cd OpenJPH
+
+# git checkout ${TAG}
+
+cd build
+cmake -DOJPH_ENABLE_TIFF_SUPPORT=OFF -DCMAKE_BUILD_TYPE=Release ..
+$SUDO cmake --build . \
+ --target install \
+ --config Release \
+ --parallel 2
+
+cd ../..
+rm -rf OpenJPH
diff --git a/src/lib/OpenEXR/CMakeLists.txt b/src/lib/OpenEXR/CMakeLists.txt
index 3c0119b317..62738a8ece 100644
--- a/src/lib/OpenEXR/CMakeLists.txt
+++ b/src/lib/OpenEXR/CMakeLists.txt
@@ -68,6 +68,7 @@ openexr_define_library(OpenEXR
ImfGenericInputFile.cpp
ImfGenericOutputFile.cpp
ImfHeader.cpp
+ ImfHTCompressor.cpp
ImfHuf.cpp
ImfIDManifest.cpp
ImfIDManifestAttribute.cpp
@@ -164,6 +165,7 @@ openexr_define_library(OpenEXR
ImfGenericInputFile.h
ImfGenericOutputFile.h
ImfHeader.h
+ ImfHTCompressor.h
ImfHuf.h
ImfIDManifest.h
ImfIDManifestAttribute.h
diff --git a/src/lib/OpenEXR/ImfCRgbaFile.h b/src/lib/OpenEXR/ImfCRgbaFile.h
index 062f2f709a..da26fc974c 100644
--- a/src/lib/OpenEXR/ImfCRgbaFile.h
+++ b/src/lib/OpenEXR/ImfCRgbaFile.h
@@ -80,7 +80,8 @@ typedef struct ImfRgba ImfRgba;
#define IMF_B44A_COMPRESSION 7
#define IMF_DWAA_COMPRESSION 8
#define IMF_DWAB_COMPRESSION 9
-#define IMF_NUM_COMPRESSION_METHODS 10
+#define IMF_HT256_COMPRESSION 10
+#define IMF_NUM_COMPRESSION_METHODS 11
/*
** Channels; values must be the same as in Imf::RgbaChannels.
diff --git a/src/lib/OpenEXR/ImfCompression.cpp b/src/lib/OpenEXR/ImfCompression.cpp
index 68c73d63d0..80478eba35 100644
--- a/src/lib/OpenEXR/ImfCompression.cpp
+++ b/src/lib/OpenEXR/ImfCompression.cpp
@@ -176,6 +176,12 @@ static const CompressionDesc IdToDesc[] = {
256,
true,
false),
+ CompressionDesc (
+ "ht256",
+ "High-Throughtput JPEG 2000 (OpenJPH, 256 lines)",
+ 256,
+ true,
+ false),
};
// clang-format on
@@ -192,6 +198,7 @@ static const std::map CompressionNameToId = {
{"b44a", Compression::B44A_COMPRESSION},
{"dwaa", Compression::DWAA_COMPRESSION},
{"dwab", Compression::DWAB_COMPRESSION},
+ {"ht256", Compression::HT256_COMPRESSION},
};
#define UNKNOWN_COMPRESSION_ID_MSG "INVALID COMPRESSION ID"
diff --git a/src/lib/OpenEXR/ImfCompression.h b/src/lib/OpenEXR/ImfCompression.h
index 2e148ff6a6..8e4ca57f86 100644
--- a/src/lib/OpenEXR/ImfCompression.h
+++ b/src/lib/OpenEXR/ImfCompression.h
@@ -51,7 +51,9 @@ enum IMF_EXPORT_ENUM Compression
// wise and faster to decode full frames
// than DWAA_COMPRESSION.
- NUM_COMPRESSION_METHODS // number of different compression methods.
+ HT256_COMPRESSION = 10,
+
+ NUM_COMPRESSION_METHODS // number of different compression methods
};
/// Returns a codec ID's short name (lowercase).
diff --git a/src/lib/OpenEXR/ImfCompressor.cpp b/src/lib/OpenEXR/ImfCompressor.cpp
index 889a27035c..b8e41c4d7a 100644
--- a/src/lib/OpenEXR/ImfCompressor.cpp
+++ b/src/lib/OpenEXR/ImfCompressor.cpp
@@ -22,6 +22,7 @@
#include
#include
+#include "ImfHTCompressor.h"
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
@@ -335,6 +336,10 @@ newCompressor (Compression c, size_t maxScanLineSize, const Header& hdr)
DwaCompressor::STATIC_HUFFMAN);
break;
+ case HT256_COMPRESSION:
+
+ return new HTCompressor (hdr, static_cast (maxScanLineSize), 256);
+
default: break;
}
// clang-format on
diff --git a/src/lib/OpenEXR/ImfHTCompressor.cpp b/src/lib/OpenEXR/ImfHTCompressor.cpp
new file mode 100644
index 0000000000..147a1a2678
--- /dev/null
+++ b/src/lib/OpenEXR/ImfHTCompressor.cpp
@@ -0,0 +1,47 @@
+//
+// SPDX-License-Identifier: BSD-3-Clause
+// Copyright (c) Contributors to the OpenEXR Project.
+//
+
+//-----------------------------------------------------------------------------
+//
+// class HTCompressor
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfHTCompressor.h"
+#include "ImfAutoArray.h"
+#include "ImfChannelList.h"
+#include "ImfCheckedArithmetic.h"
+#include "ImfHeader.h"
+#include "ImfIO.h"
+#include "ImfMisc.h"
+#include "ImfNamespace.h"
+#include "ImfXdr.h"
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+
+using IMATH_NAMESPACE::Box2i;
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+HTCompressor::HTCompressor (
+ const Header& hdr, size_t maxScanLineSize, int numScanLines)
+ : Compressor (
+ hdr,
+ EXR_COMPRESSION_LAST_TYPE,
+ maxScanLineSize,
+ numScanLines > 0 ? numScanLines : 16000)
+{}
+
+HTCompressor::~HTCompressor ()
+{}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/src/lib/OpenEXR/ImfHTCompressor.h b/src/lib/OpenEXR/ImfHTCompressor.h
new file mode 100644
index 0000000000..708d7852e7
--- /dev/null
+++ b/src/lib/OpenEXR/ImfHTCompressor.h
@@ -0,0 +1,40 @@
+//
+// SPDX-License-Identifier: BSD-3-Clause
+// Copyright (c) Contributors to the OpenEXR Project.
+//
+
+#ifndef INCLUDED_IMF_HT_COMPRESSOR_H
+#define INCLUDED_IMF_HT_COMPRESSOR_H
+
+//-----------------------------------------------------------------------------
+//
+// class HTCompressor -- uses High-Throughput JPEG 2000.
+//
+//-----------------------------------------------------------------------------
+
+#include
+
+#include "ImfNamespace.h"
+
+#include "ImfCompressor.h"
+
+#include
+#include
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class HTCompressor : public Compressor
+{
+public:
+ HTCompressor (const Header& hdr, size_t maxScanLineSize, int numScanLines);
+ virtual ~HTCompressor ();
+
+ HTCompressor (const HTCompressor& other) = delete;
+ HTCompressor& operator= (const HTCompressor& other) = delete;
+ HTCompressor (HTCompressor&& other) = delete;
+ HTCompressor& operator= (HTCompressor&& other) = delete;
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
\ No newline at end of file
diff --git a/src/lib/OpenEXRCore/CMakeLists.txt b/src/lib/OpenEXRCore/CMakeLists.txt
index 98b49aebd7..50b03a69ad 100644
--- a/src/lib/OpenEXRCore/CMakeLists.txt
+++ b/src/lib/OpenEXRCore/CMakeLists.txt
@@ -43,6 +43,8 @@ openexr_define_library(OpenEXRCore
internal_b44.c
internal_b44_table.c
internal_piz.c
+ internal_ht.cpp
+ internal_ht_common.cpp
internal_dwa.c
internal_huf.c
diff --git a/src/lib/OpenEXRCore/compression.c b/src/lib/OpenEXRCore/compression.c
index 8348bfc43e..9ea7ea4bab 100644
--- a/src/lib/OpenEXRCore/compression.c
+++ b/src/lib/OpenEXRCore/compression.c
@@ -227,6 +227,7 @@ int exr_compression_lines_per_chunk (exr_compression_t comptype)
case EXR_COMPRESSION_B44A:
case EXR_COMPRESSION_DWAA: linePerChunk = 32; break;
case EXR_COMPRESSION_DWAB: linePerChunk = 256; break;
+ case EXR_COMPRESSION_HT256: linePerChunk = 256; break;
case EXR_COMPRESSION_LAST_TYPE:
default:
/* ERROR CONDITION */
@@ -360,6 +361,8 @@ exr_compress_chunk (exr_encode_pipeline_t* encode)
case EXR_COMPRESSION_B44A: rv = internal_exr_apply_b44a (encode); break;
case EXR_COMPRESSION_DWAA: rv = internal_exr_apply_dwaa (encode); break;
case EXR_COMPRESSION_DWAB: rv = internal_exr_apply_dwab (encode); break;
+ case EXR_COMPRESSION_HT256:
+ rv = internal_exr_apply_ht (encode); break;
case EXR_COMPRESSION_LAST_TYPE:
default:
return ctxt->print_error (
@@ -436,6 +439,10 @@ decompress_data (
rv = internal_exr_undo_dwab (
decode, packbufptr, packsz, unpackbufptr, unpacksz);
break;
+ case EXR_COMPRESSION_HT256:
+ rv = internal_exr_undo_ht (
+ decode, packbufptr, packsz, unpackbufptr, unpacksz);
+ break;
case EXR_COMPRESSION_LAST_TYPE:
default:
return ctxt->print_error (
diff --git a/src/lib/OpenEXRCore/internal_compress.h b/src/lib/OpenEXRCore/internal_compress.h
index 360015c120..1cdc484a85 100644
--- a/src/lib/OpenEXRCore/internal_compress.h
+++ b/src/lib/OpenEXRCore/internal_compress.h
@@ -33,4 +33,12 @@ exr_result_t internal_exr_apply_dwaa (exr_encode_pipeline_t* encode);
exr_result_t internal_exr_apply_dwab (exr_encode_pipeline_t* encode);
+#ifdef __cplusplus
+extern "C" {
+#endif
+exr_result_t internal_exr_apply_ht (exr_encode_pipeline_t* encode);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* OPENEXR_CORE_COMPRESS_H */
diff --git a/src/lib/OpenEXRCore/internal_decompress.h b/src/lib/OpenEXRCore/internal_decompress.h
index 834b854a3e..6251c2d9c1 100644
--- a/src/lib/OpenEXRCore/internal_decompress.h
+++ b/src/lib/OpenEXRCore/internal_decompress.h
@@ -73,4 +73,17 @@ exr_result_t internal_exr_undo_dwab (
void* uncompressed_data,
uint64_t uncompressed_size);
+#ifdef __cplusplus
+extern "C" {
+#endif
+exr_result_t internal_exr_undo_ht (
+ exr_decode_pipeline_t* decode,
+ const void* compressed_data,
+ uint64_t comp_buf_size,
+ void* uncompressed_data,
+ uint64_t uncompressed_size);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* OPENEXR_CORE_DECOMPRESS_H */
diff --git a/src/lib/OpenEXRCore/internal_ht.cpp b/src/lib/OpenEXRCore/internal_ht.cpp
new file mode 100644
index 0000000000..093ed347f0
--- /dev/null
+++ b/src/lib/OpenEXRCore/internal_ht.cpp
@@ -0,0 +1,343 @@
+/*
+** SPDX-License-Identifier: BSD-3-Clause
+** Copyright Contributors to the OpenEXR Project.
+*/
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "openexr_decode.h"
+#include "openexr_encode.h"
+#include "internal_ht_common.h"
+
+extern "C" exr_result_t
+internal_exr_undo_ht (
+ exr_decode_pipeline_t* decode,
+ const void* compressed_data,
+ uint64_t comp_buf_size,
+ void* uncompressed_data,
+ uint64_t uncompressed_size)
+{
+ exr_result_t rv = EXR_ERR_SUCCESS;
+
+ std::vector cs_to_file_ch (decode->channel_count);
+ bool isRGB = make_channel_map (
+ decode->channel_count, decode->channels, cs_to_file_ch);
+
+ ojph::mem_infile infile;
+ infile.open (
+ reinterpret_cast (compressed_data), comp_buf_size);
+
+ ojph::codestream cs;
+ cs.read_headers (&infile);
+
+ ojph::param_siz siz = cs.access_siz ();
+ ojph::param_nlt nlt = cs.access_nlt ();
+
+ ojph::ui32 image_width =
+ siz.get_image_extent ().x - siz.get_image_offset ().x;
+ ojph::ui32 image_height =
+ siz.get_image_extent ().y - siz.get_image_offset ().y;
+
+ int bpl = 0;
+ bool is_planar = false;
+ for (ojph::ui32 c = 0; c < decode->channel_count; c++)
+ {
+ bpl +=
+ decode->channels[c].bytes_per_element * decode->channels[c].width;
+ if (decode->channels[c].x_samples > 1 ||
+ decode->channels[c].y_samples > 1)
+ { is_planar = true; }
+ }
+ cs.set_planar (is_planar);
+
+ assert (decode->chunk.width == image_width);
+ assert (decode->chunk.height == image_height);
+ assert (decode->channel_count == siz.get_num_components ());
+
+ cs.create ();
+
+ assert (sizeof (uint16_t) == 2);
+ assert (sizeof (uint32_t) == 4);
+ ojph::ui32 next_comp = 0;
+ ojph::line_buf* cur_line;
+ if (cs.is_planar ())
+ {
+ for (uint32_t c = 0; c < decode->channel_count; c++)
+ {
+ int file_c = cs_to_file_ch[c].file_index;
+ assert (
+ siz.get_recon_height (c) == decode->channels[file_c].height);
+ assert (decode->channels[file_c].width == siz.get_recon_width (c));
+
+ if (decode->channels[file_c].height == 0) continue;
+
+ uint8_t* line_pixels = static_cast (uncompressed_data);
+
+ for (int64_t y = decode->chunk.start_y;
+ y < image_height + decode->chunk.start_y;
+ y++)
+ {
+ for (ojph::ui32 line_c = 0; line_c < decode->channel_count;
+ line_c++)
+ {
+ if (y % decode->channels[line_c].y_samples != 0) continue;
+
+ if (line_c == file_c)
+ {
+ cur_line = cs.pull (next_comp);
+ assert (next_comp == c);
+
+ if (decode->channels[file_c].data_type ==
+ EXR_PIXEL_HALF)
+ {
+ int16_t* channel_pixels = (int16_t*) line_pixels;
+ for (uint32_t p = 0;
+ p < decode->channels[file_c].width;
+ p++)
+ {
+ *channel_pixels++ = cur_line->i32[p];
+ }
+ }
+ else
+ {
+ int32_t* channel_pixels = (int32_t*) line_pixels;
+ for (uint32_t p = 0;
+ p < decode->channels[file_c].width;
+ p++)
+ {
+ *channel_pixels++ = cur_line->i32[p];
+ }
+ }
+ }
+
+ line_pixels += decode->channels[line_c].bytes_per_element *
+ decode->channels[line_c].width;
+ }
+ }
+ }
+ }
+ else
+ {
+ uint8_t* line_pixels = static_cast (uncompressed_data);
+
+ assert (bpl * image_height == uncompressed_size);
+
+ for (uint32_t y = 0; y < image_height; ++y)
+ {
+ for (uint32_t c = 0; c < decode->channel_count; c++)
+ {
+ int file_c = cs_to_file_ch[c].file_index;
+ cur_line = cs.pull (next_comp);
+ assert (next_comp == c);
+ if (decode->channels[file_c].data_type == EXR_PIXEL_HALF)
+ {
+ int16_t* channel_pixels =
+ (int16_t*) (line_pixels + cs_to_file_ch[c].raster_line_offset);
+ for (uint32_t p = 0; p < decode->channels[file_c].width;
+ p++)
+ {
+ *channel_pixels++ = cur_line->i32[p];
+ }
+ }
+ else
+ {
+ int32_t* channel_pixels =
+ (int32_t*) (line_pixels + cs_to_file_ch[c].raster_line_offset);
+ for (uint32_t p = 0; p < decode->channels[file_c].width;
+ p++)
+ {
+ *channel_pixels++ = cur_line->i32[p];
+ }
+ }
+ }
+ line_pixels += bpl;
+ }
+ }
+
+ infile.close ();
+
+ return rv;
+}
+
+extern "C" exr_result_t
+internal_exr_apply_ht (exr_encode_pipeline_t* encode)
+{
+ exr_result_t rv = EXR_ERR_SUCCESS;
+
+ std::vector cs_to_file_ch (encode->channel_count);
+ bool isRGB = make_channel_map (
+ encode->channel_count, encode->channels, cs_to_file_ch);
+
+ int image_height = encode->chunk.height;
+ int image_width = encode->chunk.width;
+
+ ojph::codestream cs;
+
+ ojph::param_siz siz = cs.access_siz ();
+ ojph::param_nlt nlt = cs.access_nlt ();
+
+ bool isPlanar = false;
+ siz.set_num_components (encode->channel_count);
+ int bpl = 0;
+ for (ojph::ui32 c = 0; c < encode->channel_count; c++)
+ {
+ int file_c = cs_to_file_ch[c].file_index;
+ if (encode->channels[file_c].data_type != EXR_PIXEL_UINT)
+ nlt.set_nonlinear_transform (
+ c, ojph::param_nlt::nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_NLT);
+ siz.set_component (
+ c,
+ ojph::point (
+ encode->channels[file_c].x_samples,
+ encode->channels[file_c].y_samples),
+ encode->channels[file_c].data_type == EXR_PIXEL_HALF ? 16 : 32,
+ encode->channels[file_c].data_type != EXR_PIXEL_UINT);
+
+ if (encode->channels[file_c].x_samples > 1 ||
+ encode->channels[file_c].y_samples > 1)
+ { isPlanar = true; }
+
+ bpl += encode->channels[file_c].bytes_per_element *
+ encode->channels[file_c].width;
+ }
+
+ cs.set_planar (isPlanar);
+
+ siz.set_image_offset (ojph::point (0, 0));
+ siz.set_image_extent (ojph::point (image_width, image_height));
+
+ ojph::param_cod cod = cs.access_cod ();
+
+ cod.set_color_transform (isRGB && !isPlanar);
+ cod.set_reversible (true);
+ cod.set_block_dims (128, 32);
+ cod.set_num_decomposition (5);
+
+ ojph::mem_outfile output;
+
+ output.open ();
+
+ cs.write_headers (&output);
+
+ ojph::ui32 next_comp = 0;
+ ojph::line_buf* cur_line = cs.exchange (NULL, next_comp);
+
+ if (cs.is_planar ())
+ {
+ for (ojph::ui32 c = 0; c < encode->channel_count; c++)
+ {
+ if (encode->channels[c].height == 0) continue;
+
+ const uint8_t* line_pixels =
+ static_cast (encode->packed_buffer);
+ int file_c = cs_to_file_ch[c].file_index;
+
+ for (int64_t y = encode->chunk.start_y;
+ y < image_height + encode->chunk.start_y;
+ y++)
+ {
+ for (ojph::ui32 line_c = 0; line_c < encode->channel_count;
+ line_c++)
+ {
+
+ if (y % encode->channels[line_c].y_samples != 0) continue;
+
+ if (line_c == file_c)
+ {
+ if (encode->channels[file_c].data_type ==
+ EXR_PIXEL_HALF)
+ {
+ int16_t* channel_pixels = (int16_t*) (line_pixels);
+ for (uint32_t p = 0;
+ p < encode->channels[file_c].width;
+ p++)
+ {
+ cur_line->i32[p] = *channel_pixels++;
+ }
+ }
+ else
+ {
+ int32_t* channel_pixels = (int32_t*) (line_pixels);
+ for (uint32_t p = 0;
+ p < encode->channels[file_c].width;
+ p++)
+ {
+ cur_line->i32[p] = *channel_pixels++;
+ }
+ }
+
+ assert (next_comp == c);
+ cur_line = cs.exchange (cur_line, next_comp);
+ }
+
+ line_pixels += encode->channels[line_c].bytes_per_element *
+ encode->channels[line_c].width;
+ }
+ }
+ }
+ }
+ else
+ {
+ const uint8_t* line_pixels =
+ static_cast (encode->packed_buffer);
+
+ assert (bpl * image_height == encode->packed_bytes);
+
+ for (int y = 0; y < image_height; y++)
+ {
+ for (ojph::ui32 c = 0; c < encode->channel_count; c++)
+ {
+ int file_c = cs_to_file_ch[c].file_index;
+
+ if (encode->channels[file_c].data_type == EXR_PIXEL_HALF)
+ {
+ int16_t* channel_pixels =
+ (int16_t*) (line_pixels + cs_to_file_ch[c].raster_line_offset);
+ for (uint32_t p = 0; p < encode->channels[file_c].width;
+ p++)
+ {
+ cur_line->i32[p] = *channel_pixels++;
+ }
+ }
+ else
+ {
+ int32_t* channel_pixels =
+ (int32_t*) (line_pixels + cs_to_file_ch[c].raster_line_offset);
+ for (uint32_t p = 0; p < encode->channels[file_c].width;
+ p++)
+ {
+ cur_line->i32[p] = *channel_pixels++;
+ }
+ }
+ assert (next_comp == c);
+ cur_line = cs.exchange (cur_line, next_comp);
+ }
+ line_pixels += bpl;
+ }
+ }
+
+ cs.flush ();
+
+ assert (output.tell () >= 0);
+
+ int compressed_sz = static_cast (output.tell ());
+ if (compressed_sz < encode->packed_bytes)
+ {
+ memcpy (encode->compressed_buffer, output.get_data (), compressed_sz);
+ encode->compressed_bytes = compressed_sz;
+ }
+ else
+ {
+ encode->compressed_bytes = encode->packed_bytes;
+ }
+
+ return rv;
+}
diff --git a/src/lib/OpenEXRCore/internal_ht_common.cpp b/src/lib/OpenEXRCore/internal_ht_common.cpp
new file mode 100644
index 0000000000..66ea1af240
--- /dev/null
+++ b/src/lib/OpenEXRCore/internal_ht_common.cpp
@@ -0,0 +1,72 @@
+/*
+** SPDX-License-Identifier: BSD-3-Clause
+** Copyright Contributors to the OpenEXR Project.
+*/
+
+#include "internal_ht_common.h"
+#include
+#include
+#include
+
+bool
+make_channel_map (
+ int channel_count, exr_coding_channel_info_t* channels, std::vector& cs_to_file_ch)
+{
+ int r_index = -1;
+ int g_index = -1;
+ int b_index = -1;
+
+ cs_to_file_ch.resize(channel_count);
+
+ for (size_t i = 0; i < channel_count; i++)
+ {
+ std::string c_name(channels[i].channel_name);
+
+ if (c_name == "R") { r_index = i; }
+ else if (c_name == "G") { g_index = i; }
+ else if (c_name == "B") { b_index = i; }
+ }
+
+ bool isRGB = r_index >= 0 && g_index >= 0 && b_index >= 0 &&
+ channels[r_index].data_type == channels[g_index].data_type &&
+ channels[r_index].data_type == channels[b_index].data_type;
+
+ if (isRGB)
+ {
+ cs_to_file_ch[0].file_index = r_index;
+ cs_to_file_ch[1].file_index = g_index;
+ cs_to_file_ch[2].file_index = b_index;
+
+ int avail_cs_i = 3;
+ int offset = 0;
+ for (size_t file_i = 0; file_i < channel_count; file_i++)
+ {
+ int cs_i;
+ if (file_i == r_index) {
+ cs_i = 0;
+ } else if (file_i == g_index) {
+ cs_i = 1;
+ } else if (file_i == b_index) {
+ cs_i = 2;
+ } else {
+ cs_i = avail_cs_i++;
+ }
+
+ cs_to_file_ch[cs_i].file_index = file_i;
+ cs_to_file_ch[cs_i].raster_line_offset = offset;
+ offset += channels[file_i].width * channels[file_i].bytes_per_element;
+ }
+ }
+ else
+ {
+ int offset = 0;
+ for (size_t file_i = 0; file_i < channel_count; file_i++)
+ {
+ cs_to_file_ch[file_i].file_index = file_i;
+ cs_to_file_ch[file_i].raster_line_offset = offset;
+ offset += channels[file_i].width * channels[file_i].bytes_per_element;
+ }
+ }
+
+ return isRGB;
+}
diff --git a/src/lib/OpenEXRCore/internal_ht_common.h b/src/lib/OpenEXRCore/internal_ht_common.h
new file mode 100644
index 0000000000..ed76a730bc
--- /dev/null
+++ b/src/lib/OpenEXRCore/internal_ht_common.h
@@ -0,0 +1,22 @@
+/*
+** SPDX-License-Identifier: BSD-3-Clause
+** Copyright Contributors to the OpenEXR Project.
+*/
+
+#ifndef OPENEXR_PRIVATE_HT_COMMON_H
+#define OPENEXR_PRIVATE_HT_COMMON_H
+
+#include
+#include
+#include "openexr_coding.h"
+
+struct CodestreamChannelInfo {
+ int file_index;
+ size_t raster_line_offset;
+};
+
+bool
+make_channel_map (
+ int channel_count, exr_coding_channel_info_t* channels, std::vector& cs_to_file_ch);
+
+#endif /* OPENEXR_PRIVATE_HT_COMMON_H */
diff --git a/src/lib/OpenEXRCore/openexr_attr.h b/src/lib/OpenEXRCore/openexr_attr.h
index cca53d0089..6c594c8a3e 100644
--- a/src/lib/OpenEXRCore/openexr_attr.h
+++ b/src/lib/OpenEXRCore/openexr_attr.h
@@ -45,6 +45,7 @@ typedef enum
EXR_COMPRESSION_B44A = 7,
EXR_COMPRESSION_DWAA = 8,
EXR_COMPRESSION_DWAB = 9,
+ EXR_COMPRESSION_HT256 = 10,
EXR_COMPRESSION_LAST_TYPE /**< Invalid value, provided for range checking. */
} exr_compression_t;
diff --git a/src/test/OpenEXRTest/testCompressionApi.cpp b/src/test/OpenEXRTest/testCompressionApi.cpp
index 53b6ecd265..84a1dea60d 100644
--- a/src/test/OpenEXRTest/testCompressionApi.cpp
+++ b/src/test/OpenEXRTest/testCompressionApi.cpp
@@ -28,11 +28,11 @@ testCompressionApi (const string& tempDir)
cout << "Testing compression API functions." << endl;
// update this if you add a new compressor.
- string codecList = "none/rle/zips/zip/piz/pxr24/b44/b44a/dwaa/dwab";
+ string codecList = "none/rle/zips/zip/piz/pxr24/b44/b44a/dwaa/dwab/ht256";
int numMethods = static_cast (NUM_COMPRESSION_METHODS);
// update this if you add a new compressor.
- assert (numMethods == 10);
+ assert (numMethods == 11);
for (int i = 0; i < numMethods; i++)
{
diff --git a/src/wrappers/python/Imath.py b/src/wrappers/python/Imath.py
index 374b77d219..e4d7e83a21 100644
--- a/src/wrappers/python/Imath.py
+++ b/src/wrappers/python/Imath.py
@@ -94,9 +94,10 @@ class Compression(Enumerated):
B44A_COMPRESSION = 7
DWAA_COMPRESSION = 8
DWAB_COMPRESSION = 9
+ HT256_COMPRESSION = 9
names = [
"NO_COMPRESSION", "RLE_COMPRESSION", "ZIPS_COMPRESSION", "ZIP_COMPRESSION", "PIZ_COMPRESSION", "PXR24_COMPRESSION",
- "B44_COMPRESSION", "B44A_COMPRESSION", "DWAA_COMPRESSION", "DWAB_COMPRESSION"
+ "B44_COMPRESSION", "B44A_COMPRESSION", "DWAA_COMPRESSION", "DWAB_COMPRESSION", "HT256_COMPRESSION"
]
class PixelType(Enumerated):
diff --git a/src/wrappers/python/PyOpenEXR.cpp b/src/wrappers/python/PyOpenEXR.cpp
index cf8e239c02..0fef251e4f 100644
--- a/src/wrappers/python/PyOpenEXR.cpp
+++ b/src/wrappers/python/PyOpenEXR.cpp
@@ -2272,7 +2272,8 @@ PYBIND11_MODULE(OpenEXR, m)
.value("B44A_COMPRESSION", B44A_COMPRESSION)
.value("DWAA_COMPRESSION", DWAA_COMPRESSION)
.value("DWAB_COMPRESSION", DWAB_COMPRESSION)
- .value("NUM_COMPRESSION_METHODS", NUM_COMPRESSION_METHODS)
+ .value("DWAB_COMPRESSION", DWAB_COMPRESSION)
+ .value("HT256_COMPRESSION", HT256_COMPRESSION)
.export_values();
py::enum_(m, "Envmap", "Environment map type")
@@ -2590,6 +2591,7 @@ PYBIND11_MODULE(OpenEXR, m)
B44A_COMPRESSION
DWAA_COMPRESSION
DWAB_COMPRESSION
+ HT256_COMPRESSION
)pbdoc")
.def_readwrite("header", &PyPart::header,
R"pbdoc(
diff --git a/website/OpenEXRFileLayout.rst b/website/OpenEXRFileLayout.rst
index 9e99e8f4ae..b10ca6ddd3 100644
--- a/website/OpenEXRFileLayout.rst
+++ b/website/OpenEXRFileLayout.rst
@@ -696,6 +696,8 @@ per block depends on how the pixel data are compressed:
- 32
* - ``DWAB_COMPRESSION``
- 256
+ * - ``HT256_COMPRESSION``
+ - 256
Each scan line block has a y coordinate of type ``int``. The block's y
coordinate is equal to the pixel space y coordinate of the top scan line
@@ -921,6 +923,7 @@ The OpenEXR library predefines the following attribute types:
| | * ``B44A_COMPRESSION`` = 7 |
| | * ``DWAA_COMPRESSION`` = 8 |
| | * ``DWAB_COMPRESSION`` = 9 |
+| | * ``HT256_COMPRESSION`` = 10 |
| | |
+--------------------+-----------------------------------------------------------------+
| ``double`` | ``double`` |
diff --git a/website/ReadingAndWritingImageFiles.rst b/website/ReadingAndWritingImageFiles.rst
index d34d5aa35a..19be18ce2c 100644
--- a/website/ReadingAndWritingImageFiles.rst
+++ b/website/ReadingAndWritingImageFiles.rst
@@ -1777,7 +1777,12 @@ Supported compression types are:
| | faster to decode full frames than |
| | ``DWAA_COMPRESSION``. |
+-------------------+------------------------------------------------+
-
+| HT256_COMPRESSION | JPEG 2000 lossless coding, in blocks of 256 |
+| | scanlines and using the High-Throughput block |
+| | coder specified in Rec. ITU-T T.814 and |
+| | ISO/IEC 15444-15. The compressor offers both |
+| | speed and high-coding efficiency. |
++-------------------+------------------------------------------------+
``ZIP_COMPRESSION`` and ``DWA`` compression compress to a
user-controllable compression level, which determines the space/time
diff --git a/website/StandardAttributes.rst b/website/StandardAttributes.rst
index 80dbb1e225..5a80ec9da7 100644
--- a/website/StandardAttributes.rst
+++ b/website/StandardAttributes.rst
@@ -151,6 +151,7 @@ Basic Attributes
B44A_COMPRESSION - lossy 4-by-4 pixel block compression, flat fields are compressed more
DWAA_COMPRESSION - lossy DCT based compression, in blocks of 32 scanlines. More efficient for partial buffer access.
DWAB_COMPRESSION - lossy DCT based compression, in blocks of 256 scanlines. More efficient space wise and faster to decode full frames than DWAA_COMPRESSION.
+ HT256_COMPRESSION - JPEG 2000 lossless coding, in blocks of 256 scanlines and using the High-Throughput (HT) blocker. Offers both speed and high-coding efficiency.
diff --git a/website/python.rst b/website/python.rst
index a4c8c838a6..c8ca4a57ad 100644
--- a/website/python.rst
+++ b/website/python.rst
@@ -228,6 +228,7 @@ The OpenEXR module has enumerated types for certain attributes:
OpenEXR.B44A_COMPRESSION
OpenEXR.DWAA_COMPRESSION
OpenEXR.DWAB_COMPRESSION
+ OpenEXR.HT256_COMPRESSION
OpenEXR.NUM_COMPRESSION_METHODS
From bf65763cdf42caab4ee70630d109b503c657f6e3 Mon Sep 17 00:00:00 2001
From: Pierre-Anthony Lemieux
Date: Mon, 3 Feb 2025 09:18:45 -0800
Subject: [PATCH 4/7] Update src/lib/OpenEXR/ImfCompression.h
Co-authored-by: Cary Phillips
Signed-off-by: Pierre-Anthony Lemieux
---
src/lib/OpenEXR/ImfCompression.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/OpenEXR/ImfCompression.h b/src/lib/OpenEXR/ImfCompression.h
index 8e4ca57f86..54c3e7fb4e 100644
--- a/src/lib/OpenEXR/ImfCompression.h
+++ b/src/lib/OpenEXR/ImfCompression.h
@@ -51,7 +51,7 @@ enum IMF_EXPORT_ENUM Compression
// wise and faster to decode full frames
// than DWAA_COMPRESSION.
- HT256_COMPRESSION = 10,
+ HT256_COMPRESSION = 10, // High-Throughput JPEG2000 (HTJ2K), 256 scanlines
NUM_COMPRESSION_METHODS // number of different compression methods
};
From f8f1d993bd2a3ceb8c004712ddf8f42f6ab98851 Mon Sep 17 00:00:00 2001
From: Pierre-Anthony Lemieux
Date: Mon, 3 Feb 2025 09:19:04 -0800
Subject: [PATCH 5/7] Update src/lib/OpenEXR/ImfCompression.cpp
Co-authored-by: Cary Phillips
Signed-off-by: Pierre-Anthony Lemieux
---
src/lib/OpenEXR/ImfCompression.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/OpenEXR/ImfCompression.cpp b/src/lib/OpenEXR/ImfCompression.cpp
index 80478eba35..452177b78d 100644
--- a/src/lib/OpenEXR/ImfCompression.cpp
+++ b/src/lib/OpenEXR/ImfCompression.cpp
@@ -178,7 +178,7 @@ static const CompressionDesc IdToDesc[] = {
false),
CompressionDesc (
"ht256",
- "High-Throughtput JPEG 2000 (OpenJPH, 256 lines)",
+ "High-Throughput JPEG 2000 (OpenJPH, 256 lines)",
256,
true,
false),
From 543be5442e4dc94404d50b21f31b76909d94b766 Mon Sep 17 00:00:00 2001
From: Pierre-Anthony Lemieux
Date: Mon, 3 Feb 2025 09:19:20 -0800
Subject: [PATCH 6/7] Update website/ReadingAndWritingImageFiles.rst
Co-authored-by: Cary Phillips
Signed-off-by: Pierre-Anthony Lemieux
---
website/ReadingAndWritingImageFiles.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/website/ReadingAndWritingImageFiles.rst b/website/ReadingAndWritingImageFiles.rst
index 19be18ce2c..9eec32cb5b 100644
--- a/website/ReadingAndWritingImageFiles.rst
+++ b/website/ReadingAndWritingImageFiles.rst
@@ -1781,7 +1781,7 @@ Supported compression types are:
| | scanlines and using the High-Throughput block |
| | coder specified in Rec. ITU-T T.814 and |
| | ISO/IEC 15444-15. The compressor offers both |
-| | speed and high-coding efficiency. |
+| | speed and high coding efficiency. |
+-------------------+------------------------------------------------+
``ZIP_COMPRESSION`` and ``DWA`` compression compress to a
From 7148b015cbb30814f14bd10191c816a0ab4bc65e Mon Sep 17 00:00:00 2001
From: Pierre-Anthony Lemieux
Date: Wed, 5 Feb 2025 11:01:33 -0800
Subject: [PATCH 7/7] Add channel map
---
src/lib/OpenEXRCore/internal_ht.cpp | 176 ++++++++++++++++++++-
src/lib/OpenEXRCore/internal_ht_common.cpp | 6 +-
2 files changed, 173 insertions(+), 9 deletions(-)
diff --git a/src/lib/OpenEXRCore/internal_ht.cpp b/src/lib/OpenEXRCore/internal_ht.cpp
index 093ed347f0..120ee8edc5 100644
--- a/src/lib/OpenEXRCore/internal_ht.cpp
+++ b/src/lib/OpenEXRCore/internal_ht.cpp
@@ -17,6 +17,137 @@
#include "openexr_encode.h"
#include "internal_ht_common.h"
+/***********************************
+
+Structure of the HT256 chunk
+- MAGIC = 0x4854: magic number
+- PLEN: length of header payload (big endian uint32_t)
+- header payload
+ - NCH: number of channels in channel map (big endian uint16_t)
+ - for(i = 0; i < NCH; i++)
+ - CS_TO_F[i]: OpenEXR channel index corresponding to J2K component index i (big endian uint16_t)
+ - any number of opaque bytes
+- CS: JPEG 2000 Codestream
+
+***********************************/
+
+class MemoryReader
+{
+public:
+ MemoryReader (uint8_t* buffer, size_t max_sz)
+ : buffer (buffer), cur (buffer), end (buffer + max_sz){};
+
+ uint32_t pull_uint32 ()
+ {
+ if (this->end - this->cur < 4)
+ throw std::out_of_range ("Insufficient data to pull uint32_t");
+
+ uint32_t v = *this->cur++;
+ v = (v << 8) + *this->cur++;
+ v = (v << 8) + *this->cur++;
+ return (v << 8) + *cur++;
+ }
+
+ uint16_t pull_uint16 ()
+ {
+ if (this->end - this->cur < 2)
+ throw std::out_of_range ("Insufficient data to pull uint16_t");
+
+ uint32_t v = *cur++;
+ return (v << 8) + *cur++;
+ }
+
+protected:
+ uint8_t* buffer;
+ uint8_t* cur;
+ uint8_t* end;
+};
+
+class MemoryWriter
+{
+public:
+ MemoryWriter (uint8_t* buffer, size_t max_sz)
+ : buffer (buffer), cur (buffer), end (buffer + max_sz){};
+
+ void push_uint32 (uint32_t value)
+ {
+ if (this->end - this->cur < 4)
+ throw std::out_of_range ("Insufficient data to push uint32_t");
+
+ *this->cur++ = (value >> 24) & 0xFF;
+ *this->cur++ = (value >> 16) & 0xFF;
+ *this->cur++ = (value >> 8) & 0xFF;
+ *this->cur++ = value & 0xFF;
+ }
+
+ void push_uint16 (uint16_t value)
+ {
+ if (this->end - this->cur < 2)
+ throw std::out_of_range ("Insufficient data to push uint32_t");
+
+ *this->cur++ = (value >> 8) & 0xFF;
+ *this->cur++ = value & 0xFF;
+ }
+
+ size_t get_size () { return this->cur - this->buffer; }
+
+ uint8_t* get_buffer () { return this->buffer; }
+
+ uint8_t* get_cur () { return this->cur; }
+
+protected:
+ uint8_t* buffer;
+ uint8_t* cur;
+ uint8_t* end;
+};
+
+constexpr uint16_t HEADER_MARKER = 'H' * 256 + 'T';
+
+size_t
+write_header (
+ uint8_t* buffer,
+ size_t max_sz,
+ const std::vector& map)
+{
+ constexpr uint16_t HEADER_SZ = 6;
+ MemoryWriter payload (buffer + HEADER_SZ, max_sz - HEADER_SZ);
+ payload.push_uint16 (map.size ());
+ for (size_t i = 0; i < map.size (); i++)
+ {
+ payload.push_uint16 (map.at (i).file_index);
+ }
+
+ MemoryWriter header (buffer, max_sz);
+ header.push_uint16 (HEADER_MARKER);
+ header.push_uint32 (payload.get_size ());
+
+ return header.get_size () + payload.get_size ();
+}
+
+void
+read_header (
+ void* buffer,
+ size_t max_sz,
+ size_t& length,
+ std::vector& map)
+{
+ MemoryReader header ((uint8_t*) buffer, max_sz);
+ if (header.pull_uint16 () != HEADER_MARKER)
+ throw std::runtime_error (
+ "HT256 chunk header missing does not start with magic number.");
+
+ length = header.pull_uint32 ();
+
+ if (length < 2)
+ throw std::runtime_error ("Error while reading the channel map");
+
+ map.resize (header.pull_uint16 ());
+ for (size_t i = 0; i < map.size (); i++)
+ {
+ map.at (i).file_index = header.pull_uint16 ();
+ }
+}
+
extern "C" exr_result_t
internal_exr_undo_ht (
exr_decode_pipeline_t* decode,
@@ -28,12 +159,33 @@ internal_exr_undo_ht (
exr_result_t rv = EXR_ERR_SUCCESS;
std::vector cs_to_file_ch (decode->channel_count);
- bool isRGB = make_channel_map (
- decode->channel_count, decode->channels, cs_to_file_ch);
+
+ /* read the channel map */
+
+ size_t header_sz;
+ read_header (
+ (uint8_t*) compressed_data, comp_buf_size, header_sz, cs_to_file_ch);
+ if (decode->channel_count != cs_to_file_ch.size ())
+ throw std::runtime_error ("Unexpected number of channels");
+
+ std::vector offsets (decode->channel_count);
+ offsets[0] = 0;
+ for (int file_i = 1; file_i < decode->channel_count; file_i++)
+ {
+ offsets[file_i] = offsets[file_i - 1] +
+ decode->channels[file_i - 1].width *
+ decode->channels[file_i - 1].bytes_per_element;
+ }
+ for (int cs_i = 0; cs_i < decode->channel_count; cs_i++)
+ {
+ cs_to_file_ch[cs_i].raster_line_offset =
+ offsets[cs_to_file_ch[cs_i].file_index];
+ }
ojph::mem_infile infile;
infile.open (
- reinterpret_cast (compressed_data), comp_buf_size);
+ reinterpret_cast (compressed_data) + header_sz,
+ comp_buf_size - header_sz);
ojph::codestream cs;
cs.read_headers (&infile);
@@ -192,7 +344,8 @@ internal_exr_apply_ht (exr_encode_pipeline_t* encode)
int file_c = cs_to_file_ch[c].file_index;
if (encode->channels[file_c].data_type != EXR_PIXEL_UINT)
nlt.set_nonlinear_transform (
- c, ojph::param_nlt::nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_NLT);
+ c,
+ ojph::param_nlt::nonlinearity::OJPH_NLT_BINARY_COMPLEMENT_NLT);
siz.set_component (
c,
ojph::point (
@@ -326,13 +479,20 @@ internal_exr_apply_ht (exr_encode_pipeline_t* encode)
cs.flush ();
- assert (output.tell () >= 0);
+ size_t header_sz = write_header (
+ (uint8_t*) encode->compressed_buffer,
+ encode->packed_bytes,
+ cs_to_file_ch);
+ assert (output.tell () >= 0);
int compressed_sz = static_cast (output.tell ());
- if (compressed_sz < encode->packed_bytes)
+ if (compressed_sz + header_sz < encode->packed_bytes)
{
- memcpy (encode->compressed_buffer, output.get_data (), compressed_sz);
- encode->compressed_bytes = compressed_sz;
+ memcpy (
+ ((uint8_t*) encode->compressed_buffer) + header_sz,
+ output.get_data (),
+ compressed_sz);
+ encode->compressed_bytes = compressed_sz + header_sz;
}
else
{
diff --git a/src/lib/OpenEXRCore/internal_ht_common.cpp b/src/lib/OpenEXRCore/internal_ht_common.cpp
index 66ea1af240..6d1608c767 100644
--- a/src/lib/OpenEXRCore/internal_ht_common.cpp
+++ b/src/lib/OpenEXRCore/internal_ht_common.cpp
@@ -29,7 +29,11 @@ make_channel_map (
bool isRGB = r_index >= 0 && g_index >= 0 && b_index >= 0 &&
channels[r_index].data_type == channels[g_index].data_type &&
- channels[r_index].data_type == channels[b_index].data_type;
+ channels[r_index].data_type == channels[b_index].data_type &&
+ channels[r_index].x_samples == channels[g_index].x_samples &&
+ channels[r_index].x_samples == channels[b_index].x_samples &&
+ channels[r_index].y_samples == channels[g_index].y_samples &&
+ channels[r_index].y_samples == channels[b_index].y_samples;
if (isRGB)
{