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

Add iEId chunk #495

Open
ProgramMax opened this issue Jan 29, 2025 · 7 comments
Open

Add iEId chunk #495

ProgramMax opened this issue Jan 29, 2025 · 7 comments

Comments

@ProgramMax
Copy link
Collaborator

This is part of the more broad #493 discussion.

A new chunk (named iEId, "image extra id") would be added to describe an ID that gets used by the iEXt chunk #494 .

The iEId chunk starts with an ID number. (We will probably reserve ID 0 for IDAT instead of iEXt chunks.)
After the ID number would be data similar to IHDR:

  • width
  • height
  • bit depth
  • compression method
  • filter method
  • interlace method

After that would be a list of enum values which describe what data is help by iEXt chunks using this ID.
For example, an image might include an iEId with ID 1 that contains tangent space x, y, and z data.

@ProgramMax
Copy link
Collaborator Author

ProgramMax commented Jan 29, 2025

One thing to note is different enum values might require additional data.
For example, the proposal for adding gain maps #380 includes data for HDR headroom, min & max values, etc.

We could add yet another chunk that describes these descriptors. That's a bit meta.
But that would be extendable.

As proposed, the iEId chunk is parseable even if a decoder only knows about the some of the enum values. Future enum values do not break it.

If we add something like "after the enum list, the next 8 bytes give extra info for the first channel, then 4 bytes give extra info for the second channel..." we might run into a problem where 8 bytes wasn't enough. So the original 8 byte's meanings would need to stay and we would just append more bytes to the end as things change.

Bottom line: This is not yet sufficient for gain maps. We need a way to provide extra data. Later, I'll think about if we need extra data per iEId or per channel. We might need both. Either way, when we add an enum value to the list (like adding gain maps) we'll need to consider all the data needed for that enum value and specify it.

@leo-barnes
Copy link

It sounds like you envision having one iEId chunk per iEXt chunk. If so, what's the problem with simply having a variable length data blob at the end of the iEId chunk? That data blob can contain any supplementary metadata that might be required, like the gain map metadata.

@leo-barnes
Copy link

Depending on how extensible you want to make this (i.e. who can add new types, only PNG spec or anyone), you might want to take inspiration from HEIF.

Rather than making it an enum, you could make the chunk:

  • ID
  • width
  • height
  • bit depth
  • compression method
  • filter method
  • interlace method
  • Aux type URI
  • Supplementary metadata payload

The aux type URI identifies the type of the auxiliary image. The PNG spec can define some specific types that are more well-defined, but it's also possible for 3rd parties to embed their own fully proprietary auxiliary images, for example by using the Tag URI scheme or by using a URL that points to some documentation of the payload.

21496-1 for example already defines a URI to be used if you need to identify something as a gain map, so you could simply point to that as being the URI to use for that specific use-case.

@ProgramMax
Copy link
Collaborator Author

I think we will need the arbitrary data blob, which will be defined per enum/URI.

I considered including some version information. For example, maybe we include gain map v1 data but later there is a gain map v2. We could make that a separate enum/URI. But then a decoder that understands v1 won't benefit even if it is backwards compatible. So for that case, we could version the data blob.

However, for it to be backward compatible it would need to specify all the v1 data anyway. So I think we can use the size as a versioning mechanism.

Suppose gain maps v1 are 10 bytes and v2 adds 5 bytes. So long as we append new data to the end, the original 10 bytes remain backwards compatible.

I think that is the way forward. But I'm still thinking about alternatives.

As far as enum vs. URI, I don't know enough yet to have good feedback. Seems reasonable. Compatibility with HEIF sounds good.

@leo-barnes
Copy link

As far as enum vs. URI, I don't know enough yet to have good feedback. Seems reasonable. Compatibility with HEIF sounds good.

An enum is tricky when it comes to self-registration without collisions, I can't see how it would work without the PNG WG handling registrations. For URI's there are already defined ways of doing that

  • Each URN namespace has a defined registration process
  • URLs are URLs :)
  • The tag URI scheme can be used for self-registration with reasonably low risk of collision

So I guess it comes down to whether the PNG WG wants to handle registration, or whether registration via some other process/group is allowed or not.

@ProgramMax
Copy link
Collaborator Author

Currently, the candidate for the other chunk's name is "aDAt". If that name holds, this chunk should perhaps be named "aDId" to match.

@fintelia
Copy link

fintelia commented Feb 3, 2025

Another intermediate option would be to have the just array of enum values in this chunk and then anything that needs more metadata could add additional chunks. That would mirror how the IHDR / IDAT contain the basic info about the pixel data, but there's other metadata describing exactly what RGB values mean.

I'd also strongly argue for a centrally defined list of enums values rather than URLs. That's the direction that CICP went, and arguably, that's how the chunk types work as well

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