Skip to content

tooling/libpng-oracle: read back text and colour chunks so metadata preservation is oracle-testable #572

Description

@justin13888

Summary

libpng_oracle::decode returns pixels plus IHDR fields and nothing else:

pub struct DecodedImage {
    pub width: u32, pub height: u32, pub bit_depth: u8,
    pub color_type: u8, pub interlace: bool,
    pub rowbytes: usize, pub pixels: Vec<u8>,
}

So a test can ask the reference reader "does this file decode, and to the same pixels?" but never
"what metadata did you read out of it?". For gamut-png's metadata-preservation path (#483, PR
#550) that is the whole claim: a re-encode must put every eXIf / iCCP / sRGB / cICP / gAMA / cHRM /
tEXt / zTXt / iTXt payload back, in the right chunk, with the right bytes. Today that is pinned by
gamut reading its own output — a round trip, which by construction cannot see a defect symmetric
across this crate's reader and writer — plus a third-party spot check done by hand.

Proposal

In tooling/libpng-oracle/src/lib.rs, extend DecodedImage with what libpng already parsed
during png_read_info / png_read_end:

  • texts: Vec<OracleText> from png_get_text, each carrying keyword, text, and libpng's
    compression field — which distinguishes tEXt (PNG_TEXT_COMPRESSION_NONE), zTXt
    (_zTXt), and the two iTXt forms (PNG_ITXT_COMPRESSION_NONE / _zTXt) along with
    lang and lang_key. That is exactly the identity TextChunkKind records on the gamut side;
  • iccp: Option<(String, Vec<u8>)> from png_get_iCCP;
  • srgb: Option<u8> from png_get_sRGB, gamma/chromaticities from png_get_gAMA_fixed /
    png_get_cHRM_fixed, exif: Option<Vec<u8>> from png_get_eXIf_1;
  • cicp, which libpng 1.6.43 does not parse — read it as an unknown chunk via
    png_set_keep_unknown_chunks + png_get_unknown_chunks, which is also how the caBX store
    could be checked.

Then crates/gamut-png/tests/preservation.rs can assert the reference reader sees what the
source carried, rather than gamut agreeing with itself.

Note libpng needs png_set_text / keyword handling to be Latin-1-correct for the text half of
this to be meaningful — that is #571.

Why not now

tooling/ was outside PR #550's manifest.

Related: #502 (bKGD/sBIT plus a warning count), #571 (Latin-1 text payloads).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions