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

Significantly simplify gain map API #2481

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

maryla-uc
Copy link
Collaborator

  • Remove enableParsingGainMapMetadata: gain map metadata is always parsed now
  • Replace enableDecodingGainMap and ignoreColorAndAlpha with imageContentToDecode bit field
  • Remove gainMapPresent, the same information is available by checking decoder->image->gainMap != NULL

Gain map metadata is now alwayas parsed (when gain map code is enabled
at compile time).

Ideally, gain map metadata should be stored towards the beginning of the file
(since it's in the 'mdat' part).
It can be replaced with a check that image->gainMap is not NULL.
Copy link
Collaborator

@wantehchang wantehchang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maryla: Thanks a lot for the pull request! I only reviewed the changes to avif.h. Please see my comments in CHANGLOG.md and at avif.h:1182.

AVIF_CONTENT_ALL = AVIF_CONTENT_COLOR | AVIF_CONTENT_ALPHA,
#endif

AVIF_CONTENT_DECODE_DEFAULT = AVIF_CONTENT_COLOR | AVIF_CONTENT_ALPHA,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: DECODE can be omitted, unless we are planning to add AVIF_CONTENT_ENCODE_DEFAULT in the future.

// Types of image content that can be encoded/decoded.
typedef enum avifImageContentTypeFlag
{
AVIF_CONTENT_NONE = 0,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I suggest adding IMAGE to the enum constant names, i.e., AVIF_IMAGE_CONTENT_NONE, AVIF_IMAGE_CONTENT_COLOR, etc., to match the enum type name avifImageContentTypeFlag.

// the gain map's planes can also be accessed in the same way. If the gain map's height is different from
// the main image, then the number of available gain map rows is at least:
// If a gain map is present and AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP is on and
// (imageContentToDecode & AVIF_CONTENT_GAIN_MAP) is non zero, the gain map's planes can also be accessed
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: non zero => nonzero

@@ -55,7 +54,7 @@ avifResult PrintMetadataCommand::Run() {
<< decoder->diag.error << ")\n";
return result;
}
if (!decoder->gainMapPresent) {
if (decoder->image->gainMap == nullptr) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We can change NULL (e.g., at line 41) to nullptr in a separate pull request. Also check the other .cc files in this directory.

{
AVIF_CONTENT_NONE = 0,
AVIF_CONTENT_COLOR = (1 << 1),
AVIF_CONTENT_ALPHA = (1 << 2),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMPORTANT: These two enum constants are more expressive than the original ignoreColorAndAlpha boolean. I'd like to confirm with you that this is intended.

Note: ignoreColorAndAlpha is equivalent to AVIF_CONTENT_COLOR | AVIF_CONTENT_ALPHA. If we only want to match ignoreColorAndAlpha exactly, these two enum contants should be merge into AVIF_CONTENT_COLOR_AND_ALPHA.

If this is intended, we need to do the following:

  1. Inspect the API functions that take avifImage as input and make sure that they can handle an avifImage in which yuvPlanes[i] are all null but alphaPlane is not null. I took a quick look and found that most of them already handle a null yuvPlanes[[AVIF_CHAN_Y] properly. But avifImagePlaneWitdh() and avifImagePlaneHeight() probably should return 0 if image->yuvPlanes[channel] is null.
  2. Then add a test for decoder->imageContentToDecode == AVIF_CONTENT_ALPHA. Verify decoder->image->yuvPlanes[i] are all null and decoder->image->yuvRowBytes[i] are all zero, and call some API functions on decoder->image.

@@ -1174,6 +1174,23 @@ typedef enum avifProgressiveState
} avifProgressiveState;
AVIF_API const char * avifProgressiveStateToString(avifProgressiveState progressiveState);

// Types of image content that can be encoded/decoded.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: It seems that this enum type is only applicable to decoding. The encoder probably should encode all the image content in the input avifImage. See also my comment at line 1190.

The `gainMapPresent` field is now only populated if enableParsingGainMapMetadata
is true.
Simplify gain map API: remove the enableParsingGainMapMetadata setting, now gain
map metadata is always parsed if present and if this feature is compiled in.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since gain map metadata is always parsed if present, we should write gain map metadata early in the file.

In src/write.c, we have

static avifResult avifEncoderWriteMediaDataBox(avifEncoder * encoder,
                                               avifRWStream * s,
                                               avifEncoderItemReferenceArray * layeredColorItems,
                                               avifEncoderItemReferenceArray * layeredAlphaItems)
{
    ...
    for (uint32_t itemPasses = 0; itemPasses < 3; ++itemPasses) {
        // Use multiple passes to pack in the following order:
        //   * Pass 0: metadata (Exif/XMP)
        //   * Pass 1: alpha, gain map (AV1)
        //   * Pass 2: all other item data (AV1 color)

Should we move gain map from Pass 1 to Pass 0 or even a new pass before the current Pass 0?

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

Successfully merging this pull request may close these issues.

2 participants