diff --git a/src/doc/builtinplugins.rst b/src/doc/builtinplugins.rst index 74a3cf3d06..7a99036efb 100644 --- a/src/doc/builtinplugins.rst +++ b/src/doc/builtinplugins.rst @@ -1566,8 +1566,9 @@ The official OpenEXR site is http://www.openexr.com/. * - ``compression`` - string - one of: ``"none"``, ``"rle"``, ``"zip"``, ``"zips"``, ``"piz"``, - ``"pxr24"``, ``"b44"``, ``"b44a"``, ``"dwaa"``, ``"dwab"``, ``"htj2k256"`` or ``"htj2k32"``. + ``"pxr24"``, ``"b44"``, ``"b44a"``, ``"dwaa"``, ``"dwab"``, ``"htj2k256"``, ``"htj2k32"`` or ``"zstd"``. (``"htj2k256"`` and ``"htj2k32"`` are only supported with OpenEXR 3.4 or later.) + (``"zstd"`` are 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 @@ -1577,6 +1578,9 @@ The official OpenEXR site is http://www.openexr.com/. compression, a level from 1 to 9 may be appended (the default is ``"zip:4"``), but note that this is only honored when building against OpenEXR 3.1.3 or later. + For ``"zstd"`` compression, a level from 1 to 22 may be appended (the default is + ``"zstd:5"``), but note that this is only honored when building + against OpenEXR 3.5.0 or later. * - ``textureformat`` - string - ``"Plain Texture"`` for MIP-mapped OpenEXR files, ``"CubeFace diff --git a/src/openexr.imageio/exrinput.cpp b/src/openexr.imageio/exrinput.cpp index b830ed54b7..38bcf2f2fb 100644 --- a/src/openexr.imageio/exrinput.cpp +++ b/src/openexr.imageio/exrinput.cpp @@ -447,6 +447,9 @@ OpenEXRInput::PartInfo::parse_header(OpenEXRInput* in, #endif #ifdef IMF_HTJ2K32_COMPRESSION case Imf::HTJ2K32_COMPRESSION: comp = "htj2k32"; break; +#endif +#ifdef IMF_ZSTD_COMPRESSION + case Imf::ZSTD_COMPRESSION: comp = "zstd"; break; #endif default: break; } diff --git a/src/openexr.imageio/exrinput_c.cpp b/src/openexr.imageio/exrinput_c.cpp index 1b2c56847a..8022568e66 100644 --- a/src/openexr.imageio/exrinput_c.cpp +++ b/src/openexr.imageio/exrinput_c.cpp @@ -577,6 +577,9 @@ OpenEXRCoreInput::PartInfo::parse_header(OpenEXRCoreInput* in, #endif #ifdef IMF_HTJ2K32_COMPRESSION case EXR_COMPRESSION_HTJ2K32: comp = "htj2k32"; break; +#endif +#ifdef IMF_ZSTD_COMPRESSION + case ZSTD_COMPRESSION: comp = "zstd"; break; #endif default: break; } diff --git a/src/openexr.imageio/exroutput.cpp b/src/openexr.imageio/exroutput.cpp index 3b3c29ffaa..f86aedabe6 100644 --- a/src/openexr.imageio/exroutput.cpp +++ b/src/openexr.imageio/exroutput.cpp @@ -950,6 +950,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 quality 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 @@ -1204,6 +1212,10 @@ OpenEXROutput::put_parameter(const std::string& name, TypeDesc type, #ifdef IMF_HTJ2K32_COMPRESSION else if (Strutil::iequals(str, "htj2k32")) header.compression() = Imf::HTJ2K32_COMPRESSION; +#endif +#ifdef ZSTD_COMPRESSION + else if (Strutil::iequals(str, "zstd")) + header.compression() = Imf::ZSTD_COMPRESSION; #endif } return true;