Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Treatment of unknown chunks #221

Open
HeroicKatora opened this issue Jun 15, 2020 · 4 comments
Open

Treatment of unknown chunks #221

HeroicKatora opened this issue Jun 15, 2020 · 4 comments

Comments

@HeroicKatora
Copy link
Member

Several png tools would profit from or require processing unknown chunks. We should also check and help that the chunk flag bits are adhered to in all such processing. This requires some plan on how to embed chunk processing in the decoder, likely with a trait/callback API:

  • Should it be possible to change the chunk callback on the fly?
  • Should the callback be allowed to influence the chunk iteration, and if so, how?
  • Should we always decode all known chunks or should the chunk processor be allowed to intercept and replace that decoding beforehand?
  • How do we ensure that future versions do not decode more or other chunks that callbacks of previous versions did not yet recognize? How would we be able to still evolve the interface?
  • Should a chunk processor be allowed to switch off checksumming for a single chunk?
@zlstringham
Copy link
Contributor

Fwiw, the PNG spec also dictates that chunk ordering matters. In some cases, this means that the unknown chunk's position relative to other critical chunks is important.

While I doubt this necessitates storing every chunk in the decoder, full support probably requires:

  • Surface the unknown chunk's "position" relative to other chunks somehow.
  • Allow an encoder to interleave the unknown chunk between arbitrary chunks, potentially between critical chunks and potentially before/after the IDAT chunk(s).
    • IHDR and IEND must still be first and last, respectively.

@HeroicKatora
Copy link
Member Author

Prior art: libpng 1.6

typedef struct png_unknown_chunk_t
{
   png_byte name[5]; /* Textual chunk name with '\0' terminator */
   png_byte *data;   /* Data, should not be modified on read! */
   size_t size;

   /* On write 'location' must be set using the flag values listed below.
    * Notice that on read it is set by libpng however the values stored have
    * more bits set than are listed below.  Always treat the value as a
    * bitmask.  On write set only one bit - setting multiple bits may cause the
    * chunk to be written in multiple places.
    */
   png_byte location; /* mode of operation at read time */
}
png_unknown_chunk;

// In Rust: fn png_user_chunk_ptr(png_structp, png_unknownn_chunkp) -> int;
typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp,
    png_unknown_chunkp));

Furthermore, the support must be enabled by calling png_set_keep_unknown_chunks which has four different methods of handling them. The flag PNG_HANDLE_AS_UNKNOWN_SUPPORTED can be checked to find out if handling is supported by the library at all. Then options are roughly as follows:

  1. PNG_HANDLE_CHUNK_AS_DEFAULT: write safe-to-copy chunks and other chunks only if a global default is set to ALWAYS
  2. PNG_HANDLE_CHUNK_NEVER: discard unknown chunks
  3. PNG_HANDLE_CHUNK_IF_SAFE:: only write safe-to-copy chunks
  4. PNG_HANDLE_CHUNK_ALWAYS: do not check the chunk type for writes

@mainrs
Copy link

mainrs commented Jan 30, 2021

How is this currently handled? Does the library just not work when reading unknown chunks?

@HeroicKatora
Copy link
Member Author

Unknown chunks are currently always skipped over. This is technically not quite right but at least it won't fail to decode images.

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

No branches or pull requests

3 participants