Skip to content

Releases: imazen/zencodec

v0.1.20

21 Apr 08:06

Choose a tag to compare

Added

  • ISO_21496_1_URN: &[u8; 28] — the ISO-defined namespace URN for gain-map payloads in URN-namespaced containers (most notably JPEG APP2). Byte-identical to libultrahdr's kIsoNameSpace.
  • ISO_21496_1_PRIMARY_APP2_BODY: &[u8; 32] — the full JPEG APP2 body (URN + min_version=0, writer_version=0) that the primary image of a canonical Ultra HDR JPEG carries to advertise ISO 21496-1 awareness. Goes directly inside the APP2 segment after the FF E2 marker + length header; detected by exact bytes match.
  • Iso21496Format::JxlJhgm — canonical name for the bare ISO 21496-1 payload (no URN, no version byte). Naming parallels AvifTmap: each variant names the container that consumes exactly those bytes.
  • Iso21496Format::JpegApp2BodyWithUrn — full JPEG APP2 body (URN + bare payload), handled in one parse_iso21496_fmt / serialize_iso21496_fmt call. Does NOT include the JPEG FF E2 marker or u16 BE length word (those stay with the caller as JPEG syntax).
  • Iso21496Format discriminants pinned with explicit = 0..3 values plus a const _: () = assert!(...) block, so accidental reorders/removals trip at compile time instead of silently shifting as u8 results.
  • gainmap::serialize_iso21496_fmt_into(params, format, &mut Vec<u8>) — append-to-buffer partner for serialize_iso21496_fmt, lets callers embed the ISO payload inside a larger buffer (e.g., a JPEG APP2 marker + length + body) in one allocation.
  • GainMapParseError::UrnMismatch — returned when parsing under Iso21496Format::JpegApp2BodyWithUrn and the input does not begin with ISO_21496_1_URN.

Deprecated

  • Iso21496Format::JpegApp2 — misleading name. The bytes it produces are the bare ISO 21496-1 payload (no URN), not a standalone JPEG APP2 body. Use JxlJhgm for the same bytes under a clearer name, or JpegApp2BodyWithUrn for the full APP2 body including the URN. Kept at its original discriminant 0 so existing as u8 casts keep working; it and JxlJhgm are distinct variants that serialize to identical bytes (Rust does not allow two variants to share a discriminant).

Fixed

  • Formatting fixup so cargo fmt --check is clean (41f7162).

Why

The URN is ISO-defined, not JPEG-defined, and belongs next to Iso21496Format rather than duplicated across codec crates. Folding URN framing into the format enum collapses the API surface to one parse/serialize pair and each variant now names the container that consumes exactly those bytes. The FF E2 + u16 BE length envelope remains pure JPEG syntax and stays in zenjpeg.

Full changelog: https://github.com/imazen/zencodec/blob/v0.1.20/CHANGELOG.md#0120---2026-04-21

v0.1.19

17 Apr 03:20

Choose a tag to compare

Full Changelog: v0.1.18...v0.1.19

v0.1.18

15 Apr 10:51

Choose a tag to compare

Full Changelog: v0.1.17...v0.1.18

zencodec 0.1.17

15 Apr 07:42

Choose a tag to compare

Authority-aware color resolution.

Added:

  • SourceColor::to_color_context() — drops non-authoritative field.
  • helpers::descriptor_for_decoded_pixels_v2 — widens corrected_to to Option<&ColorProfileSource>; drops placebo IccMatchTolerance.
  • helpers::resolve_color — composable (ColorPrimaries, TransferFunction) resolution for per-format descriptors.

Fixed:

  • descriptor_for_decoded_pixels now respects color_authority when both CICP and ICC are populated (previously CICP always won, violating JPEG/PNG-iCCP spec).

Deprecated:

  • helpers::descriptor_for_decoded_pixels — migrate to _v2.

Changed:

  • Bump zenpixels 0.2.7 → 0.2.8.

See CHANGELOG.md for full notes.

v0.1.16

14 Apr 20:52

Choose a tag to compare

Changed

  • Bump zenpixels to 0.2.7 with the icc feature enabled. All ICC identification now delegates to zenpixels::icc, which ships a superset of the web-corpus table (163 RGB + 18 grayscale profiles vs. our 118+14, with intent-safety masks cross-validated against moxcms and lcms2).
  • icc_extract_cicp → deprecated shim around zenpixels::icc::extract_cicp.
  • helpers::identify_well_known_icc, helpers::icc_profile_is_srgb → deprecated shims around zenpixels::icc::{identify_common, is_common_srgb}.
  • helpers::IccMatchTolerance → deprecated placebo. identify_common uses Tolerance::Intent internally; sub-Intent variants are indistinguishable at 8-bit and 10-bit output. All in-tree callers already pass Intent.

