From 32ea70c6acb9f092716a3d14ad57dc8c9906d29a Mon Sep 17 00:00:00 2001 From: Todica Ionut Date: Fri, 8 Aug 2025 09:44:23 +0300 Subject: [PATCH 1/5] add zstd exr output Signed-off-by: Todica Ionut --- src/openexr.imageio/exroutput.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/openexr.imageio/exroutput.cpp b/src/openexr.imageio/exroutput.cpp index 6fa387f178..980b1567e6 100644 --- a/src/openexr.imageio/exroutput.cpp +++ b/src/openexr.imageio/exroutput.cpp @@ -742,6 +742,14 @@ OpenEXROutput::spec_to_header(ImageSpec& spec, int subimage, if (Strutil::istarts_with(comp, "zip")) { header.zipCompressionLevel() = (qual >= 1 && qual <= 9) ? qual : 4; } +#endif +#if OPENEXR_CODED_VERSION >= 30500 + // OpenEXR 3.5.0 and later allow us to pick the level. We've found + // that 5 is a great tradeoff between size and speed, so that is our + // default. + if (Strutil::istarts_with(comp, "zstd")) { + header.zstdCompressionLevel() = (qual >= 1 && qual <= 22) ? qual : 5; + } #endif if (Strutil::istarts_with(comp, "dwa") && qual > 0) { #if OPENEXR_CODED_VERSION >= 30103 @@ -964,6 +972,10 @@ OpenEXROutput::put_parameter(const std::string& name, TypeDesc type, #ifdef IMF_HTJ2K_COMPRESSION else if (Strutil::iequals(str, "htj2k")) header.compression() = Imf::HTJ2K_COMPRESSION; +#endif +#ifdef IMF_ZSTD_COMPRESSION + else if (Strutil::iequals(str, "zstd")) + header.compression() = Imf::ZSTD_COMPRESSION; #endif } return true; From 5e212e1527ba5bef81e5f0b0b55d0a4a5ee38945 Mon Sep 17 00:00:00 2001 From: Todica Ionut Date: Fri, 8 Aug 2025 09:47:39 +0300 Subject: [PATCH 2/5] add zstd exr c Signed-off-by: Todica Ionut --- src/openexr.imageio/exrinput_c.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/openexr.imageio/exrinput_c.cpp b/src/openexr.imageio/exrinput_c.cpp index 00489b5b8d..5f09d778f3 100644 --- a/src/openexr.imageio/exrinput_c.cpp +++ b/src/openexr.imageio/exrinput_c.cpp @@ -570,6 +570,9 @@ OpenEXRCoreInput::PartInfo::parse_header(OpenEXRCoreInput* in, case EXR_COMPRESSION_DWAB: comp = "dwab"; break; #ifdef IMF_HTJ2K_COMPRESSION case EXR_COMPRESSION_HTJ2K: comp = "htj2k"; break; +#endif +#ifdef IMF_ZSTD_COMPRESSION + case EXR_COMPRESSION_ZSTD: comp = "zstd"; break; #endif default: break; } From b4b57f75950a246d3c9ee6e146186b2cb186eaf6 Mon Sep 17 00:00:00 2001 From: Todica Ionut Date: Fri, 8 Aug 2025 09:48:50 +0300 Subject: [PATCH 3/5] add zstd exr Signed-off-by: Todica Ionut --- src/openexr.imageio/exrinput.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/openexr.imageio/exrinput.cpp b/src/openexr.imageio/exrinput.cpp index 94293a3fd2..839874b1a2 100644 --- a/src/openexr.imageio/exrinput.cpp +++ b/src/openexr.imageio/exrinput.cpp @@ -433,6 +433,9 @@ OpenEXRInput::PartInfo::parse_header(OpenEXRInput* in, case Imf::DWAB_COMPRESSION: comp = "dwab"; break; #ifdef IMF_HTJ2K_COMPRESSION case Imf::HTJ2K_COMPRESSION: comp = "htj2k"; break; +#endif +#ifdef IMF_ZSTD_COMPRESSION + case Imf::ZSTD_COMPRESSION: comp = "zstd"; break; #endif default: break; } From fef6d511603392d0294f4b4d9410cc0fab45267b Mon Sep 17 00:00:00 2001 From: Todica Ionut Date: Fri, 8 Aug 2025 19:18:53 +0300 Subject: [PATCH 4/5] blosc2 zstd Signed-off-by: Todica Ionut --- src/openexr.imageio/exroutput.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openexr.imageio/exroutput.cpp b/src/openexr.imageio/exroutput.cpp index 980b1567e6..a599fd106d 100644 --- a/src/openexr.imageio/exroutput.cpp +++ b/src/openexr.imageio/exroutput.cpp @@ -748,7 +748,7 @@ OpenEXROutput::spec_to_header(ImageSpec& spec, int subimage, // that 5 is a great tradeoff between size and speed, so that is our // default. if (Strutil::istarts_with(comp, "zstd")) { - header.zstdCompressionLevel() = (qual >= 1 && qual <= 22) ? qual : 5; + header.zstdCompressionLevel() = (qual >= 1 && qual <= 9) ? qual : 5; } #endif if (Strutil::istarts_with(comp, "dwa") && qual > 0) { From cfda2707d105465ef51c8594589abe6b14fb683e Mon Sep 17 00:00:00 2001 From: Todica Ionut Date: Fri, 8 Aug 2025 19:31:40 +0300 Subject: [PATCH 5/5] documentation for zstd Signed-off-by: Todica Ionut --- src/doc/builtinplugins.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/doc/builtinplugins.rst b/src/doc/builtinplugins.rst index 93772b0bfc..afdc1c24eb 100644 --- a/src/doc/builtinplugins.rst +++ b/src/doc/builtinplugins.rst @@ -1543,16 +1543,17 @@ The official OpenEXR site is http://www.openexr.com/. * - ``compression`` - string - one of: ``"none"``, ``"rle"``, ``"zip"``, ``"zips"``, ``"piz"``, - ``"pxr24"``, ``"b44"``, ``"b44a"``, ``"dwaa"``, ``"dwab"`` or ``"htj2k"``. + ``"pxr24"``, ``"b44"``, ``"b44a"``, ``"dwaa"``, ``"dwab"``, ``"htj2k"`` or ``"zstd"``. (``"htj2k"`` is only supported with OpenEXR 3.4 or later.) + (``"zstd"`` is only supported with OpenEXR 3.5 or later.) If the writer receives a request for a compression type it does not recognize or is not supported by the version of OpenEXR on the system, it will use ``"zip"`` by default. For ``"dwaa"`` and ``"dwab"``, the dwaCompressionLevel may be optionally appended to the compression name after a colon, like this: ``"dwaa:200"``. (The - default DWA compression value is 45.) For ``"zip"`` and ``"zips"`` + default DWA compression value is 45.) For ``"zip"``, ``"zips"`` and ``"zstd"`` compression, a level from 1 to 9 may be appended (the default is - ``"zip:4"``), but note that this is only honored when building + ``"zip:4"`` and ``"zstd:5"``), but note that this is only honored when building against OpenEXR 3.1.3 or later. * - ``textureformat`` - string