diff --git a/.github/workflows/ci_steps.yml b/.github/workflows/ci_steps.yml index f4b9f727a..57eb6b4af 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" @@ -154,9 +163,9 @@ 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 + name: ${{ env.INSTALL_MANIFEST }} path: _build/${{ env.INSTALL_MANIFEST }} - name: Validate install @@ -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 f87dec6f6..5afbb601a 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 4dbc1c9f3..e3d4ed6c5 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@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 897f7dcae..1913f25f8 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@v4 with: name: wheels-${{ matrix.os }} path: | diff --git a/.github/workflows/python-wheels-publish.yml b/.github/workflows/python-wheels-publish.yml index a5ce3f208..f1cbd19f6 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@v4 with: name: wheels-${{ matrix.os }} path: | diff --git a/.github/workflows/python-wheels.yml b/.github/workflows/python-wheels.yml index 06e2a5167..b114a998d 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@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + 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 6af412fac..252fc9164 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@v4 with: name: SARIF file path: results.sarif diff --git a/BUILD.bazel b/BUILD.bazel index e29bd10dc..67c94305a 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 f6e967799..5dd63a6b4 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 000000000..1be231113 --- /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 000000000..e68e24e9a --- /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 6e8c424fc..7c3462e06 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 4fdce3462..22f4553be 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 0f76c3365..37cb08afe 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 15c0837e7..4e007dbe4 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 8a2e32195..a1e649463 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 c263380c4..db3593cf8 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 01fc2bd87..3f51a0c6e 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 0f76c3365..37cb08afe 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 0f76c3365..9063f25c4 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 669a1cdaf..9ef1a4247 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 669a1cdaf..9ef1a4247 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 2e8a401d7..43b5b26bd 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 f2e6b5e8b..888428c04 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 78b49be7f..ea171071e 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 c44e7a1b6..870eea544 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 8d7f85e74..1098520f3 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 2f1285e00..beaa47db4 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 669a1cdaf..9ef1a4247 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 669a1cdaf..9ef1a4247 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 b71d2e9f1..cdebeb065 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 d87af55e0..25bec4b55 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 76dc51a25..3b5ed0156 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 b71d2e9f1..cdebeb065 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 09e3f282e..aa3ab1430 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 b71d2e9f1..cdebeb065 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 000000000..f2526fa80 --- /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 3c0119b31..62738a8ec 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 062f2f709..da26fc974 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 68c73d63d..80478eba3 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 2e148ff6a..8e4ca57f8 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 889a27035..b8e41c4d7 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 000000000..147a1a267 --- /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 000000000..708d7852e --- /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 98b49aebd..50b03a69a 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 8348bfc43..9ea7ea4ba 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 360015c12..1cdc484a8 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 834b854a3..6251c2d9c 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 000000000..093ed347f --- /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 000000000..66ea1af24 --- /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 000000000..ed76a730b --- /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 cca53d008..6c594c8a3 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 53b6ecd26..84a1dea60 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 374b77d21..e4d7e83a2 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 cf8e239c0..0fef251e4 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 9e99e8f4a..b10ca6ddd 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 d34d5aa35..19be18ce2 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 80dbb1e22..5a80ec9da 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 a4c8c838a..c8ca4a57a 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