Removed

  • src/helpers/icc_table_{rgb,gray}.inc — superseded by the tables shipped in zenpixels::icc.
  • scripts/mega_test.rs, scripts/verify_via_moxcms.rs, scripts/fetch-profiles.sh — superseded by zenpixels/scripts/icc-gen (a proper superset with lcms2 cross-validation) and the icc-fetch recipe in zenpixels/justfile.
  • examples/verify_via_moxcms.rs, examples/gen_moxcms_profiles.rs — superseded by zenpixels/scripts/icc-gen.

Queued for next minor

The deprecated shims (icc_extract_cicp, helpers::IccMatchTolerance, helpers::identify_well_known_icc, helpers::icc_profile_is_srgb) will be removed. descriptor_for_decoded_pixels will drop its placebo IccMatchTolerance parameter. Migrate to zenpixels::icc::{extract_cicp, identify_common, is_common_srgb}.

Release history note

0.1.14 is yanked (premature zenpixels 0.3.0 dep). 0.1.15 was in-tree only. 0.1.16 is the correct successor to the published 0.1.13.

v0.1.14

13 Apr 03:00

Choose a tag to compare

What's Changed

  • feat: lower MSRV to 1.88 by @lilith in #9
  • Add icc_extract_cicp() and ColorAuthority to SourceColor by @lilith in #8

Full Changelog: v0.1.13...v0.1.14

v0.1.13

08 Apr 04:31

Choose a tag to compare

Features

  • New format detection: JP2 (JPEG 2000), DNG (Digital Negative), camera RAW (CR2/CR3, RAF, RW2, ORF, SubIFD TIFFs), and SVG. Detection priority is DNG > RAW > TIFF to handle shared TIFF magic bytes; SVGZ is intentionally excluded to avoid gzip false positives. (02dd783)
  • ResourceLimits::max_total_pixels: cumulative pixel cap across all frames (width × height × frame_count). Closes a gap where animations with many individually-legal frames could still exhaust memory. New builder with_max_total_pixels(), check_total_pixels(), and LimitExceeded::TotalPixels variant; wired into check_image_info() when frame_count is known. (86dffb6)

Docs

  • Clarify that max_pixels is per-frame and max_total_pixels is the sum across all frames. (0d430a6)

Full Changelog: v0.1.12...v0.1.13

v0.1.12

01 Apr 20:30

Choose a tag to compare

What's new

ISO 21496-1 gain map improvements

  • Explicit format selection: New parse_iso21496_fmt / serialize_iso21496_fmt functions with Iso21496Format enum (JpegApp2 or AvifTmap) for unambiguous wire format handling.
  • Continued-fraction encoding: Fraction::from_f64_cf and UFraction::from_f64_cf produce canonical ISO 21496-1 fractions (e.g. 1/64 instead of 15625/1000000), matching the algorithm used by libultrahdr.
  • Common-denominator parsing: Supports compact encoding (flag bit 3) used by libultrahdr.
  • Backward direction flag: Full roundtrip support for the backward direction bit in gain map metadata.

Bug fixes

  • Panic removal in ISOBMFF box_size handling and gain map parsing edge cases.
  • Clippy warning cleanup.

Dependency updates

  • zenpixels / zenpixels-convert bumped to 0.2.2
  • archmage, magetypes, enough, whereat, linear-srgb bumped to latest

Deprecations

  • Fraction::from_f64(value, denominator) → use Fraction::from_f64_cf(value)
  • UFraction::from_f64(value, denominator) → use UFraction::from_f64_cf(value)
  • parse_iso21496(data) → use parse_iso21496_fmt(data, Iso21496Format::JpegApp2)
  • serialize_iso21496(params) → use serialize_iso21496_fmt(params, Iso21496Format::JpegApp2)

The unsuffixed parse_iso21496 / serialize_iso21496 changed from AVIF tmap format to JpegApp2 format in this release. Use the _fmt variants with an explicit Iso21496Format to avoid ambiguity.

v0.1.11

30 Mar 04:09

Choose a tag to compare

Full Changelog: v0.1.10...v0.1.11

v0.1.10

30 Mar 03:14

Choose a tag to compare

Full Changelog: v0.1.9...v0.1.10