// Copyright 2019 Joe Drago. All rights reserved.
// SPDX-License-Identifier: BSD-2-Clause

#include "avif/internal.h"

#include <assert.h>
#include <ctype.h>
#include <inttypes.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <string.h>

#define AUXTYPE_SIZE 64
#define CONTENTTYPE_SIZE 64

// class VisualSampleEntry(codingname) extends SampleEntry(codingname) {
//     unsigned int(16) pre_defined = 0;
//     const unsigned int(16) reserved = 0;
//     unsigned int(32)[3] pre_defined = 0;
//     unsigned int(16) width;
//     unsigned int(16) height;
//     template unsigned int(32) horizresolution = 0x00480000; // 72 dpi
//     template unsigned int(32) vertresolution = 0x00480000;  // 72 dpi
//     const unsigned int(32) reserved = 0;
//     template unsigned int(16) frame_count = 1;
//     string[32] compressorname;
//     template unsigned int(16) depth = 0x0018;
//     int(16) pre_defined = -1;
//     // other boxes from derived specifications
//     CleanApertureBox clap;    // optional
//     PixelAspectRatioBox pasp; // optional
// }
static const size_t VISUALSAMPLEENTRY_SIZE = 78;

// The only supported ipma box values for both version and flags are [0,1], so there technically
// can't be more than 4 unique tuples right now.
#define MAX_IPMA_VERSION_AND_FLAGS_SEEN 4

// ---------------------------------------------------------------------------
// AVIF codec type (AV1 or AV2)

static avifCodecType avifGetCodecType(const uint8_t * fourcc)
{
    if (!memcmp(fourcc, "av01", 4)) {
        return AVIF_CODEC_TYPE_AV1;
    }
#if defined(AVIF_CODEC_AVM)
    if (!memcmp(fourcc, "av02", 4)) {
        return AVIF_CODEC_TYPE_AV2;
    }
#endif
    return AVIF_CODEC_TYPE_UNKNOWN;
}

static const char * avifGetConfigurationPropertyName(avifCodecType codecType)
{
    switch (codecType) {
        case AVIF_CODEC_TYPE_AV1:
            return "av1C";
#if defined(AVIF_CODEC_AVM)
        case AVIF_CODEC_TYPE_AV2:
            return "av2C";
#endif
        default:
            assert(AVIF_FALSE);
            return NULL;
    }
}

// ---------------------------------------------------------------------------
// Box data structures

typedef uint8_t avifBrand[4];
AVIF_ARRAY_DECLARE(avifBrandArray, avifBrand, brand);

// ftyp
typedef struct avifFileType
{
    uint8_t majorBrand[4];
    uint8_t minorVersion[4];
    // If not null, points to a memory block of 4 * compatibleBrandsCount bytes.
    const uint8_t * compatibleBrands;
    int compatibleBrandsCount;
} avifFileType;

// ispe
typedef struct avifImageSpatialExtents
{
    uint32_t width;
    uint32_t height;
} avifImageSpatialExtents;

// auxC
typedef struct avifAuxiliaryType
{
    char auxType[AUXTYPE_SIZE];
} avifAuxiliaryType;

// infe mime content_type
typedef struct avifContentType
{
    char contentType[CONTENTTYPE_SIZE];
} avifContentType;

// colr
typedef struct avifColourInformationBox
{
    avifBool hasICC;
    uint64_t iccOffset;
    size_t iccSize;

    avifBool hasNCLX;
    avifColorPrimaries colorPrimaries;
    avifTransferCharacteristics transferCharacteristics;
    avifMatrixCoefficients matrixCoefficients;
    avifRange range;
} avifColourInformationBox;

#define MAX_PIXI_PLANE_DEPTHS 4
typedef struct avifPixelInformationProperty
{
    uint8_t planeDepths[MAX_PIXI_PLANE_DEPTHS];
    uint8_t planeCount;
} avifPixelInformationProperty;

typedef struct avifOperatingPointSelectorProperty
{
    uint8_t opIndex;
} avifOperatingPointSelectorProperty;

typedef struct avifLayerSelectorProperty
{
    uint16_t layerID;
} avifLayerSelectorProperty;

typedef struct avifAV1LayeredImageIndexingProperty
{
    uint32_t layerSize[3];
} avifAV1LayeredImageIndexingProperty;

// ---------------------------------------------------------------------------
// Top-level structures

struct avifMeta;

// Temporary storage for ipco/stsd contents until they can be associated and memcpy'd to an avifDecoderItem
typedef struct avifProperty
{
    uint8_t type[4];
    union
    {
        avifImageSpatialExtents ispe;
        avifAuxiliaryType auxC;
        avifColourInformationBox colr;
        avifCodecConfigurationBox av1C; // TODO(yguyon): Rename or add av2C
        avifPixelAspectRatioBox pasp;
        avifCleanApertureBox clap;
        avifImageRotation irot;
        avifImageMirror imir;
        avifPixelInformationProperty pixi;
        avifOperatingPointSelectorProperty a1op;
        avifLayerSelectorProperty lsel;
        avifAV1LayeredImageIndexingProperty a1lx;
        avifContentLightLevelInformationBox clli;
    } u;
} avifProperty;
AVIF_ARRAY_DECLARE(avifPropertyArray, avifProperty, prop);

// Finds the first property of a given type.
static const avifProperty * avifPropertyArrayFind(const avifPropertyArray * properties, const char * type)
{
    for (uint32_t propertyIndex = 0; propertyIndex < properties->count; ++propertyIndex) {
        const avifProperty * prop = &properties->prop[propertyIndex];
        if (!memcmp(prop->type, type, 4)) {
            return prop;
        }
    }
    return NULL;
}

AVIF_ARRAY_DECLARE(avifExtentArray, avifExtent, extent);

// one "item" worth for decoding (all iref, iloc, iprp, etc refer to one of these)
typedef struct avifDecoderItem
{
    uint32_t id;
    struct avifMeta * meta; // Unowned; A back-pointer for convenience
    uint8_t type[4];
    size_t size;
    avifBool idatStored; // If true, offset is relative to the associated meta box's idat box (iloc construction_method==1)
    uint32_t width;      // Set from this item's ispe property, if present
    uint32_t height;     // Set from this item's ispe property, if present
    avifContentType contentType;
    avifPropertyArray properties;
    avifExtentArray extents;       // All extent offsets/sizes
    avifRWData mergedExtents;      // if set, is a single contiguous block of this item's extents (unused when extents.count == 1)
    avifBool ownsMergedExtents;    // if true, mergedExtents must be freed when this item is destroyed
    avifBool partialMergedExtents; // If true, mergedExtents doesn't have all of the item data yet
    uint32_t thumbnailForID;       // if non-zero, this item is a thumbnail for Item #{thumbnailForID}
    uint32_t auxForID;             // if non-zero, this item is an auxC plane for Item #{auxForID}
    uint32_t descForID;            // if non-zero, this item is a content description for Item #{descForID}
    uint32_t dimgForID;            // if non-zero, this item is an input of derived Item #{dimgForID}
    uint32_t dimgIdx; // If dimgForId is non-zero, this is the zero-based index of this item in the list of Item #{dimgForID}'s dimg.
    avifBool hasDimgFrom; // whether there is a 'dimg' box with this item's id as 'fromID'
    uint32_t premByID;    // if non-zero, this item is premultiplied by Item #{premByID}
    avifBool hasUnsupportedEssentialProperty; // If true, this item cites a property flagged as 'essential' that libavif doesn't support (yet). Ignore the item, if so.
    avifBool ipmaSeen;    // if true, this item already received a property association
    avifBool progressive; // if true, this item has progressive layers (a1lx), but does not select a specific layer (the layer_id value in lsel is set to 0xFFFF)
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
    avifPixelFormat miniBoxPixelFormat; // Set from the MinimizedImageBox, if present (AVIF_PIXEL_FORMAT_NONE otherwise)
    avifChromaSamplePosition miniBoxChromaSamplePosition; // Set from the MinimizedImageBox, if present (AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN otherwise)
#endif
} avifDecoderItem;
AVIF_ARRAY_DECLARE(avifDecoderItemArray, avifDecoderItem *, item);

// grid storage
typedef struct avifImageGrid
{
    uint32_t rows;    // Legal range: [1-256]
    uint32_t columns; // Legal range: [1-256]
    uint32_t outputWidth;
    uint32_t outputHeight;
} avifImageGrid;

// ---------------------------------------------------------------------------
// avifTrack

typedef struct avifSampleTableChunk
{
    uint64_t offset;
} avifSampleTableChunk;
AVIF_ARRAY_DECLARE(avifSampleTableChunkArray, avifSampleTableChunk, chunk);

typedef struct avifSampleTableSampleToChunk
{
    uint32_t firstChunk;
    uint32_t samplesPerChunk;
    uint32_t sampleDescriptionIndex;
} avifSampleTableSampleToChunk;
AVIF_ARRAY_DECLARE(avifSampleTableSampleToChunkArray, avifSampleTableSampleToChunk, sampleToChunk);

typedef struct avifSampleTableSampleSize
{
    uint32_t size;
} avifSampleTableSampleSize;
AVIF_ARRAY_DECLARE(avifSampleTableSampleSizeArray, avifSampleTableSampleSize, sampleSize);

typedef struct avifSampleTableTimeToSample
{
    uint32_t sampleCount;
    uint32_t sampleDelta;
} avifSampleTableTimeToSample;
AVIF_ARRAY_DECLARE(avifSampleTableTimeToSampleArray, avifSampleTableTimeToSample, timeToSample);

typedef struct avifSyncSample
{
    uint32_t sampleNumber;
} avifSyncSample;
AVIF_ARRAY_DECLARE(avifSyncSampleArray, avifSyncSample, syncSample);

typedef struct avifSampleDescription
{
    uint8_t format[4];
    avifPropertyArray properties;
} avifSampleDescription;
AVIF_ARRAY_DECLARE(avifSampleDescriptionArray, avifSampleDescription, description);

typedef struct avifSampleTable
{
    avifSampleTableChunkArray chunks;
    avifSampleDescriptionArray sampleDescriptions;
    avifSampleTableSampleToChunkArray sampleToChunks;
    avifSampleTableSampleSizeArray sampleSizes;
    avifSampleTableTimeToSampleArray timeToSamples;
    avifSyncSampleArray syncSamples;
    uint32_t allSamplesSize; // If this is non-zero, sampleSizes will be empty and all samples will be this size
} avifSampleTable;

static void avifSampleTableDestroy(avifSampleTable * sampleTable);

static avifSampleTable * avifSampleTableCreate(void)
{
    avifSampleTable * sampleTable = (avifSampleTable *)avifAlloc(sizeof(avifSampleTable));
    if (sampleTable == NULL) {
        return NULL;
    }
    memset(sampleTable, 0, sizeof(avifSampleTable));
    if (!avifArrayCreate(&sampleTable->chunks, sizeof(avifSampleTableChunk), 16) ||
        !avifArrayCreate(&sampleTable->sampleDescriptions, sizeof(avifSampleDescription), 2) ||
        !avifArrayCreate(&sampleTable->sampleToChunks, sizeof(avifSampleTableSampleToChunk), 16) ||
        !avifArrayCreate(&sampleTable->sampleSizes, sizeof(avifSampleTableSampleSize), 16) ||
        !avifArrayCreate(&sampleTable->timeToSamples, sizeof(avifSampleTableTimeToSample), 16) ||
        !avifArrayCreate(&sampleTable->syncSamples, sizeof(avifSyncSample), 16)) {
        avifSampleTableDestroy(sampleTable);
        return NULL;
    }
    return sampleTable;
}

static void avifSampleTableDestroy(avifSampleTable * sampleTable)
{
    avifArrayDestroy(&sampleTable->chunks);
    for (uint32_t i = 0; i < sampleTable->sampleDescriptions.count; ++i) {
        avifSampleDescription * description = &sampleTable->sampleDescriptions.description[i];
        avifArrayDestroy(&description->properties);
    }
    avifArrayDestroy(&sampleTable->sampleDescriptions);
    avifArrayDestroy(&sampleTable->sampleToChunks);
    avifArrayDestroy(&sampleTable->sampleSizes);
    avifArrayDestroy(&sampleTable->timeToSamples);
    avifArrayDestroy(&sampleTable->syncSamples);
    avifFree(sampleTable);
}

static uint32_t avifSampleTableGetImageDelta(const avifSampleTable * sampleTable, uint32_t imageIndex)
{
    uint32_t maxSampleIndex = 0;
    for (uint32_t i = 0; i < sampleTable->timeToSamples.count; ++i) {
        const avifSampleTableTimeToSample * timeToSample = &sampleTable->timeToSamples.timeToSample[i];
        maxSampleIndex += timeToSample->sampleCount;
        if ((imageIndex < maxSampleIndex) || (i == (sampleTable->timeToSamples.count - 1))) {
            return timeToSample->sampleDelta;
        }
    }

    // TODO: fail here?
    return 1;
}

static avifCodecType avifSampleTableGetCodecType(const avifSampleTable * sampleTable)
{
    for (uint32_t i = 0; i < sampleTable->sampleDescriptions.count; ++i) {
        const avifCodecType codecType = avifGetCodecType(sampleTable->sampleDescriptions.description[i].format);
        if (codecType != AVIF_CODEC_TYPE_UNKNOWN) {
            return codecType;
        }
    }
    return AVIF_CODEC_TYPE_UNKNOWN;
}

static uint32_t avifCodecConfigurationBoxGetDepth(const avifCodecConfigurationBox * av1C)
{
    if (av1C->twelveBit) {
        return 12;
    } else if (av1C->highBitdepth) {
        return 10;
    }
    return 8;
}

// This is used as a hint to validating the clap box in avifDecoderItemValidateProperties.
static avifPixelFormat avifCodecConfigurationBoxGetFormat(const avifCodecConfigurationBox * av1C)
{
    if (av1C->monochrome) {
        return AVIF_PIXEL_FORMAT_YUV400;
    } else if (av1C->chromaSubsamplingY == 1) {
        return AVIF_PIXEL_FORMAT_YUV420;
    } else if (av1C->chromaSubsamplingX == 1) {
        return AVIF_PIXEL_FORMAT_YUV422;
    }
    return AVIF_PIXEL_FORMAT_YUV444;
}

static const avifPropertyArray * avifSampleTableGetProperties(const avifSampleTable * sampleTable, avifCodecType codecType)
{
    for (uint32_t i = 0; i < sampleTable->sampleDescriptions.count; ++i) {
        const avifSampleDescription * description = &sampleTable->sampleDescriptions.description[i];
        if (avifGetCodecType(description->format) == codecType) {
            return &description->properties;
        }
    }
    return NULL;
}

// one video track ("trak" contents)
typedef struct avifTrack
{
    uint32_t id;
    uint32_t auxForID; // if non-zero, this track is an auxC plane for Track #{auxForID}
    uint32_t premByID; // if non-zero, this track is premultiplied by Track #{premByID}
    uint32_t mediaTimescale;
    uint64_t mediaDuration;
    uint64_t trackDuration;
    uint64_t segmentDuration;
    avifBool isRepeating;
    int repetitionCount;
    uint32_t width;
    uint32_t height;
    avifSampleTable * sampleTable;
    struct avifMeta * meta;
} avifTrack;
AVIF_ARRAY_DECLARE(avifTrackArray, avifTrack, track);

// ---------------------------------------------------------------------------
// avifCodecDecodeInput

avifCodecDecodeInput * avifCodecDecodeInputCreate(void)
{
    avifCodecDecodeInput * decodeInput = (avifCodecDecodeInput *)avifAlloc(sizeof(avifCodecDecodeInput));
    if (decodeInput == NULL) {
        return NULL;
    }
    memset(decodeInput, 0, sizeof(avifCodecDecodeInput));
    if (!avifArrayCreate(&decodeInput->samples, sizeof(avifDecodeSample), 1)) {
        avifFree(decodeInput);
        return NULL;
    }
    return decodeInput;
}

void avifCodecDecodeInputDestroy(avifCodecDecodeInput * decodeInput)
{
    for (uint32_t sampleIndex = 0; sampleIndex < decodeInput->samples.count; ++sampleIndex) {
        avifDecodeSample * sample = &decodeInput->samples.sample[sampleIndex];
        if (sample->ownsData) {
            avifRWDataFree((avifRWData *)&sample->data);
        }
    }
    avifArrayDestroy(&decodeInput->samples);
    avifFree(decodeInput);
}

// Returns how many samples are in the chunk.
static uint32_t avifGetSampleCountOfChunk(const avifSampleTableSampleToChunkArray * sampleToChunks, uint32_t chunkIndex)
{
    uint32_t sampleCount = 0;
    for (int sampleToChunkIndex = sampleToChunks->count - 1; sampleToChunkIndex >= 0; --sampleToChunkIndex) {
        const avifSampleTableSampleToChunk * sampleToChunk = &sampleToChunks->sampleToChunk[sampleToChunkIndex];
        if (sampleToChunk->firstChunk <= (chunkIndex + 1)) {
            sampleCount = sampleToChunk->samplesPerChunk;
            break;
        }
    }
    return sampleCount;
}

static avifResult avifCodecDecodeInputFillFromSampleTable(avifCodecDecodeInput * decodeInput,
                                                          avifSampleTable * sampleTable,
                                                          const uint32_t imageCountLimit,
                                                          const uint64_t sizeHint,
                                                          avifDiagnostics * diag)
{
    if (imageCountLimit) {
        // Verify that the we're not about to exceed the frame count limit.

        uint32_t imageCountLeft = imageCountLimit;
        for (uint32_t chunkIndex = 0; chunkIndex < sampleTable->chunks.count; ++chunkIndex) {
            // First, figure out how many samples are in this chunk
            uint32_t sampleCount = avifGetSampleCountOfChunk(&sampleTable->sampleToChunks, chunkIndex);
            if (sampleCount == 0) {
                // chunks with 0 samples are invalid
                avifDiagnosticsPrintf(diag, "Sample table contains a chunk with 0 samples");
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }

            if (sampleCount > imageCountLeft) {
                // This file exceeds the imageCountLimit, bail out
                avifDiagnosticsPrintf(diag, "Exceeded avifDecoder's imageCountLimit");
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            imageCountLeft -= sampleCount;
        }
    }

    uint32_t sampleSizeIndex = 0;
    for (uint32_t chunkIndex = 0; chunkIndex < sampleTable->chunks.count; ++chunkIndex) {
        avifSampleTableChunk * chunk = &sampleTable->chunks.chunk[chunkIndex];

        // First, figure out how many samples are in this chunk
        uint32_t sampleCount = avifGetSampleCountOfChunk(&sampleTable->sampleToChunks, chunkIndex);
        if (sampleCount == 0) {
            // chunks with 0 samples are invalid
            avifDiagnosticsPrintf(diag, "Sample table contains a chunk with 0 samples");
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }

        uint64_t sampleOffset = chunk->offset;
        for (uint32_t sampleIndex = 0; sampleIndex < sampleCount; ++sampleIndex) {
            uint32_t sampleSize = sampleTable->allSamplesSize;
            if (sampleSize == 0) {
                if (sampleSizeIndex >= sampleTable->sampleSizes.count) {
                    // We've run out of samples to sum
                    avifDiagnosticsPrintf(diag, "Truncated sample table");
                    return AVIF_RESULT_BMFF_PARSE_FAILED;
                }
                avifSampleTableSampleSize * sampleSizePtr = &sampleTable->sampleSizes.sampleSize[sampleSizeIndex];
                sampleSize = sampleSizePtr->size;
            }

            avifDecodeSample * sample = (avifDecodeSample *)avifArrayPush(&decodeInput->samples);
            AVIF_CHECKERR(sample != NULL, AVIF_RESULT_OUT_OF_MEMORY);
            sample->offset = sampleOffset;
            sample->size = sampleSize;
            sample->spatialID = AVIF_SPATIAL_ID_UNSET; // Not filtering by spatial_id
            sample->sync = AVIF_FALSE;                 // to potentially be set to true following the outer loop

            if (sampleSize > UINT64_MAX - sampleOffset) {
                avifDiagnosticsPrintf(diag,
                                      "Sample table contains an offset/size pair which overflows: [%" PRIu64 " / %u]",
                                      sampleOffset,
                                      sampleSize);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            if (sizeHint && ((sampleOffset + sampleSize) > sizeHint)) {
                avifDiagnosticsPrintf(diag, "Exceeded avifIO's sizeHint, possibly truncated data");
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }

            sampleOffset += sampleSize;
            ++sampleSizeIndex;
        }
    }

    // Mark appropriate samples as sync
    for (uint32_t syncSampleIndex = 0; syncSampleIndex < sampleTable->syncSamples.count; ++syncSampleIndex) {
        uint32_t frameIndex = sampleTable->syncSamples.syncSample[syncSampleIndex].sampleNumber - 1; // sampleNumber is 1-based
        if (frameIndex < decodeInput->samples.count) {
            decodeInput->samples.sample[frameIndex].sync = AVIF_TRUE;
        }
    }

    // Assume frame 0 is sync, just in case the stss box is absent in the BMFF. (Unnecessary?)
    if (decodeInput->samples.count > 0) {
        decodeInput->samples.sample[0].sync = AVIF_TRUE;
    }
    return AVIF_RESULT_OK;
}

static avifResult avifCodecDecodeInputFillFromDecoderItem(avifCodecDecodeInput * decodeInput,
                                                          avifDecoderItem * item,
                                                          avifBool allowProgressive,
                                                          const uint32_t imageCountLimit,
                                                          const uint64_t sizeHint,
                                                          avifDiagnostics * diag)
{
    if (sizeHint && (item->size > sizeHint)) {
        avifDiagnosticsPrintf(diag, "Exceeded avifIO's sizeHint, possibly truncated data");
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }

    uint8_t layerCount = 0;
    size_t layerSizes[4] = { 0 };
    const avifProperty * a1lxProp = avifPropertyArrayFind(&item->properties, "a1lx");
    if (a1lxProp) {
        // Calculate layer count and all layer sizes from the a1lx box, and then validate

        size_t remainingSize = item->size;
        for (int i = 0; i < 3; ++i) {
            ++layerCount;

            const size_t layerSize = (size_t)a1lxProp->u.a1lx.layerSize[i];
            if (layerSize) {
                if (layerSize >= remainingSize) { // >= instead of > because there must be room for the last layer
                    avifDiagnosticsPrintf(diag, "a1lx layer index [%d] does not fit in item size", i);
                    return AVIF_RESULT_BMFF_PARSE_FAILED;
                }
                layerSizes[i] = layerSize;
                remainingSize -= layerSize;
            } else {
                layerSizes[i] = remainingSize;
                remainingSize = 0;
                break;
            }
        }
        if (remainingSize > 0) {
            AVIF_ASSERT_OR_RETURN(layerCount == 3);
            ++layerCount;
            layerSizes[3] = remainingSize;
        }
    }

    const avifProperty * lselProp = avifPropertyArrayFind(&item->properties, "lsel");
    // Progressive images offer layers via the a1lxProp, but don't specify a layer selection with lsel.
    //
    // For backward compatibility with earlier drafts of AVIF spec v1.1.0, treat an absent lsel as
    // equivalent to layer_id == 0xFFFF during the transitional period. Remove !lselProp when the test
    // images have been updated to the v1.1.0 spec.
    item->progressive = (a1lxProp && (!lselProp || (lselProp->u.lsel.layerID == 0xFFFF)));
    if (lselProp && (lselProp->u.lsel.layerID != 0xFFFF)) {
        // Layer selection. This requires that the underlying AV1 codec decodes all layers,
        // and then only returns the requested layer as a single frame. To the user of libavif,
        // this appears to be a single frame.

        decodeInput->allLayers = AVIF_TRUE;

        size_t sampleSize = 0;
        if (layerCount > 0) {
            // Optimization: If we're selecting a layer that doesn't require the entire image's payload (hinted via the a1lx box)

            if (lselProp->u.lsel.layerID >= layerCount) {
                avifDiagnosticsPrintf(diag,
                                      "lsel property requests layer index [%u] which isn't present in a1lx property ([%u] layers)",
                                      lselProp->u.lsel.layerID,
                                      layerCount);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }

            for (uint8_t i = 0; i <= lselProp->u.lsel.layerID; ++i) {
                sampleSize += layerSizes[i];
            }
        } else {
            // This layer's payload subsection is unknown, just use the whole payload
            sampleSize = item->size;
        }

        avifDecodeSample * sample = (avifDecodeSample *)avifArrayPush(&decodeInput->samples);
        AVIF_CHECKERR(sample != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        sample->itemID = item->id;
        sample->offset = 0;
        sample->size = sampleSize;
        AVIF_ASSERT_OR_RETURN(lselProp->u.lsel.layerID < AVIF_MAX_AV1_LAYER_COUNT);
        sample->spatialID = (uint8_t)lselProp->u.lsel.layerID;
        sample->sync = AVIF_TRUE;
    } else if (allowProgressive && item->progressive) {
        // Progressive image. Decode all layers and expose them all to the user.

        if (imageCountLimit && (layerCount > imageCountLimit)) {
            avifDiagnosticsPrintf(diag, "Exceeded avifDecoder's imageCountLimit (progressive)");
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }

        decodeInput->allLayers = AVIF_TRUE;

        size_t offset = 0;
        for (int i = 0; i < layerCount; ++i) {
            avifDecodeSample * sample = (avifDecodeSample *)avifArrayPush(&decodeInput->samples);
            AVIF_CHECKERR(sample != NULL, AVIF_RESULT_OUT_OF_MEMORY);
            sample->itemID = item->id;
            sample->offset = offset;
            sample->size = layerSizes[i];
            sample->spatialID = AVIF_SPATIAL_ID_UNSET;
            sample->sync = (i == 0); // Assume all layers depend on the first layer

            offset += layerSizes[i];
        }
    } else {
        // Typical case: Use the entire item's payload for a single frame output

        avifDecodeSample * sample = (avifDecodeSample *)avifArrayPush(&decodeInput->samples);
        AVIF_CHECKERR(sample != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        sample->itemID = item->id;
        sample->offset = 0;
        sample->size = item->size;
        sample->spatialID = AVIF_SPATIAL_ID_UNSET;
        sample->sync = AVIF_TRUE;
    }
    return AVIF_RESULT_OK;
}

// ---------------------------------------------------------------------------
// Helper macros / functions

#define BEGIN_STREAM(VARNAME, PTR, SIZE, DIAG, CONTEXT) \
    avifROStream VARNAME;                               \
    avifROData VARNAME##_roData;                        \
    VARNAME##_roData.data = PTR;                        \
    VARNAME##_roData.size = SIZE;                       \
    avifROStreamStart(&VARNAME, &VARNAME##_roData, DIAG, CONTEXT)

// Use this to keep track of whether or not a child box that must be unique (0 or 1 present) has
// been seen yet, when parsing a parent box. If the "seen" bit is already set for a given box when
// it is encountered during parse, an error is thrown. Which bit corresponds to which box is
// dictated entirely by the calling function.
static avifBool uniqueBoxSeen(uint32_t * uniqueBoxFlags, uint32_t whichFlag, const char * parentBoxType, const char * boxType, avifDiagnostics * diagnostics)
{
    const uint32_t flag = 1 << whichFlag;
    if (*uniqueBoxFlags & flag) {
        // This box has already been seen. Error!
        avifDiagnosticsPrintf(diagnostics, "Box[%s] contains a duplicate unique box of type '%s'", parentBoxType, boxType);
        return AVIF_FALSE;
    }

    // Mark this box as seen.
    *uniqueBoxFlags |= flag;
    return AVIF_TRUE;
}

// ---------------------------------------------------------------------------
// avifDecoderData

typedef struct avifTile
{
    avifCodecDecodeInput * input;
    avifCodecType codecType;
    // This may point to a codec that it owns or point to a shared codec that it does not own. In the shared case, this will
    // point to one of the avifCodec instances in avifDecoderData.
    struct avifCodec * codec;
    avifImage * image;
    uint32_t width;  // Either avifTrack.width or avifDecoderItem.width
    uint32_t height; // Either avifTrack.height or avifDecoderItem.height
    uint8_t operatingPoint;
} avifTile;
AVIF_ARRAY_DECLARE(avifTileArray, avifTile, tile);

// This holds one "meta" box (from the BMFF and HEIF standards) worth of relevant-to-AVIF information.
// * If a meta box is parsed from the root level of the BMFF, it can contain the information about
//   "items" which might be color planes, alpha planes, or EXIF or XMP metadata.
// * If a meta box is parsed from inside of a track ("trak") box, any metadata (EXIF/XMP) items inside
//   of that box are implicitly associated with that track.
typedef struct avifMeta
{
    // Items (from HEIF) are the generic storage for any data that does not require timed processing
    // (single image color planes, alpha planes, EXIF, XMP, etc). Each item has a unique integer ID >1,
    // and is defined by a series of child boxes in a meta box:
    //  * iloc - location:     byte offset to item data, item size in bytes
    //  * iinf - information:  type of item (color planes, alpha plane, EXIF, XMP)
    //  * ipco - properties:   dimensions, aspect ratio, image transformations, references to other items
    //  * ipma - associations: Attaches an item in the properties list to a given item
    //
    // Items are lazily created in this array when any of the above boxes refer to one by a new (unseen) ID,
    // and are then further modified/updated as new information for an item's ID is parsed.
    avifDecoderItemArray items;

    // Any ipco boxes explained above are populated into this array as a staging area, which are
    // then duplicated into the appropriate items upon encountering an item property association
    // (ipma) box.
    avifPropertyArray properties;

    // Filled with the contents of this meta box's "idat" box, which is raw data that an item can
    // directly refer to in its item location box (iloc) instead of just giving an offset into the
    // overall file. If all items' iloc boxes simply point at an offset/length in the file itself,
    // this buffer will likely be empty.
    avifRWData idat;

    // Ever-incrementing ID for uniquely identifying which 'meta' box contains an idat (when
    // multiple meta boxes exist as BMFF siblings). Each time avifParseMetaBox() is called on an
    // avifMeta struct, this value is incremented. Any time an additional meta box is detected at
    // the same "level" (root level, trak level, etc), this ID helps distinguish which meta box's
    // "idat" is which, as items implicitly reference idat boxes that exist in the same meta
    // box.
    uint32_t idatID;

    // Contents of a pitm box, which signal which of the items in this file is the main image. For
    // AVIF, this should point at an image item containing color planes, and all other items
    // are ignored unless they refer to this item in some way (alpha plane, EXIF/XMP metadata).
    uint32_t primaryItemID;

#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
    // If true, the fields above were extracted from a MinimizedImageBox.
    avifBool fromMiniBox;
#endif

#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
    // Parsed from Sample Transform metadata if present, otherwise empty.
    avifSampleTransformExpression sampleTransformExpression;
    // Bit depth extracted from the pixi property of the Sample Transform derived image item, if any.
    uint32_t sampleTransformDepth;
#endif
} avifMeta;

static void avifMetaDestroy(avifMeta * meta);

static avifMeta * avifMetaCreate(void)
{
    avifMeta * meta = (avifMeta *)avifAlloc(sizeof(avifMeta));
    if (meta == NULL) {
        return NULL;
    }
    memset(meta, 0, sizeof(avifMeta));
    if (!avifArrayCreate(&meta->items, sizeof(avifDecoderItem *), 8) || !avifArrayCreate(&meta->properties, sizeof(avifProperty), 16)) {
        avifMetaDestroy(meta);
        return NULL;
    }
    return meta;
}

static void avifMetaDestroy(avifMeta * meta)
{
    for (uint32_t i = 0; i < meta->items.count; ++i) {
        avifDecoderItem * item = meta->items.item[i];
        avifArrayDestroy(&item->properties);
        avifArrayDestroy(&item->extents);
        if (item->ownsMergedExtents) {
            avifRWDataFree(&item->mergedExtents);
        }
        avifFree(item);
    }
    avifArrayDestroy(&meta->items);
    avifArrayDestroy(&meta->properties);
    avifRWDataFree(&meta->idat);
#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
    avifArrayDestroy(&meta->sampleTransformExpression);
#endif
    avifFree(meta);
}

static avifResult avifCheckItemID(const char * boxFourcc, uint32_t itemID, avifDiagnostics * diag)
{
    if (itemID == 0) {
        avifDiagnosticsPrintf(diag, "Box[%.4s] has an invalid item ID [%u]", boxFourcc, itemID);
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }
    return AVIF_RESULT_OK;
}

static avifResult avifMetaFindOrCreateItem(avifMeta * meta, uint32_t itemID, avifDecoderItem ** item)
{
    *item = NULL;
    AVIF_ASSERT_OR_RETURN(itemID != 0);

    for (uint32_t i = 0; i < meta->items.count; ++i) {
        if (meta->items.item[i]->id == itemID) {
            *item = meta->items.item[i];
            return AVIF_RESULT_OK;
        }
    }

    avifDecoderItem ** itemPtr = (avifDecoderItem **)avifArrayPush(&meta->items);
    AVIF_CHECKERR(itemPtr != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    *item = (avifDecoderItem *)avifAlloc(sizeof(avifDecoderItem));
    if (*item == NULL) {
        avifArrayPop(&meta->items);
        return AVIF_RESULT_OUT_OF_MEMORY;
    }
    memset(*item, 0, sizeof(avifDecoderItem));

    *itemPtr = *item;
    if (!avifArrayCreate(&(*item)->properties, sizeof(avifProperty), 16)) {
        avifFree(*item);
        *item = NULL;
        avifArrayPop(&meta->items);
        return AVIF_RESULT_OUT_OF_MEMORY;
    }
    if (!avifArrayCreate(&(*item)->extents, sizeof(avifExtent), 1)) {
        avifArrayDestroy(&(*item)->properties);
        avifFree(*item);
        *item = NULL;
        avifArrayPop(&meta->items);
        return AVIF_RESULT_OUT_OF_MEMORY;
    }
    (*item)->id = itemID;
    (*item)->meta = meta;
    return AVIF_RESULT_OK;
}

// A group of AVIF tiles in an image item, such as a single tile or a grid of multiple tiles.
typedef struct avifTileInfo
{
    unsigned int tileCount;
    unsigned int decodedTileCount;
    unsigned int firstTileIndex; // Within avifDecoderData.tiles.
    avifImageGrid grid;
} avifTileInfo;

typedef struct avifDecoderData
{
    avifMeta * meta; // The root-level meta box
    avifTrackArray tracks;
    avifTileArray tiles;
    avifTileInfo tileInfos[AVIF_ITEM_CATEGORY_COUNT];
    avifDecoderSource source;
    // When decoding AVIF images with grid, use a single decoder instance for all the tiles instead of creating a decoder instance
    // for each tile. If that is the case, |codec| will be used by all the tiles.
    //
    // There are some edge cases where we will still need multiple decoder instances:
    // * For animated AVIF with alpha, we will need two instances (one for the color planes and one for the alpha plane since they are both
    //   encoded as separate video sequences). In this case, |codec| will be used for the color planes and |codecAlpha| will be
    //   used for the alpha plane.
    // * For grid images with multiple layers. In this case, each tile will need its own decoder instance since there would be
    //   multiple layers in each tile. In this case, |codec| and |codecAlpha| are not used and each tile will have its own
    //   decoder instance.
    // * For grid images where the operating points of all the tiles are not the same. In this case, each tile needs its own
    //   decoder instance (same as above).
    avifCodec * codec;
    avifCodec * codecAlpha;
    uint8_t majorBrand[4];                     // From the file's ftyp, used by AVIF_DECODER_SOURCE_AUTO
    avifBrandArray compatibleBrands;           // From the file's ftyp
    avifDiagnostics * diag;                    // Shallow copy; owned by avifDecoder
    const avifSampleTable * sourceSampleTable; // NULL unless (source == AVIF_DECODER_SOURCE_TRACKS), owned by an avifTrack
    avifBool cicpSet;                          // True if avifDecoder's image has had its CICP set correctly yet.
                                               // This allows nclx colr boxes to override AV1 CICP, as specified in the MIAF
                                               // standard (ISO/IEC 23000-22:2019), section 7.3.6.4:
                                               //   The colour information property takes precedence over any colour information
                                               //   in the image bitstream, i.e. if the property is present, colour information in
                                               //   the bitstream shall be ignored.

#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
    // Remember the dimg association order to the Sample Transform derived image item.
    // Colour items only. The alpha items are implicit.
    uint8_t sampleTransformNumInputImageItems; // At most AVIF_SAMPLE_TRANSFORM_MAX_NUM_INPUT_IMAGE_ITEMS.
    avifItemCategory sampleTransformInputImageItems[AVIF_SAMPLE_TRANSFORM_MAX_NUM_INPUT_IMAGE_ITEMS];
#endif
} avifDecoderData;

static void avifDecoderDataDestroy(avifDecoderData * data);

static avifDecoderData * avifDecoderDataCreate(void)
{
    avifDecoderData * data = (avifDecoderData *)avifAlloc(sizeof(avifDecoderData));
    if (data == NULL) {
        return NULL;
    }
    memset(data, 0, sizeof(avifDecoderData));
    data->meta = avifMetaCreate();
    if (data->meta == NULL || !avifArrayCreate(&data->tracks, sizeof(avifTrack), 2) ||
        !avifArrayCreate(&data->tiles, sizeof(avifTile), 8)) {
        avifDecoderDataDestroy(data);
        return NULL;
    }
    return data;
}

static void avifDecoderDataResetCodec(avifDecoderData * data)
{
    for (unsigned int i = 0; i < data->tiles.count; ++i) {
        avifTile * tile = &data->tiles.tile[i];
        if (tile->image) {
            avifImageFreePlanes(tile->image, AVIF_PLANES_ALL); // forget any pointers into codec image buffers
        }
        if (tile->codec) {
            // Check if tile->codec was created separately and destroy it in that case.
            if (tile->codec != data->codec && tile->codec != data->codecAlpha) {
                avifCodecDestroy(tile->codec);
            }
            tile->codec = NULL;
        }
    }
    for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
        data->tileInfos[c].decodedTileCount = 0;
    }
    if (data->codec) {
        avifCodecDestroy(data->codec);
        data->codec = NULL;
    }
    if (data->codecAlpha) {
        avifCodecDestroy(data->codecAlpha);
        data->codecAlpha = NULL;
    }
}

static avifTile * avifDecoderDataCreateTile(avifDecoderData * data, avifCodecType codecType, uint32_t width, uint32_t height, uint8_t operatingPoint)
{
    avifTile * tile = (avifTile *)avifArrayPush(&data->tiles);
    if (tile == NULL) {
        return NULL;
    }
    tile->codecType = codecType;
    tile->image = avifImageCreateEmpty();
    if (!tile->image) {
        goto error;
    }
    tile->input = avifCodecDecodeInputCreate();
    if (!tile->input) {
        goto error;
    }
    tile->width = width;
    tile->height = height;
    tile->operatingPoint = operatingPoint;
    return tile;

error:
    if (tile->input) {
        avifCodecDecodeInputDestroy(tile->input);
    }
    if (tile->image) {
        avifImageDestroy(tile->image);
    }
    avifArrayPop(&data->tiles);
    return NULL;
}

static avifTrack * avifDecoderDataCreateTrack(avifDecoderData * data)
{
    avifTrack * track = (avifTrack *)avifArrayPush(&data->tracks);
    if (track == NULL) {
        return NULL;
    }
    track->meta = avifMetaCreate();
    if (track->meta == NULL) {
        avifArrayPop(&data->tracks);
        return NULL;
    }
    return track;
}

static void avifDecoderDataClearTiles(avifDecoderData * data)
{
    for (unsigned int i = 0; i < data->tiles.count; ++i) {
        avifTile * tile = &data->tiles.tile[i];
        if (tile->input) {
            avifCodecDecodeInputDestroy(tile->input);
            tile->input = NULL;
        }
        if (tile->codec) {
            // Check if tile->codec was created separately and destroy it in that case.
            if (tile->codec != data->codec && tile->codec != data->codecAlpha) {
                avifCodecDestroy(tile->codec);
            }
            tile->codec = NULL;
        }
        if (tile->image) {
            avifImageDestroy(tile->image);
            tile->image = NULL;
        }
    }
    data->tiles.count = 0;
    for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
        data->tileInfos[c].tileCount = 0;
        data->tileInfos[c].decodedTileCount = 0;
    }
    if (data->codec) {
        avifCodecDestroy(data->codec);
        data->codec = NULL;
    }
    if (data->codecAlpha) {
        avifCodecDestroy(data->codecAlpha);
        data->codecAlpha = NULL;
    }
}

static void avifDecoderDataDestroy(avifDecoderData * data)
{
    if (data->meta) {
        avifMetaDestroy(data->meta);
    }
    for (uint32_t i = 0; i < data->tracks.count; ++i) {
        avifTrack * track = &data->tracks.track[i];
        if (track->sampleTable) {
            avifSampleTableDestroy(track->sampleTable);
        }
        if (track->meta) {
            avifMetaDestroy(track->meta);
        }
    }
    avifArrayDestroy(&data->tracks);
    avifDecoderDataClearTiles(data);
    avifArrayDestroy(&data->tiles);
    avifArrayDestroy(&data->compatibleBrands);
    avifFree(data);
}

// This returns the max extent that has to be read in order to decode this item. If
// the item is stored in an idat, the data has already been read during Parse() and
// this function will return AVIF_RESULT_OK with a 0-byte extent.
static avifResult avifDecoderItemMaxExtent(const avifDecoderItem * item, const avifDecodeSample * sample, avifExtent * outExtent)
{
    if (item->extents.count == 0) {
        return AVIF_RESULT_TRUNCATED_DATA;
    }

    if (item->idatStored) {
        // construction_method: idat(1)

        if (item->meta->idat.size > 0) {
            // Already read from a meta box during Parse()
            memset(outExtent, 0, sizeof(avifExtent));
            return AVIF_RESULT_OK;
        }

        // no associated idat box was found in the meta box, bail out
        return AVIF_RESULT_NO_CONTENT;
    }

    // construction_method: file(0)

    if (sample->size == 0) {
        return AVIF_RESULT_TRUNCATED_DATA;
    }
    uint64_t remainingOffset = sample->offset;
    size_t remainingBytes = sample->size; // This may be smaller than item->size if the item is progressive

    // Assert that the for loop below will execute at least one iteration.
    AVIF_ASSERT_OR_RETURN(item->extents.count != 0);
    uint64_t minOffset = UINT64_MAX;
    uint64_t maxOffset = 0;
    for (uint32_t extentIter = 0; extentIter < item->extents.count; ++extentIter) {
        avifExtent * extent = &item->extents.extent[extentIter];

        // Make local copies of extent->offset and extent->size as they might need to be adjusted
        // due to the sample's offset.
        uint64_t startOffset = extent->offset;
        size_t extentSize = extent->size;
        if (remainingOffset) {
            if (remainingOffset >= extentSize) {
                remainingOffset -= extentSize;
                continue;
            } else {
                if (remainingOffset > UINT64_MAX - startOffset) {
                    return AVIF_RESULT_BMFF_PARSE_FAILED;
                }
                startOffset += remainingOffset;
                extentSize -= (size_t)remainingOffset;
                remainingOffset = 0;
            }
        }

        const size_t usedExtentSize = (extentSize < remainingBytes) ? extentSize : remainingBytes;

        if (usedExtentSize > UINT64_MAX - startOffset) {
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }
        const uint64_t endOffset = startOffset + usedExtentSize;

        if (minOffset > startOffset) {
            minOffset = startOffset;
        }
        if (maxOffset < endOffset) {
            maxOffset = endOffset;
        }

        remainingBytes -= usedExtentSize;
        if (remainingBytes == 0) {
            // We've got enough bytes for this sample.
            break;
        }
    }

    if (remainingBytes != 0) {
        return AVIF_RESULT_TRUNCATED_DATA;
    }

    outExtent->offset = minOffset;
    const uint64_t extentLength = maxOffset - minOffset;
    if (extentLength > SIZE_MAX) {
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }
    outExtent->size = (size_t)extentLength;
    return AVIF_RESULT_OK;
}

static uint8_t avifDecoderItemOperatingPoint(const avifDecoderItem * item)
{
    const avifProperty * a1opProp = avifPropertyArrayFind(&item->properties, "a1op");
    if (a1opProp) {
        return a1opProp->u.a1op.opIndex;
    }
    return 0; // default
}

static avifResult avifDecoderItemValidateProperties(const avifDecoderItem * item,
                                                    const char * configPropName,
                                                    avifDiagnostics * diag,
                                                    const avifStrictFlags strictFlags)
{
    const avifProperty * const configProp = avifPropertyArrayFind(&item->properties, configPropName);
    if (!configProp) {
        // An item configuration property box is mandatory in all valid AVIF configurations. Bail out.
        avifDiagnosticsPrintf(diag, "Item ID %u of type '%.4s' is missing mandatory %s property", item->id, (const char *)item->type, configPropName);
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }

    if (!memcmp(item->type, "grid", 4)) {
        for (uint32_t i = 0; i < item->meta->items.count; ++i) {
            avifDecoderItem * tile = item->meta->items.item[i];
            if (tile->dimgForID != item->id) {
                continue;
            }
            // Tile item types were checked in avifDecoderGenerateImageTiles(), no need to do it here.

            // MIAF (ISO 23000-22:2019), Section 7.3.11.4.1:
            //   All input images of a grid image item shall use the same [...] chroma sampling format,
            //   and the same decoder configuration (see 7.3.6.2).

            // The chroma sampling format is part of the decoder configuration.
            const avifProperty * tileConfigProp = avifPropertyArrayFind(&tile->properties, configPropName);
            if (!tileConfigProp) {
                avifDiagnosticsPrintf(diag,
                                      "Tile item ID %u of type '%.4s' is missing mandatory %s property",
                                      tile->id,
                                      (const char *)tile->type,
                                      configPropName);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            // configProp was copied from a tile item to the grid item. Comparing tileConfigProp with it
            // is equivalent to comparing tileConfigProp with the configPropName from the first tile.
            if ((tileConfigProp->u.av1C.seqProfile != configProp->u.av1C.seqProfile) ||
                (tileConfigProp->u.av1C.seqLevelIdx0 != configProp->u.av1C.seqLevelIdx0) ||
                (tileConfigProp->u.av1C.seqTier0 != configProp->u.av1C.seqTier0) ||
                (tileConfigProp->u.av1C.highBitdepth != configProp->u.av1C.highBitdepth) ||
                (tileConfigProp->u.av1C.twelveBit != configProp->u.av1C.twelveBit) ||
                (tileConfigProp->u.av1C.monochrome != configProp->u.av1C.monochrome) ||
                (tileConfigProp->u.av1C.chromaSubsamplingX != configProp->u.av1C.chromaSubsamplingX) ||
                (tileConfigProp->u.av1C.chromaSubsamplingY != configProp->u.av1C.chromaSubsamplingY) ||
                (tileConfigProp->u.av1C.chromaSamplePosition != configProp->u.av1C.chromaSamplePosition)) {
                avifDiagnosticsPrintf(diag,
                                      "The fields of the %s property of tile item ID %u of type '%.4s' differs from other tiles",
                                      configPropName,
                                      tile->id,
                                      (const char *)tile->type);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
        }
    }

    const avifProperty * pixiProp = avifPropertyArrayFind(&item->properties, "pixi");
    if (!pixiProp && (strictFlags & AVIF_STRICT_PIXI_REQUIRED)) {
        // A pixi box is mandatory in all valid AVIF configurations. Bail out.
        avifDiagnosticsPrintf(diag,
                              "[Strict] Item ID %u of type '%.4s' is missing mandatory pixi property",
                              item->id,
                              (const char *)item->type);
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }

    if (pixiProp) {
        const uint32_t configDepth = avifCodecConfigurationBoxGetDepth(&configProp->u.av1C);
        for (uint8_t i = 0; i < pixiProp->u.pixi.planeCount; ++i) {
            if (pixiProp->u.pixi.planeDepths[i] != configDepth) {
                // pixi depth must match configuration property depth
                avifDiagnosticsPrintf(diag,
                                      "Item ID %u depth specified by pixi property [%u] does not match %s property depth [%u]",
                                      item->id,
                                      pixiProp->u.pixi.planeDepths[i],
                                      configPropName,
                                      configDepth);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
        }
    }

#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
    if (item->miniBoxPixelFormat != AVIF_PIXEL_FORMAT_NONE) {
        // This is a MinimizedImageBox ('mini').

        if (item->miniBoxPixelFormat != avifCodecConfigurationBoxGetFormat(&configProp->u.av1C)) {
            avifDiagnosticsPrintf(diag,
                                  "Item ID %u format [%s] specified by MinimizedImageBox does not match %s property format [%s]",
                                  item->id,
                                  avifPixelFormatToString(item->miniBoxPixelFormat),
                                  configPropName,
                                  avifPixelFormatToString(avifCodecConfigurationBoxGetFormat(&configProp->u.av1C)));
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }

        if (configProp->u.av1C.chromaSamplePosition == /*CSP_UNKNOWN=*/0) {
            // Section 6.4.2. Color config semantics of AV1 specification says:
            //   CSP_UNKNOWN - the source video transfer function must be signaled outside the AV1 bitstream
            // See https://aomediacodec.github.io/av1-spec/#color-config-semantics

            // So item->miniBoxChromaSamplePosition can differ and will override the AV1 value.
        } else if ((uint8_t)item->miniBoxChromaSamplePosition != configProp->u.av1C.chromaSamplePosition) {
            avifDiagnosticsPrintf(diag,
                                  "Item ID %u chroma sample position [%u] specified by MinimizedImageBox does not match %s property chroma sample position [%u]",
                                  item->id,
                                  (uint32_t)item->miniBoxChromaSamplePosition,
                                  configPropName,
                                  configProp->u.av1C.chromaSamplePosition);
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }
    }
#endif // AVIF_ENABLE_EXPERIMENTAL_MINI

    if (strictFlags & AVIF_STRICT_CLAP_VALID) {
        const avifProperty * clapProp = avifPropertyArrayFind(&item->properties, "clap");
        if (clapProp) {
            const avifProperty * ispeProp = avifPropertyArrayFind(&item->properties, "ispe");
            if (!ispeProp) {
                avifDiagnosticsPrintf(diag,
                                      "[Strict] Item ID %u is missing an ispe property, so its clap property cannot be validated",
                                      item->id);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }

            avifCropRect cropRect;
            const uint32_t imageW = ispeProp->u.ispe.width;
            const uint32_t imageH = ispeProp->u.ispe.height;
            const avifPixelFormat configFormat = avifCodecConfigurationBoxGetFormat(&configProp->u.av1C);
            avifBool validClap = avifCropRectConvertCleanApertureBox(&cropRect, &clapProp->u.clap, imageW, imageH, configFormat, diag);
            if (!validClap) {
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
        }
    }
    return AVIF_RESULT_OK;
}

static avifResult avifDecoderItemRead(avifDecoderItem * item,
                                      avifIO * io,
                                      avifROData * outData,
                                      size_t offset,
                                      size_t partialByteCount,
                                      avifDiagnostics * diag)
{
    if (item->mergedExtents.data && !item->partialMergedExtents) {
        // Multiple extents have already been concatenated for this item, just return it
        if (offset >= item->mergedExtents.size) {
            avifDiagnosticsPrintf(diag, "Item ID %u read has overflowing offset", item->id);
            return AVIF_RESULT_TRUNCATED_DATA;
        }
        outData->data = item->mergedExtents.data + offset;
        outData->size = item->mergedExtents.size - offset;
        return AVIF_RESULT_OK;
    }

    if (item->extents.count == 0) {
        avifDiagnosticsPrintf(diag, "Item ID %u has zero extents", item->id);
        return AVIF_RESULT_TRUNCATED_DATA;
    }

    // Find this item's source of all extents' data, based on the construction method
    const avifRWData * idatBuffer = NULL;
    if (item->idatStored) {
        // construction_method: idat(1)

        if (item->meta->idat.size > 0) {
            idatBuffer = &item->meta->idat;
        } else {
            // no associated idat box was found in the meta box, bail out
            avifDiagnosticsPrintf(diag, "Item ID %u is stored in an idat, but no associated idat box was found", item->id);
            return AVIF_RESULT_NO_CONTENT;
        }
    }

    // Merge extents into a single contiguous buffer
    if ((io->sizeHint > 0) && (item->size > io->sizeHint)) {
        // Sanity check: somehow the sum of extents exceeds the entire file or idat size!
        avifDiagnosticsPrintf(diag, "Item ID %u reported size failed size hint sanity check. Truncated data?", item->id);
        return AVIF_RESULT_TRUNCATED_DATA;
    }

    if (offset >= item->size) {
        avifDiagnosticsPrintf(diag, "Item ID %u read has overflowing offset", item->id);
        return AVIF_RESULT_TRUNCATED_DATA;
    }
    const size_t maxOutputSize = item->size - offset;
    const size_t readOutputSize = (partialByteCount && (partialByteCount < maxOutputSize)) ? partialByteCount : maxOutputSize;
    const size_t totalBytesToRead = offset + readOutputSize;

    // If there is a single extent for this item and the source of the read buffer is going to be
    // persistent for the lifetime of the avifDecoder (whether it comes from its own internal
    // idatBuffer or from a known-persistent IO), we can avoid buffer duplication and just use the
    // preexisting buffer.
    avifBool singlePersistentBuffer = ((item->extents.count == 1) && (idatBuffer || io->persistent));
    if (!singlePersistentBuffer) {
        // Always allocate the item's full size here, as progressive image decodes will do partial
        // reads into this buffer and begin feeding the buffer to the underlying AV1 decoder, but
        // will then write more into this buffer without flushing the AV1 decoder (which is still
        // holding the address of the previous allocation of this buffer). This strategy avoids
        // use-after-free issues in the AV1 decoder and unnecessary reallocs as a typical
        // progressive decode use case will eventually decode the final layer anyway.
        AVIF_CHECKRES(avifRWDataRealloc(&item->mergedExtents, item->size));
        item->ownsMergedExtents = AVIF_TRUE;
    }

    // Set this until we manage to fill the entire mergedExtents buffer
    item->partialMergedExtents = AVIF_TRUE;

    uint8_t * front = item->mergedExtents.data;
    size_t remainingBytes = totalBytesToRead;
    for (uint32_t extentIter = 0; extentIter < item->extents.count; ++extentIter) {
        avifExtent * extent = &item->extents.extent[extentIter];

        size_t bytesToRead = extent->size;
        if (bytesToRead > remainingBytes) {
            bytesToRead = remainingBytes;
        }

        avifROData offsetBuffer;
        if (idatBuffer) {
            if (extent->offset > idatBuffer->size) {
                avifDiagnosticsPrintf(diag, "Item ID %u has impossible extent offset in idat buffer", item->id);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            // Since extent->offset (a uint64_t) is not bigger than idatBuffer->size (a size_t),
            // it is safe to cast extent->offset to size_t.
            const size_t extentOffset = (size_t)extent->offset;
            if (extent->size > idatBuffer->size - extentOffset) {
                avifDiagnosticsPrintf(diag, "Item ID %u has impossible extent size in idat buffer", item->id);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            offsetBuffer.data = idatBuffer->data + extentOffset;
            offsetBuffer.size = idatBuffer->size - extentOffset;
        } else {
            // construction_method: file(0)

            if ((io->sizeHint > 0) && (extent->offset > io->sizeHint)) {
                avifDiagnosticsPrintf(diag, "Item ID %u extent offset failed size hint sanity check. Truncated data?", item->id);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            avifResult readResult = io->read(io, 0, extent->offset, bytesToRead, &offsetBuffer);
            if (readResult != AVIF_RESULT_OK) {
                return readResult;
            }
            if (bytesToRead != offsetBuffer.size) {
                avifDiagnosticsPrintf(diag,
                                      "Item ID %u tried to read %zu bytes, but only received %zu bytes",
                                      item->id,
                                      bytesToRead,
                                      offsetBuffer.size);
                return AVIF_RESULT_TRUNCATED_DATA;
            }
        }

        if (singlePersistentBuffer) {
            memcpy(&item->mergedExtents, &offsetBuffer, sizeof(avifRWData));
            item->mergedExtents.size = bytesToRead;
        } else {
            AVIF_ASSERT_OR_RETURN(item->ownsMergedExtents);
            AVIF_ASSERT_OR_RETURN(front);
            memcpy(front, offsetBuffer.data, bytesToRead);
            front += bytesToRead;
        }

        remainingBytes -= bytesToRead;
        if (remainingBytes == 0) {
            // This happens when partialByteCount is set
            break;
        }
    }
    if (remainingBytes != 0) {
        // This should be impossible?
        avifDiagnosticsPrintf(diag, "Item ID %u has %zu unexpected trailing bytes", item->id, remainingBytes);
        return AVIF_RESULT_TRUNCATED_DATA;
    }

    outData->data = item->mergedExtents.data + offset;
    outData->size = readOutputSize;
    item->partialMergedExtents = (item->size != totalBytesToRead);
    return AVIF_RESULT_OK;
}

// Returns the avifCodecType of the first tile of the gridItem.
static avifCodecType avifDecoderItemGetGridCodecType(const avifDecoderItem * gridItem)
{
    for (uint32_t i = 0; i < gridItem->meta->items.count; ++i) {
        avifDecoderItem * item = gridItem->meta->items.item[i];
        const avifCodecType tileCodecType = avifGetCodecType(item->type);
        if ((item->dimgForID == gridItem->id) && (tileCodecType != AVIF_CODEC_TYPE_UNKNOWN)) {
            return tileCodecType;
        }
    }
    return AVIF_CODEC_TYPE_UNKNOWN;
}

// Fills the dimgIdxToItemIdx array with a mapping from each 0-based tile index in the 'dimg' reference
// to its corresponding 0-based index in the avifMeta::items array.
static avifResult avifFillDimgIdxToItemIdxArray(uint32_t * dimgIdxToItemIdx, uint32_t numExpectedTiles, const avifDecoderItem * gridItem)
{
    const uint32_t itemIndexNotSet = UINT32_MAX;
    for (uint32_t dimgIdx = 0; dimgIdx < numExpectedTiles; ++dimgIdx) {
        dimgIdxToItemIdx[dimgIdx] = itemIndexNotSet;
    }
    uint32_t numTiles = 0;
    for (uint32_t i = 0; i < gridItem->meta->items.count; ++i) {
        if (gridItem->meta->items.item[i]->dimgForID == gridItem->id) {
            const uint32_t tileItemDimgIdx = gridItem->meta->items.item[i]->dimgIdx;
            AVIF_CHECKERR(tileItemDimgIdx < numExpectedTiles, AVIF_RESULT_INVALID_IMAGE_GRID);
            AVIF_CHECKERR(dimgIdxToItemIdx[tileItemDimgIdx] == itemIndexNotSet, AVIF_RESULT_INVALID_IMAGE_GRID);
            dimgIdxToItemIdx[tileItemDimgIdx] = i;
            ++numTiles;
        }
    }
    // The number of tiles has been verified in avifDecoderItemReadAndParse().
    AVIF_ASSERT_OR_RETURN(numTiles == numExpectedTiles);
    return AVIF_RESULT_OK;
}

// Creates the tiles and associate them to the items in the order of the 'dimg' association.
static avifResult avifDecoderGenerateImageGridTiles(avifDecoder * decoder,
                                                    avifDecoderItem * gridItem,
                                                    avifItemCategory itemCategory,
                                                    const uint32_t * dimgIdxToItemIdx,
                                                    uint32_t numTiles)
{
    avifDecoderItem * firstTileItem = NULL;
    avifBool progressive = AVIF_TRUE;
    for (uint32_t dimgIdx = 0; dimgIdx < numTiles; ++dimgIdx) {
        const uint32_t itemIdx = dimgIdxToItemIdx[dimgIdx];
        AVIF_ASSERT_OR_RETURN(itemIdx < gridItem->meta->items.count);
        avifDecoderItem * item = gridItem->meta->items.item[itemIdx];

        // According to HEIF (ISO 14496-12), Section 6.6.2.3.1, the SingleItemTypeReferenceBox of type 'dimg'
        // identifies the input images of the derived image item of type 'grid'. Since the reference_count
        // shall be equal to rows*columns, unknown tile item types cannot be skipped but must be considered
        // as errors.
        const avifCodecType tileCodecType = avifGetCodecType(item->type);
        if (tileCodecType == AVIF_CODEC_TYPE_UNKNOWN) {
            char type[4];
            for (int j = 0; j < 4; j++) {
                if (isprint((unsigned char)item->type[j])) {
                    type[j] = item->type[j];
                } else {
                    type[j] = '.';
                }
            }
            avifDiagnosticsPrintf(&decoder->diag,
                                  "Tile item ID %u has an unknown item type '%.4s' (%02x%02x%02x%02x)",
                                  item->id,
                                  type,
                                  item->type[0],
                                  item->type[1],
                                  item->type[2],
                                  item->type[3]);
            return AVIF_RESULT_INVALID_IMAGE_GRID;
        }

        if (item->hasUnsupportedEssentialProperty) {
            // An essential property isn't supported by libavif; can't
            // decode a grid image if any tile in the grid isn't supported.
            avifDiagnosticsPrintf(&decoder->diag, "Grid image contains tile with an unsupported property marked as essential");
            return AVIF_RESULT_INVALID_IMAGE_GRID;
        }

        const avifTile * tile =
            avifDecoderDataCreateTile(decoder->data, tileCodecType, item->width, item->height, avifDecoderItemOperatingPoint(item));
        AVIF_CHECKERR(tile != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        AVIF_CHECKRES(avifCodecDecodeInputFillFromDecoderItem(tile->input,
                                                              item,
                                                              decoder->allowProgressive,
                                                              decoder->imageCountLimit,
                                                              decoder->io->sizeHint,
                                                              &decoder->diag));
        tile->input->itemCategory = itemCategory;

        if (firstTileItem == NULL) {
            firstTileItem = item;

            // Adopt the configuration property of the first image item tile, so that it can be queried from
            // the top-level color/alpha item during avifDecoderReset().
            const avifCodecType codecType = avifGetCodecType(item->type);
            const char * configPropName = avifGetConfigurationPropertyName(codecType);
            const avifProperty * srcProp = avifPropertyArrayFind(&item->properties, configPropName);
            if (!srcProp) {
                avifDiagnosticsPrintf(&decoder->diag, "Grid image's first tile is missing an %s property", configPropName);
                return AVIF_RESULT_INVALID_IMAGE_GRID;
            }
            avifProperty * dstProp = (avifProperty *)avifArrayPush(&gridItem->properties);
            AVIF_CHECKERR(dstProp != NULL, AVIF_RESULT_OUT_OF_MEMORY);
            *dstProp = *srcProp;

        } else if (memcmp(item->type, firstTileItem->type, 4)) {
            // MIAF (ISO 23000-22:2019), Section 7.3.11.4.1:
            //   All input images of a grid image item shall use the same coding format [...]
            // The coding format is defined by the item type.
            avifDiagnosticsPrintf(&decoder->diag,
                                  "Tile item ID %u of type '%.4s' differs from other tile type '%.4s'",
                                  item->id,
                                  (const char *)item->type,
                                  (const char *)firstTileItem->type);
            return AVIF_RESULT_INVALID_IMAGE_GRID;
        }
        if (!item->progressive) {
            progressive = AVIF_FALSE;
        }
    }
    if (itemCategory == AVIF_ITEM_COLOR && progressive) {
        // If all the items that make up the grid are progressive, then propagate that status to the top-level grid item.
        gridItem->progressive = AVIF_TRUE;
    }
    return AVIF_RESULT_OK;
}

// Allocates the dstImage. Also verifies some spec compliance rules for grids, if relevant.
static avifResult avifDecoderDataAllocateImagePlanes(avifDecoderData * data, const avifTileInfo * info, avifImage * dstImage)
{
    const avifTile * tile = &data->tiles.tile[info->firstTileIndex];
    uint32_t dstWidth;
    uint32_t dstHeight;

    if (info->grid.rows > 0 && info->grid.columns > 0) {
        const avifImageGrid * grid = &info->grid;
        // Validate grid image size and tile size.
        //
        // HEIF (ISO/IEC 23008-12:2017), Section 6.6.2.3.1:
        //   The tiled input images shall completely "cover" the reconstructed image grid canvas, ...
        if (((tile->image->width * grid->columns) < grid->outputWidth) || ((tile->image->height * grid->rows) < grid->outputHeight)) {
            avifDiagnosticsPrintf(data->diag,
                                  "Grid image tiles do not completely cover the image (HEIF (ISO/IEC 23008-12:2017), Section 6.6.2.3.1)");
            return AVIF_RESULT_INVALID_IMAGE_GRID;
        }
        // Tiles in the rightmost column and bottommost row must overlap the reconstructed image grid canvas. See MIAF (ISO/IEC 23000-22:2019), Section 7.3.11.4.2, Figure 2.
        if (((tile->image->width * (grid->columns - 1)) >= grid->outputWidth) ||
            ((tile->image->height * (grid->rows - 1)) >= grid->outputHeight)) {
            avifDiagnosticsPrintf(data->diag,
                                  "Grid image tiles in the rightmost column and bottommost row do not overlap the reconstructed image grid canvas. See MIAF (ISO/IEC 23000-22:2019), Section 7.3.11.4.2, Figure 2");
            return AVIF_RESULT_INVALID_IMAGE_GRID;
        }
        if (!avifAreGridDimensionsValid(tile->image->yuvFormat,
                                        grid->outputWidth,
                                        grid->outputHeight,
                                        tile->image->width,
                                        tile->image->height,
                                        data->diag)) {
            return AVIF_RESULT_INVALID_IMAGE_GRID;
        }
        dstWidth = grid->outputWidth;
        dstHeight = grid->outputHeight;
    } else {
        // Only one tile. Width and height are inherited from the 'ispe' property of the corresponding avifDecoderItem.
        dstWidth = tile->width;
        dstHeight = tile->height;
    }

    const avifBool alpha = avifIsAlpha(tile->input->itemCategory);
    if (alpha) {
        // An alpha tile does not contain any YUV pixels.
        AVIF_ASSERT_OR_RETURN(tile->image->yuvFormat == AVIF_PIXEL_FORMAT_NONE);
    }

    const uint32_t dstDepth = tile->image->depth;

    // Lazily populate dstImage with the new frame's properties.
    const avifBool dimsOrDepthIsDifferent = (dstImage->width != dstWidth) || (dstImage->height != dstHeight) ||
                                            (dstImage->depth != dstDepth);
    const avifBool yuvFormatIsDifferent = !alpha && (dstImage->yuvFormat != tile->image->yuvFormat);
    if (dimsOrDepthIsDifferent || yuvFormatIsDifferent) {
        if (alpha) {
            // Alpha doesn't match size, just bail out
            avifDiagnosticsPrintf(data->diag, "Alpha plane dimensions do not match color plane dimensions");
            return AVIF_RESULT_INVALID_IMAGE_GRID;
        }

        if (dimsOrDepthIsDifferent) {
            avifImageFreePlanes(dstImage, AVIF_PLANES_ALL);
            dstImage->width = dstWidth;
            dstImage->height = dstHeight;
            dstImage->depth = dstDepth;
        }
        if (yuvFormatIsDifferent) {
            avifImageFreePlanes(dstImage, AVIF_PLANES_YUV);
            dstImage->yuvFormat = tile->image->yuvFormat;
        }
        // Keep dstImage->yuvRange which is already set to its correct value
        // (extracted from the 'colr' box if parsed or from a Sequence Header OBU otherwise).

        if (!data->cicpSet) {
            data->cicpSet = AVIF_TRUE;
            dstImage->colorPrimaries = tile->image->colorPrimaries;
            dstImage->transferCharacteristics = tile->image->transferCharacteristics;
            dstImage->matrixCoefficients = tile->image->matrixCoefficients;
        }
    }

    if (avifImageAllocatePlanes(dstImage, alpha ? AVIF_PLANES_A : AVIF_PLANES_YUV) != AVIF_RESULT_OK) {
        avifDiagnosticsPrintf(data->diag, "Image allocation failure");
        return AVIF_RESULT_OUT_OF_MEMORY;
    }
    return AVIF_RESULT_OK;
}

// Copies over the pixels from the tile into dstImage.
// Verifies that the relevant properties of the tile match those of the first tile in case of a grid.
static avifResult avifDecoderDataCopyTileToImage(avifDecoderData * data,
                                                 const avifTileInfo * info,
                                                 avifImage * dstImage,
                                                 const avifTile * tile,
                                                 unsigned int tileIndex)
{
    const avifTile * firstTile = &data->tiles.tile[info->firstTileIndex];
    if (tile != firstTile) {
        // Check for tile consistency. All tiles in a grid image should match the first tile in the properties checked below.
        if ((tile->image->width != firstTile->image->width) || (tile->image->height != firstTile->image->height) ||
            (tile->image->depth != firstTile->image->depth) || (tile->image->yuvFormat != firstTile->image->yuvFormat) ||
            (tile->image->yuvRange != firstTile->image->yuvRange) || (tile->image->colorPrimaries != firstTile->image->colorPrimaries) ||
            (tile->image->transferCharacteristics != firstTile->image->transferCharacteristics) ||
            (tile->image->matrixCoefficients != firstTile->image->matrixCoefficients)) {
            avifDiagnosticsPrintf(data->diag, "Grid image contains mismatched tiles");
            return AVIF_RESULT_INVALID_IMAGE_GRID;
        }
    }

    avifImage srcView;
    avifImageSetDefaults(&srcView);
    avifImage dstView;
    avifImageSetDefaults(&dstView);
    avifCropRect dstViewRect = { 0, 0, firstTile->image->width, firstTile->image->height };
    if (info->grid.rows > 0 && info->grid.columns > 0) {
        unsigned int rowIndex = tileIndex / info->grid.columns;
        unsigned int colIndex = tileIndex % info->grid.columns;
        dstViewRect.x = firstTile->image->width * colIndex;
        dstViewRect.y = firstTile->image->height * rowIndex;
        if (dstViewRect.x + dstViewRect.width > info->grid.outputWidth) {
            dstViewRect.width = info->grid.outputWidth - dstViewRect.x;
        }
        if (dstViewRect.y + dstViewRect.height > info->grid.outputHeight) {
            dstViewRect.height = info->grid.outputHeight - dstViewRect.y;
        }
    }
    const avifCropRect srcViewRect = { 0, 0, dstViewRect.width, dstViewRect.height };
    AVIF_ASSERT_OR_RETURN(avifImageSetViewRect(&dstView, dstImage, &dstViewRect) == AVIF_RESULT_OK &&
                          avifImageSetViewRect(&srcView, tile->image, &srcViewRect) == AVIF_RESULT_OK);
    avifImageCopySamples(&dstView, &srcView, avifIsAlpha(tile->input->itemCategory) ? AVIF_PLANES_A : AVIF_PLANES_YUV);
    return AVIF_RESULT_OK;
}

// If colorId == 0 (a sentinel value as item IDs must be nonzero), accept any found EXIF/XMP metadata. Passing in 0
// is used when finding metadata in a meta box embedded in a trak box, as any items inside of a meta box that is
// inside of a trak box are implicitly associated to the track.
static avifResult avifDecoderFindMetadata(avifDecoder * decoder, avifMeta * meta, avifImage * image, uint32_t colorId)
{
    if (decoder->ignoreExif && decoder->ignoreXMP) {
        // Nothing to do!
        return AVIF_RESULT_OK;
    }

    for (uint32_t itemIndex = 0; itemIndex < meta->items.count; ++itemIndex) {
        avifDecoderItem * item = meta->items.item[itemIndex];
        if (!item->size) {
            continue;
        }
        if (item->hasUnsupportedEssentialProperty) {
            // An essential property isn't supported by libavif; ignore the item.
            continue;
        }

        if ((colorId > 0) && (item->descForID != colorId)) {
            // Not a content description (metadata) for the colorOBU, skip it
            continue;
        }

        if (!decoder->ignoreExif && !memcmp(item->type, "Exif", 4)) {
            avifROData exifContents;
            avifResult readResult = avifDecoderItemRead(item, decoder->io, &exifContents, 0, 0, &decoder->diag);
            if (readResult != AVIF_RESULT_OK) {
                return readResult;
            }

            // Advance past Annex A.2.1's header
            BEGIN_STREAM(exifBoxStream, exifContents.data, exifContents.size, &decoder->diag, "Exif header");
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
            // The MinimizedImageBox does not signal the exifTiffHeaderOffset.
            if (!meta->fromMiniBox)
#endif
            {
                uint32_t exifTiffHeaderOffset;
                AVIF_CHECKERR(avifROStreamReadU32(&exifBoxStream, &exifTiffHeaderOffset),
                              AVIF_RESULT_INVALID_EXIF_PAYLOAD); // unsigned int(32) exif_tiff_header_offset;
                size_t expectedExifTiffHeaderOffset;
                AVIF_CHECKRES(avifGetExifTiffHeaderOffset(avifROStreamCurrent(&exifBoxStream),
                                                          avifROStreamRemainingBytes(&exifBoxStream),
                                                          &expectedExifTiffHeaderOffset));
                AVIF_CHECKERR(exifTiffHeaderOffset == expectedExifTiffHeaderOffset, AVIF_RESULT_INVALID_EXIF_PAYLOAD);
            }

            AVIF_CHECKRES(avifRWDataSet(&image->exif, avifROStreamCurrent(&exifBoxStream), avifROStreamRemainingBytes(&exifBoxStream)));
        } else if (!decoder->ignoreXMP && !memcmp(item->type, "mime", 4) &&
                   !strcmp(item->contentType.contentType, AVIF_CONTENT_TYPE_XMP)) {
            avifROData xmpContents;
            avifResult readResult = avifDecoderItemRead(item, decoder->io, &xmpContents, 0, 0, &decoder->diag);
            if (readResult != AVIF_RESULT_OK) {
                return readResult;
            }

            AVIF_CHECKRES(avifImageSetMetadataXMP(image, xmpContents.data, xmpContents.size));
        }
    }
    return AVIF_RESULT_OK;
}

// ---------------------------------------------------------------------------
// URN

static avifBool isAlphaURN(const char * urn)
{
    return !strcmp(urn, AVIF_URN_ALPHA0) || !strcmp(urn, AVIF_URN_ALPHA1);
}

// ---------------------------------------------------------------------------
// BMFF Parsing

static avifBool avifParseHandlerBox(const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[hdlr]");

    AVIF_CHECK(avifROStreamReadAndEnforceVersion(&s, 0));

    uint32_t predefined;
    AVIF_CHECK(avifROStreamReadU32(&s, &predefined)); // unsigned int(32) pre_defined = 0;
    if (predefined != 0) {
        avifDiagnosticsPrintf(diag, "Box[hdlr] contains a pre_defined value that is nonzero");
        return AVIF_FALSE;
    }

    uint8_t handlerType[4];
    AVIF_CHECK(avifROStreamRead(&s, handlerType, 4)); // unsigned int(32) handler_type;
    if (memcmp(handlerType, "pict", 4) != 0) {
        avifDiagnosticsPrintf(diag, "Box[hdlr] handler_type is not 'pict'");
        return AVIF_FALSE;
    }

    for (int i = 0; i < 3; ++i) {
        uint32_t reserved;
        AVIF_CHECK(avifROStreamReadU32(&s, &reserved)); // const unsigned int(32)[3] reserved = 0;
    }

    // Verify that a valid string is here, but don't bother to store it
    AVIF_CHECK(avifROStreamReadString(&s, NULL, 0)); // string name;
    return AVIF_TRUE;
}

static avifResult avifParseItemLocationBox(avifMeta * meta, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[iloc]");

    // Section 8.11.3.2 of ISO/IEC 14496-12.
    uint8_t version;
    AVIF_CHECKERR(avifROStreamReadVersionAndFlags(&s, &version, NULL), AVIF_RESULT_BMFF_PARSE_FAILED);
    if (version > 2) {
        avifDiagnosticsPrintf(diag, "Box[iloc] has an unsupported version [%u]", version);
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }

    uint8_t offsetSize, lengthSize, baseOffsetSize, indexSize = 0;
    uint32_t reserved;
    AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &offsetSize, /*bitCount=*/4), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(4) offset_size;
    AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &lengthSize, /*bitCount=*/4), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(4) length_size;
    AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &baseOffsetSize, /*bitCount=*/4), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(4) base_offset_size;
    if (version == 1 || version == 2) {
        AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &indexSize, /*bitCount=*/4), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(4) index_size;
    } else {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &reserved, /*bitCount=*/4), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(4) reserved;
    }

    // Section 8.11.3.3 of ISO/IEC 14496-12.
    if ((offsetSize != 0 && offsetSize != 4 && offsetSize != 8) || (lengthSize != 0 && lengthSize != 4 && lengthSize != 8) ||
        (baseOffsetSize != 0 && baseOffsetSize != 4 && baseOffsetSize != 8) || (indexSize != 0 && indexSize != 4 && indexSize != 8)) {
        avifDiagnosticsPrintf(diag, "Box[iloc] has an invalid size");
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }

    uint16_t tmp16;
    uint32_t itemCount;
    if (version < 2) {
        AVIF_CHECKERR(avifROStreamReadU16(&s, &tmp16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) item_count;
        itemCount = tmp16;
    } else {
        AVIF_CHECKERR(avifROStreamReadU32(&s, &itemCount), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) item_count;
    }
    for (uint32_t i = 0; i < itemCount; ++i) {
        uint32_t itemID;
        if (version < 2) {
            AVIF_CHECKERR(avifROStreamReadU16(&s, &tmp16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) item_ID;
            itemID = tmp16;
        } else {
            AVIF_CHECKERR(avifROStreamReadU32(&s, &itemID), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) item_ID;
        }
        AVIF_CHECKRES(avifCheckItemID("iloc", itemID, diag));

        avifDecoderItem * item;
        AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, itemID, &item));
        if (item->extents.count > 0) {
            // This item has already been given extents via this iloc box. This is invalid.
            avifDiagnosticsPrintf(diag, "Item ID [%u] contains duplicate sets of extents", itemID);
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }

        if (version == 1 || version == 2) {
            AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &reserved, /*bitCount=*/12), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(12) reserved = 0;
            if (reserved) {
                avifDiagnosticsPrintf(diag, "Box[iloc] has a non null reserved field [%u]", reserved);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            uint8_t constructionMethod;
            AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &constructionMethod, /*bitCount=*/4),
                          AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(4) construction_method;
            if (constructionMethod != 0 /* file offset */ && constructionMethod != 1 /* idat offset */) {
                // construction method 2 (item offset) unsupported
                avifDiagnosticsPrintf(diag, "Box[iloc] has an unsupported construction method [%u]", constructionMethod);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            if (constructionMethod == 1) {
                item->idatStored = AVIF_TRUE;
            }
        }

        uint16_t dataReferenceIndex;
        AVIF_CHECKERR(avifROStreamReadU16(&s, &dataReferenceIndex), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) data_reference_index;
        uint64_t baseOffset;
        AVIF_CHECKERR(avifROStreamReadUX8(&s, &baseOffset, baseOffsetSize), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(base_offset_size*8) base_offset;
        uint16_t extentCount;
        AVIF_CHECKERR(avifROStreamReadU16(&s, &extentCount), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) extent_count;
        for (int extentIter = 0; extentIter < extentCount; ++extentIter) {
            if ((version == 1 || version == 2) && indexSize > 0) {
                // Section 8.11.3.1 of ISO/IEC 14496-12:
                //   The item_reference_index is only used for the method item_offset; it indicates the 1-based index
                //   of the item reference with referenceType 'iloc' linked from this item. If index_size is 0, then
                //   the value 1 is implied; the value 0 is reserved.
                uint64_t itemReferenceIndex; // Ignored unless construction_method=2 which is unsupported, but still read it.
                AVIF_CHECKERR(avifROStreamReadUX8(&s, &itemReferenceIndex, indexSize),
                              AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(index_size*8) item_reference_index;
            }

            uint64_t extentOffset;
            AVIF_CHECKERR(avifROStreamReadUX8(&s, &extentOffset, offsetSize), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(offset_size*8) extent_offset;
            uint64_t extentLength;
            AVIF_CHECKERR(avifROStreamReadUX8(&s, &extentLength, lengthSize), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(length_size*8) extent_length;

            avifExtent * extent = (avifExtent *)avifArrayPush(&item->extents);
            AVIF_CHECKERR(extent != NULL, AVIF_RESULT_OUT_OF_MEMORY);
            if (extentOffset > UINT64_MAX - baseOffset) {
                avifDiagnosticsPrintf(diag,
                                      "Item ID [%u] contains an extent offset which overflows: [base: %" PRIu64 " offset:%" PRIu64 "]",
                                      itemID,
                                      baseOffset,
                                      extentOffset);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            uint64_t offset = baseOffset + extentOffset;
            extent->offset = offset;
            if (extentLength > SIZE_MAX) {
                avifDiagnosticsPrintf(diag, "Item ID [%u] contains an extent length which overflows: [%" PRIu64 "]", itemID, extentLength);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            extent->size = (size_t)extentLength;
            if (extent->size > SIZE_MAX - item->size) {
                avifDiagnosticsPrintf(diag,
                                      "Item ID [%u] contains an extent length which overflows the item size: [%zu, %zu]",
                                      itemID,
                                      extent->size,
                                      item->size);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            item->size += extent->size;
        }
    }
    return AVIF_RESULT_OK;
}

static avifBool avifParseImageGridBox(avifImageGrid * grid,
                                      const uint8_t * raw,
                                      size_t rawLen,
                                      uint32_t imageSizeLimit,
                                      uint32_t imageDimensionLimit,
                                      avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[grid]");

    uint8_t version, flags;
    AVIF_CHECK(avifROStreamRead(&s, &version, 1)); // unsigned int(8) version = 0;
    if (version != 0) {
        avifDiagnosticsPrintf(diag, "Box[grid] has unsupported version [%u]", version);
        return AVIF_FALSE;
    }
    uint8_t rowsMinusOne, columnsMinusOne;
    AVIF_CHECK(avifROStreamRead(&s, &flags, 1));           // unsigned int(8) flags;
    AVIF_CHECK(avifROStreamRead(&s, &rowsMinusOne, 1));    // unsigned int(8) rows_minus_one;
    AVIF_CHECK(avifROStreamRead(&s, &columnsMinusOne, 1)); // unsigned int(8) columns_minus_one;
    grid->rows = (uint32_t)rowsMinusOne + 1;
    grid->columns = (uint32_t)columnsMinusOne + 1;

    uint32_t fieldLength = ((flags & 1) + 1) * 16;
    if (fieldLength == 16) {
        uint16_t outputWidth16, outputHeight16;
        AVIF_CHECK(avifROStreamReadU16(&s, &outputWidth16));  // unsigned int(FieldLength) output_width;
        AVIF_CHECK(avifROStreamReadU16(&s, &outputHeight16)); // unsigned int(FieldLength) output_height;
        grid->outputWidth = outputWidth16;
        grid->outputHeight = outputHeight16;
    } else {
        if (fieldLength != 32) {
            // This should be impossible
            avifDiagnosticsPrintf(diag, "Grid box contains illegal field length: [%u]", fieldLength);
            return AVIF_FALSE;
        }
        AVIF_CHECK(avifROStreamReadU32(&s, &grid->outputWidth));  // unsigned int(FieldLength) output_width;
        AVIF_CHECK(avifROStreamReadU32(&s, &grid->outputHeight)); // unsigned int(FieldLength) output_height;
    }
    if ((grid->outputWidth == 0) || (grid->outputHeight == 0)) {
        avifDiagnosticsPrintf(diag, "Grid box contains illegal dimensions: [%u x %u]", grid->outputWidth, grid->outputHeight);
        return AVIF_FALSE;
    }
    if (avifDimensionsTooLarge(grid->outputWidth, grid->outputHeight, imageSizeLimit, imageDimensionLimit)) {
        avifDiagnosticsPrintf(diag, "Grid box dimensions are too large: [%u x %u]", grid->outputWidth, grid->outputHeight);
        return AVIF_FALSE;
    }
    return avifROStreamRemainingBytes(&s) == 0;
}

#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)

static avifBool avifParseGainMapMetadata(avifGainMap * gainMap, avifROStream * s)
{
    uint32_t isMultichannel;
    AVIF_CHECK(avifROStreamReadBitsU32(s, &isMultichannel, 1)); // unsigned int(1) is_multichannel;
    const uint8_t channelCount = isMultichannel ? 3 : 1;

    uint32_t useBaseColorSpace;
    AVIF_CHECK(avifROStreamReadBitsU32(s, &useBaseColorSpace, 1)); // unsigned int(1) use_base_colour_space;
    gainMap->useBaseColorSpace = useBaseColorSpace ? AVIF_TRUE : AVIF_FALSE;

    uint32_t reserved;
    AVIF_CHECK(avifROStreamReadBitsU32(s, &reserved, 6)); // unsigned int(6) reserved;

    AVIF_CHECK(avifROStreamReadU32(s, &gainMap->baseHdrHeadroom.n));      // unsigned int(32) base_hdr_headroom_numerator;
    AVIF_CHECK(avifROStreamReadU32(s, &gainMap->baseHdrHeadroom.d));      // unsigned int(32) base_hdr_headroom_denominator;
    AVIF_CHECK(avifROStreamReadU32(s, &gainMap->alternateHdrHeadroom.n)); // unsigned int(32) alternate_hdr_headroom_numerator;
    AVIF_CHECK(avifROStreamReadU32(s, &gainMap->alternateHdrHeadroom.d)); // unsigned int(32) alternate_hdr_headroom_denominator;

    for (int c = 0; c < channelCount; ++c) {
        AVIF_CHECK(avifROStreamReadU32(s, (uint32_t *)&gainMap->gainMapMin[c].n)); // int(32) gain_map_min_numerator;
        AVIF_CHECK(avifROStreamReadU32(s, &gainMap->gainMapMin[c].d));             // unsigned int(32) gain_map_min_denominator;
        AVIF_CHECK(avifROStreamReadU32(s, (uint32_t *)&gainMap->gainMapMax[c].n)); // int(32) gain_map_max_numerator;
        AVIF_CHECK(avifROStreamReadU32(s, &gainMap->gainMapMax[c].d));             // unsigned int(32) gain_map_max_denominator;
        AVIF_CHECK(avifROStreamReadU32(s, &gainMap->gainMapGamma[c].n));           // unsigned int(32) gamma_numerator;
        AVIF_CHECK(avifROStreamReadU32(s, &gainMap->gainMapGamma[c].d));           // unsigned int(32) gamma_denominator;
        AVIF_CHECK(avifROStreamReadU32(s, (uint32_t *)&gainMap->baseOffset[c].n)); // int(32) base_offset_numerator;
        AVIF_CHECK(avifROStreamReadU32(s, &gainMap->baseOffset[c].d));             // unsigned int(32) base_offset_denominator;
        AVIF_CHECK(avifROStreamReadU32(s, (uint32_t *)&gainMap->alternateOffset[c].n)); // int(32) alternate_offset_numerator;
        AVIF_CHECK(avifROStreamReadU32(s, &gainMap->alternateOffset[c].d)); // unsigned int(32) alternate_offset_denominator;
    }

    // Fill the remaining values by copying those from the first channel.
    for (int c = channelCount; c < 3; ++c) {
        gainMap->gainMapMin[c] = gainMap->gainMapMin[0];
        gainMap->gainMapMax[c] = gainMap->gainMapMax[0];
        gainMap->gainMapGamma[c] = gainMap->gainMapGamma[0];
        gainMap->baseOffset[c] = gainMap->baseOffset[0];
        gainMap->alternateOffset[c] = gainMap->alternateOffset[0];
    }
    return AVIF_TRUE;
}

// If the gain map's version or minimum_version tag is not supported, returns AVIF_RESULT_NOT_IMPLEMENTED.
static avifResult avifParseToneMappedImageBox(avifGainMap * gainMap, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[tmap]");

    uint8_t version;
    AVIF_CHECKERR(avifROStreamRead(&s, &version, 1), AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE); // unsigned int(8) version = 0;
    if (version != 0) {
        avifDiagnosticsPrintf(diag, "Box[tmap] has unsupported version [%u]", version);
        return AVIF_RESULT_NOT_IMPLEMENTED;
    }

    uint16_t minimumVersion;
    AVIF_CHECKERR(avifROStreamReadU16(&s, &minimumVersion), AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE); // unsigned int(16) minimum_version;
    const uint16_t supportedMetadataVersion = 0;
    if (minimumVersion > supportedMetadataVersion) {
        avifDiagnosticsPrintf(diag, "Box[tmap] has unsupported minimum version [%u]", minimumVersion);
        return AVIF_RESULT_NOT_IMPLEMENTED;
    }
    uint16_t writerVersion;
    AVIF_CHECKERR(avifROStreamReadU16(&s, &writerVersion), AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE); // unsigned int(16) writer_version;
    AVIF_CHECKERR(writerVersion >= minimumVersion, AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE);

    AVIF_CHECKERR(avifParseGainMapMetadata(gainMap, &s), AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE);

    if (writerVersion <= supportedMetadataVersion) {
        AVIF_CHECKERR(avifROStreamRemainingBytes(&s) == 0, AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE);
    }
    return AVIF_RESULT_OK;
}
#endif // AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP

#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
// bit_depth is assumed to be 2 (32-bit).
static avifResult avifParseSampleTransformTokens(avifROStream * s, avifSampleTransformExpression * expression)
{
    uint8_t tokenCount;
    AVIF_CHECK(avifROStreamRead(s, &tokenCount, /*size=*/1)); // unsigned int(8) token_count;
    AVIF_CHECKERR(tokenCount != 0, AVIF_RESULT_BMFF_PARSE_FAILED);
    AVIF_CHECKERR(avifArrayCreate(expression, sizeof(expression->tokens[0]), tokenCount), AVIF_RESULT_OUT_OF_MEMORY);

    for (uint32_t t = 0; t < tokenCount; ++t) {
        avifSampleTransformToken * token = (avifSampleTransformToken *)avifArrayPush(expression);
        AVIF_CHECKERR(token != NULL, AVIF_RESULT_OUT_OF_MEMORY);

        AVIF_CHECK(avifROStreamRead(s, &token->type, /*size=*/1)); // unsigned int(8) token;
        if (token->type == AVIF_SAMPLE_TRANSFORM_CONSTANT) {
            // Two's complement representation is assumed here.
            uint32_t constant;
            AVIF_CHECK(avifROStreamReadU32(s, &constant)); // signed int(1<<(bit_depth+3)) constant;
            token->constant = *(int32_t *)&constant;       // maybe =(int32_t)constant; is enough
        } else if (token->type == AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX) {
            AVIF_CHECK(avifROStreamRead(s, &token->inputImageItemIndex, 1)); // unsigned int(8) input_image_item_index;
        }
    }
    AVIF_CHECKERR(avifROStreamRemainingBytes(s) == 0, AVIF_RESULT_BMFF_PARSE_FAILED);
    return AVIF_RESULT_OK;
}

// Parses the raw bitstream of the 'sato' Sample Transform derived image item and extracts the expression.
static avifResult avifParseSampleTransformImageBox(const uint8_t * raw,
                                                   size_t rawLen,
                                                   uint32_t numInputImageItems,
                                                   avifSampleTransformExpression * expression,
                                                   avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[sato]");

    uint8_t version, bitDepth;
    AVIF_CHECK(avifROStreamReadBitsU8(&s, &version, /*bitCount=*/6));  // unsigned int(6) version = 0;
    AVIF_CHECK(avifROStreamReadBitsU8(&s, &bitDepth, /*bitCount=*/2)); // unsigned int(2) bit_depth;
    AVIF_CHECKERR(version == 0, AVIF_RESULT_NOT_IMPLEMENTED);
    AVIF_CHECKERR(bitDepth == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_32, AVIF_RESULT_NOT_IMPLEMENTED);

    const avifResult result = avifParseSampleTransformTokens(&s, expression);
    if (result != AVIF_RESULT_OK) {
        avifArrayDestroy(expression);
        return result;
    }
    if (!avifSampleTransformExpressionIsValid(expression, numInputImageItems)) {
        avifArrayDestroy(expression);
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }
    return AVIF_RESULT_OK;
}

static avifResult avifDecoderSampleTransformItemValidateProperties(const avifDecoderItem * item, avifDiagnostics * diag)
{
    const avifProperty * pixiProp = avifPropertyArrayFind(&item->properties, "pixi");
    if (!pixiProp) {
        avifDiagnosticsPrintf(diag, "Item ID %u of type '%.4s' is missing mandatory pixi property", item->id, (const char *)item->type);
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }
    for (uint8_t i = 0; i < pixiProp->u.pixi.planeCount; ++i) {
        if (pixiProp->u.pixi.planeDepths[i] != pixiProp->u.pixi.planeDepths[0]) {
            avifDiagnosticsPrintf(diag,
                                  "Item ID %u of type '%.4s' has different depths specified by pixi property [%u, %u], this is not supported",
                                  item->id,
                                  (const char *)item->type,
                                  pixiProp->u.pixi.planeDepths[0],
                                  pixiProp->u.pixi.planeDepths[i]);
            return AVIF_RESULT_NOT_IMPLEMENTED;
        }
    }

    const avifProperty * ispeProp = avifPropertyArrayFind(&item->properties, "ispe");
    if (!ispeProp) {
        avifDiagnosticsPrintf(diag, "Item ID %u of type '%.4s' is missing mandatory ispe property", item->id, (const char *)item->type);
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }

    for (uint32_t i = 0; i < item->meta->items.count; ++i) {
        avifDecoderItem * inputImageItem = item->meta->items.item[i];
        if (inputImageItem->dimgForID != item->id) {
            continue;
        }
        // Even if inputImageItem is a grid, the ispe property from its first tile should have been copied to the grid item.
        const avifProperty * inputImageItemIspeProp = avifPropertyArrayFind(&inputImageItem->properties, "ispe");
        AVIF_ASSERT_OR_RETURN(inputImageItemIspeProp != NULL);
        if (inputImageItemIspeProp->u.ispe.width != ispeProp->u.ispe.width ||
            inputImageItemIspeProp->u.ispe.height != ispeProp->u.ispe.height) {
            avifDiagnosticsPrintf(diag,
                                  "The fields of the ispe property of item ID %u of type '%.4s' differs from item ID %u",
                                  inputImageItem->id,
                                  (const char *)inputImageItem->type,
                                  item->id);
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }
        // TODO(yguyon): Check that all input image items share the same codec config (except for the bit depth value).
    }

    AVIF_CHECKERR(avifPropertyArrayFind(&item->properties, "clap") == NULL, AVIF_RESULT_NOT_IMPLEMENTED);
    return AVIF_RESULT_OK;
}
#endif // AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM

// Extracts the codecType from the item type or from its children.
// Also parses and outputs grid information if the item is a grid.
// isItemInInput must be false if the item is a made-up structure
// (and thus not part of the parseable input bitstream).
static avifResult avifDecoderItemReadAndParse(const avifDecoder * decoder,
                                              avifDecoderItem * item,
                                              avifBool isItemInInput,
                                              avifImageGrid * grid,
                                              avifCodecType * codecType)
{
    if (!memcmp(item->type, "grid", 4)) {
        if (isItemInInput) {
            avifROData readData;
            AVIF_CHECKRES(avifDecoderItemRead(item, decoder->io, &readData, 0, 0, decoder->data->diag));
            AVIF_CHECKERR(avifParseImageGridBox(grid,
                                                readData.data,
                                                readData.size,
                                                decoder->imageSizeLimit,
                                                decoder->imageDimensionLimit,
                                                decoder->data->diag),
                          AVIF_RESULT_INVALID_IMAGE_GRID);
            // Validate that there are exactly the same number of dimg items to form the grid.
            uint32_t dimgItemCount = 0;
            for (uint32_t i = 0; i < item->meta->items.count; ++i) {
                if (item->meta->items.item[i]->dimgForID == item->id) {
                    ++dimgItemCount;
                }
            }
            AVIF_CHECKERR(dimgItemCount == grid->rows * grid->columns, AVIF_RESULT_INVALID_IMAGE_GRID);
        } else {
            // item was generated for convenience and is not part of the bitstream.
            // grid information should already be set.
            AVIF_ASSERT_OR_RETURN(grid->rows > 0 && grid->columns > 0);
        }
        *codecType = avifDecoderItemGetGridCodecType(item);
        AVIF_CHECKERR(*codecType != AVIF_CODEC_TYPE_UNKNOWN, AVIF_RESULT_INVALID_IMAGE_GRID);
    } else {
        *codecType = avifGetCodecType(item->type);
        AVIF_ASSERT_OR_RETURN(*codecType != AVIF_CODEC_TYPE_UNKNOWN);
    }
    // TODO(yguyon): If AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM is defined, backward-incompatible
    //               files with a primary 'sato' Sample Transform derived image item could be
    //               handled here (compared to backward-compatible files with a 'sato' item in the
    //               same 'altr' group as the primary regular color item which are handled in
    //               avifDecoderDataFindSampleTransformImageItem() below).
    return AVIF_RESULT_OK;
}

static avifBool avifParseImageSpatialExtentsProperty(avifProperty * prop, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[ispe]");
    AVIF_CHECK(avifROStreamReadAndEnforceVersion(&s, 0));

    avifImageSpatialExtents * ispe = &prop->u.ispe;
    AVIF_CHECK(avifROStreamReadU32(&s, &ispe->width));
    AVIF_CHECK(avifROStreamReadU32(&s, &ispe->height));
    return AVIF_TRUE;
}

static avifBool avifParseAuxiliaryTypeProperty(avifProperty * prop, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[auxC]");
    AVIF_CHECK(avifROStreamReadAndEnforceVersion(&s, 0));

    AVIF_CHECK(avifROStreamReadString(&s, prop->u.auxC.auxType, AUXTYPE_SIZE));
    return AVIF_TRUE;
}

static avifBool avifParseColourInformationBox(avifProperty * prop, uint64_t rawOffset, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[colr]");

    avifColourInformationBox * colr = &prop->u.colr;
    colr->hasICC = AVIF_FALSE;
    colr->hasNCLX = AVIF_FALSE;

    uint8_t colorType[4]; // unsigned int(32) colour_type;
    AVIF_CHECK(avifROStreamRead(&s, colorType, 4));
    if (!memcmp(colorType, "rICC", 4) || !memcmp(colorType, "prof", 4)) {
        colr->hasICC = AVIF_TRUE;
        // Remember the offset of the ICC payload relative to the beginning of the stream. A direct pointer cannot be stored
        // because decoder->io->persistent could have been AVIF_FALSE when obtaining raw through decoder->io->read().
        // The bytes could be copied now instead of remembering the offset, but it is as invasive as passing rawOffset everywhere.
        colr->iccOffset = rawOffset + avifROStreamOffset(&s);
        colr->iccSize = avifROStreamRemainingBytes(&s);
    } else if (!memcmp(colorType, "nclx", 4)) {
        AVIF_CHECK(avifROStreamReadU16(&s, &colr->colorPrimaries));          // unsigned int(16) colour_primaries;
        AVIF_CHECK(avifROStreamReadU16(&s, &colr->transferCharacteristics)); // unsigned int(16) transfer_characteristics;
        AVIF_CHECK(avifROStreamReadU16(&s, &colr->matrixCoefficients));      // unsigned int(16) matrix_coefficients;
        uint8_t full_range_flag;
        AVIF_CHECK(avifROStreamReadBitsU8(&s, &full_range_flag, /*bitCount=*/1)); // unsigned int(1) full_range_flag;
        colr->range = full_range_flag ? AVIF_RANGE_FULL : AVIF_RANGE_LIMITED;
        uint8_t reserved;
        AVIF_CHECK(avifROStreamReadBitsU8(&s, &reserved, /*bitCount=*/7)); // unsigned int(7) reserved = 0;
        if (reserved) {
            avifDiagnosticsPrintf(diag, "Box[colr] contains nonzero reserved bits [%u]", reserved);
            return AVIF_FALSE;
        }
        colr->hasNCLX = AVIF_TRUE;
    }
    return AVIF_TRUE;
}

static avifResult avifParseContentLightLevelInformation(avifROStream * s, avifContentLightLevelInformationBox * clli)
{
    AVIF_CHECKERR(avifROStreamReadBitsU16(s, &clli->maxCLL, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) max_content_light_level
    AVIF_CHECKERR(avifROStreamReadBitsU16(s, &clli->maxPALL, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) max_pic_average_light_level
    return AVIF_RESULT_OK;
}
static avifResult avifParseContentLightLevelInformationBox(avifProperty * prop, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[clli]");
    AVIF_CHECKRES(avifParseContentLightLevelInformation(&s, &prop->u.clli));
    return AVIF_RESULT_OK;
}

#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI) && defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
static avifResult avifSkipMasteringDisplayColourVolume(avifROStream * s)
{
    for (int c = 0; c < 3; c++) {
        AVIF_CHECKERR(avifROStreamSkipBits(s, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) display_primaries_x;
        AVIF_CHECKERR(avifROStreamSkipBits(s, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) display_primaries_y;
    }
    AVIF_CHECKERR(avifROStreamSkipBits(s, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) white_point_x;
    AVIF_CHECKERR(avifROStreamSkipBits(s, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) white_point_y;
    AVIF_CHECKERR(avifROStreamSkipBits(s, 32), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) max_display_mastering_luminance;
    AVIF_CHECKERR(avifROStreamSkipBits(s, 32), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) min_display_mastering_luminance;
    return AVIF_RESULT_OK;
}

static avifResult avifSkipContentColourVolume(avifROStream * s)
{
    AVIF_CHECKERR(avifROStreamSkipBits(s, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) reserved = 0; // ccv_cancel_flag
    AVIF_CHECKERR(avifROStreamSkipBits(s, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) reserved = 0; // ccv_persistence_flag
    uint8_t ccvPrimariesPresent;
    AVIF_CHECKERR(avifROStreamReadBitsU8(s, &ccvPrimariesPresent, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) ccv_primaries_present_flag;
    uint8_t ccvMinLuminanceValuePresent, ccvMaxLuminanceValuePresent, ccvAvgLuminanceValuePresent;
    AVIF_CHECKERR(avifROStreamReadBitsU8(s, &ccvMinLuminanceValuePresent, 1),
                  AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) ccv_min_luminance_value_present_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU8(s, &ccvMaxLuminanceValuePresent, 1),
                  AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) ccv_max_luminance_value_present_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU8(s, &ccvAvgLuminanceValuePresent, 1),
                  AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) ccv_avg_luminance_value_present_flag;
    AVIF_CHECKERR(avifROStreamSkipBits(s, 2), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(2) reserved = 0;

    if (ccvPrimariesPresent) {
        for (int c = 0; c < 3; c++) {
            AVIF_CHECKERR(avifROStreamSkipBits(s, 32), AVIF_RESULT_BMFF_PARSE_FAILED); // signed int(32) ccv_primaries_x[[c]];
            AVIF_CHECKERR(avifROStreamSkipBits(s, 32), AVIF_RESULT_BMFF_PARSE_FAILED); // signed int(32) ccv_primaries_y[[c]];
        }
    }
    if (ccvMinLuminanceValuePresent) {
        AVIF_CHECKERR(avifROStreamSkipBits(s, 32), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) ccv_min_luminance_value;
    }
    if (ccvMaxLuminanceValuePresent) {
        AVIF_CHECKERR(avifROStreamSkipBits(s, 32), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) ccv_max_luminance_value;
    }
    if (ccvAvgLuminanceValuePresent) {
        AVIF_CHECKERR(avifROStreamSkipBits(s, 32), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) ccv_avg_luminance_value;
    }
    return AVIF_RESULT_OK;
}

static avifResult avifSkipAmbientViewingEnvironment(avifROStream * s)
{
    AVIF_CHECKERR(avifROStreamSkipBits(s, 32), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) ambient_illuminance;
    AVIF_CHECKERR(avifROStreamSkipBits(s, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) ambient_light_x;
    AVIF_CHECKERR(avifROStreamSkipBits(s, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) ambient_light_y;
    return AVIF_RESULT_OK;
}

static avifResult avifSkipReferenceViewingEnvironment(avifROStream * s)
{
    AVIF_CHECKERR(avifROStreamSkipBits(s, 32), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) surround_luminance;
    AVIF_CHECKERR(avifROStreamSkipBits(s, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) surround_light_x;
    AVIF_CHECKERR(avifROStreamSkipBits(s, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) surround_light_y;
    AVIF_CHECKERR(avifROStreamSkipBits(s, 32), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) periphery_luminance;
    AVIF_CHECKERR(avifROStreamSkipBits(s, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) periphery_light_x;
    AVIF_CHECKERR(avifROStreamSkipBits(s, 16), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) periphery_light_y;
    return AVIF_RESULT_OK;
}

static avifResult avifSkipNominalDiffuseWhite(avifROStream * s)
{
    AVIF_CHECKERR(avifROStreamSkipBits(s, 32), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) diffuse_white_luminance;
    return AVIF_RESULT_OK;
}

static avifResult avifParseMiniHDRProperties(avifROStream * s, uint32_t * hasClli, avifContentLightLevelInformationBox * clli)
{
    AVIF_CHECKERR(avifROStreamReadBitsU32(s, hasClli, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) clli_flag;
    uint32_t hasMdcv, hasCclv, hasAmve, hasReve, hasNdwt;
    AVIF_CHECKERR(avifROStreamReadBitsU32(s, &hasMdcv, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) mdcv_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(s, &hasCclv, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) cclv_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(s, &hasAmve, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) amve_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(s, &hasReve, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) reve_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(s, &hasNdwt, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) ndwt_flag;
    if (*hasClli) {
        AVIF_CHECKRES(avifParseContentLightLevelInformation(s, clli)); // ContentLightLevel clli;
    }
    if (hasMdcv) {
        AVIF_CHECKRES(avifSkipMasteringDisplayColourVolume(s)); // MasteringDisplayColourVolume mdcv;
    }
    if (hasCclv) {
        AVIF_CHECKRES(avifSkipContentColourVolume(s)); // ContentColourVolume cclv;
    }
    if (hasAmve) {
        AVIF_CHECKRES(avifSkipAmbientViewingEnvironment(s)); // AmbientViewingEnvironment amve;
    }
    if (hasReve) {
        AVIF_CHECKRES(avifSkipReferenceViewingEnvironment(s)); // ReferenceViewingEnvironment reve;
    }
    if (hasNdwt) {
        AVIF_CHECKRES(avifSkipNominalDiffuseWhite(s)); // NominalDiffuseWhite ndwt;
    }
    return AVIF_RESULT_OK;
}
#endif // AVIF_ENABLE_EXPERIMENTAL_MINI && AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP

// Implementation of section 2.3.3 of AV1 Codec ISO Media File Format Binding specification v1.2.0.
// See https://aomediacodec.github.io/av1-isobmff/v1.2.0.html#av1codecconfigurationbox-syntax.
static avifBool avifParseCodecConfiguration(avifROStream * s, avifCodecConfigurationBox * config, const char * configPropName, avifDiagnostics * diag)
{
    const size_t av1COffset = s->offset;

    uint32_t marker, version;
    AVIF_CHECK(avifROStreamReadBitsU32(s, &marker, /*bitCount=*/1)); // unsigned int (1) marker = 1;
    if (!marker) {
        avifDiagnosticsPrintf(diag, "%.4s contains illegal marker: [%u]", configPropName, marker);
        return AVIF_FALSE;
    }
    AVIF_CHECK(avifROStreamReadBitsU32(s, &version, /*bitCount=*/7)); // unsigned int (7) version = 1;
    if (version != 1) {
        avifDiagnosticsPrintf(diag, "%.4s contains illegal version: [%u]", configPropName, version);
        return AVIF_FALSE;
    }

    AVIF_CHECK(avifROStreamReadBitsU8(s, &config->seqProfile, /*bitCount=*/3));         // unsigned int (3) seq_profile;
    AVIF_CHECK(avifROStreamReadBitsU8(s, &config->seqLevelIdx0, /*bitCount=*/5));       // unsigned int (5) seq_level_idx_0;
    AVIF_CHECK(avifROStreamReadBitsU8(s, &config->seqTier0, /*bitCount=*/1));           // unsigned int (1) seq_tier_0;
    AVIF_CHECK(avifROStreamReadBitsU8(s, &config->highBitdepth, /*bitCount=*/1));       // unsigned int (1) high_bitdepth;
    AVIF_CHECK(avifROStreamReadBitsU8(s, &config->twelveBit, /*bitCount=*/1));          // unsigned int (1) twelve_bit;
    AVIF_CHECK(avifROStreamReadBitsU8(s, &config->monochrome, /*bitCount=*/1));         // unsigned int (1) monochrome;
    AVIF_CHECK(avifROStreamReadBitsU8(s, &config->chromaSubsamplingX, /*bitCount=*/1)); // unsigned int (1) chroma_subsampling_x;
    AVIF_CHECK(avifROStreamReadBitsU8(s, &config->chromaSubsamplingY, /*bitCount=*/1)); // unsigned int (1) chroma_subsampling_y;
    AVIF_CHECK(avifROStreamReadBitsU8(s, &config->chromaSamplePosition, /*bitCount=*/2)); // unsigned int (2) chroma_sample_position;

    // unsigned int (3) reserved = 0;
    // unsigned int (1) initial_presentation_delay_present;
    // if (initial_presentation_delay_present) {
    //   unsigned int (4) initial_presentation_delay_minus_one;
    // } else {
    //   unsigned int (4) reserved = 0;
    // }
    AVIF_CHECK(avifROStreamSkip(s, /*byteCount=*/1));

    // According to section 2.2.1 of AV1 Image File Format specification v1.1.0:
    //   - Sequence Header OBUs should not be present in the AV1CodecConfigurationBox.
    //   - If a Sequence Header OBU is present in the AV1CodecConfigurationBox,
    //     it shall match the Sequence Header OBU in the AV1 Image Item Data.
    //   - Metadata OBUs, if present, shall match the values given in other item properties,
    //     such as the PixelInformationProperty or ColourInformationBox.
    // See https://aomediacodec.github.io/av1-avif/v1.1.0.html#av1-configuration-item-property.
    // For simplicity, the constraints above are not enforced.
    // The following is skipped by avifParseItemPropertyContainerBox().
    // unsigned int (8) configOBUs[];

    AVIF_CHECK(s->offset - av1COffset == 4); // Make sure avifParseCodecConfiguration() reads exactly 4 bytes.
    return AVIF_TRUE;
}

static avifBool avifParseCodecConfigurationBoxProperty(avifProperty * prop,
                                                       const uint8_t * raw,
                                                       size_t rawLen,
                                                       const char * configPropName,
                                                       avifDiagnostics * diag)
{
    char diagContext[10];
    snprintf(diagContext, sizeof(diagContext), "Box[%.4s]", configPropName); // "Box[av1C]" or "Box[av2C]"
    BEGIN_STREAM(s, raw, rawLen, diag, diagContext);
    return avifParseCodecConfiguration(&s, &prop->u.av1C, configPropName, diag);
}

static avifBool avifParsePixelAspectRatioBoxProperty(avifProperty * prop, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[pasp]");

    avifPixelAspectRatioBox * pasp = &prop->u.pasp;
    AVIF_CHECK(avifROStreamReadU32(&s, &pasp->hSpacing)); // unsigned int(32) hSpacing;
    AVIF_CHECK(avifROStreamReadU32(&s, &pasp->vSpacing)); // unsigned int(32) vSpacing;
    return AVIF_TRUE;
}

static avifBool avifParseCleanApertureBoxProperty(avifProperty * prop, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[clap]");

    avifCleanApertureBox * clap = &prop->u.clap;
    AVIF_CHECK(avifROStreamReadU32(&s, &clap->widthN));    // unsigned int(32) cleanApertureWidthN;
    AVIF_CHECK(avifROStreamReadU32(&s, &clap->widthD));    // unsigned int(32) cleanApertureWidthD;
    AVIF_CHECK(avifROStreamReadU32(&s, &clap->heightN));   // unsigned int(32) cleanApertureHeightN;
    AVIF_CHECK(avifROStreamReadU32(&s, &clap->heightD));   // unsigned int(32) cleanApertureHeightD;
    AVIF_CHECK(avifROStreamReadU32(&s, &clap->horizOffN)); // unsigned int(32) horizOffN;
    AVIF_CHECK(avifROStreamReadU32(&s, &clap->horizOffD)); // unsigned int(32) horizOffD;
    AVIF_CHECK(avifROStreamReadU32(&s, &clap->vertOffN));  // unsigned int(32) vertOffN;
    AVIF_CHECK(avifROStreamReadU32(&s, &clap->vertOffD));  // unsigned int(32) vertOffD;
    return AVIF_TRUE;
}

static avifBool avifParseImageRotationProperty(avifProperty * prop, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[irot]");

    avifImageRotation * irot = &prop->u.irot;
    uint8_t reserved;
    AVIF_CHECK(avifROStreamReadBitsU8(&s, &reserved, /*bitCount=*/6)); // unsigned int (6) reserved = 0;
    if (reserved) {
        avifDiagnosticsPrintf(diag, "Box[irot] contains nonzero reserved bits [%u]", reserved);
        return AVIF_FALSE;
    }
    AVIF_CHECK(avifROStreamReadBitsU8(&s, &irot->angle, /*bitCount=*/2)); // unsigned int (2) angle;
    return AVIF_TRUE;
}

static avifBool avifParseImageMirrorProperty(avifProperty * prop, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[imir]");

    avifImageMirror * imir = &prop->u.imir;
    uint8_t reserved;
    AVIF_CHECK(avifROStreamReadBitsU8(&s, &reserved, /*bitCount=*/7)); // unsigned int(7) reserved = 0;
    if (reserved) {
        avifDiagnosticsPrintf(diag, "Box[imir] contains nonzero reserved bits [%u]", reserved);
        return AVIF_FALSE;
    }
    AVIF_CHECK(avifROStreamReadBitsU8(&s, &imir->axis, /*bitCount=*/1)); // unsigned int(1) axis;
    return AVIF_TRUE;
}

static avifBool avifParsePixelInformationProperty(avifProperty * prop, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[pixi]");
    AVIF_CHECK(avifROStreamReadAndEnforceVersion(&s, 0));

    avifPixelInformationProperty * pixi = &prop->u.pixi;
    AVIF_CHECK(avifROStreamRead(&s, &pixi->planeCount, 1)); // unsigned int (8) num_channels;
    if (pixi->planeCount < 1 || pixi->planeCount > MAX_PIXI_PLANE_DEPTHS) {
        avifDiagnosticsPrintf(diag, "Box[pixi] contains unsupported plane count [%u]", pixi->planeCount);
        return AVIF_FALSE;
    }
    for (uint8_t i = 0; i < pixi->planeCount; ++i) {
        AVIF_CHECK(avifROStreamRead(&s, &pixi->planeDepths[i], 1)); // unsigned int (8) bits_per_channel;
        if (pixi->planeDepths[i] != pixi->planeDepths[0]) {
            avifDiagnosticsPrintf(diag,
                                  "Box[pixi] contains unsupported mismatched plane depths [%u != %u]",
                                  pixi->planeDepths[i],
                                  pixi->planeDepths[0]);
            return AVIF_FALSE;
        }
    }
    return AVIF_TRUE;
}

static avifBool avifParseOperatingPointSelectorProperty(avifProperty * prop, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[a1op]");

    avifOperatingPointSelectorProperty * a1op = &prop->u.a1op;
    AVIF_CHECK(avifROStreamRead(&s, &a1op->opIndex, 1));
    if (a1op->opIndex > 31) { // 31 is AV1's max operating point value
        avifDiagnosticsPrintf(diag, "Box[a1op] contains an unsupported operating point [%u]", a1op->opIndex);
        return AVIF_FALSE;
    }
    return AVIF_TRUE;
}

static avifBool avifParseLayerSelectorProperty(avifProperty * prop, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[lsel]");

    avifLayerSelectorProperty * lsel = &prop->u.lsel;
    AVIF_CHECK(avifROStreamReadU16(&s, &lsel->layerID));
    if ((lsel->layerID != 0xFFFF) && (lsel->layerID >= AVIF_MAX_AV1_LAYER_COUNT)) {
        avifDiagnosticsPrintf(diag, "Box[lsel] contains an unsupported layer [%u]", lsel->layerID);
        return AVIF_FALSE;
    }
    return AVIF_TRUE;
}

static avifBool avifParseAV1LayeredImageIndexingProperty(avifProperty * prop, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[a1lx]");

    avifAV1LayeredImageIndexingProperty * a1lx = &prop->u.a1lx;

    uint8_t largeSize = 0;
    AVIF_CHECK(avifROStreamRead(&s, &largeSize, 1));
    if (largeSize & 0xFE) {
        avifDiagnosticsPrintf(diag, "Box[a1lx] has bits set in the reserved section [%u]", largeSize);
        return AVIF_FALSE;
    }

    for (int i = 0; i < 3; ++i) {
        if (largeSize) {
            AVIF_CHECK(avifROStreamReadU32(&s, &a1lx->layerSize[i]));
        } else {
            uint16_t layerSize16;
            AVIF_CHECK(avifROStreamReadU16(&s, &layerSize16));
            a1lx->layerSize[i] = (uint32_t)layerSize16;
        }
    }

    // Layer sizes will be validated later (when the item's size is known)
    return AVIF_TRUE;
}

static avifResult avifParseItemPropertyContainerBox(avifPropertyArray * properties,
                                                    uint64_t rawOffset,
                                                    const uint8_t * raw,
                                                    size_t rawLen,
                                                    avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[ipco]");

    while (avifROStreamHasBytesLeft(&s, 1)) {
        avifBoxHeader header;
        AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &header), AVIF_RESULT_BMFF_PARSE_FAILED);

        avifProperty * prop = (avifProperty *)avifArrayPush(properties);
        AVIF_CHECKERR(prop != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        memcpy(prop->type, header.type, 4);
        if (!memcmp(header.type, "ispe", 4)) {
            AVIF_CHECKERR(avifParseImageSpatialExtentsProperty(prop, avifROStreamCurrent(&s), header.size, diag),
                          AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "auxC", 4)) {
            AVIF_CHECKERR(avifParseAuxiliaryTypeProperty(prop, avifROStreamCurrent(&s), header.size, diag), AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "colr", 4)) {
            AVIF_CHECKERR(avifParseColourInformationBox(prop, rawOffset + avifROStreamOffset(&s), avifROStreamCurrent(&s), header.size, diag),
                          AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "av1C", 4)) {
            AVIF_CHECKERR(avifParseCodecConfigurationBoxProperty(prop, avifROStreamCurrent(&s), header.size, "av1C", diag),
                          AVIF_RESULT_BMFF_PARSE_FAILED);
#if defined(AVIF_CODEC_AVM)
        } else if (!memcmp(header.type, "av2C", 4)) {
            AVIF_CHECKERR(avifParseCodecConfigurationBoxProperty(prop, avifROStreamCurrent(&s), header.size, "av2C", diag),
                          AVIF_RESULT_BMFF_PARSE_FAILED);
#endif
        } else if (!memcmp(header.type, "pasp", 4)) {
            AVIF_CHECKERR(avifParsePixelAspectRatioBoxProperty(prop, avifROStreamCurrent(&s), header.size, diag),
                          AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "clap", 4)) {
            AVIF_CHECKERR(avifParseCleanApertureBoxProperty(prop, avifROStreamCurrent(&s), header.size, diag),
                          AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "irot", 4)) {
            AVIF_CHECKERR(avifParseImageRotationProperty(prop, avifROStreamCurrent(&s), header.size, diag), AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "imir", 4)) {
            AVIF_CHECKERR(avifParseImageMirrorProperty(prop, avifROStreamCurrent(&s), header.size, diag), AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "pixi", 4)) {
            AVIF_CHECKERR(avifParsePixelInformationProperty(prop, avifROStreamCurrent(&s), header.size, diag),
                          AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "a1op", 4)) {
            AVIF_CHECKERR(avifParseOperatingPointSelectorProperty(prop, avifROStreamCurrent(&s), header.size, diag),
                          AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "lsel", 4)) {
            AVIF_CHECKERR(avifParseLayerSelectorProperty(prop, avifROStreamCurrent(&s), header.size, diag), AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "a1lx", 4)) {
            AVIF_CHECKERR(avifParseAV1LayeredImageIndexingProperty(prop, avifROStreamCurrent(&s), header.size, diag),
                          AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "clli", 4)) {
            AVIF_CHECKRES(avifParseContentLightLevelInformationBox(prop, avifROStreamCurrent(&s), header.size, diag));
        }

        AVIF_CHECKERR(avifROStreamSkip(&s, header.size), AVIF_RESULT_BMFF_PARSE_FAILED);
    }
    return AVIF_RESULT_OK;
}

static avifResult avifParseItemPropertyAssociation(avifMeta * meta, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag, uint32_t * outVersionAndFlags)
{
    // NOTE: If this function ever adds support for versions other than [0,1] or flags other than
    //       [0,1], please increase the value of MAX_IPMA_VERSION_AND_FLAGS_SEEN accordingly.

    BEGIN_STREAM(s, raw, rawLen, diag, "Box[ipma]");

    uint8_t version;
    uint32_t flags;
    AVIF_CHECKERR(avifROStreamReadVersionAndFlags(&s, &version, &flags), AVIF_RESULT_BMFF_PARSE_FAILED);
    avifBool propertyIndexIsU15 = ((flags & 0x1) != 0);
    *outVersionAndFlags = ((uint32_t)version << 24) | flags;

    uint32_t entryCount;
    AVIF_CHECKERR(avifROStreamReadU32(&s, &entryCount), AVIF_RESULT_BMFF_PARSE_FAILED);
    unsigned int prevItemID = 0;
    for (uint32_t entryIndex = 0; entryIndex < entryCount; ++entryIndex) {
        // ISO/IEC 14496-12, Seventh edition, 2022-01, Section 8.11.14.1:
        //   Each ItemPropertyAssociationBox shall be ordered by increasing item_ID, and there shall
        //   be at most one occurrence of a given item_ID, in the set of ItemPropertyAssociationBox
        //   boxes.
        unsigned int itemID;
        if (version < 1) {
            uint16_t tmp;
            AVIF_CHECKERR(avifROStreamReadU16(&s, &tmp), AVIF_RESULT_BMFF_PARSE_FAILED);
            itemID = tmp;
        } else {
            AVIF_CHECKERR(avifROStreamReadU32(&s, &itemID), AVIF_RESULT_BMFF_PARSE_FAILED);
        }
        AVIF_CHECKRES(avifCheckItemID("ipma", itemID, diag));
        if (itemID <= prevItemID) {
            avifDiagnosticsPrintf(diag, "Box[ipma] item IDs are not ordered by increasing ID");
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }
        prevItemID = itemID;

        avifDecoderItem * item;
        AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, itemID, &item));
        if (item->ipmaSeen) {
            avifDiagnosticsPrintf(diag, "Duplicate Box[ipma] for item ID [%u]", itemID);
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }
        item->ipmaSeen = AVIF_TRUE;

        uint8_t associationCount;
        AVIF_CHECKERR(avifROStreamRead(&s, &associationCount, 1), AVIF_RESULT_BMFF_PARSE_FAILED);
        for (uint8_t associationIndex = 0; associationIndex < associationCount; ++associationIndex) {
            uint8_t essential;
            AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &essential, /*bitCount=*/1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) essential;
            uint32_t propertyIndex;
            AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &propertyIndex, /*bitCount=*/propertyIndexIsU15 ? 15 : 7),
                          AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(7/15) property_index;

            if (propertyIndex == 0) {
                // Not associated with any item
                continue;
            }
            --propertyIndex; // 1-indexed

            if (propertyIndex >= meta->properties.count) {
                avifDiagnosticsPrintf(diag,
                                      "Box[ipma] for item ID [%u] contains an illegal property index [%u] (out of [%u] properties)",
                                      itemID,
                                      propertyIndex,
                                      meta->properties.count);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }

            // Copy property to item
            const avifProperty * srcProp = &meta->properties.prop[propertyIndex];

            static const char * supportedTypes[] = {
                "ispe",
                "auxC",
                "colr",
                "av1C",
#if defined(AVIF_CODEC_AVM)
                "av2C",
#endif
                "pasp",
                "clap",
                "irot",
                "imir",
                "pixi",
                "a1op",
                "lsel",
                "a1lx",
                "clli"
            };
            size_t supportedTypesCount = sizeof(supportedTypes) / sizeof(supportedTypes[0]);
            avifBool supportedType = AVIF_FALSE;
            for (size_t i = 0; i < supportedTypesCount; ++i) {
                if (!memcmp(srcProp->type, supportedTypes[i], 4)) {
                    supportedType = AVIF_TRUE;
                    break;
                }
            }
            if (supportedType) {
                if (essential) {
                    // Verify that it is legal for this property to be flagged as essential. Any
                    // types in this list are *required* in the spec to not be flagged as essential
                    // when associated with an item.
                    static const char * const nonessentialTypes[] = {

                        // AVIF: Section 2.3.2.3.2: "If associated, it shall not be marked as essential."
                        "a1lx"

                    };
                    size_t nonessentialTypesCount = sizeof(nonessentialTypes) / sizeof(nonessentialTypes[0]);
                    for (size_t i = 0; i < nonessentialTypesCount; ++i) {
                        if (!memcmp(srcProp->type, nonessentialTypes[i], 4)) {
                            avifDiagnosticsPrintf(diag,
                                                  "Item ID [%u] has a %s property association which must not be marked essential, but is",
                                                  itemID,
                                                  nonessentialTypes[i]);
                            return AVIF_RESULT_BMFF_PARSE_FAILED;
                        }
                    }
                } else {
                    // Verify that it is legal for this property to not be flagged as essential. Any
                    // types in this list are *required* in the spec to be flagged as essential when
                    // associated with an item.
                    static const char * const essentialTypes[] = {

                        // AVIF: Section 2.3.2.1.1: "If associated, it shall be marked as essential."
                        "a1op",

                        // HEIF: Section 6.5.11.1: "essential shall be equal to 1 for an 'lsel' item property."
                        "lsel"

                    };
                    size_t essentialTypesCount = sizeof(essentialTypes) / sizeof(essentialTypes[0]);
                    for (size_t i = 0; i < essentialTypesCount; ++i) {
                        if (!memcmp(srcProp->type, essentialTypes[i], 4)) {
                            avifDiagnosticsPrintf(diag,
                                                  "Item ID [%u] has a %s property association which must be marked essential, but is not",
                                                  itemID,
                                                  essentialTypes[i]);
                            return AVIF_RESULT_BMFF_PARSE_FAILED;
                        }
                    }
                }

                // Supported and valid; associate it with this item.
                avifProperty * dstProp = (avifProperty *)avifArrayPush(&item->properties);
                AVIF_CHECKERR(dstProp != NULL, AVIF_RESULT_OUT_OF_MEMORY);
                *dstProp = *srcProp;
            } else {
                if (essential) {
                    // Discovered an essential item property that libavif doesn't support!
                    // Make a note to ignore this item later.
                    item->hasUnsupportedEssentialProperty = AVIF_TRUE;
                }
            }
        }
    }
    return AVIF_RESULT_OK;
}

static avifBool avifParsePrimaryItemBox(avifMeta * meta, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    if (meta->primaryItemID > 0) {
        // Illegal to have multiple pitm boxes, bail out
        avifDiagnosticsPrintf(diag, "Multiple boxes of unique Box[pitm] found");
        return AVIF_FALSE;
    }

    BEGIN_STREAM(s, raw, rawLen, diag, "Box[pitm]");

    uint8_t version;
    AVIF_CHECK(avifROStreamReadVersionAndFlags(&s, &version, NULL));

    if (version == 0) {
        uint16_t tmp16;
        AVIF_CHECK(avifROStreamReadU16(&s, &tmp16)); // unsigned int(16) item_ID;
        meta->primaryItemID = tmp16;
    } else {
        AVIF_CHECK(avifROStreamReadU32(&s, &meta->primaryItemID)); // unsigned int(32) item_ID;
    }
    return AVIF_TRUE;
}

static avifBool avifParseItemDataBox(avifMeta * meta, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    // Check to see if we've already seen an idat box for this meta box. If so, bail out
    if (meta->idat.size > 0) {
        avifDiagnosticsPrintf(diag, "Meta box contains multiple idat boxes");
        return AVIF_FALSE;
    }
    if (rawLen == 0) {
        avifDiagnosticsPrintf(diag, "idat box has a length of 0");
        return AVIF_FALSE;
    }

    if (avifRWDataSet(&meta->idat, raw, rawLen) != AVIF_RESULT_OK) {
        return AVIF_FALSE;
    }
    return AVIF_TRUE;
}

static avifResult avifParseItemPropertiesBox(avifMeta * meta, uint64_t rawOffset, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[iprp]");

    avifBoxHeader ipcoHeader;
    AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &ipcoHeader), AVIF_RESULT_BMFF_PARSE_FAILED);
    if (memcmp(ipcoHeader.type, "ipco", 4)) {
        avifDiagnosticsPrintf(diag, "Failed to find Box[ipco] as the first box in Box[iprp]");
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }

    // Read all item properties inside of ItemPropertyContainerBox
    AVIF_CHECKRES(avifParseItemPropertyContainerBox(&meta->properties,
                                                    rawOffset + avifROStreamOffset(&s),
                                                    avifROStreamCurrent(&s),
                                                    ipcoHeader.size,
                                                    diag));
    AVIF_CHECKERR(avifROStreamSkip(&s, ipcoHeader.size), AVIF_RESULT_BMFF_PARSE_FAILED);

    uint32_t versionAndFlagsSeen[MAX_IPMA_VERSION_AND_FLAGS_SEEN];
    uint32_t versionAndFlagsSeenCount = 0;

    // Now read all ItemPropertyAssociation until the end of the box, and make associations
    while (avifROStreamHasBytesLeft(&s, 1)) {
        avifBoxHeader ipmaHeader;
        AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &ipmaHeader), AVIF_RESULT_BMFF_PARSE_FAILED);

        if (!memcmp(ipmaHeader.type, "ipma", 4)) {
            uint32_t versionAndFlags;
            AVIF_CHECKRES(avifParseItemPropertyAssociation(meta, avifROStreamCurrent(&s), ipmaHeader.size, diag, &versionAndFlags));
            for (uint32_t i = 0; i < versionAndFlagsSeenCount; ++i) {
                if (versionAndFlagsSeen[i] == versionAndFlags) {
                    // BMFF (ISO/IEC 14496-12:2022) 8.11.14.1 - There shall be at most one
                    // ItemPropertyAssociationBox with a given pair of values of version and
                    // flags.
                    avifDiagnosticsPrintf(diag, "Multiple Box[ipma] with a given pair of values of version and flags. See BMFF (ISO/IEC 14496-12:2022) 8.11.14.1");
                    return AVIF_RESULT_BMFF_PARSE_FAILED;
                }
            }
            if (versionAndFlagsSeenCount == MAX_IPMA_VERSION_AND_FLAGS_SEEN) {
                avifDiagnosticsPrintf(diag, "Exceeded possible count of unique ipma version and flags tuples");
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            versionAndFlagsSeen[versionAndFlagsSeenCount] = versionAndFlags;
            ++versionAndFlagsSeenCount;
        } else {
            // These must all be type ipma
            avifDiagnosticsPrintf(diag, "Box[iprp] contains a box that isn't type 'ipma'");
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }

        AVIF_CHECKERR(avifROStreamSkip(&s, ipmaHeader.size), AVIF_RESULT_BMFF_PARSE_FAILED);
    }
    return AVIF_RESULT_OK;
}

static avifResult avifParseItemInfoEntry(avifMeta * meta, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    // Section 8.11.6.2 of ISO/IEC 14496-12.
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[infe]");

    uint8_t version;
    uint32_t flags;
    AVIF_CHECKERR(avifROStreamReadVersionAndFlags(&s, &version, &flags), AVIF_RESULT_BMFF_PARSE_FAILED);
    // Version 2+ is required for item_type
    if (version != 2 && version != 3) {
        avifDiagnosticsPrintf(s.diag, "%s: Expecting box version 2 or 3, got version %u", s.diagContext, version);
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }
    // TODO: check flags. ISO/IEC 23008-12:2017, Section 9.2 says:
    //   The flags field of ItemInfoEntry with version greater than or equal to 2 is specified as
    //   follows:
    //
    //   (flags & 1) equal to 1 indicates that the item is not intended to be a part of the
    //   presentation. For example, when (flags & 1) is equal to 1 for an image item, the image
    //   item should not be displayed.
    //   (flags & 1) equal to 0 indicates that the item is intended to be a part of the
    //   presentation.
    //
    // See also Section 6.4.2.

    uint32_t itemID;
    if (version == 2) {
        uint16_t tmp;
        AVIF_CHECKERR(avifROStreamReadU16(&s, &tmp), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) item_ID;
        itemID = tmp;
    } else {
        AVIF_ASSERT_OR_RETURN(version == 3);
        AVIF_CHECKERR(avifROStreamReadU32(&s, &itemID), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) item_ID;
    }
    AVIF_CHECKRES(avifCheckItemID("infe", itemID, diag));
    uint16_t itemProtectionIndex;
    AVIF_CHECKERR(avifROStreamReadU16(&s, &itemProtectionIndex), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) item_protection_index;
    uint8_t itemType[4];
    AVIF_CHECKERR(avifROStreamRead(&s, itemType, 4), AVIF_RESULT_BMFF_PARSE_FAILED);   // unsigned int(32) item_type;
    AVIF_CHECKERR(avifROStreamReadString(&s, NULL, 0), AVIF_RESULT_BMFF_PARSE_FAILED); // utf8string item_name; (skipped)
    avifContentType contentType;
    if (!memcmp(itemType, "mime", 4)) {
        AVIF_CHECKERR(avifROStreamReadString(&s, contentType.contentType, CONTENTTYPE_SIZE), AVIF_RESULT_BMFF_PARSE_FAILED); // utf8string content_type;
        // utf8string content_encoding; //optional
    } else {
        // if (item_type == 'uri ') {
        //  utf8string item_uri_type;
        // }
        memset(&contentType, 0, sizeof(contentType));
    }

    avifDecoderItem * item;
    AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, itemID, &item));

    memcpy(item->type, itemType, sizeof(itemType));
    item->contentType = contentType;
    return AVIF_RESULT_OK;
}

static avifResult avifParseItemInfoBox(avifMeta * meta, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[iinf]");

    uint8_t version;
    AVIF_CHECKERR(avifROStreamReadVersionAndFlags(&s, &version, NULL), AVIF_RESULT_BMFF_PARSE_FAILED);
    uint32_t entryCount;
    if (version == 0) {
        uint16_t tmp;
        AVIF_CHECKERR(avifROStreamReadU16(&s, &tmp), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) entry_count;
        entryCount = tmp;
    } else if (version == 1) {
        AVIF_CHECKERR(avifROStreamReadU32(&s, &entryCount), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) entry_count;
    } else {
        avifDiagnosticsPrintf(diag, "Box[iinf] has an unsupported version %u", version);
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }

    for (uint32_t entryIndex = 0; entryIndex < entryCount; ++entryIndex) {
        avifBoxHeader infeHeader;
        AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &infeHeader), AVIF_RESULT_BMFF_PARSE_FAILED);

        if (!memcmp(infeHeader.type, "infe", 4)) {
            AVIF_CHECKRES(avifParseItemInfoEntry(meta, avifROStreamCurrent(&s), infeHeader.size, diag));
        } else {
            // These must all be type infe
            avifDiagnosticsPrintf(diag, "Box[iinf] contains a box that isn't type 'infe'");
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }

        AVIF_CHECKERR(avifROStreamSkip(&s, infeHeader.size), AVIF_RESULT_BMFF_PARSE_FAILED);
    }

    return AVIF_RESULT_OK;
}

static avifResult avifParseItemReferenceBox(avifMeta * meta, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[iref]");

    uint8_t version;
    AVIF_CHECKERR(avifROStreamReadVersionAndFlags(&s, &version, NULL), AVIF_RESULT_BMFF_PARSE_FAILED);
    if (version > 1) {
        // iref versions > 1 are not supported. Skip it.
        return AVIF_RESULT_OK;
    }

    while (avifROStreamHasBytesLeft(&s, 1)) {
        avifBoxHeader irefHeader;
        AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &irefHeader), AVIF_RESULT_BMFF_PARSE_FAILED);

        uint32_t fromID = 0;
        if (version == 0) {
            uint16_t tmp;
            AVIF_CHECKERR(avifROStreamReadU16(&s, &tmp), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) from_item_ID;
            fromID = tmp;
        } else {
            // version == 1
            AVIF_CHECKERR(avifROStreamReadU32(&s, &fromID), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) from_item_ID;
        }
        // ISO 14496-12 section 8.11.12.1: "index values start at 1"
        AVIF_CHECKRES(avifCheckItemID("iref", fromID, diag));

        avifDecoderItem * item;
        AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, fromID, &item));
        if (!memcmp(irefHeader.type, "dimg", 4)) {
            if (item->hasDimgFrom) {
                // ISO/IEC 23008-12 (HEIF) 6.6.1: The number of SingleItemTypeReferenceBoxes with the box type 'dimg'
                // and with the same value of from_item_ID shall not be greater than 1.
                avifDiagnosticsPrintf(diag, "Box[iinf] contains duplicate boxes of type 'dimg' with the same from_item_ID value %u", fromID);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            item->hasDimgFrom = AVIF_TRUE;
        }

        uint16_t referenceCount = 0;
        AVIF_CHECKERR(avifROStreamReadU16(&s, &referenceCount), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) reference_count;

        for (uint16_t refIndex = 0; refIndex < referenceCount; ++refIndex) {
            uint32_t toID = 0;
            if (version == 0) {
                uint16_t tmp;
                AVIF_CHECKERR(avifROStreamReadU16(&s, &tmp), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(16) to_item_ID;
                toID = tmp;
            } else {
                // version == 1
                AVIF_CHECKERR(avifROStreamReadU32(&s, &toID), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) to_item_ID;
            }
            AVIF_CHECKRES(avifCheckItemID("iref", toID, diag));

            // Read this reference as "{fromID} is a {irefType} for {toID}"
            if (!memcmp(irefHeader.type, "thmb", 4)) {
                item->thumbnailForID = toID;
            } else if (!memcmp(irefHeader.type, "auxl", 4)) {
                item->auxForID = toID;
            } else if (!memcmp(irefHeader.type, "cdsc", 4)) {
                item->descForID = toID;
            } else if (!memcmp(irefHeader.type, "dimg", 4)) {
                // derived images refer in the opposite direction
                avifDecoderItem * dimg;
                AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, toID, &dimg));

                // Section 8.11.12.1 of ISO/IEC 14496-12:
                //   The items linked to are then represented by an array of to_item_IDs;
                //   within a given array, a given value shall occur at most once.
                AVIF_CHECKERR(dimg->dimgForID != fromID, AVIF_RESULT_INVALID_IMAGE_GRID);
                // A given value may occur within multiple arrays but this is not supported by libavif.
                AVIF_CHECKERR(dimg->dimgForID == 0, AVIF_RESULT_NOT_IMPLEMENTED);
                dimg->dimgForID = fromID;
                dimg->dimgIdx = refIndex;
            } else if (!memcmp(irefHeader.type, "prem", 4)) {
                item->premByID = toID;
            }
        }
    }

    return AVIF_RESULT_OK;
}

static avifResult avifParseMetaBox(avifMeta * meta, uint64_t rawOffset, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[meta]");

    uint8_t version;
    uint32_t flags;
    AVIF_CHECKERR(avifROStreamReadVersionAndFlags(&s, &version, &flags), AVIF_RESULT_BMFF_PARSE_FAILED);

    if (version != 0) {
        avifDiagnosticsPrintf(diag, "Box[meta]: Expecting box version 0, got version %u", version);
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }

    ++meta->idatID; // for tracking idat

    avifBool firstBox = AVIF_TRUE;
    uint32_t uniqueBoxFlags = 0;
    while (avifROStreamHasBytesLeft(&s, 1)) {
        avifBoxHeader header;
        AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &header), AVIF_RESULT_BMFF_PARSE_FAILED);

        if (firstBox) {
            if (!memcmp(header.type, "hdlr", 4)) {
                AVIF_CHECKERR(avifParseHandlerBox(avifROStreamCurrent(&s), header.size, diag), AVIF_RESULT_BMFF_PARSE_FAILED);
                firstBox = AVIF_FALSE;
            } else {
                // hdlr must be the first box!
                avifDiagnosticsPrintf(diag, "Box[meta] does not have a Box[hdlr] as its first child box");
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
        } else if (!memcmp(header.type, "hdlr", 4)) {
            avifDiagnosticsPrintf(diag, "Box[meta] contains a duplicate unique box of type 'hdlr'");
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        } else if (!memcmp(header.type, "iloc", 4)) {
            AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 0, "meta", "iloc", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
            AVIF_CHECKRES(avifParseItemLocationBox(meta, avifROStreamCurrent(&s), header.size, diag));
        } else if (!memcmp(header.type, "pitm", 4)) {
            AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 1, "meta", "pitm", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
            AVIF_CHECKERR(avifParsePrimaryItemBox(meta, avifROStreamCurrent(&s), header.size, diag), AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "idat", 4)) {
            AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 2, "meta", "idat", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
            AVIF_CHECKERR(avifParseItemDataBox(meta, avifROStreamCurrent(&s), header.size, diag), AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "iprp", 4)) {
            AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 3, "meta", "iprp", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
            AVIF_CHECKRES(avifParseItemPropertiesBox(meta, rawOffset + avifROStreamOffset(&s), avifROStreamCurrent(&s), header.size, diag));
        } else if (!memcmp(header.type, "iinf", 4)) {
            AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 4, "meta", "iinf", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
            AVIF_CHECKRES(avifParseItemInfoBox(meta, avifROStreamCurrent(&s), header.size, diag));
        } else if (!memcmp(header.type, "iref", 4)) {
            AVIF_CHECKERR(uniqueBoxSeen(&uniqueBoxFlags, 5, "meta", "iref", diag), AVIF_RESULT_BMFF_PARSE_FAILED);
            AVIF_CHECKRES(avifParseItemReferenceBox(meta, avifROStreamCurrent(&s), header.size, diag));
        }

        AVIF_CHECKERR(avifROStreamSkip(&s, header.size), AVIF_RESULT_BMFF_PARSE_FAILED);
    }
    if (firstBox) {
        // The meta box must not be empty (it must contain at least a hdlr box)
        avifDiagnosticsPrintf(diag, "Box[meta] has no child boxes");
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }
    return AVIF_RESULT_OK;
}

static avifBool avifParseTrackHeaderBox(avifTrack * track,
                                        const uint8_t * raw,
                                        size_t rawLen,
                                        uint32_t imageSizeLimit,
                                        uint32_t imageDimensionLimit,
                                        avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[tkhd]");

    uint8_t version;
    AVIF_CHECK(avifROStreamReadVersionAndFlags(&s, &version, NULL));

    uint32_t ignored32, trackID;
    uint64_t ignored64;
    if (version == 1) {
        AVIF_CHECK(avifROStreamReadU64(&s, &ignored64));            // unsigned int(64) creation_time;
        AVIF_CHECK(avifROStreamReadU64(&s, &ignored64));            // unsigned int(64) modification_time;
        AVIF_CHECK(avifROStreamReadU32(&s, &trackID));              // unsigned int(32) track_ID;
        AVIF_CHECK(avifROStreamReadU32(&s, &ignored32));            // const unsigned int(32) reserved = 0;
        AVIF_CHECK(avifROStreamReadU64(&s, &track->trackDuration)); // unsigned int(64) duration;
    } else if (version == 0) {
        uint32_t trackDuration;
        AVIF_CHECK(avifROStreamReadU32(&s, &ignored32));     // unsigned int(32) creation_time;
        AVIF_CHECK(avifROStreamReadU32(&s, &ignored32));     // unsigned int(32) modification_time;
        AVIF_CHECK(avifROStreamReadU32(&s, &trackID));       // unsigned int(32) track_ID;
        AVIF_CHECK(avifROStreamReadU32(&s, &ignored32));     // const unsigned int(32) reserved = 0;
        AVIF_CHECK(avifROStreamReadU32(&s, &trackDuration)); // unsigned int(32) duration;
        track->trackDuration = (trackDuration == AVIF_INDEFINITE_DURATION32) ? AVIF_INDEFINITE_DURATION64 : trackDuration;
    } else {
        // Unsupported version
        avifDiagnosticsPrintf(diag, "Box[tkhd] has an unsupported version [%u]", version);
        return AVIF_FALSE;
    }

    // Skipping the following 52 bytes here:
    // ------------------------------------
    // const unsigned int(32)[2] reserved = 0;
    // template int(16) layer = 0;
    // template int(16) alternate_group = 0;
    // template int(16) volume = {if track_is_audio 0x0100 else 0};
    // const unsigned int(16) reserved = 0;
    // template int(32)[9] matrix= { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 }; // unity matrix
    AVIF_CHECK(avifROStreamSkip(&s, 52));

    uint32_t width, height;
    AVIF_CHECK(avifROStreamReadU32(&s, &width));  // unsigned int(32) width;
    AVIF_CHECK(avifROStreamReadU32(&s, &height)); // unsigned int(32) height;
    track->width = width >> 16;
    track->height = height >> 16;

    if ((track->width == 0) || (track->height == 0)) {
        avifDiagnosticsPrintf(diag, "Track ID [%u] has an invalid size [%ux%u]", track->id, track->width, track->height);
        return AVIF_FALSE;
    }
    if (avifDimensionsTooLarge(track->width, track->height, imageSizeLimit, imageDimensionLimit)) {
        avifDiagnosticsPrintf(diag, "Track ID [%u] dimensions are too large [%ux%u]", track->id, track->width, track->height);
        return AVIF_FALSE;
    }

    // TODO: support scaling based on width/height track header info?

    track->id = trackID;
    return AVIF_TRUE;
}

static avifBool avifParseMediaHeaderBox(avifTrack * track, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[mdhd]");

    uint8_t version;
    AVIF_CHECK(avifROStreamReadVersionAndFlags(&s, &version, NULL));

    uint32_t ignored32, mediaTimescale, mediaDuration32;
    uint64_t ignored64, mediaDuration64;
    if (version == 1) {
        AVIF_CHECK(avifROStreamReadU64(&s, &ignored64));       // unsigned int(64) creation_time;
        AVIF_CHECK(avifROStreamReadU64(&s, &ignored64));       // unsigned int(64) modification_time;
        AVIF_CHECK(avifROStreamReadU32(&s, &mediaTimescale));  // unsigned int(32) timescale;
        AVIF_CHECK(avifROStreamReadU64(&s, &mediaDuration64)); // unsigned int(64) duration;
        track->mediaDuration = mediaDuration64;
    } else if (version == 0) {
        AVIF_CHECK(avifROStreamReadU32(&s, &ignored32));       // unsigned int(32) creation_time;
        AVIF_CHECK(avifROStreamReadU32(&s, &ignored32));       // unsigned int(32) modification_time;
        AVIF_CHECK(avifROStreamReadU32(&s, &mediaTimescale));  // unsigned int(32) timescale;
        AVIF_CHECK(avifROStreamReadU32(&s, &mediaDuration32)); // unsigned int(32) duration;
        track->mediaDuration = (uint64_t)mediaDuration32;
    } else {
        // Unsupported version
        avifDiagnosticsPrintf(diag, "Box[mdhd] has an unsupported version [%u]", version);
        return AVIF_FALSE;
    }

    track->mediaTimescale = mediaTimescale;
    return AVIF_TRUE;
}

static avifResult avifParseChunkOffsetBox(avifSampleTable * sampleTable, avifBool largeOffsets, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, largeOffsets ? "Box[co64]" : "Box[stco]");

    AVIF_CHECKERR(avifROStreamReadAndEnforceVersion(&s, 0), AVIF_RESULT_BMFF_PARSE_FAILED);

    uint32_t entryCount;
    AVIF_CHECKERR(avifROStreamReadU32(&s, &entryCount), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) entry_count;
    for (uint32_t i = 0; i < entryCount; ++i) {
        uint64_t offset;
        if (largeOffsets) {
            AVIF_CHECKERR(avifROStreamReadU64(&s, &offset), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(64) chunk_offset;
        } else {
            uint32_t offset32;
            AVIF_CHECKERR(avifROStreamReadU32(&s, &offset32), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) chunk_offset;
            offset = (uint64_t)offset32;
        }

        avifSampleTableChunk * chunk = (avifSampleTableChunk *)avifArrayPush(&sampleTable->chunks);
        AVIF_CHECKERR(chunk != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        chunk->offset = offset;
    }
    return AVIF_RESULT_OK;
}

static avifResult avifParseSampleToChunkBox(avifSampleTable * sampleTable, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[stsc]");

    AVIF_CHECKERR(avifROStreamReadAndEnforceVersion(&s, 0), AVIF_RESULT_BMFF_PARSE_FAILED);

    uint32_t entryCount;
    AVIF_CHECKERR(avifROStreamReadU32(&s, &entryCount), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) entry_count;
    uint32_t prevFirstChunk = 0;
    for (uint32_t i = 0; i < entryCount; ++i) {
        avifSampleTableSampleToChunk * sampleToChunk = (avifSampleTableSampleToChunk *)avifArrayPush(&sampleTable->sampleToChunks);
        AVIF_CHECKERR(sampleToChunk != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        AVIF_CHECKERR(avifROStreamReadU32(&s, &sampleToChunk->firstChunk), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) first_chunk;
        AVIF_CHECKERR(avifROStreamReadU32(&s, &sampleToChunk->samplesPerChunk), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) samples_per_chunk;
        AVIF_CHECKERR(avifROStreamReadU32(&s, &sampleToChunk->sampleDescriptionIndex),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) sample_description_index;
        // The first_chunk fields should start with 1 and be strictly increasing.
        if (i == 0) {
            if (sampleToChunk->firstChunk != 1) {
                avifDiagnosticsPrintf(diag, "Box[stsc] does not begin with chunk 1 [%u]", sampleToChunk->firstChunk);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
        } else {
            if (sampleToChunk->firstChunk <= prevFirstChunk) {
                avifDiagnosticsPrintf(diag, "Box[stsc] chunks are not strictly increasing");
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
        }
        prevFirstChunk = sampleToChunk->firstChunk;
    }
    return AVIF_RESULT_OK;
}

static avifResult avifParseSampleSizeBox(avifSampleTable * sampleTable, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[stsz]");

    AVIF_CHECKERR(avifROStreamReadAndEnforceVersion(&s, 0), AVIF_RESULT_BMFF_PARSE_FAILED);

    uint32_t allSamplesSize, sampleCount;
    AVIF_CHECKERR(avifROStreamReadU32(&s, &allSamplesSize), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) sample_size;
    AVIF_CHECKERR(avifROStreamReadU32(&s, &sampleCount), AVIF_RESULT_BMFF_PARSE_FAILED);    // unsigned int(32) sample_count;

    if (allSamplesSize > 0) {
        sampleTable->allSamplesSize = allSamplesSize;
    } else {
        for (uint32_t i = 0; i < sampleCount; ++i) {
            avifSampleTableSampleSize * sampleSize = (avifSampleTableSampleSize *)avifArrayPush(&sampleTable->sampleSizes);
            AVIF_CHECKERR(sampleSize != NULL, AVIF_RESULT_OUT_OF_MEMORY);
            AVIF_CHECKERR(avifROStreamReadU32(&s, &sampleSize->size), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) entry_size;
        }
    }
    return AVIF_RESULT_OK;
}

static avifResult avifParseSyncSampleBox(avifSampleTable * sampleTable, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[stss]");

    AVIF_CHECKERR(avifROStreamReadAndEnforceVersion(&s, 0), AVIF_RESULT_BMFF_PARSE_FAILED);

    uint32_t entryCount;
    AVIF_CHECKERR(avifROStreamReadU32(&s, &entryCount), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) entry_count;

    for (uint32_t i = 0; i < entryCount; ++i) {
        uint32_t sampleNumber = 0;
        AVIF_CHECKERR(avifROStreamReadU32(&s, &sampleNumber), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) sample_number;
        avifSyncSample * syncSample = (avifSyncSample *)avifArrayPush(&sampleTable->syncSamples);
        AVIF_CHECKERR(syncSample != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        syncSample->sampleNumber = sampleNumber;
    }
    return AVIF_RESULT_OK;
}

static avifResult avifParseTimeToSampleBox(avifSampleTable * sampleTable, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[stts]");

    AVIF_CHECKERR(avifROStreamReadAndEnforceVersion(&s, 0), AVIF_RESULT_BMFF_PARSE_FAILED);

    uint32_t entryCount;
    AVIF_CHECKERR(avifROStreamReadU32(&s, &entryCount), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) entry_count;

    for (uint32_t i = 0; i < entryCount; ++i) {
        avifSampleTableTimeToSample * timeToSample = (avifSampleTableTimeToSample *)avifArrayPush(&sampleTable->timeToSamples);
        AVIF_CHECKERR(timeToSample != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        AVIF_CHECKERR(avifROStreamReadU32(&s, &timeToSample->sampleCount), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) sample_count;
        AVIF_CHECKERR(avifROStreamReadU32(&s, &timeToSample->sampleDelta), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) sample_delta;
    }
    return AVIF_RESULT_OK;
}

static avifResult avifParseSampleDescriptionBox(avifSampleTable * sampleTable,
                                                uint64_t rawOffset,
                                                const uint8_t * raw,
                                                size_t rawLen,
                                                avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[stsd]");

    uint8_t version;
    AVIF_CHECKERR(avifROStreamReadVersionAndFlags(&s, &version, NULL), AVIF_RESULT_BMFF_PARSE_FAILED);

    // Section 8.5.2.3 of ISO/IEC 14496-12:
    //   version is set to zero. A version number of 1 shall be treated as a version of 0.
    if (version != 0 && version != 1) {
        avifDiagnosticsPrintf(diag, "Box[stsd]: Expecting box version 0 or 1, got version %u", version);
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }

    uint32_t entryCount;
    AVIF_CHECKERR(avifROStreamReadU32(&s, &entryCount), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(32) entry_count;

    for (uint32_t i = 0; i < entryCount; ++i) {
        avifBoxHeader sampleEntryHeader;
        AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &sampleEntryHeader), AVIF_RESULT_BMFF_PARSE_FAILED);

        avifSampleDescription * description = (avifSampleDescription *)avifArrayPush(&sampleTable->sampleDescriptions);
        AVIF_CHECKERR(description != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        if (!avifArrayCreate(&description->properties, sizeof(avifProperty), 16)) {
            avifArrayPop(&sampleTable->sampleDescriptions);
            return AVIF_RESULT_OUT_OF_MEMORY;
        }
        memcpy(description->format, sampleEntryHeader.type, sizeof(description->format));
        const size_t sampleEntryBytes = sampleEntryHeader.size;
        if (avifGetCodecType(description->format) != AVIF_CODEC_TYPE_UNKNOWN) {
            if (sampleEntryBytes < VISUALSAMPLEENTRY_SIZE) {
                avifDiagnosticsPrintf(diag, "Not enough bytes to parse VisualSampleEntry");
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            AVIF_CHECKRES(avifParseItemPropertyContainerBox(&description->properties,
                                                            rawOffset + avifROStreamOffset(&s) + VISUALSAMPLEENTRY_SIZE,
                                                            avifROStreamCurrent(&s) + VISUALSAMPLEENTRY_SIZE,
                                                            sampleEntryBytes - VISUALSAMPLEENTRY_SIZE,
                                                            diag));
        }

        AVIF_CHECKERR(avifROStreamSkip(&s, sampleEntryBytes), AVIF_RESULT_BMFF_PARSE_FAILED);
    }
    return AVIF_RESULT_OK;
}

static avifResult avifParseSampleTableBox(avifTrack * track, uint64_t rawOffset, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    if (track->sampleTable) {
        // A TrackBox may only have one SampleTable
        avifDiagnosticsPrintf(diag, "Duplicate Box[stbl] for a single track detected");
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }
    track->sampleTable = avifSampleTableCreate();
    AVIF_CHECKERR(track->sampleTable != NULL, AVIF_RESULT_OUT_OF_MEMORY);

    BEGIN_STREAM(s, raw, rawLen, diag, "Box[stbl]");

    while (avifROStreamHasBytesLeft(&s, 1)) {
        avifBoxHeader header;
        AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &header), AVIF_RESULT_BMFF_PARSE_FAILED);

        if (!memcmp(header.type, "stco", 4)) {
            AVIF_CHECKRES(avifParseChunkOffsetBox(track->sampleTable, AVIF_FALSE, avifROStreamCurrent(&s), header.size, diag));
        } else if (!memcmp(header.type, "co64", 4)) {
            AVIF_CHECKRES(avifParseChunkOffsetBox(track->sampleTable, AVIF_TRUE, avifROStreamCurrent(&s), header.size, diag));
        } else if (!memcmp(header.type, "stsc", 4)) {
            AVIF_CHECKRES(avifParseSampleToChunkBox(track->sampleTable, avifROStreamCurrent(&s), header.size, diag));
        } else if (!memcmp(header.type, "stsz", 4)) {
            AVIF_CHECKRES(avifParseSampleSizeBox(track->sampleTable, avifROStreamCurrent(&s), header.size, diag));
        } else if (!memcmp(header.type, "stss", 4)) {
            AVIF_CHECKRES(avifParseSyncSampleBox(track->sampleTable, avifROStreamCurrent(&s), header.size, diag));
        } else if (!memcmp(header.type, "stts", 4)) {
            AVIF_CHECKRES(avifParseTimeToSampleBox(track->sampleTable, avifROStreamCurrent(&s), header.size, diag));
        } else if (!memcmp(header.type, "stsd", 4)) {
            AVIF_CHECKRES(avifParseSampleDescriptionBox(track->sampleTable,
                                                        rawOffset + avifROStreamOffset(&s),
                                                        avifROStreamCurrent(&s),
                                                        header.size,
                                                        diag));
        }

        AVIF_CHECKERR(avifROStreamSkip(&s, header.size), AVIF_RESULT_BMFF_PARSE_FAILED);
    }
    return AVIF_RESULT_OK;
}

static avifResult avifParseMediaInformationBox(avifTrack * track, uint64_t rawOffset, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[minf]");

    while (avifROStreamHasBytesLeft(&s, 1)) {
        avifBoxHeader header;
        AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &header), AVIF_RESULT_BMFF_PARSE_FAILED);

        if (!memcmp(header.type, "stbl", 4)) {
            AVIF_CHECKRES(avifParseSampleTableBox(track, rawOffset + avifROStreamOffset(&s), avifROStreamCurrent(&s), header.size, diag));
        }

        AVIF_CHECKERR(avifROStreamSkip(&s, header.size), AVIF_RESULT_BMFF_PARSE_FAILED);
    }
    return AVIF_RESULT_OK;
}

static avifResult avifParseMediaBox(avifTrack * track, uint64_t rawOffset, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[mdia]");

    while (avifROStreamHasBytesLeft(&s, 1)) {
        avifBoxHeader header;
        AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &header), AVIF_RESULT_BMFF_PARSE_FAILED);

        if (!memcmp(header.type, "mdhd", 4)) {
            AVIF_CHECKERR(avifParseMediaHeaderBox(track, avifROStreamCurrent(&s), header.size, diag), AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "minf", 4)) {
            AVIF_CHECKRES(
                avifParseMediaInformationBox(track, rawOffset + avifROStreamOffset(&s), avifROStreamCurrent(&s), header.size, diag));
        }

        AVIF_CHECKERR(avifROStreamSkip(&s, header.size), AVIF_RESULT_BMFF_PARSE_FAILED);
    }
    return AVIF_RESULT_OK;
}

static avifBool avifTrackReferenceBox(avifTrack * track, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[tref]");

    while (avifROStreamHasBytesLeft(&s, 1)) {
        avifBoxHeader header;
        AVIF_CHECK(avifROStreamReadBoxHeader(&s, &header));

        if (!memcmp(header.type, "auxl", 4)) {
            uint32_t toID;
            AVIF_CHECK(avifROStreamReadU32(&s, &toID));                       // unsigned int(32) track_IDs[];
            AVIF_CHECK(avifROStreamSkip(&s, header.size - sizeof(uint32_t))); // just take the first one
            track->auxForID = toID;
        } else if (!memcmp(header.type, "prem", 4)) {
            uint32_t byID;
            AVIF_CHECK(avifROStreamReadU32(&s, &byID));                       // unsigned int(32) track_IDs[];
            AVIF_CHECK(avifROStreamSkip(&s, header.size - sizeof(uint32_t))); // just take the first one
            track->premByID = byID;
        } else {
            AVIF_CHECK(avifROStreamSkip(&s, header.size));
        }
    }
    return AVIF_TRUE;
}

static avifBool avifParseEditListBox(avifTrack * track, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[elst]");

    uint8_t version;
    uint32_t flags;
    AVIF_CHECK(avifROStreamReadVersionAndFlags(&s, &version, &flags));

    if ((flags & 1) == 0) {
        track->isRepeating = AVIF_FALSE;
        return AVIF_TRUE;
    }

    track->isRepeating = AVIF_TRUE;
    uint32_t entryCount;
    AVIF_CHECK(avifROStreamReadU32(&s, &entryCount)); // unsigned int(32) entry_count;
    if (entryCount != 1) {
        avifDiagnosticsPrintf(diag, "Box[elst] contains an entry_count != 1 [%u]", entryCount);
        return AVIF_FALSE;
    }

    if (version == 1) {
        AVIF_CHECK(avifROStreamReadU64(&s, &track->segmentDuration)); // unsigned int(64) segment_duration;
    } else if (version == 0) {
        uint32_t segmentDuration;
        AVIF_CHECK(avifROStreamReadU32(&s, &segmentDuration)); // unsigned int(32) segment_duration;
        track->segmentDuration = segmentDuration;
    } else {
        // Unsupported version
        avifDiagnosticsPrintf(diag, "Box[elst] has an unsupported version [%u]", version);
        return AVIF_FALSE;
    }
    if (track->segmentDuration == 0) {
        avifDiagnosticsPrintf(diag, "Box[elst] Invalid value for segment_duration (0).");
        return AVIF_FALSE;
    }
    return AVIF_TRUE;
}

static avifBool avifParseEditBox(avifTrack * track, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[edts]");

    avifBool elstBoxSeen = AVIF_FALSE;
    while (avifROStreamHasBytesLeft(&s, 1)) {
        avifBoxHeader header;
        AVIF_CHECK(avifROStreamReadBoxHeader(&s, &header));

        if (!memcmp(header.type, "elst", 4)) {
            if (elstBoxSeen) {
                avifDiagnosticsPrintf(diag, "More than one [elst] Box was found.");
                return AVIF_FALSE;
            }
            AVIF_CHECK(avifParseEditListBox(track, avifROStreamCurrent(&s), header.size, diag));
            elstBoxSeen = AVIF_TRUE;
        }
        AVIF_CHECK(avifROStreamSkip(&s, header.size));
    }
    if (!elstBoxSeen) {
        avifDiagnosticsPrintf(diag, "Box[edts] contains no [elst] Box.");
        return AVIF_FALSE;
    }
    return AVIF_TRUE;
}

static avifResult avifParseTrackBox(avifDecoderData * data,
                                    uint64_t rawOffset,
                                    const uint8_t * raw,
                                    size_t rawLen,
                                    uint32_t imageSizeLimit,
                                    uint32_t imageDimensionLimit)
{
    BEGIN_STREAM(s, raw, rawLen, data->diag, "Box[trak]");

    avifTrack * track = avifDecoderDataCreateTrack(data);
    AVIF_CHECKERR(track != NULL, AVIF_RESULT_OUT_OF_MEMORY);

    avifBool edtsBoxSeen = AVIF_FALSE;
    avifBool tkhdSeen = AVIF_FALSE;
    while (avifROStreamHasBytesLeft(&s, 1)) {
        avifBoxHeader header;
        AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &header), AVIF_RESULT_BMFF_PARSE_FAILED);

        if (!memcmp(header.type, "tkhd", 4)) {
            if (tkhdSeen) {
                avifDiagnosticsPrintf(data->diag, "Box[trak] contains a duplicate unique box of type 'tkhd'");
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            AVIF_CHECKERR(avifParseTrackHeaderBox(track, avifROStreamCurrent(&s), header.size, imageSizeLimit, imageDimensionLimit, data->diag),
                          AVIF_RESULT_BMFF_PARSE_FAILED);
            tkhdSeen = AVIF_TRUE;
        } else if (!memcmp(header.type, "meta", 4)) {
            AVIF_CHECKRES(
                avifParseMetaBox(track->meta, rawOffset + avifROStreamOffset(&s), avifROStreamCurrent(&s), header.size, data->diag));
        } else if (!memcmp(header.type, "mdia", 4)) {
            AVIF_CHECKRES(avifParseMediaBox(track, rawOffset + avifROStreamOffset(&s), avifROStreamCurrent(&s), header.size, data->diag));
        } else if (!memcmp(header.type, "tref", 4)) {
            AVIF_CHECKERR(avifTrackReferenceBox(track, avifROStreamCurrent(&s), header.size, data->diag), AVIF_RESULT_BMFF_PARSE_FAILED);
        } else if (!memcmp(header.type, "edts", 4)) {
            if (edtsBoxSeen) {
                avifDiagnosticsPrintf(data->diag, "Box[trak] contains a duplicate unique box of type 'edts'");
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            AVIF_CHECKERR(avifParseEditBox(track, avifROStreamCurrent(&s), header.size, data->diag), AVIF_RESULT_BMFF_PARSE_FAILED);
            edtsBoxSeen = AVIF_TRUE;
        }

        AVIF_CHECKERR(avifROStreamSkip(&s, header.size), AVIF_RESULT_BMFF_PARSE_FAILED);
    }
    if (!tkhdSeen) {
        avifDiagnosticsPrintf(data->diag, "Box[trak] does not contain a mandatory [tkhd] box");
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }
    if (!edtsBoxSeen) {
        track->repetitionCount = AVIF_REPETITION_COUNT_UNKNOWN;
    } else if (track->isRepeating) {
        if (track->trackDuration == AVIF_INDEFINITE_DURATION64) {
            // If isRepeating is true and the track duration is unknown/indefinite, then set the repetition count to infinite
            // (Section 9.6.1 of ISO/IEC 23008-12 Part 12).
            track->repetitionCount = AVIF_REPETITION_COUNT_INFINITE;
        } else {
            // Section 9.6.1. of ISO/IEC 23008-12 Part 12: 1, the entire edit list is repeated a sufficient number of times to
            // equal the track duration.
            //
            // Since libavif uses repetitionCount (which is 0-based), we subtract the value by 1 to derive the number of
            // repetitions.
            AVIF_ASSERT_OR_RETURN(track->segmentDuration != 0);
            // We specifically check for trackDuration == 0 here and not when it is actually read in order to accept files which
            // inadvertently has a trackDuration of 0 without any edit lists.
            if (track->trackDuration == 0) {
                avifDiagnosticsPrintf(data->diag, "Invalid track duration 0.");
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            const uint64_t repetitionCount =
                (track->trackDuration / track->segmentDuration) + (track->trackDuration % track->segmentDuration != 0) - 1;
            if (repetitionCount > INT_MAX) {
                // repetitionCount does not fit in an integer and hence it is
                // likely to be a very large value. So, we just set it to
                // infinite.
                track->repetitionCount = AVIF_REPETITION_COUNT_INFINITE;
            } else {
                track->repetitionCount = (int)repetitionCount;
            }
        }
    } else {
        track->repetitionCount = 0;
    }

    return AVIF_RESULT_OK;
}

static avifResult avifParseMovieBox(avifDecoderData * data,
                                    uint64_t rawOffset,
                                    const uint8_t * raw,
                                    size_t rawLen,
                                    uint32_t imageSizeLimit,
                                    uint32_t imageDimensionLimit)
{
    BEGIN_STREAM(s, raw, rawLen, data->diag, "Box[moov]");

    avifBool hasTrak = AVIF_FALSE;
    while (avifROStreamHasBytesLeft(&s, 1)) {
        avifBoxHeader header;
        AVIF_CHECKERR(avifROStreamReadBoxHeader(&s, &header), AVIF_RESULT_BMFF_PARSE_FAILED);

        if (!memcmp(header.type, "trak", 4)) {
            AVIF_CHECKRES(
                avifParseTrackBox(data, rawOffset + avifROStreamOffset(&s), avifROStreamCurrent(&s), header.size, imageSizeLimit, imageDimensionLimit));
            hasTrak = AVIF_TRUE;
        }

        AVIF_CHECKERR(avifROStreamSkip(&s, header.size), AVIF_RESULT_BMFF_PARSE_FAILED);
    }
    if (!hasTrak) {
        avifDiagnosticsPrintf(data->diag, "moov box does not contain any tracks");
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }
    return AVIF_RESULT_OK;
}

#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
static avifProperty * avifMetaCreateProperty(avifMeta * meta, const char * propertyType)
{
    avifProperty * metaProperty = avifArrayPush(&meta->properties);
    AVIF_CHECK(metaProperty);
    memcpy(metaProperty->type, propertyType, 4);
    return metaProperty;
}

static avifProperty * avifDecoderItemAddProperty(avifDecoderItem * item, const avifProperty * metaProperty)
{
    avifProperty * itemProperty = avifArrayPush(&item->properties);
    AVIF_CHECK(itemProperty);
    *itemProperty = *metaProperty;
    return itemProperty;
}

static avifResult avifParseMinimizedImageBox(avifDecoderData * data,
                                             uint64_t rawOffset,
                                             const uint8_t * raw,
                                             size_t rawLen,
                                             avifBool isAvifAccordingToMinorVersion,
                                             avifDiagnostics * diag)
{
    avifMeta * meta = data->meta;
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[mini]");

    meta->fromMiniBox = AVIF_TRUE;

    uint32_t version;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &version, 2), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(2) version = 0;
    AVIF_CHECKERR(version == 0, AVIF_RESULT_BMFF_PARSE_FAILED);

    // flags
    uint32_t hasExplicitCodecTypes, floatFlag, fullRange, hasAlpha, hasExplicitCicp, hasHdr, hasIcc, hasExif, hasXmp;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &hasExplicitCodecTypes, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) explicit_codec_types_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &floatFlag, 1), AVIF_RESULT_BMFF_PARSE_FAILED);             // bit(1) float_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &fullRange, 1), AVIF_RESULT_BMFF_PARSE_FAILED);       // bit(1) full_range_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &hasAlpha, 1), AVIF_RESULT_BMFF_PARSE_FAILED);        // bit(1) alpha_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &hasExplicitCicp, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) explicit_cicp_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &hasHdr, 1), AVIF_RESULT_BMFF_PARSE_FAILED);          // bit(1) hdr_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &hasIcc, 1), AVIF_RESULT_BMFF_PARSE_FAILED);          // bit(1) icc_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &hasExif, 1), AVIF_RESULT_BMFF_PARSE_FAILED);         // bit(1) exif_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &hasXmp, 1), AVIF_RESULT_BMFF_PARSE_FAILED);          // bit(1) xmp_flag;

    uint32_t chromaSubsampling, orientation;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &chromaSubsampling, 2), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(2) chroma_subsampling;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &orientation, 3), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(3) orientation_minus1;
    ++orientation;

    // Spatial extents
    uint32_t smallDimensionsFlag, width, height;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &smallDimensionsFlag, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) small_dimensions_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &width, smallDimensionsFlag ? 7 : 15),
                  AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(small_dimensions_flag ? 7 : 15) width_minus1;
    ++width;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &height, smallDimensionsFlag ? 7 : 15),
                  AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(small_dimensions_flag ? 7 : 15) height_minus1;
    ++height;

    // Pixel information
    uint32_t chromaIsHorizontallyCentered = 0, chromaIsVerticallyCentered = 0;
    if (chromaSubsampling == 1 || chromaSubsampling == 2) {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &chromaIsHorizontallyCentered, 1),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) chroma_is_horizontally_centered;
    }
    if (chromaSubsampling == 1) {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &chromaIsVerticallyCentered, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) chroma_is_vertically_centered;
    }

    uint32_t bitDepth;
    if (floatFlag) {
        // bit(2) bit_depth_log2_minus4;
        return AVIF_RESULT_BMFF_PARSE_FAILED; // Either invalid AVIF or unsupported non-AVIF.
    } else {
        uint32_t highBitDepthFlag;
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &highBitDepthFlag, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) high_bit_depth_flag;
        if (highBitDepthFlag) {
            AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &bitDepth, 3), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(3) bit_depth_minus9;
            bitDepth += 9;
        } else {
            bitDepth = 8;
        }
    }

    uint32_t alphaIsPremultiplied = 0;
    if (hasAlpha) {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &alphaIsPremultiplied, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) alpha_is_premultiplied;
    }

    // Colour properties
    uint8_t colorPrimaries;
    uint8_t transferCharacteristics;
    uint8_t matrixCoefficients;
    if (hasExplicitCicp) {
        AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &colorPrimaries, 8), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(8) colour_primaries;
        AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &transferCharacteristics, 8), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(8) transfer_characteristics;
        if (chromaSubsampling != 0) {
            AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &matrixCoefficients, 8), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(8) matrix_coefficients;
        } else {
            matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED; // 2
        }
    } else {
        colorPrimaries = hasIcc ? AVIF_COLOR_PRIMARIES_UNSPECIFIED                         // 2
                                : AVIF_COLOR_PRIMARIES_BT709;                              // 1
        transferCharacteristics = hasIcc ? AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED       // 2
                                         : AVIF_TRANSFER_CHARACTERISTICS_SRGB;             // 13
        matrixCoefficients = chromaSubsampling == 0 ? AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED // 2
                                                    : AVIF_MATRIX_COEFFICIENTS_BT601;      // 6
    }

    uint8_t infeType[4];
    uint8_t codecConfigType[4];
    if (hasExplicitCodecTypes) {
        // bit(32) infe_type;
        for (int i = 0; i < 4; ++i) {
            AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &infeType[i], 8), AVIF_RESULT_BMFF_PARSE_FAILED);
        }
        // bit(32) codec_config_type;
        for (int i = 0; i < 4; ++i) {
            AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &codecConfigType[i], 8), AVIF_RESULT_BMFF_PARSE_FAILED);
        }
#if defined(AVIF_CODEC_AVM)
        if (!memcmp(infeType, "av02", 4) && !memcmp(codecConfigType, "av2C", 4)) {
            return AVIF_RESULT_NOT_IMPLEMENTED;
        }
#endif
        AVIF_CHECKERR(!memcmp(infeType, "av01", 4) && !memcmp(codecConfigType, "av1C", 4), AVIF_RESULT_BMFF_PARSE_FAILED);
    } else {
        AVIF_CHECKERR(isAvifAccordingToMinorVersion, AVIF_RESULT_BMFF_PARSE_FAILED);
        memcpy(infeType, "av01", 4);
        memcpy(codecConfigType, "av1C", 4);
    }

    // High Dynamic Range properties
    uint32_t hasGainmap = AVIF_FALSE;
    uint32_t tmapHasIcc = AVIF_FALSE;
    uint32_t gainmapWidth = 0, gainmapHeight = 0;
    uint8_t gainmapMatrixCoefficients = 0;
    uint32_t gainmapFullRange = 0;
    uint32_t gainmapChromaSubsampling = 0;
    uint32_t gainmapBitDepth = 0;
    uint32_t tmapHasExplicitCicp = AVIF_FALSE;
    uint8_t tmapColorPrimaries = AVIF_COLOR_PRIMARIES_UNKNOWN;
    uint8_t tmapTransferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN;
    uint8_t tmapMatrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
    uint32_t tmapFullRange = AVIF_FALSE;
    uint32_t hasClli = AVIF_FALSE, tmapHasClli = AVIF_FALSE;
    avifContentLightLevelInformationBox clli = {}, tmapClli = {};
    if (hasHdr) {
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &hasGainmap, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) gainmap_flag;
        if (hasGainmap) {
            // avifDecoderReset() requires the 'tmap' brand to be registered for the tone mapping derived image item to be parsed.
            if (data->compatibleBrands.capacity == 0) {
                AVIF_CHECKERR(avifArrayCreate(&data->compatibleBrands, sizeof(avifBrand), 1), AVIF_RESULT_OUT_OF_MEMORY);
            }
            avifBrand * brand = avifArrayPush(&data->compatibleBrands);
            AVIF_CHECKERR(brand != NULL, AVIF_RESULT_OUT_OF_MEMORY);
            memcpy(brand, "tmap", sizeof(avifBrand));

            AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapWidth, smallDimensionsFlag ? 7 : 15),
                          AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(small_dimensions_flag ? 7 : 15) gainmap_width_minus1;
            ++gainmapWidth;
            AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapHeight, smallDimensionsFlag ? 7 : 15),
                          AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(small_dimensions_flag ? 7 : 15) gainmap_height_minus1;
            ++gainmapHeight;
            AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &gainmapMatrixCoefficients, 8), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(8) gainmap_matrix_coefficients;
            AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapFullRange, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) gainmap_full_range_flag;

            AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapChromaSubsampling, 2), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(2) gainmap_chroma_subsampling;
            uint32_t gainmapChromaIsHorizontallyCentered = 0, gainmapChromaIsVerticallyCentered = 0;
            if (gainmapChromaSubsampling == 1 || gainmapChromaSubsampling == 2) {
                AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapChromaIsHorizontallyCentered, 1),
                              AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) gainmap_chroma_is_horizontally_centered;
            }
            if (gainmapChromaSubsampling == 1) {
                AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapChromaIsVerticallyCentered, 1),
                              AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) gainmap_chroma_is_vertically_centered;
            }

            uint32_t gainmapFloatFlag;
            AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapFloatFlag, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) gainmap_float_flag;
            if (gainmapFloatFlag) {
                // bit(2) gainmap_bit_depth_log2_minus4;
                return AVIF_RESULT_BMFF_PARSE_FAILED; // Either invalid AVIF or unsupported non-AVIF.
            } else {
                uint32_t gainmapHighBitDepthFlag;
                AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapHighBitDepthFlag, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) gainmap_high_bit_depth_flag;
                if (gainmapHighBitDepthFlag) {
                    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapBitDepth, 3), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(3) gainmap_bit_depth_minus9;
                    gainmapBitDepth += 9;
                } else {
                    gainmapBitDepth = 8;
                }
            }

            AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &tmapHasIcc, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) tmap_icc_flag;
            AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &tmapHasExplicitCicp, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) tmap_explicit_cicp_flag;
            if (tmapHasExplicitCicp) {
                AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &tmapColorPrimaries, 8), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(8) tmap_colour_primaries;
                AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &tmapTransferCharacteristics, 8),
                              AVIF_RESULT_BMFF_PARSE_FAILED); // bit(8) tmap_transfer_characteristics;
                AVIF_CHECKERR(avifROStreamReadBitsU8(&s, &tmapMatrixCoefficients, 8), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(8) tmap_matrix_coefficients;
                AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &tmapFullRange, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) tmap_full_range_flag;
            } else {
                tmapColorPrimaries = AVIF_COLOR_PRIMARIES_BT709;                  // 1
                tmapTransferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_SRGB; // 13
                tmapMatrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT601;          // 6
                tmapFullRange = 1;
            }
        }
        AVIF_CHECKRES(avifParseMiniHDRProperties(&s, &hasClli, &clli));
        if (hasGainmap) {
            AVIF_CHECKRES(avifParseMiniHDRProperties(&s, &tmapHasClli, &tmapClli));
        }
#else
        return AVIF_RESULT_NOT_IMPLEMENTED;
#endif // AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP
    }

    // Chunk sizes
    uint32_t fewMetadataBytesFlag = 0, fewCodecConfigBytesFlag = 0, fewItemDataBytesFlag = 0;
    if (hasIcc || hasExif || hasXmp || (hasHdr && hasGainmap)) {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &fewMetadataBytesFlag, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) few_metadata_bytes_flag;
    }
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &fewCodecConfigBytesFlag, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) few_codec_config_bytes_flag;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &fewItemDataBytesFlag, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // bit(1) few_item_data_bytes_flag;

    uint32_t iccDataSize = 0;
    if (hasIcc) {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &iccDataSize, fewMetadataBytesFlag ? 10 : 20),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(few_metadata_bytes_flag ? 10 : 20) icc_data_size_minus1;
        ++iccDataSize;
    }
    uint32_t tmapIccDataSize = 0;
    if (hasHdr && hasGainmap && tmapHasIcc) {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &tmapIccDataSize, fewMetadataBytesFlag ? 10 : 20),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(few_metadata_bytes_flag ? 10 : 20) tmap_icc_data_size_minus1;
        ++tmapIccDataSize;
    }

    uint32_t gainmapMetadataSize = 0, gainmapItemDataSize = 0, gainmapItemCodecConfigSize = 0;
    if (hasHdr && hasGainmap) {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapMetadataSize, fewMetadataBytesFlag ? 10 : 20),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(few_metadata_bytes_flag ? 10 : 20) gainmap_metadata_size;
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapItemDataSize, fewItemDataBytesFlag ? 15 : 28),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(few_item_data_bytes_flag ? 15 : 28) gainmap_item_data_size;
        if (gainmapItemDataSize > 0) {
            AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &gainmapItemCodecConfigSize, fewCodecConfigBytesFlag ? 3 : 12),
                          AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(few_codec_config_bytes_flag ? 3 : 12) gainmap_item_codec_config_size;
        }
    }

    uint32_t mainItemCodecConfigSize, mainItemDataSize;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &mainItemCodecConfigSize, fewCodecConfigBytesFlag ? 3 : 12),
                  AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(few_codec_config_bytes_flag ? 3 : 12) main_item_codec_config_size;
    AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &mainItemDataSize, fewItemDataBytesFlag ? 15 : 28),
                  AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(few_item_data_bytes_flag ? 15 : 28) main_item_data_size_minus1;
    ++mainItemDataSize;

    uint32_t alphaItemCodecConfigSize = 0, alphaItemDataSize = 0;
    if (hasAlpha) {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &alphaItemDataSize, fewItemDataBytesFlag ? 15 : 28),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(few_item_data_bytes_flag ? 15 : 28) alpha_item_data_size;
    }
    if (hasAlpha && alphaItemDataSize != 0) {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &alphaItemCodecConfigSize, fewCodecConfigBytesFlag ? 3 : 12),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(few_codec_config_bytes_flag ? 3 : 12) alpha_item_codec_config_size;
    }

    uint32_t exifDataSize = 0;
    if (hasExif) {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &exifDataSize, fewMetadataBytesFlag ? 10 : 20),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(few_metadata_bytes_flag ? 10 : 20) exif_data_size_minus_one;
        ++exifDataSize;
    }
    uint32_t xmpDataSize = 0;
    if (hasXmp) {
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &xmpDataSize, fewMetadataBytesFlag ? 10 : 20),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(few_metadata_bytes_flag ? 10 : 20) xmp_data_size_minus_one;
        ++xmpDataSize;
    }

    // trailing_bits(); // bit padding till byte alignment
    if (s.numUsedBitsInPartialByte) {
        uint32_t padding;
        AVIF_CHECKERR(avifROStreamReadBitsU32(&s, &padding, 8 - s.numUsedBitsInPartialByte), AVIF_RESULT_BMFF_PARSE_FAILED);
        AVIF_CHECKERR(padding == 0, AVIF_RESULT_BMFF_PARSE_FAILED); // Only accept zeros as padding.
    }

    // Codec configuration ('av1C' always uses 4 bytes)
    avifCodecConfigurationBox alphaItemCodecConfig = { 0 };
    if (hasAlpha && alphaItemDataSize != 0 && alphaItemCodecConfigSize != 0) {
        AVIF_CHECKERR(alphaItemCodecConfigSize == 4, AVIF_RESULT_BMFF_PARSE_FAILED);
        AVIF_CHECKERR(avifParseCodecConfiguration(&s, &alphaItemCodecConfig, (const char *)codecConfigType, diag),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(8) alpha_item_codec_config[alpha_item_codec_config_size];
    }
    avifCodecConfigurationBox gainmapItemCodecConfig = { 0 };
    if (hasHdr && hasGainmap && gainmapItemCodecConfigSize != 0) {
        AVIF_CHECKERR(gainmapItemCodecConfigSize == 4, AVIF_RESULT_BMFF_PARSE_FAILED);
        AVIF_CHECKERR(avifParseCodecConfiguration(&s, &gainmapItemCodecConfig, (const char *)codecConfigType, diag),
                      AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(8) gainmap_item_codec_config[gainmap_item_codec_config_size];
    }
    avifCodecConfigurationBox mainItemCodecConfig;
    AVIF_CHECKERR(mainItemCodecConfigSize == 4, AVIF_RESULT_BMFF_PARSE_FAILED);
    AVIF_CHECKERR(avifParseCodecConfiguration(&s, &mainItemCodecConfig, (const char *)codecConfigType, diag),
                  AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(8) main_item_codec_config[main_item_codec_config_size];

    // Make sure all metadata and coded chunks fit into the 'meta' box whose size is rawLen.
    // There should be no missing nor unused byte.

    AVIF_CHECKERR(avifROStreamRemainingBytes(&s) == (uint64_t)iccDataSize + tmapIccDataSize + gainmapMetadataSize + alphaItemDataSize +
                                                        gainmapItemDataSize + mainItemDataSize + exifDataSize + xmpDataSize,
                  AVIF_RESULT_BMFF_PARSE_FAILED);

    // Create the items and properties generated by the MinimizedImageBox.
    // The MinimizedImageBox always creates 8 properties for specification easiness.
    // Use FreeSpaceBoxes as no-op placeholder properties when necessary.
    // There is no need to use placeholder items because item IDs do not have to
    // be contiguous, whereas property indices shall be 1, 2, 3, 4, 5 etc.

    meta->primaryItemID = 1;
    avifDecoderItem * colorItem;
    AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, meta->primaryItemID, &colorItem));
    memcpy(colorItem->type, infeType, 4);
    colorItem->width = width;
    colorItem->height = height;
    colorItem->miniBoxPixelFormat = chromaSubsampling == 0   ? AVIF_PIXEL_FORMAT_YUV400
                                    : chromaSubsampling == 1 ? AVIF_PIXEL_FORMAT_YUV420
                                    : chromaSubsampling == 2 ? AVIF_PIXEL_FORMAT_YUV422
                                                             : AVIF_PIXEL_FORMAT_YUV444;
    if (colorItem->miniBoxPixelFormat == AVIF_PIXEL_FORMAT_YUV422) {
        // In AV1, the chroma_sample_position syntax element is not present for the YUV 4:2:2 format.
        // Assume that AV1 uses the same 4:2:2 chroma sample location as HEVC and VVC (colocated).
        AVIF_CHECKERR(!chromaIsHorizontallyCentered, AVIF_RESULT_BMFF_PARSE_FAILED);
        // chromaIsVerticallyCentered: Ignored unless chroma_subsampling is 1.
        colorItem->miniBoxChromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
    } else if (colorItem->miniBoxPixelFormat == AVIF_PIXEL_FORMAT_YUV420) {
        if (chromaIsHorizontallyCentered) {
            // There is no way to describe this with AV1's chroma_sample_position enum besides CSP_UNKNOWN.
            // There is a proposal to assign the reserved value 3 (CSP_RESERVED) to the center chroma sample position.
            colorItem->miniBoxChromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
        } else {
            colorItem->miniBoxChromaSamplePosition = chromaIsVerticallyCentered ? AVIF_CHROMA_SAMPLE_POSITION_VERTICAL
                                                                                : AVIF_CHROMA_SAMPLE_POSITION_COLOCATED;
        }
    } else {
        // chromaIsHorizontallyCentered: Ignored unless chroma_subsampling is 1 or 2.
        // chromaIsVerticallyCentered: Ignored unless chroma_subsampling is 1.
        colorItem->miniBoxChromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
    }

    avifDecoderItem * alphaItem = NULL;
    if (hasAlpha) {
        AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, /*itemID=*/2, &alphaItem));
        memcpy(alphaItem->type, infeType, 4);
        alphaItem->width = width;
        alphaItem->height = height;
        alphaItem->miniBoxPixelFormat = AVIF_PIXEL_FORMAT_YUV400;
        alphaItem->miniBoxChromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
    }

    avifDecoderItem * tmapItem = NULL;
    if (hasGainmap) {
        AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, /*itemID=*/3, &tmapItem));
        memcpy(tmapItem->type, "tmap", 4);
        colorItem->dimgForID = tmapItem->id;
        colorItem->dimgIdx = 0;
    }
    avifDecoderItem * gainmapItem = NULL;
    if (gainmapItemDataSize != 0) {
        AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, /*itemID=*/4, &gainmapItem));
        memcpy(gainmapItem->type, infeType, 4);
        gainmapItem->width = gainmapWidth;
        gainmapItem->height = gainmapHeight;
        gainmapItem->dimgForID = tmapItem->id;
        gainmapItem->dimgIdx = 1;
    }

    // Property with fixed index 1.
    avifProperty * colorCodecConfigProp = avifMetaCreateProperty(meta, (const char *)codecConfigType);
    AVIF_CHECKERR(colorCodecConfigProp, AVIF_RESULT_OUT_OF_MEMORY);
    colorCodecConfigProp->u.av1C = mainItemCodecConfig;
    AVIF_CHECKERR(avifDecoderItemAddProperty(colorItem, colorCodecConfigProp), AVIF_RESULT_OUT_OF_MEMORY);

    // Property with fixed index 2.
    avifProperty * ispeProp = avifMetaCreateProperty(meta, "ispe");
    AVIF_CHECKERR(ispeProp, AVIF_RESULT_OUT_OF_MEMORY);
    ispeProp->u.ispe.width = width;
    ispeProp->u.ispe.height = height;
    AVIF_CHECKERR(avifDecoderItemAddProperty(colorItem, ispeProp), AVIF_RESULT_OUT_OF_MEMORY);

    // Property with fixed index 3.
    avifProperty * pixiProp = avifMetaCreateProperty(meta, "pixi");
    AVIF_CHECKERR(pixiProp, AVIF_RESULT_OUT_OF_MEMORY);
    pixiProp->u.pixi.planeCount = chromaSubsampling == 0 ? 1 : 3;
    for (uint8_t plane = 0; plane < pixiProp->u.pixi.planeCount; ++plane) {
        pixiProp->u.pixi.planeDepths[plane] = (uint8_t)bitDepth;
    }
    AVIF_CHECKERR(avifDecoderItemAddProperty(colorItem, pixiProp), AVIF_RESULT_OUT_OF_MEMORY);

    // Property with fixed index 4.
    avifProperty * colrPropNCLX = avifMetaCreateProperty(meta, "colr");
    AVIF_CHECKERR(colrPropNCLX, AVIF_RESULT_OUT_OF_MEMORY);
    colrPropNCLX->u.colr.hasNCLX = AVIF_TRUE; // colour_type "nclx"
    colrPropNCLX->u.colr.colorPrimaries = (avifColorPrimaries)colorPrimaries;
    colrPropNCLX->u.colr.transferCharacteristics = (avifTransferCharacteristics)transferCharacteristics;
    colrPropNCLX->u.colr.matrixCoefficients = (avifMatrixCoefficients)matrixCoefficients;
    colrPropNCLX->u.colr.range = fullRange ? AVIF_RANGE_FULL : AVIF_RANGE_LIMITED;
    AVIF_CHECKERR(avifDecoderItemAddProperty(colorItem, colrPropNCLX), AVIF_RESULT_OUT_OF_MEMORY);

    // Property with fixed index 5.
    if (iccDataSize != 0) {
        avifProperty * colrPropICC = avifMetaCreateProperty(meta, "colr");
        AVIF_CHECKERR(colrPropICC, AVIF_RESULT_OUT_OF_MEMORY);
        colrPropICC->u.colr.hasICC = AVIF_TRUE; // colour_type "rICC" or "prof"
        colrPropICC->u.colr.iccOffset = rawOffset + avifROStreamOffset(&s);
        colrPropICC->u.colr.iccSize = (size_t)iccDataSize;
        AVIF_CHECKERR(avifROStreamSkip(&s, colrPropICC->u.colr.iccSize), AVIF_RESULT_BMFF_PARSE_FAILED);
        AVIF_CHECKERR(avifDecoderItemAddProperty(colorItem, colrPropICC), AVIF_RESULT_OUT_OF_MEMORY);
    } else {
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY); // Placeholder.
    }

    if (hasAlpha) {
        // Property with fixed index 6.
        avifProperty * alphaCodecConfigProp = avifMetaCreateProperty(meta, (const char *)codecConfigType);
        AVIF_CHECKERR(alphaCodecConfigProp, AVIF_RESULT_OUT_OF_MEMORY);
        alphaCodecConfigProp->u.av1C = alphaItemCodecConfig;
        AVIF_CHECKERR(avifDecoderItemAddProperty(alphaItem, alphaCodecConfigProp), AVIF_RESULT_OUT_OF_MEMORY);

        // Property with fixed index 7.
        alphaItem->auxForID = colorItem->id;
        colorItem->premByID = alphaIsPremultiplied;
        avifProperty * alphaAuxProp = avifMetaCreateProperty(meta, "auxC");
        AVIF_CHECKERR(alphaAuxProp, AVIF_RESULT_OUT_OF_MEMORY);
        strcpy(alphaAuxProp->u.auxC.auxType, AVIF_URN_ALPHA0);
        AVIF_CHECKERR(avifDecoderItemAddProperty(alphaItem, alphaAuxProp), AVIF_RESULT_OUT_OF_MEMORY);

        // Property with fixed index 2 (reused).
        AVIF_CHECKERR(avifDecoderItemAddProperty(alphaItem, ispeProp), AVIF_RESULT_OUT_OF_MEMORY);

        // Property with fixed index 8.
        avifProperty * alphaPixiProp = avifMetaCreateProperty(meta, "pixi");
        AVIF_CHECKERR(alphaPixiProp, AVIF_RESULT_OUT_OF_MEMORY);
        memcpy(alphaPixiProp->type, "pixi", 4);
        alphaPixiProp->u.pixi.planeCount = 1;
        alphaPixiProp->u.pixi.planeDepths[0] = (uint8_t)bitDepth;
        AVIF_CHECKERR(avifDecoderItemAddProperty(alphaItem, alphaPixiProp), AVIF_RESULT_OUT_OF_MEMORY);
    } else {
        // Placeholders 6, 7 and 8.
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY);
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY);
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY);
    }

    // Same behavior as avifImageExtractExifOrientationToIrotImir().
    if (orientation == 3 || orientation == 5 || orientation == 6 || orientation == 7 || orientation == 8) {
        // Property with fixed index 9.
        avifProperty * irotProp = avifMetaCreateProperty(meta, "irot");
        AVIF_CHECKERR(irotProp, AVIF_RESULT_OUT_OF_MEMORY);
        irotProp->u.irot.angle = orientation == 3 ? 2 : (orientation == 5 || orientation == 8) ? 1 : 3;
        AVIF_CHECKERR(avifDecoderItemAddProperty(colorItem, irotProp), AVIF_RESULT_OUT_OF_MEMORY);
    } else {
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY); // Placeholder.
    }
    if (orientation == 2 || orientation == 4 || orientation == 5 || orientation == 7) {
        // Property with fixed index 10.
        avifProperty * imirProp = avifMetaCreateProperty(meta, "imir");
        AVIF_CHECKERR(imirProp, AVIF_RESULT_OUT_OF_MEMORY);
        imirProp->u.imir.axis = orientation == 2 ? 1 : 0;
        AVIF_CHECKERR(avifDecoderItemAddProperty(colorItem, imirProp), AVIF_RESULT_OUT_OF_MEMORY);
    } else {
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY); // Placeholder.
    }

    if (hasClli) {
        // Property with fixed index 11.
        avifProperty * clliProp = avifMetaCreateProperty(meta, "clli");
        AVIF_CHECKERR(clliProp, AVIF_RESULT_OUT_OF_MEMORY);
        clliProp->u.clli = clli;
        AVIF_CHECKERR(avifDecoderItemAddProperty(colorItem, clliProp), AVIF_RESULT_OUT_OF_MEMORY);
    } else {
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY); // Placeholder.
    }
    // Properties with fixed indices 12 to 16 are ignored by libavif (mdcv, cclv, amve, reve and ndwt).
    for (int i = 12; i <= 16; ++i) {
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY); // Placeholder.
    }

    if (gainmapItemCodecConfigSize != 0) {
        // Property with fixed index 17.
        avifProperty * gainmapCodecConfigProp = avifMetaCreateProperty(meta, (const char *)codecConfigType);
        AVIF_CHECKERR(gainmapCodecConfigProp, AVIF_RESULT_OUT_OF_MEMORY);
        gainmapCodecConfigProp->u.av1C = gainmapItemCodecConfig;
        AVIF_CHECKERR(avifDecoderItemAddProperty(gainmapItem, gainmapCodecConfigProp), AVIF_RESULT_OUT_OF_MEMORY);
    } else {
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY); // Placeholder.
    }

    if (gainmapItemDataSize != 0) {
        // Property with fixed index 18.
        avifProperty * gainmapIspeProp = avifMetaCreateProperty(meta, "ispe");
        AVIF_CHECKERR(gainmapIspeProp, AVIF_RESULT_OUT_OF_MEMORY);
        gainmapIspeProp->u.ispe.width = gainmapWidth;
        gainmapIspeProp->u.ispe.height = gainmapHeight;
        AVIF_CHECKERR(avifDecoderItemAddProperty(gainmapItem, gainmapIspeProp), AVIF_RESULT_OUT_OF_MEMORY);

        // Property with fixed index 19.
        avifProperty * gainmapPixiProp = avifMetaCreateProperty(meta, "pixi");
        AVIF_CHECKERR(gainmapPixiProp, AVIF_RESULT_OUT_OF_MEMORY);
        memcpy(gainmapPixiProp->type, "pixi", 4);
        gainmapPixiProp->u.pixi.planeCount = gainmapChromaSubsampling == 0 ? 1 : 3;
        for (uint8_t plane = 0; plane < gainmapPixiProp->u.pixi.planeCount; ++plane) {
            gainmapPixiProp->u.pixi.planeDepths[plane] = (uint8_t)gainmapBitDepth;
        }
        AVIF_CHECKERR(avifDecoderItemAddProperty(gainmapItem, gainmapPixiProp), AVIF_RESULT_OUT_OF_MEMORY);

        // Property with fixed index 20.
        avifProperty * gainmapColrPropNCLX = avifMetaCreateProperty(meta, "colr");
        AVIF_CHECKERR(gainmapColrPropNCLX, AVIF_RESULT_OUT_OF_MEMORY);
        gainmapColrPropNCLX->u.colr.hasNCLX = AVIF_TRUE;                                                 // colour_type "nclx"
        gainmapColrPropNCLX->u.colr.colorPrimaries = AVIF_COLOR_PRIMARIES_UNSPECIFIED;                   // 2
        gainmapColrPropNCLX->u.colr.transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED; // 2
        gainmapColrPropNCLX->u.colr.matrixCoefficients = (avifMatrixCoefficients)gainmapMatrixCoefficients;
        gainmapColrPropNCLX->u.colr.range = gainmapFullRange ? AVIF_RANGE_FULL : AVIF_RANGE_LIMITED;
        AVIF_CHECKERR(avifDecoderItemAddProperty(gainmapItem, gainmapColrPropNCLX), AVIF_RESULT_OUT_OF_MEMORY);
    } else {
        // Placeholders 18, 19 and 20.
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY);
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY);
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY);
    }

    if (hasGainmap) {
        // Property with fixed index 21.
        avifProperty * tmapIspeProp = avifMetaCreateProperty(meta, "ispe");
        AVIF_CHECKERR(tmapIspeProp, AVIF_RESULT_OUT_OF_MEMORY);
        tmapIspeProp->u.ispe.width = orientation <= 4 ? width : height;
        tmapIspeProp->u.ispe.height = orientation <= 4 ? height : width;
        AVIF_CHECKERR(avifDecoderItemAddProperty(tmapItem, tmapIspeProp), AVIF_RESULT_OUT_OF_MEMORY);
    } else {
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY); // Placeholder.
    }

    if (hasGainmap && (tmapHasExplicitCicp || !tmapHasIcc)) {
        // Property with fixed index 22.
        avifProperty * tmapColrPropNCLX = avifMetaCreateProperty(meta, "colr");
        AVIF_CHECKERR(tmapColrPropNCLX, AVIF_RESULT_OUT_OF_MEMORY);
        tmapColrPropNCLX->u.colr.hasNCLX = AVIF_TRUE; // colour_type "nclx"
        tmapColrPropNCLX->u.colr.colorPrimaries = (avifColorPrimaries)tmapColorPrimaries;
        tmapColrPropNCLX->u.colr.transferCharacteristics = (avifTransferCharacteristics)tmapTransferCharacteristics;
        tmapColrPropNCLX->u.colr.matrixCoefficients = (avifMatrixCoefficients)tmapMatrixCoefficients;
        tmapColrPropNCLX->u.colr.range = tmapFullRange ? AVIF_RANGE_FULL : AVIF_RANGE_LIMITED;
        AVIF_CHECKERR(avifDecoderItemAddProperty(tmapItem, tmapColrPropNCLX), AVIF_RESULT_OUT_OF_MEMORY);
    } else {
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY); // Placeholder.
    }

    if (tmapIccDataSize != 0) {
        // Property with fixed index 23.
        avifProperty * tmapColrPropICC = avifMetaCreateProperty(meta, "colr");
        AVIF_CHECKERR(tmapColrPropICC, AVIF_RESULT_OUT_OF_MEMORY);
        tmapColrPropICC->u.colr.hasICC = AVIF_TRUE; // colour_type "rICC" or "prof"
        tmapColrPropICC->u.colr.iccOffset = rawOffset + avifROStreamOffset(&s);
        tmapColrPropICC->u.colr.iccSize = tmapIccDataSize;
        AVIF_CHECKERR(avifROStreamSkip(&s, tmapColrPropICC->u.colr.iccSize), AVIF_RESULT_BMFF_PARSE_FAILED);
        AVIF_CHECKERR(avifDecoderItemAddProperty(colorItem, tmapColrPropICC), AVIF_RESULT_OUT_OF_MEMORY);
    } else {
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY); // Placeholder.
    }

    if (tmapHasClli) {
        // Property with fixed index 24.
        avifProperty * tmapClliProp = avifMetaCreateProperty(meta, "clli");
        AVIF_CHECKERR(tmapClliProp, AVIF_RESULT_OUT_OF_MEMORY);
        tmapClliProp->u.clli = tmapClli;
        AVIF_CHECKERR(avifDecoderItemAddProperty(tmapItem, tmapClliProp), AVIF_RESULT_OUT_OF_MEMORY);
    } else {
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY); // Placeholder.
    }
    // Properties with fixed indices 25 to 29 are ignored by libavif (mdcv, cclv, amve, reve and ndwt).
    for (int i = 25; i <= 29; ++i) {
        AVIF_CHECKERR(avifMetaCreateProperty(meta, "skip"), AVIF_RESULT_OUT_OF_MEMORY); // Placeholder.
    }
    AVIF_ASSERT_OR_RETURN(meta->properties.count == 29);

    // Extents.

    if (gainmapMetadataSize != 0) {
        // Prepend the version field to the GainMapMetadata to form the ToneMapImage syntax.
        tmapItem->size = gainmapMetadataSize + 1;
        AVIF_CHECKRES(avifRWDataRealloc(&tmapItem->mergedExtents, tmapItem->size));
        tmapItem->ownsMergedExtents = AVIF_TRUE;
        tmapItem->mergedExtents.data[0] = 0; // unsigned int(8) version = 0;
        AVIF_CHECKERR(avifROStreamRead(&s, tmapItem->mergedExtents.data + 1, gainmapMetadataSize), AVIF_RESULT_BMFF_PARSE_FAILED);
    }

    if (hasAlpha) {
        avifExtent * alphaExtent = (avifExtent *)avifArrayPush(&alphaItem->extents);
        AVIF_CHECKERR(alphaExtent, AVIF_RESULT_OUT_OF_MEMORY);
        alphaExtent->offset = rawOffset + avifROStreamOffset(&s);
        alphaExtent->size = alphaItemDataSize;
        AVIF_CHECKERR(avifROStreamSkip(&s, alphaExtent->size), AVIF_RESULT_BMFF_PARSE_FAILED);
        alphaItem->size = alphaExtent->size;
    }

    if (gainmapItemDataSize != 0) {
        avifExtent * gainmapExtent = (avifExtent *)avifArrayPush(&gainmapItem->extents);
        AVIF_CHECKERR(gainmapExtent, AVIF_RESULT_OUT_OF_MEMORY);
        gainmapExtent->offset = rawOffset + avifROStreamOffset(&s);
        gainmapExtent->size = gainmapItemDataSize;
        AVIF_CHECKERR(avifROStreamSkip(&s, gainmapExtent->size), AVIF_RESULT_BMFF_PARSE_FAILED);
        gainmapItem->size = gainmapExtent->size;
    }

    avifExtent * colorExtent = (avifExtent *)avifArrayPush(&colorItem->extents);
    AVIF_CHECKERR(colorExtent, AVIF_RESULT_OUT_OF_MEMORY);
    colorExtent->offset = rawOffset + avifROStreamOffset(&s);
    colorExtent->size = mainItemDataSize;
    AVIF_CHECKERR(avifROStreamSkip(&s, colorExtent->size), AVIF_RESULT_BMFF_PARSE_FAILED);
    colorItem->size = colorExtent->size;

    if (hasExif) {
        avifDecoderItem * exifItem;
        AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, /*itemID=*/6, &exifItem));
        memcpy(exifItem->type, "Exif", 4);
        exifItem->descForID = colorItem->id; // 'cdsc'

        avifExtent * exifExtent = (avifExtent *)avifArrayPush(&exifItem->extents);
        AVIF_CHECKERR(exifExtent, AVIF_RESULT_OUT_OF_MEMORY);
        exifExtent->offset = rawOffset + avifROStreamOffset(&s);
        exifExtent->size = exifDataSize; // Does not include unsigned int(32) exif_tiff_header_offset;
        AVIF_CHECKERR(avifROStreamSkip(&s, exifExtent->size), AVIF_RESULT_BMFF_PARSE_FAILED);
        exifItem->size = exifExtent->size;
    }

    if (hasXmp) {
        avifDecoderItem * xmpItem;
        AVIF_CHECKRES(avifMetaFindOrCreateItem(meta, /*itemID=*/7, &xmpItem));
        memcpy(xmpItem->type, "mime", 4);
        memcpy(xmpItem->contentType.contentType, AVIF_CONTENT_TYPE_XMP, sizeof(AVIF_CONTENT_TYPE_XMP));
        xmpItem->descForID = colorItem->id; // 'cdsc'

        avifExtent * xmpExtent = (avifExtent *)avifArrayPush(&xmpItem->extents);
        AVIF_CHECKERR(xmpExtent, AVIF_RESULT_OUT_OF_MEMORY);
        xmpExtent->offset = rawOffset + avifROStreamOffset(&s);
        xmpExtent->size = xmpDataSize;
        AVIF_CHECKERR(avifROStreamSkip(&s, xmpExtent->size), AVIF_RESULT_BMFF_PARSE_FAILED);
        xmpItem->size = xmpExtent->size;
    }
    return AVIF_RESULT_OK;
}
#endif // AVIF_ENABLE_EXPERIMENTAL_MINI

static avifBool avifParseFileTypeBox(avifFileType * ftyp, const uint8_t * raw, size_t rawLen, avifDiagnostics * diag)
{
    BEGIN_STREAM(s, raw, rawLen, diag, "Box[ftyp]");

    AVIF_CHECK(avifROStreamRead(&s, ftyp->majorBrand, 4));
    AVIF_CHECK(avifROStreamRead(&s, ftyp->minorVersion, 4));

    size_t compatibleBrandsBytes = avifROStreamRemainingBytes(&s);
    if ((compatibleBrandsBytes % 4) != 0) {
        avifDiagnosticsPrintf(diag, "Box[ftyp] contains a compatible brands section that isn't divisible by 4 [%zu]", compatibleBrandsBytes);
        return AVIF_FALSE;
    }
    ftyp->compatibleBrands = avifROStreamCurrent(&s);
    AVIF_CHECK(avifROStreamSkip(&s, compatibleBrandsBytes));
    ftyp->compatibleBrandsCount = (int)compatibleBrandsBytes / 4;

    return AVIF_TRUE;
}

static avifBool avifFileTypeHasBrand(avifFileType * ftyp, const char * brand);
static avifBool avifFileTypeIsCompatible(avifFileType * ftyp);

static avifResult avifParse(avifDecoder * decoder)
{
    // Note: this top-level function is the only avifParse*() function that returns avifResult instead of avifBool.
    // Be sure to use AVIF_CHECKERR() in this function with an explicit error result instead of simply using AVIF_CHECK().

    avifResult readResult;
    uint64_t parseOffset = 0;
    avifDecoderData * data = decoder->data;
    avifBool ftypSeen = AVIF_FALSE;
    avifBool metaSeen = AVIF_FALSE;
    avifBool metaIsSizeZero = AVIF_FALSE;
    avifBool moovSeen = AVIF_FALSE;
    avifBool needsMeta = AVIF_FALSE;
    avifBool needsMoov = AVIF_FALSE;
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
    avifBool miniSeen = AVIF_FALSE;
    avifBool needsMini = AVIF_FALSE;
#endif
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
    avifBool needsTmap = AVIF_FALSE;
    avifBool tmapSeen = AVIF_FALSE;
#endif
    avifFileType ftyp = {};

    for (;;) {
        // Read just enough to get the next box header (a max of 32 bytes)
        avifROData headerContents;
        if ((decoder->io->sizeHint > 0) && (parseOffset > decoder->io->sizeHint)) {
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }
        readResult = decoder->io->read(decoder->io, 0, parseOffset, 32, &headerContents);
        if (readResult != AVIF_RESULT_OK) {
            return readResult;
        }
        if (!headerContents.size) {
            // If we got AVIF_RESULT_OK from the reader but received 0 bytes,
            // we've reached the end of the file with no errors. Hooray!
            break;
        }

        // Parse the header, and find out how many bytes it actually was
        BEGIN_STREAM(headerStream, headerContents.data, headerContents.size, &decoder->diag, "File-level box header");
        avifBoxHeader header;
        AVIF_CHECKERR(avifROStreamReadBoxHeaderPartial(&headerStream, &header, /*topLevel=*/AVIF_TRUE), AVIF_RESULT_BMFF_PARSE_FAILED);
        parseOffset += headerStream.offset;
        AVIF_ASSERT_OR_RETURN(decoder->io->sizeHint == 0 || parseOffset <= decoder->io->sizeHint);

        // Try to get the remainder of the box, if necessary
        uint64_t boxOffset = 0;
        avifROData boxContents = AVIF_DATA_EMPTY;

        avifBool isFtyp = AVIF_FALSE, isMeta = AVIF_FALSE, isMoov = AVIF_FALSE;
        avifBool isNonSkippableVariableLengthBox = AVIF_FALSE;
        if (!memcmp(header.type, "ftyp", 4)) {
            isFtyp = AVIF_TRUE;
            isNonSkippableVariableLengthBox = AVIF_TRUE;
        } else if (!memcmp(header.type, "meta", 4)) {
            isMeta = AVIF_TRUE;
            isNonSkippableVariableLengthBox = AVIF_TRUE;
            metaIsSizeZero = header.isSizeZeroBox;
        } else if (!memcmp(header.type, "moov", 4)) {
            isMoov = AVIF_TRUE;
            isNonSkippableVariableLengthBox = AVIF_TRUE;
        }
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
        avifBool isMini = AVIF_FALSE;
        if (!isNonSkippableVariableLengthBox && !memcmp(header.type, "mini", 4)) {
            isMini = AVIF_TRUE;
            isNonSkippableVariableLengthBox = AVIF_TRUE;
        }
#endif

        if (!isFtyp && (isNonSkippableVariableLengthBox || !memcmp(header.type, "free", 4) || !memcmp(header.type, "skip", 4) ||
                        !memcmp(header.type, "mdat", 4))) {
            // Section 6.3.4 of ISO/IEC 14496-12:
            //   The FileTypeBox shall occur before any variable-length box (e.g. movie, free space, media data).
            AVIF_CHECKERR(ftypSeen, AVIF_RESULT_BMFF_PARSE_FAILED);
        }

        if (isNonSkippableVariableLengthBox) {
            boxOffset = parseOffset;
            size_t sizeToRead;
            if (header.isSizeZeroBox) {
                // The box body goes till the end of the file.
                if (decoder->io->sizeHint != 0 && decoder->io->sizeHint - parseOffset < SIZE_MAX) {
                    sizeToRead = decoder->io->sizeHint - parseOffset;
                } else {
                    sizeToRead = SIZE_MAX; // This will get truncated. See the documentation of avifIOReadFunc.
                }
            } else {
                sizeToRead = header.size;
            }
            readResult = decoder->io->read(decoder->io, 0, parseOffset, sizeToRead, &boxContents);
            if (readResult != AVIF_RESULT_OK) {
                return readResult;
            }
            if (header.isSizeZeroBox) {
                header.size = boxContents.size;
            } else if (boxContents.size != header.size) {
                // A truncated box, bail out
                return AVIF_RESULT_TRUNCATED_DATA;
            }
        } else if (header.isSizeZeroBox) {
            // An unknown top level box with size 0 was found. If we reach here it means we haven't completed parsing successfully
            // since there are no further boxes left.
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        } else if (header.size > (UINT64_MAX - parseOffset)) {
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }
        parseOffset += header.size;

        if (isFtyp) {
            AVIF_CHECKERR(!ftypSeen, AVIF_RESULT_BMFF_PARSE_FAILED);
            AVIF_CHECKERR(avifParseFileTypeBox(&ftyp, boxContents.data, boxContents.size, data->diag), AVIF_RESULT_BMFF_PARSE_FAILED);
            AVIF_CHECKERR(avifFileTypeIsCompatible(&ftyp), AVIF_RESULT_INVALID_FTYP);
            ftypSeen = AVIF_TRUE;
            memcpy(data->majorBrand, ftyp.majorBrand, 4); // Remember the major brand for future AVIF_DECODER_SOURCE_AUTO decisions
            if (ftyp.compatibleBrandsCount > 0) {
                AVIF_CHECKERR(avifArrayCreate(&data->compatibleBrands, sizeof(avifBrand), ftyp.compatibleBrandsCount),
                              AVIF_RESULT_OUT_OF_MEMORY);
                memcpy(data->compatibleBrands.brand, ftyp.compatibleBrands, sizeof(avifBrand) * ftyp.compatibleBrandsCount);
                data->compatibleBrands.count = ftyp.compatibleBrandsCount;
            }
            needsMeta = avifFileTypeHasBrand(&ftyp, "avif");
            needsMoov = avifFileTypeHasBrand(&ftyp, "avis");
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
            needsMini = avifFileTypeHasBrand(&ftyp, "mif3");
            if (needsMini) {
                AVIF_CHECKERR(!needsMeta, AVIF_RESULT_INVALID_FTYP);
                // Section O.2.1.2 of ISO/IEC 23008-12:2014, CDAM 2:
                //   When the 'mif3' brand is present as the major_brand of the FileTypeBox,
                //   the minor_version of the FileTypeBox shall be 0 or a brand that is either
                //   structurally compatible with the 'mif3' brand, such as a codec brand
                //   complying with the 'mif3' structural brand, or a brand to which the file
                //   conforms after the equivalent MetaBox has been transformed from
                //   MinimizedImageBox as specified in Clause O.4.
                AVIF_CHECKERR(!memcmp(ftyp.minorVersion, "\0\0\0\0", 4) || !memcmp(ftyp.minorVersion, "avif", 4),
                              AVIF_RESULT_BMFF_PARSE_FAILED);
            }
#endif // AVIF_ENABLE_EXPERIMENTAL_MINI
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
            needsTmap = avifFileTypeHasBrand(&ftyp, "tmap");
            if (needsTmap) {
                needsMeta = AVIF_TRUE;
            }
#endif
        } else if (isMeta) {
            AVIF_CHECKERR(!metaSeen, AVIF_RESULT_BMFF_PARSE_FAILED);
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
            AVIF_CHECKERR(!miniSeen, AVIF_RESULT_BMFF_PARSE_FAILED);
#endif
            AVIF_CHECKRES(avifParseMetaBox(data->meta, boxOffset, boxContents.data, boxContents.size, data->diag));
            metaSeen = AVIF_TRUE;

#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
            for (uint32_t itemIndex = 0; itemIndex < data->meta->items.count; ++itemIndex) {
                if (!memcmp(data->meta->items.item[itemIndex]->type, "tmap", 4)) {
                    tmapSeen = AVIF_TRUE;
                    break;
                }
            }
#endif

#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
        } else if (isMini) {
            AVIF_CHECKERR(!metaSeen, AVIF_RESULT_BMFF_PARSE_FAILED);
            AVIF_CHECKERR(!miniSeen, AVIF_RESULT_BMFF_PARSE_FAILED);
            const avifBool isAvifAccordingToMinorVersion = !memcmp(ftyp.minorVersion, "avif", 4);
            AVIF_CHECKRES(
                avifParseMinimizedImageBox(data, boxOffset, boxContents.data, boxContents.size, isAvifAccordingToMinorVersion, data->diag));
            miniSeen = AVIF_TRUE;
#endif
        } else if (isMoov) {
            AVIF_CHECKERR(!moovSeen, AVIF_RESULT_BMFF_PARSE_FAILED);
            AVIF_CHECKRES(
                avifParseMovieBox(data, boxOffset, boxContents.data, boxContents.size, decoder->imageSizeLimit, decoder->imageDimensionLimit));
            moovSeen = AVIF_TRUE;
            decoder->imageSequenceTrackPresent = AVIF_TRUE;
        }

#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
        if (ftypSeen && !needsMini) {
            // When MinimizedImageBox is present in a file, the 'mif3' brand or a derived brand that implies the 'mif3'
            // brand shall be the major brand or present among the compatible brands in the FileTypeBox.
            AVIF_CHECKERR(!miniSeen, AVIF_RESULT_BMFF_PARSE_FAILED);
        }
#endif // AVIF_ENABLE_EXPERIMENTAL_MINI

        // See if there is enough information to consider Parse() a success and early-out:
        // * If the brand 'avif' is present, require a meta box
        // * If the brand 'avis' is present, require a moov box
        // * If AVIF_ENABLE_EXPERIMENTAL_MINI is defined and the brand 'mif3' is present, require a mini box
        avifBool sawEverythingNeeded = ftypSeen && (!needsMeta || metaSeen) && (!needsMoov || moovSeen);
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
        sawEverythingNeeded = sawEverythingNeeded && (!needsMini || miniSeen);
#endif
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
        sawEverythingNeeded = sawEverythingNeeded && (!needsTmap || tmapSeen);
#endif
        if (sawEverythingNeeded) {
            return AVIF_RESULT_OK;
        }
    }
    if (!ftypSeen) {
        return AVIF_RESULT_INVALID_FTYP;
    }
    if ((needsMeta && !metaSeen) || (needsMoov && !moovSeen)) {
        return AVIF_RESULT_TRUNCATED_DATA;
    }
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
    if (needsTmap && !tmapSeen) {
        return metaIsSizeZero ? AVIF_RESULT_TRUNCATED_DATA : AVIF_RESULT_BMFF_PARSE_FAILED;
    }
#else
    (void)metaIsSizeZero;
#endif
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
    if (needsMini && !miniSeen) {
        return AVIF_RESULT_TRUNCATED_DATA;
    }
#endif
    return AVIF_RESULT_OK;
}

// ---------------------------------------------------------------------------

static avifBool avifFileTypeHasBrand(avifFileType * ftyp, const char * brand)
{
    if (!memcmp(ftyp->majorBrand, brand, 4)) {
        return AVIF_TRUE;
    }

    for (int compatibleBrandIndex = 0; compatibleBrandIndex < ftyp->compatibleBrandsCount; ++compatibleBrandIndex) {
        const uint8_t * compatibleBrand = &ftyp->compatibleBrands[4 * compatibleBrandIndex];
        if (!memcmp(compatibleBrand, brand, 4)) {
            return AVIF_TRUE;
        }
    }
    return AVIF_FALSE;
}

static avifBool avifFileTypeIsCompatible(avifFileType * ftyp)
{
    return avifFileTypeHasBrand(ftyp, "avif") || avifFileTypeHasBrand(ftyp, "avis")
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
           || avifFileTypeHasBrand(ftyp, "mif3")
#endif // AVIF_ENABLE_EXPERIMENTAL_MINI
        ;
}

avifBool avifPeekCompatibleFileType(const avifROData * input)
{
    BEGIN_STREAM(s, input->data, input->size, NULL, NULL);

    avifBoxHeader header;
    if (!avifROStreamReadBoxHeaderPartial(&s, &header, /*topLevel=*/AVIF_TRUE) || memcmp(header.type, "ftyp", 4)) {
        return AVIF_FALSE;
    }
    if (header.isSizeZeroBox) {
        // The ftyp box goes on till the end of the file. Either there is no brand requiring anything in the file but a
        // FileTypebox (so not AVIF), or it is invalid.
        return AVIF_FALSE;
    }
    AVIF_CHECK(avifROStreamHasBytesLeft(&s, header.size));

    avifFileType ftyp;
    memset(&ftyp, 0, sizeof(avifFileType));
    avifBool parsed = avifParseFileTypeBox(&ftyp, avifROStreamCurrent(&s), header.size, NULL);
    if (!parsed) {
        return AVIF_FALSE;
    }
    return avifFileTypeIsCompatible(&ftyp);
}

#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
static avifBool avifBrandArrayHasBrand(avifBrandArray * brands, const char * brand)
{
    for (uint32_t brandIndex = 0; brandIndex < brands->count; ++brandIndex) {
        if (!memcmp(brands->brand[brandIndex], brand, 4)) {
            return AVIF_TRUE;
        }
    }
    return AVIF_FALSE;
}
#endif

// ---------------------------------------------------------------------------

avifDecoder * avifDecoderCreate(void)
{
    avifDecoder * decoder = (avifDecoder *)avifAlloc(sizeof(avifDecoder));
    if (decoder == NULL) {
        return NULL;
    }
    memset(decoder, 0, sizeof(avifDecoder));
    decoder->maxThreads = 1;
    decoder->imageSizeLimit = AVIF_DEFAULT_IMAGE_SIZE_LIMIT;
    decoder->imageDimensionLimit = AVIF_DEFAULT_IMAGE_DIMENSION_LIMIT;
    decoder->imageCountLimit = AVIF_DEFAULT_IMAGE_COUNT_LIMIT;
    decoder->strictFlags = AVIF_STRICT_ENABLED;
    return decoder;
}

static void avifDecoderCleanup(avifDecoder * decoder)
{
    if (decoder->data) {
        avifDecoderDataDestroy(decoder->data);
        decoder->data = NULL;
    }

    if (decoder->image) {
        avifImageDestroy(decoder->image);
        decoder->image = NULL;
    }
    avifDiagnosticsClearError(&decoder->diag);
}

void avifDecoderDestroy(avifDecoder * decoder)
{
    avifDecoderCleanup(decoder);
    avifIODestroy(decoder->io);
    avifFree(decoder);
}

avifResult avifDecoderSetSource(avifDecoder * decoder, avifDecoderSource source)
{
    decoder->requestedSource = source;
    return avifDecoderReset(decoder);
}

void avifDecoderSetIO(avifDecoder * decoder, avifIO * io)
{
    avifIODestroy(decoder->io);
    decoder->io = io;
}

avifResult avifDecoderSetIOMemory(avifDecoder * decoder, const uint8_t * data, size_t size)
{
    avifIO * io = avifIOCreateMemoryReader(data, size);
    AVIF_CHECKERR(io != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    avifDecoderSetIO(decoder, io);
    return AVIF_RESULT_OK;
}

avifResult avifDecoderSetIOFile(avifDecoder * decoder, const char * filename)
{
    avifIO * io = avifIOCreateFileReader(filename);
    if (!io) {
        return AVIF_RESULT_IO_ERROR;
    }
    avifDecoderSetIO(decoder, io);
    return AVIF_RESULT_OK;
}

// 0-byte extents are ignored/overwritten during the merge, as they are the signal from helper
// functions that no extent was necessary for this given sample. If both provided extents are
// >0 bytes, this will set dst to be an extent that bounds both supplied extents.
static avifResult avifExtentMerge(avifExtent * dst, const avifExtent * src)
{
    if (!dst->size) {
        *dst = *src;
        return AVIF_RESULT_OK;
    }
    if (!src->size) {
        return AVIF_RESULT_OK;
    }

    const uint64_t minExtent1 = dst->offset;
    const uint64_t maxExtent1 = dst->offset + dst->size;
    const uint64_t minExtent2 = src->offset;
    const uint64_t maxExtent2 = src->offset + src->size;
    dst->offset = AVIF_MIN(minExtent1, minExtent2);
    const uint64_t extentLength = AVIF_MAX(maxExtent1, maxExtent2) - dst->offset;
    if (extentLength > SIZE_MAX) {
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }
    dst->size = (size_t)extentLength;
    return AVIF_RESULT_OK;
}

avifResult avifDecoderNthImageMaxExtent(const avifDecoder * decoder, uint32_t frameIndex, avifExtent * outExtent)
{
    if (!decoder->data) {
        // Nothing has been parsed yet
        return AVIF_RESULT_NO_CONTENT;
    }

    memset(outExtent, 0, sizeof(avifExtent));

    uint32_t startFrameIndex = avifDecoderNearestKeyframe(decoder, frameIndex);
    uint32_t endFrameIndex = frameIndex;
    for (uint32_t currentFrameIndex = startFrameIndex; currentFrameIndex <= endFrameIndex; ++currentFrameIndex) {
        for (unsigned int tileIndex = 0; tileIndex < decoder->data->tiles.count; ++tileIndex) {
            avifTile * tile = &decoder->data->tiles.tile[tileIndex];
            if (currentFrameIndex >= tile->input->samples.count) {
                return AVIF_RESULT_NO_IMAGES_REMAINING;
            }

            avifDecodeSample * sample = &tile->input->samples.sample[currentFrameIndex];
            avifExtent sampleExtent;
            if (sample->itemID) {
                // The data comes from an item. Let avifDecoderItemMaxExtent() do the heavy lifting.

                avifDecoderItem * item;
                AVIF_CHECKRES(avifMetaFindOrCreateItem(decoder->data->meta, sample->itemID, &item));
                avifResult maxExtentResult = avifDecoderItemMaxExtent(item, sample, &sampleExtent);
                if (maxExtentResult != AVIF_RESULT_OK) {
                    return maxExtentResult;
                }
            } else {
                // The data likely comes from a sample table. Use the sample position directly.

                sampleExtent.offset = sample->offset;
                sampleExtent.size = sample->size;
            }

            if (sampleExtent.size > UINT64_MAX - sampleExtent.offset) {
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }

            avifResult extentMergeResult = avifExtentMerge(outExtent, &sampleExtent);
            if (extentMergeResult != AVIF_RESULT_OK) {
                return extentMergeResult;
            }
        }
    }
    return AVIF_RESULT_OK;
}

static avifResult avifDecoderPrepareSample(avifDecoder * decoder, avifDecodeSample * sample, size_t partialByteCount)
{
    if (!sample->data.size || sample->partialData) {
        // This sample hasn't been read from IO or had its extents fully merged yet.

        size_t bytesToRead = sample->size;
        if (partialByteCount && (bytesToRead > partialByteCount)) {
            bytesToRead = partialByteCount;
        }

        if (sample->itemID) {
            // The data comes from an item. Let avifDecoderItemRead() do the heavy lifting.

            avifDecoderItem * item;
            AVIF_CHECKRES(avifMetaFindOrCreateItem(decoder->data->meta, sample->itemID, &item));
            avifROData itemContents;
            if (sample->offset > SIZE_MAX) {
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            size_t offset = (size_t)sample->offset;
            avifResult readResult = avifDecoderItemRead(item, decoder->io, &itemContents, offset, bytesToRead, &decoder->diag);
            if (readResult != AVIF_RESULT_OK) {
                return readResult;
            }

            // avifDecoderItemRead is guaranteed to already be persisted by either the underlying IO
            // or by mergedExtents; just reuse the buffer here.
            sample->data = itemContents;
            sample->ownsData = AVIF_FALSE;
            sample->partialData = item->partialMergedExtents;
        } else {
            // The data likely comes from a sample table. Pull the sample and make a copy if necessary.

            avifROData sampleContents;
            if ((decoder->io->sizeHint > 0) && (sample->offset > decoder->io->sizeHint)) {
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            avifResult readResult = decoder->io->read(decoder->io, 0, sample->offset, bytesToRead, &sampleContents);
            if (readResult != AVIF_RESULT_OK) {
                return readResult;
            }
            if (sampleContents.size != bytesToRead) {
                return AVIF_RESULT_TRUNCATED_DATA;
            }

            sample->ownsData = !decoder->io->persistent;
            sample->partialData = (bytesToRead != sample->size);
            if (decoder->io->persistent) {
                sample->data = sampleContents;
            } else {
                AVIF_CHECKRES(avifRWDataSet((avifRWData *)&sample->data, sampleContents.data, sampleContents.size));
            }
        }
    }
    return AVIF_RESULT_OK;
}

// Returns AVIF_TRUE if the item should be skipped. Items should be skipped for one of the following reasons:
//  * Size is 0.
//  * Has an essential property that isn't supported by libavif.
//  * Item is not a single image or a grid.
//  * Item is a thumbnail.
static avifBool avifDecoderItemShouldBeSkipped(const avifDecoderItem * item)
{
    return !item->size || item->hasUnsupportedEssentialProperty ||
           (avifGetCodecType(item->type) == AVIF_CODEC_TYPE_UNKNOWN && memcmp(item->type, "grid", 4)) || item->thumbnailForID != 0;
}

avifResult avifDecoderParse(avifDecoder * decoder)
{
    avifDiagnosticsClearError(&decoder->diag);

    // An imageSizeLimit greater than AVIF_DEFAULT_IMAGE_SIZE_LIMIT and the special value of 0 to
    // disable the limit are not yet implemented.
    if ((decoder->imageSizeLimit > AVIF_DEFAULT_IMAGE_SIZE_LIMIT) || (decoder->imageSizeLimit == 0)) {
        return AVIF_RESULT_NOT_IMPLEMENTED;
    }
    if (!decoder->io || !decoder->io->read) {
        return AVIF_RESULT_IO_NOT_SET;
    }
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
    if (decoder->enableDecodingGainMap && !decoder->enableParsingGainMapMetadata) {
        avifDiagnosticsPrintf(&decoder->diag, "If enableDecodingGainMap is true, enableParsingGainMapMetadata must also be true");
        return AVIF_RESULT_INVALID_ARGUMENT;
    }
#endif

    // Cleanup anything lingering in the decoder
    avifDecoderCleanup(decoder);

    // -----------------------------------------------------------------------
    // Parse BMFF boxes

    decoder->data = avifDecoderDataCreate();
    AVIF_CHECKERR(decoder->data != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    decoder->data->diag = &decoder->diag;

    AVIF_CHECKRES(avifParse(decoder));

    // Walk the decoded items (if any) and harvest ispe
    avifDecoderData * data = decoder->data;
    for (uint32_t itemIndex = 0; itemIndex < data->meta->items.count; ++itemIndex) {
        avifDecoderItem * item = data->meta->items.item[itemIndex];
        if (avifDecoderItemShouldBeSkipped(item)) {
            continue;
        }

        const avifProperty * ispeProp = avifPropertyArrayFind(&item->properties, "ispe");
        if (ispeProp) {
            item->width = ispeProp->u.ispe.width;
            item->height = ispeProp->u.ispe.height;

            if ((item->width == 0) || (item->height == 0)) {
                avifDiagnosticsPrintf(data->diag, "Item ID [%u] has an invalid size [%ux%u]", item->id, item->width, item->height);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            if (avifDimensionsTooLarge(item->width, item->height, decoder->imageSizeLimit, decoder->imageDimensionLimit)) {
                avifDiagnosticsPrintf(data->diag, "Item ID [%u] dimensions are too large [%ux%u]", item->id, item->width, item->height);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
        } else {
            const avifProperty * auxCProp = avifPropertyArrayFind(&item->properties, "auxC");
            if (auxCProp && isAlphaURN(auxCProp->u.auxC.auxType)) {
                if (decoder->strictFlags & AVIF_STRICT_ALPHA_ISPE_REQUIRED) {
                    avifDiagnosticsPrintf(data->diag,
                                          "[Strict] Alpha auxiliary image item ID [%u] is missing a mandatory ispe property",
                                          item->id);
                    return AVIF_RESULT_BMFF_PARSE_FAILED;
                }
            } else {
                avifDiagnosticsPrintf(data->diag, "Item ID [%u] is missing a mandatory ispe property", item->id);
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
        }
    }
    return avifDecoderReset(decoder);
}

static avifResult avifCodecCreateInternal(avifCodecChoice choice, const avifTile * tile, avifDiagnostics * diag, avifCodec ** codec)
{
#if defined(AVIF_CODEC_AVM)
    // AVIF_CODEC_CHOICE_AUTO leads to AVIF_CODEC_TYPE_AV1 by default. Reroute correctly.
    if (choice == AVIF_CODEC_CHOICE_AUTO && tile->codecType == AVIF_CODEC_TYPE_AV2) {
        choice = AVIF_CODEC_CHOICE_AVM;
    }
#endif

    const avifCodecType codecTypeFromChoice = avifCodecTypeFromChoice(choice, AVIF_CODEC_FLAG_CAN_DECODE);
    if (codecTypeFromChoice == AVIF_CODEC_TYPE_UNKNOWN) {
        avifDiagnosticsPrintf(diag,
                              "Tile type is %s but there is no compatible codec available to decode it",
                              avifGetConfigurationPropertyName(tile->codecType));
        return AVIF_RESULT_NO_CODEC_AVAILABLE;
    } else if (choice != AVIF_CODEC_CHOICE_AUTO && codecTypeFromChoice != tile->codecType) {
        avifDiagnosticsPrintf(diag,
                              "Tile type is %s but incompatible %s codec was explicitly set as decoding implementation",
                              avifGetConfigurationPropertyName(tile->codecType),
                              avifCodecName(choice, AVIF_CODEC_FLAG_CAN_DECODE));
        return AVIF_RESULT_DECODE_COLOR_FAILED;
    }

    AVIF_CHECKRES(avifCodecCreate(choice, AVIF_CODEC_FLAG_CAN_DECODE, codec));
    AVIF_CHECKERR(*codec, AVIF_RESULT_OUT_OF_MEMORY);
    (*codec)->diag = diag;
    (*codec)->operatingPoint = tile->operatingPoint;
    (*codec)->allLayers = tile->input->allLayers;
    return AVIF_RESULT_OK;
}

static avifBool avifTilesCanBeDecodedWithSameCodecInstance(avifDecoderData * data)
{
    int32_t numImageBuffers = 0, numStolenImageBuffers = 0;
    for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
        if (data->tileInfos[c].tileCount > 0) {
            ++numImageBuffers;
        }
#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
        // The sample operations require multiple buffers for compositing so no plane is stolen
        // when there is a 'sato' Sample Transform derived image item.
        if (c >= AVIF_SAMPLE_TRANSFORM_MIN_CATEGORY && c <= AVIF_SAMPLE_TRANSFORM_MAX_CATEGORY && data->tileInfos[c].tileCount > 0) {
            continue;
        }
#endif
        if (data->tileInfos[c].tileCount == 1) {
            ++numStolenImageBuffers;
        }
    }
    if (numStolenImageBuffers > 0 && numImageBuffers > 1) {
        // Single tile image with single tile alpha plane or gain map. In this case each tile needs its own decoder since the planes will be
        // "stolen". Stealing either the color or the alpha plane (or gain map) will invalidate the other ones when decode is called the second
        // (or third) time.
        return AVIF_FALSE;
    }
    const uint8_t firstTileOperatingPoint = data->tiles.tile[0].operatingPoint;
    const avifBool firstTileAllLayers = data->tiles.tile[0].input->allLayers;
    for (unsigned int i = 1; i < data->tiles.count; ++i) {
        const avifTile * tile = &data->tiles.tile[i];
        if (tile->operatingPoint != firstTileOperatingPoint || tile->input->allLayers != firstTileAllLayers) {
            return AVIF_FALSE;
        }
        // avifDecoderItemValidateProperties() verified during avifDecoderParse() that all tiles
        // share the same coding format so no need to check for codecType equality here.
    }
    return AVIF_TRUE;
}

static avifResult avifDecoderCreateCodecs(avifDecoder * decoder)
{
    avifDecoderData * data = decoder->data;
    avifDecoderDataResetCodec(data);

    if (data->source == AVIF_DECODER_SOURCE_TRACKS) {
        // In this case, we will use at most two codec instances (one for the color planes and one for the alpha plane).
        // Gain maps are not supported.
        AVIF_CHECKRES(avifCodecCreateInternal(decoder->codecChoice, &decoder->data->tiles.tile[0], &decoder->diag, &data->codec));
        data->tiles.tile[0].codec = data->codec;
        if (data->tiles.count > 1) {
            AVIF_CHECKRES(avifCodecCreateInternal(decoder->codecChoice, &decoder->data->tiles.tile[1], &decoder->diag, &data->codecAlpha));
            data->tiles.tile[1].codec = data->codecAlpha;
        }
    } else {
        // In this case, we will use one codec instance when there is only one tile or when all of the following conditions are
        // met:
        //   - The image must have exactly one layer (i.e.) decoder->imageCount == 1.
        //   - All the tiles must have the same operating point (because the codecs take operating point once at initialization
        //     and do not allow it to be changed later).
        //   - All the tiles must have the same value for allLayers (because the codecs take allLayers once at initialization
        //     and do not allow it to be changed later).
        //   - If the image has a single tile, it must not have a single tile alpha plane (in this case we will steal the planes
        //     from the decoder, so we cannot use the same decoder for both the color and the alpha planes).
        //   - All tiles have the same type (AV1 or AV2).
        // Otherwise, we will use |tiles.count| decoder instances (one instance for each tile).
        avifBool canUseSingleCodecInstance = (data->tiles.count == 1) ||
                                             (decoder->imageCount == 1 && avifTilesCanBeDecodedWithSameCodecInstance(data));
        if (canUseSingleCodecInstance) {
            AVIF_CHECKRES(avifCodecCreateInternal(decoder->codecChoice, &decoder->data->tiles.tile[0], &decoder->diag, &data->codec));
            for (unsigned int i = 0; i < decoder->data->tiles.count; ++i) {
                decoder->data->tiles.tile[i].codec = data->codec;
            }
        } else {
            for (unsigned int i = 0; i < decoder->data->tiles.count; ++i) {
                avifTile * tile = &decoder->data->tiles.tile[i];
                AVIF_CHECKRES(avifCodecCreateInternal(decoder->codecChoice, tile, &decoder->diag, &tile->codec));
            }
        }
    }
    return AVIF_RESULT_OK;
}

// Returns the primary color item if found, or NULL.
static avifDecoderItem * avifMetaFindColorItem(avifMeta * meta)
{
    for (uint32_t itemIndex = 0; itemIndex < meta->items.count; ++itemIndex) {
        avifDecoderItem * item = meta->items.item[itemIndex];
        if (avifDecoderItemShouldBeSkipped(item)) {
            continue;
        }
        if (item->id == meta->primaryItemID) {
            return item;
        }
    }
    return NULL;
}

// Returns AVIF_TRUE if item is an alpha auxiliary item of the parent color
// item.
static avifBool avifDecoderItemIsAlphaAux(const avifDecoderItem * item, uint32_t colorItemId)
{
    if (item->auxForID != colorItemId)
        return AVIF_FALSE;
    const avifProperty * auxCProp = avifPropertyArrayFind(&item->properties, "auxC");
    return auxCProp && isAlphaURN(auxCProp->u.auxC.auxType);
}

// Finds the alpha item whose parent item is colorItem and sets it in the alphaItem output parameter. Returns AVIF_RESULT_OK on
// success. Note that *alphaItem can be NULL even if the return value is AVIF_RESULT_OK. If the colorItem is a grid and the alpha
// item is represented as a set of auxl items to each color tile, then a fake item will be created and *isAlphaItemInInput will be
// set to AVIF_FALSE. In this case, the alpha item merely exists to hold the locations of the alpha tile items. The data of this
// item need not be read and the pixi property cannot be validated. Otherwise, *isAlphaItemInInput will be set to AVIF_TRUE when
// *alphaItem is not NULL.
static avifResult avifMetaFindAlphaItem(avifMeta * meta,
                                        const avifDecoderItem * colorItem,
                                        const avifTileInfo * colorInfo,
                                        avifDecoderItem ** alphaItem,
                                        avifTileInfo * alphaInfo,
                                        avifBool * isAlphaItemInInput)
{
    for (uint32_t itemIndex = 0; itemIndex < meta->items.count; ++itemIndex) {
        avifDecoderItem * item = meta->items.item[itemIndex];
        if (avifDecoderItemShouldBeSkipped(item)) {
            continue;
        }
        if (avifDecoderItemIsAlphaAux(item, colorItem->id)) {
            *alphaItem = item;
            *isAlphaItemInInput = AVIF_TRUE;
            return AVIF_RESULT_OK;
        }
    }
    if (memcmp(colorItem->type, "grid", 4)) {
        *alphaItem = NULL;
        *isAlphaItemInInput = AVIF_FALSE;
        return AVIF_RESULT_OK;
    }
    // If color item is a grid, check if there is an alpha channel which is represented as an auxl item to each color tile item.
    const uint32_t tileCount = colorInfo->grid.rows * colorInfo->grid.columns;
    if (tileCount == 0) {
        *alphaItem = NULL;
        *isAlphaItemInInput = AVIF_FALSE;
        return AVIF_RESULT_OK;
    }
    // Keep the same 'dimg' order as it defines where each tile is located in the reconstructed image.
    uint32_t * dimgIdxToAlphaItemIdx = (uint32_t *)avifAlloc(tileCount * sizeof(uint32_t));
    AVIF_CHECKERR(dimgIdxToAlphaItemIdx != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    const uint32_t itemIndexNotSet = UINT32_MAX;
    for (uint32_t dimgIdx = 0; dimgIdx < tileCount; ++dimgIdx) {
        dimgIdxToAlphaItemIdx[dimgIdx] = itemIndexNotSet;
    }
    uint32_t alphaItemCount = 0;
    for (uint32_t i = 0; i < meta->items.count; ++i) {
        const avifDecoderItem * const item = meta->items.item[i];
        if (item->dimgForID == colorItem->id) {
            avifBool seenAlphaForCurrentItem = AVIF_FALSE;
            for (uint32_t j = 0; j < meta->items.count; ++j) {
                avifDecoderItem * auxlItem = meta->items.item[j];
                if (avifDecoderItemIsAlphaAux(auxlItem, item->id)) {
                    if (seenAlphaForCurrentItem || auxlItem->dimgForID != 0 || item->dimgIdx >= tileCount ||
                        dimgIdxToAlphaItemIdx[item->dimgIdx] != itemIndexNotSet) {
                        // One of the following invalid cases:
                        // * Multiple items are claiming to be the alpha auxiliary of the current item.
                        // * Alpha auxiliary is dimg for another item.
                        // * There are too many items in the dimg array (also checked later in avifFillDimgIdxToItemIdxArray()).
                        // * There is a repetition in the dimg array (also checked later in avifFillDimgIdxToItemIdxArray()).
                        avifFree(dimgIdxToAlphaItemIdx);
                        return AVIF_RESULT_INVALID_IMAGE_GRID;
                    }
                    dimgIdxToAlphaItemIdx[item->dimgIdx] = j;
                    ++alphaItemCount;
                    seenAlphaForCurrentItem = AVIF_TRUE;
                }
            }
            if (!seenAlphaForCurrentItem) {
                // No alpha auxiliary item was found for the current item. Treat this as an image without alpha.
                avifFree(dimgIdxToAlphaItemIdx);
                *alphaItem = NULL;
                *isAlphaItemInInput = AVIF_FALSE;
                return AVIF_RESULT_OK;
            }
        }
    }
    if (alphaItemCount != tileCount) {
        avifFree(dimgIdxToAlphaItemIdx);
        return AVIF_RESULT_INVALID_IMAGE_GRID;
    }
    // Find an unused ID.
    avifResult result;
    if (meta->items.count >= UINT32_MAX - 1) {
        // In the improbable case where all IDs are used.
        result = AVIF_RESULT_DECODE_ALPHA_FAILED;
    } else {
        uint32_t newItemID = 0;
        avifBool isUsed;
        do {
            ++newItemID;
            isUsed = AVIF_FALSE;
            for (uint32_t i = 0; i < meta->items.count; ++i) {
                if (meta->items.item[i]->id == newItemID) {
                    isUsed = AVIF_TRUE;
                    break;
                }
            }
        } while (isUsed && newItemID != 0);
        result = avifMetaFindOrCreateItem(meta, newItemID, alphaItem); // Create new empty item.
    }
    if (result != AVIF_RESULT_OK) {
        avifFree(dimgIdxToAlphaItemIdx);
        return result;
    }
    memcpy((*alphaItem)->type, "grid", 4); // Make it a grid and register alpha items as its tiles.
    (*alphaItem)->width = colorItem->width;
    (*alphaItem)->height = colorItem->height;
    for (uint32_t dimgIdx = 0; dimgIdx < tileCount; ++dimgIdx) {
        if (dimgIdxToAlphaItemIdx[dimgIdx] >= meta->items.count) {
            avifFree(dimgIdxToAlphaItemIdx);
            AVIF_ASSERT_OR_RETURN(AVIF_FALSE);
        }
        avifDecoderItem * alphaTileItem = meta->items.item[dimgIdxToAlphaItemIdx[dimgIdx]];
        alphaTileItem->dimgForID = (*alphaItem)->id;
        alphaTileItem->dimgIdx = dimgIdx;
    }
    avifFree(dimgIdxToAlphaItemIdx);
    *isAlphaItemInInput = AVIF_FALSE;
    alphaInfo->grid = colorInfo->grid;
    return AVIF_RESULT_OK;
}

// On success, this function returns AVIF_RESULT_OK and does the following:
// * If a nclx property was found in |properties|:
//   - Set |*colorPrimaries|, |*transferCharacteristics|, |*matrixCoefficients|
//     and |*yuvRange|.
//   - If cicpSet is not NULL, set |*cicpSet| to AVIF_TRUE.
// This function fails if more than one nclx property is found in |properties|.
// The output parameters may be populated even in case of failure and must be
// ignored.
static avifResult avifReadColorNclxProperty(const avifPropertyArray * properties,
                                            avifColorPrimaries * colorPrimaries,
                                            avifTransferCharacteristics * transferCharacteristics,
                                            avifMatrixCoefficients * matrixCoefficients,
                                            avifRange * yuvRange,
                                            avifBool * cicpSet)
{
    avifBool colrNCLXSeen = AVIF_FALSE;
    for (uint32_t propertyIndex = 0; propertyIndex < properties->count; ++propertyIndex) {
        avifProperty * prop = &properties->prop[propertyIndex];
        if (!memcmp(prop->type, "colr", 4) && prop->u.colr.hasNCLX) {
            if (colrNCLXSeen) {
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            colrNCLXSeen = AVIF_TRUE;
            if (cicpSet != NULL) {
                *cicpSet = AVIF_TRUE;
            }
            *colorPrimaries = prop->u.colr.colorPrimaries;
            *transferCharacteristics = prop->u.colr.transferCharacteristics;
            *matrixCoefficients = prop->u.colr.matrixCoefficients;
            *yuvRange = prop->u.colr.range;
        }
    }
    return AVIF_RESULT_OK;
}

// On success, this function returns AVIF_RESULT_OK and does the following:
// * If a colr property was found in |properties|:
//   - Read the icc data into |icc| from |io|.
//   - Sets the CICP values as documented in avifReadColorNclxProperty().
// This function fails if more than one icc or nclx property is found in
// |properties|. The output parameters may be populated even in case of failure
// and must be ignored (and the |icc| object may need to be freed).
static avifResult avifReadColorProperties(avifIO * io,
                                          const avifPropertyArray * properties,
                                          avifRWData * icc,
                                          avifColorPrimaries * colorPrimaries,
                                          avifTransferCharacteristics * transferCharacteristics,
                                          avifMatrixCoefficients * matrixCoefficients,
                                          avifRange * yuvRange,
                                          avifBool * cicpSet)
{
    // Find and adopt all colr boxes "at most one for a given value of colour type" (HEIF 6.5.5.1, from Amendment 3)
    // Accept one of each type, and bail out if more than one of a given type is provided.
    avifBool colrICCSeen = AVIF_FALSE;
    for (uint32_t propertyIndex = 0; propertyIndex < properties->count; ++propertyIndex) {
        avifProperty * prop = &properties->prop[propertyIndex];
        if (!memcmp(prop->type, "colr", 4) && prop->u.colr.hasICC) {
            if (colrICCSeen) {
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }
            avifROData iccRead;
            AVIF_CHECKRES(io->read(io, 0, prop->u.colr.iccOffset, prop->u.colr.iccSize, &iccRead));
            colrICCSeen = AVIF_TRUE;
            AVIF_CHECKRES(avifRWDataSet(icc, iccRead.data, iccRead.size));
        }
    }
    return avifReadColorNclxProperty(properties, colorPrimaries, transferCharacteristics, matrixCoefficients, yuvRange, cicpSet);
}

#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
// Finds a 'tmap' (tone mapped image item) box associated with the given 'colorItem'.
// If found, fills 'toneMappedImageItem' and  sets 'gainMapItemID' to the id of the gain map
// item associated with the box. Otherwise, sets 'toneMappedImageItem' to NULL.
// Returns AVIF_RESULT_OK if no errors were encountered (whether or not a tmap box was found).
// Assumes that there is a single tmap item, and not, e.g., a grid of tmap items.
// TODO(maryla): add support for files with multiple tmap items if it gets allowed by the spec.
static avifResult avifDecoderDataFindToneMappedImageItem(const avifDecoderData * data,
                                                         const avifDecoderItem * colorItem,
                                                         avifDecoderItem ** toneMappedImageItem,
                                                         uint32_t * gainMapItemID)
{
    for (uint32_t itemIndex = 0; itemIndex < data->meta->items.count; ++itemIndex) {
        avifDecoderItem * item = data->meta->items.item[itemIndex];
        if (!item->size || item->hasUnsupportedEssentialProperty || item->thumbnailForID != 0) {
            continue;
        }
        if (!memcmp(item->type, "tmap", 4)) {
            // The tmap box should be associated (via 'iref'->'dimg') to two items:
            // the first one is the base image, the second one is the gain map.
            uint32_t dimgItemIDs[2] = { 0, 0 };
            uint32_t numDimgItemIDs = 0;
            for (uint32_t otherItemIndex = 0; otherItemIndex < data->meta->items.count; ++otherItemIndex) {
                avifDecoderItem * otherItem = data->meta->items.item[otherItemIndex];
                if (otherItem->dimgForID != item->id) {
                    continue;
                }
                if (otherItem->dimgIdx < 2) {
                    AVIF_ASSERT_OR_RETURN(dimgItemIDs[otherItem->dimgIdx] == 0);
                    dimgItemIDs[otherItem->dimgIdx] = otherItem->id;
                }
                numDimgItemIDs++;
            }
            // Even with numDimgItemIDs == 2, one of the ids could be 0 if there are duplicate entries in the 'dimg' box.
            if (numDimgItemIDs != 2 || dimgItemIDs[0] == 0 || dimgItemIDs[1] == 0) {
                avifDiagnosticsPrintf(data->diag, "box[dimg] for 'tmap' item %d must have exactly 2 entries with distinct ids", item->id);
                return AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE;
            }
            if (dimgItemIDs[0] != colorItem->id) {
                continue;
            }

            *toneMappedImageItem = item;
            *gainMapItemID = dimgItemIDs[1];
            return AVIF_RESULT_OK;
        }
    }
    *toneMappedImageItem = NULL;
    *gainMapItemID = 0;
    return AVIF_RESULT_OK;
}

// Finds a 'tmap' (tone mapped image item) box associated with the given 'colorItem',
// then finds the associated gain map image.
// If found, fills 'toneMappedImageItem', 'gainMapItem' and 'gainMapCodecType', and
// allocates and fills metadata in decoder->image->gainMap.
// Otherwise, sets 'toneMappedImageItem' and 'gainMapItem' to NULL.
// Returns AVIF_RESULT_OK if no errors were encountered (whether or not a gain map was found).
// Assumes that there is a single tmap item, and not, e.g., a grid of tmap items.
static avifResult avifDecoderFindGainMapItem(const avifDecoder * decoder,
                                             const avifDecoderItem * colorItem,
                                             avifDecoderItem ** toneMappedImageItem,
                                             avifDecoderItem ** gainMapItem,
                                             avifCodecType * gainMapCodecType)
{
    *toneMappedImageItem = NULL;
    *gainMapItem = NULL;
    *gainMapCodecType = AVIF_CODEC_TYPE_UNKNOWN;

    avifDecoderData * data = decoder->data;

    uint32_t gainMapItemID;
    avifDecoderItem * toneMappedImageItemTmp;
    AVIF_CHECKRES(avifDecoderDataFindToneMappedImageItem(data, colorItem, &toneMappedImageItemTmp, &gainMapItemID));
    if (!toneMappedImageItemTmp) {
        return AVIF_RESULT_OK;
    }

    AVIF_ASSERT_OR_RETURN(gainMapItemID != 0);
    avifDecoderItem * gainMapItemTmp;
    AVIF_CHECKRES(avifMetaFindOrCreateItem(data->meta, gainMapItemID, &gainMapItemTmp));
    if (avifDecoderItemShouldBeSkipped(gainMapItemTmp)) {
        avifDiagnosticsPrintf(data->diag, "Box[tmap] gain map item %d is not a supported image type", gainMapItemID);
        return AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE;
    }

    AVIF_CHECKRES(avifDecoderItemReadAndParse(decoder,
                                              gainMapItemTmp,
                                              /*isItemInInput=*/AVIF_TRUE,
                                              &data->tileInfos[AVIF_ITEM_GAIN_MAP].grid,
                                              gainMapCodecType));

    decoder->image->gainMap = avifGainMapCreate();
    AVIF_CHECKERR(decoder->image->gainMap, AVIF_RESULT_OUT_OF_MEMORY);

    avifGainMap * const gainMap = decoder->image->gainMap;
    AVIF_CHECKRES(avifReadColorProperties(decoder->io,
                                          &toneMappedImageItemTmp->properties,
                                          &gainMap->altICC,
                                          &gainMap->altColorPrimaries,
                                          &gainMap->altTransferCharacteristics,
                                          &gainMap->altMatrixCoefficients,
                                          &gainMap->altYUVRange,
                                          /*cicpSet=*/NULL));

    const avifProperty * clliProp = avifPropertyArrayFind(&toneMappedImageItemTmp->properties, "clli");
    if (clliProp) {
        gainMap->altCLLI = clliProp->u.clli;
    }

    const avifProperty * pixiProp = avifPropertyArrayFind(&toneMappedImageItemTmp->properties, "pixi");
    if (pixiProp) {
        gainMap->altPlaneCount = pixiProp->u.pixi.planeCount;
        gainMap->altDepth = pixiProp->u.pixi.planeDepths[0];
    }

    if (avifPropertyArrayFind(&toneMappedImageItemTmp->properties, "pasp") ||
        avifPropertyArrayFind(&toneMappedImageItemTmp->properties, "clap") ||
        avifPropertyArrayFind(&toneMappedImageItemTmp->properties, "irot") ||
        avifPropertyArrayFind(&toneMappedImageItemTmp->properties, "imir")) {
        // libavif requires the bitstream contain the same pasp, clap, irot, imir
        // properties for both the base and gain map image items used as input to
        // the tone-mapped derived image item. libavif also requires the tone-mapped
        // derived image item itself not be associated with these properties. This is
        // enforced at encoding. Other patterns are rejected at decoding.
        avifDiagnosticsPrintf(data->diag,
                              "Box[tmap] 'pasp', 'clap', 'irot' and 'imir' properties must be associated with base and gain map items instead of 'tmap'");
        return AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE;
    }

    if (decoder->enableDecodingGainMap) {
        gainMap->image = avifImageCreateEmpty();
        AVIF_CHECKERR(gainMap->image, AVIF_RESULT_OUT_OF_MEMORY);

        // Look for a colr nclx box. Other colr box types (e.g. ICC) are not supported.
        AVIF_CHECKRES(avifReadColorNclxProperty(&gainMapItemTmp->properties,
                                                &gainMap->image->colorPrimaries,
                                                &gainMap->image->transferCharacteristics,
                                                &gainMap->image->matrixCoefficients,
                                                &gainMap->image->yuvRange,
                                                /*cicpSet=*/NULL));
    }

    // Only set the output parameters after everything has been validated.
    *toneMappedImageItem = toneMappedImageItemTmp;
    *gainMapItem = gainMapItemTmp;
    return AVIF_RESULT_OK;
}

static avifResult aviDecoderCheckGainMapProperties(avifDecoder * decoder, const avifPropertyArray * gainMapProperties)
{
    const avifImage * image = decoder->image;
    // libavif requires the bitstream contain the same 'pasp', 'clap', 'irot', 'imir'
    // properties for both the base and gain map image items used as input to
    // the tone-mapped derived image item. libavif also requires the tone-mapped
    // derived image item itself not be associated with these properties. This is
    // enforced at encoding. Other patterns are rejected at decoding.
    const avifProperty * paspProp = avifPropertyArrayFind(gainMapProperties, "pasp");
    if (!paspProp != !(image->transformFlags & AVIF_TRANSFORM_PASP) ||
        (paspProp && (paspProp->u.pasp.hSpacing != image->pasp.hSpacing || paspProp->u.pasp.vSpacing != image->pasp.vSpacing))) {
        avifDiagnosticsPrintf(&decoder->diag,
                              "Pixel aspect ratio property mismatch between input items of tone-mapping derived image item");
        return AVIF_RESULT_DECODE_GAIN_MAP_FAILED;
    }
    const avifProperty * clapProp = avifPropertyArrayFind(gainMapProperties, "clap");
    if (!clapProp != !(image->transformFlags & AVIF_TRANSFORM_CLAP) ||
        (clapProp && (clapProp->u.clap.widthN != image->clap.widthN || clapProp->u.clap.widthD != image->clap.widthD ||
                      clapProp->u.clap.heightN != image->clap.heightN || clapProp->u.clap.heightD != image->clap.heightD ||
                      clapProp->u.clap.horizOffN != image->clap.horizOffN || clapProp->u.clap.horizOffD != image->clap.horizOffD ||
                      clapProp->u.clap.vertOffN != image->clap.vertOffN || clapProp->u.clap.vertOffD != image->clap.vertOffD))) {
        avifDiagnosticsPrintf(&decoder->diag, "Clean aperture property mismatch between input items of tone-mapping derived image item");
        return AVIF_RESULT_DECODE_GAIN_MAP_FAILED;
    }
    const avifProperty * irotProp = avifPropertyArrayFind(gainMapProperties, "irot");
    if (!irotProp != !(image->transformFlags & AVIF_TRANSFORM_IROT) || (irotProp && irotProp->u.irot.angle != image->irot.angle)) {
        avifDiagnosticsPrintf(&decoder->diag, "Rotation property mismatch between input items of tone-mapping derived image item");
        return AVIF_RESULT_DECODE_GAIN_MAP_FAILED;
    }
    const avifProperty * imirProp = avifPropertyArrayFind(gainMapProperties, "imir");
    if (!imirProp != !(image->transformFlags & AVIF_TRANSFORM_IMIR) || (imirProp && imirProp->u.imir.axis != image->imir.axis)) {
        avifDiagnosticsPrintf(&decoder->diag, "Mirroring property mismatch between input items of tone-mapping derived image item");
        return AVIF_RESULT_DECODE_GAIN_MAP_FAILED;
    }
    return AVIF_RESULT_OK;
}
#endif // AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP

#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
// Finds a 'sato' Sample Transform derived image item box.
// If found, fills 'sampleTransformItem'. Otherwise, sets 'sampleTransformItem' to NULL.
// Returns AVIF_RESULT_OK on success (whether or not a 'sato' box was found).
// Assumes that there is a single 'sato' item.
// Assumes that the 'sato' item is not the primary item and that both the primary item and 'sato'
// are in the same 'altr' group.
// TODO(yguyon): Check instead of assuming.
static avifResult avifDecoderDataFindSampleTransformImageItem(avifDecoderData * data, avifDecoderItem ** sampleTransformItem)
{
    for (uint32_t itemIndex = 0; itemIndex < data->meta->items.count; ++itemIndex) {
        avifDecoderItem * item = data->meta->items.item[itemIndex];
        if (!item->size || item->hasUnsupportedEssentialProperty || item->thumbnailForID != 0) {
            continue;
        }
        if (!memcmp(item->type, "sato", 4)) {
            *sampleTransformItem = item;
            return AVIF_RESULT_OK;
        }
    }
    *sampleTransformItem = NULL;
    return AVIF_RESULT_OK;
}
#endif // AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM

static avifResult avifDecoderGenerateImageTiles(avifDecoder * decoder, avifTileInfo * info, avifDecoderItem * item, avifItemCategory itemCategory)
{
    const uint32_t previousTileCount = decoder->data->tiles.count;
    if ((info->grid.rows > 0) && (info->grid.columns > 0)) {
        // The number of tiles was verified in avifDecoderItemReadAndParse().
        const uint32_t numTiles = info->grid.rows * info->grid.columns;
        uint32_t * dimgIdxToItemIdx = (uint32_t *)avifAlloc(numTiles * sizeof(uint32_t));
        AVIF_CHECKERR(dimgIdxToItemIdx != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        avifResult result = avifFillDimgIdxToItemIdxArray(dimgIdxToItemIdx, numTiles, item);
        if (result == AVIF_RESULT_OK) {
            result = avifDecoderGenerateImageGridTiles(decoder, item, itemCategory, dimgIdxToItemIdx, numTiles);
        }
        avifFree(dimgIdxToItemIdx);
        AVIF_CHECKRES(result);
    } else {
        AVIF_CHECKERR(item->size != 0, AVIF_RESULT_MISSING_IMAGE_ITEM);

        const avifCodecType codecType = avifGetCodecType(item->type);
        AVIF_ASSERT_OR_RETURN(codecType != AVIF_CODEC_TYPE_UNKNOWN);
        avifTile * tile =
            avifDecoderDataCreateTile(decoder->data, codecType, item->width, item->height, avifDecoderItemOperatingPoint(item));
        AVIF_CHECKERR(tile, AVIF_RESULT_OUT_OF_MEMORY);
        AVIF_CHECKRES(avifCodecDecodeInputFillFromDecoderItem(tile->input,
                                                              item,
                                                              decoder->allowProgressive,
                                                              decoder->imageCountLimit,
                                                              decoder->io->sizeHint,
                                                              &decoder->diag));
        tile->input->itemCategory = itemCategory;
    }
    info->tileCount = decoder->data->tiles.count - previousTileCount;
    return AVIF_RESULT_OK;
}

// Populates depth, yuvFormat and yuvChromaSamplePosition fields on 'image' based on data from the codec config property (e.g. "av1C").
static avifResult avifReadCodecConfigProperty(avifImage * image, const avifPropertyArray * properties, avifCodecType codecType)
{
    const avifProperty * configProp = avifPropertyArrayFind(properties, avifGetConfigurationPropertyName(codecType));
    if (configProp) {
        image->depth = avifCodecConfigurationBoxGetDepth(&configProp->u.av1C);
        if (configProp->u.av1C.monochrome) {
            image->yuvFormat = AVIF_PIXEL_FORMAT_YUV400;
        } else {
            if (configProp->u.av1C.chromaSubsamplingX && configProp->u.av1C.chromaSubsamplingY) {
                image->yuvFormat = AVIF_PIXEL_FORMAT_YUV420;
            } else if (configProp->u.av1C.chromaSubsamplingX) {
                image->yuvFormat = AVIF_PIXEL_FORMAT_YUV422;
            } else {
                image->yuvFormat = AVIF_PIXEL_FORMAT_YUV444;
            }
        }
        image->yuvChromaSamplePosition = (avifChromaSamplePosition)configProp->u.av1C.chromaSamplePosition;
    } else {
        // A configuration property box is mandatory in all valid AVIF configurations. Bail out.
        return AVIF_RESULT_BMFF_PARSE_FAILED;
    }
    return AVIF_RESULT_OK;
}

avifResult avifDecoderReset(avifDecoder * decoder)
{
    avifDiagnosticsClearError(&decoder->diag);

    avifDecoderData * data = decoder->data;
    if (!data) {
        // Nothing to reset.
        return AVIF_RESULT_OK;
    }

    for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
        memset(&data->tileInfos[c].grid, 0, sizeof(data->tileInfos[c].grid));
    }
    avifDecoderDataClearTiles(data);

    // Prepare / cleanup decoded image state
    if (decoder->image) {
        avifImageDestroy(decoder->image);
    }
    decoder->image = avifImageCreateEmpty();
    AVIF_CHECKERR(decoder->image, AVIF_RESULT_OUT_OF_MEMORY);
    decoder->progressiveState = AVIF_PROGRESSIVE_STATE_UNAVAILABLE;
    data->cicpSet = AVIF_FALSE;

    memset(&decoder->ioStats, 0, sizeof(decoder->ioStats));

    // -----------------------------------------------------------------------
    // Build decode input

    data->sourceSampleTable = NULL; // Reset
    if (decoder->requestedSource == AVIF_DECODER_SOURCE_AUTO) {
        // Honor the major brand (avif or avis) if present, otherwise prefer avis (tracks) if possible.
        if (!memcmp(data->majorBrand, "avis", 4)) {
            data->source = AVIF_DECODER_SOURCE_TRACKS;
        } else if (!memcmp(data->majorBrand, "avif", 4)) {
            data->source = AVIF_DECODER_SOURCE_PRIMARY_ITEM;
        } else if (data->tracks.count > 0) {
            data->source = AVIF_DECODER_SOURCE_TRACKS;
        } else {
            data->source = AVIF_DECODER_SOURCE_PRIMARY_ITEM;
        }
    } else {
        data->source = decoder->requestedSource;
    }

    avifCodecType colorCodecType = AVIF_CODEC_TYPE_UNKNOWN;
    const avifPropertyArray * colorProperties = NULL;
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
    const avifPropertyArray * gainMapProperties = NULL;
#endif
    if (data->source == AVIF_DECODER_SOURCE_TRACKS) {
        avifTrack * colorTrack = NULL;
        avifTrack * alphaTrack = NULL;

        // Find primary track - this probably needs some better detection
        uint32_t colorTrackIndex = 0;
        for (; colorTrackIndex < data->tracks.count; ++colorTrackIndex) {
            avifTrack * track = &data->tracks.track[colorTrackIndex];
            if (!track->sampleTable) {
                continue;
            }
            if (!track->id) { // trak box might be missing a tkhd box inside, skip it
                continue;
            }
            if (!track->sampleTable->chunks.count) {
                continue;
            }
            colorCodecType = avifSampleTableGetCodecType(track->sampleTable);
            if (colorCodecType == AVIF_CODEC_TYPE_UNKNOWN) {
                continue;
            }
            if (track->auxForID != 0) {
                continue;
            }

            // Found one!
            break;
        }
        if (colorTrackIndex == data->tracks.count) {
            avifDiagnosticsPrintf(&decoder->diag, "Failed to find AV1 color track");
            return AVIF_RESULT_NO_CONTENT;
        }
        colorTrack = &data->tracks.track[colorTrackIndex];

        colorProperties = avifSampleTableGetProperties(colorTrack->sampleTable, colorCodecType);
        if (!colorProperties) {
            avifDiagnosticsPrintf(&decoder->diag, "Failed to find AV1 color track's color properties");
            return AVIF_RESULT_BMFF_PARSE_FAILED;
        }

        // Find Exif and/or XMP metadata, if any
        if (colorTrack->meta) {
            // See the comment above avifDecoderFindMetadata() for the explanation of using 0 here
            avifResult findResult = avifDecoderFindMetadata(decoder, colorTrack->meta, decoder->image, 0);
            if (findResult != AVIF_RESULT_OK) {
                return findResult;
            }
        }

        uint32_t alphaTrackIndex = 0;
        avifCodecType alphaCodecType = AVIF_CODEC_TYPE_UNKNOWN;
        for (; alphaTrackIndex < data->tracks.count; ++alphaTrackIndex) {
            avifTrack * track = &data->tracks.track[alphaTrackIndex];
            if (!track->sampleTable) {
                continue;
            }
            if (!track->id) {
                continue;
            }
            if (!track->sampleTable->chunks.count) {
                continue;
            }
            alphaCodecType = avifSampleTableGetCodecType(track->sampleTable);
            if (alphaCodecType == AVIF_CODEC_TYPE_UNKNOWN) {
                continue;
            }
            if (track->auxForID == colorTrack->id) {
                // Found it!
                break;
            }
        }
        if (alphaTrackIndex != data->tracks.count) {
            alphaTrack = &data->tracks.track[alphaTrackIndex];
        }

        const uint8_t operatingPoint = 0; // No way to set operating point via tracks
        avifTile * colorTile = avifDecoderDataCreateTile(data, colorCodecType, colorTrack->width, colorTrack->height, operatingPoint);
        AVIF_CHECKERR(colorTile != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        AVIF_CHECKRES(avifCodecDecodeInputFillFromSampleTable(colorTile->input,
                                                              colorTrack->sampleTable,
                                                              decoder->imageCountLimit,
                                                              decoder->io->sizeHint,
                                                              data->diag));
        data->tileInfos[AVIF_ITEM_COLOR].tileCount = 1;

        if (alphaTrack) {
            avifTile * alphaTile = avifDecoderDataCreateTile(data, alphaCodecType, alphaTrack->width, alphaTrack->height, operatingPoint);
            AVIF_CHECKERR(alphaTile != NULL, AVIF_RESULT_OUT_OF_MEMORY);
            AVIF_CHECKRES(avifCodecDecodeInputFillFromSampleTable(alphaTile->input,
                                                                  alphaTrack->sampleTable,
                                                                  decoder->imageCountLimit,
                                                                  decoder->io->sizeHint,
                                                                  data->diag));
            alphaTile->input->itemCategory = AVIF_ITEM_ALPHA;
            data->tileInfos[AVIF_ITEM_ALPHA].tileCount = 1;
        }

        // Stash off sample table for future timing information
        data->sourceSampleTable = colorTrack->sampleTable;

        // Image sequence timing
        decoder->imageIndex = -1;
        decoder->imageCount = (int)colorTile->input->samples.count;
        decoder->timescale = colorTrack->mediaTimescale;
        decoder->durationInTimescales = colorTrack->mediaDuration;
        if (colorTrack->mediaTimescale) {
            decoder->duration = (double)decoder->durationInTimescales / (double)colorTrack->mediaTimescale;
        } else {
            decoder->duration = 0;
        }
        // If the alphaTrack->repetitionCount and colorTrack->repetitionCount are different, we will simply use the
        // colorTrack's repetitionCount.
        decoder->repetitionCount = colorTrack->repetitionCount;

        memset(&decoder->imageTiming, 0, sizeof(decoder->imageTiming)); // to be set in avifDecoderNextImage()

        decoder->image->width = colorTrack->width;
        decoder->image->height = colorTrack->height;
        decoder->alphaPresent = (alphaTrack != NULL);
        decoder->image->alphaPremultiplied = decoder->alphaPresent && (colorTrack->premByID == alphaTrack->id);
    } else {
        // Create from items

        if (data->meta->primaryItemID == 0) {
            // A primary item is required
            avifDiagnosticsPrintf(&decoder->diag, "Primary item not specified");
            return AVIF_RESULT_MISSING_IMAGE_ITEM;
        }

        // Main item of each group category (top-level item such as grid or single tile), if any.
        avifDecoderItem * mainItems[AVIF_ITEM_CATEGORY_COUNT];
        avifCodecType codecType[AVIF_ITEM_CATEGORY_COUNT];
        for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
            mainItems[c] = NULL;
            codecType[c] = AVIF_CODEC_TYPE_UNKNOWN;
        }

        // Mandatory primary color item
        mainItems[AVIF_ITEM_COLOR] = avifMetaFindColorItem(data->meta);
        if (!mainItems[AVIF_ITEM_COLOR]) {
            avifDiagnosticsPrintf(&decoder->diag, "Primary item not found");
            return AVIF_RESULT_MISSING_IMAGE_ITEM;
        }
        AVIF_CHECKRES(avifDecoderItemReadAndParse(decoder,
                                                  mainItems[AVIF_ITEM_COLOR],
                                                  /*isItemInInput=*/AVIF_TRUE,
                                                  &data->tileInfos[AVIF_ITEM_COLOR].grid,
                                                  &codecType[AVIF_ITEM_COLOR]));
        colorProperties = &mainItems[AVIF_ITEM_COLOR]->properties;
        colorCodecType = codecType[AVIF_ITEM_COLOR];

        // Optional alpha auxiliary item
        avifBool isAlphaItemInInput;
        AVIF_CHECKRES(avifMetaFindAlphaItem(data->meta,
                                            mainItems[AVIF_ITEM_COLOR],
                                            &data->tileInfos[AVIF_ITEM_COLOR],
                                            &mainItems[AVIF_ITEM_ALPHA],
                                            &data->tileInfos[AVIF_ITEM_ALPHA],
                                            &isAlphaItemInInput));
        if (mainItems[AVIF_ITEM_ALPHA]) {
            AVIF_CHECKRES(avifDecoderItemReadAndParse(decoder,
                                                      mainItems[AVIF_ITEM_ALPHA],
                                                      isAlphaItemInInput,
                                                      &data->tileInfos[AVIF_ITEM_ALPHA].grid,
                                                      &codecType[AVIF_ITEM_ALPHA]));
        }

#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
        // Section 10.2.6 of 23008-12:2024/AMD 1:2024(E):
        //   'tmap' brand
        //   This brand enables file players to identify and decode HEIF files containing tone-map derived image
        //   items. When present, this brand shall be among the brands included in the compatible_brands
        //   array of the FileTypeBox.
        //
        // If the file contains a 'tmap' item but doesn't have the 'tmap' brand, it is technically invalid.
        // However, we don't report any error because in order to do detect this case consistently, we would
        // need to remove the early exit in avifParse() to check if a 'tmap' item might be present
        // further down the file. Instead, we simply ignore tmap items in files that lack the 'tmap' brand.
        if (decoder->enableParsingGainMapMetadata && avifBrandArrayHasBrand(&data->compatibleBrands, "tmap")) {
            avifDecoderItem * toneMappedImageItem;
            avifDecoderItem * gainMapItem;
            avifCodecType gainMapCodecType;
            AVIF_CHECKRES(
                avifDecoderFindGainMapItem(decoder, mainItems[AVIF_ITEM_COLOR], &toneMappedImageItem, &gainMapItem, &gainMapCodecType));
            if (toneMappedImageItem != NULL) {
                // Read the gain map's metadata.
                avifROData tmapData;
                AVIF_CHECKRES(avifDecoderItemRead(toneMappedImageItem, decoder->io, &tmapData, 0, 0, data->diag));
                AVIF_ASSERT_OR_RETURN(decoder->image->gainMap != NULL);
                const avifResult tmapParsingRes =
                    avifParseToneMappedImageBox(decoder->image->gainMap, tmapData.data, tmapData.size, data->diag);
                if (tmapParsingRes == AVIF_RESULT_NOT_IMPLEMENTED) {
                    // Unsupported gain map version. Simply ignore the gain map.
                    avifGainMapDestroy(decoder->image->gainMap);
                    decoder->image->gainMap = NULL;
                } else {
                    AVIF_CHECKRES(tmapParsingRes);
                    decoder->gainMapPresent = AVIF_TRUE;
                    if (decoder->enableDecodingGainMap) {
                        mainItems[AVIF_ITEM_GAIN_MAP] = gainMapItem;
                        codecType[AVIF_ITEM_GAIN_MAP] = gainMapCodecType;
                    }
                }
            }
        }
#endif // AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP

#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
        // AVIF_ITEM_SAMPLE_TRANSFORM (not used through mainItems because not a coded item (well grids are not coded items either but it's different)).
        avifDecoderItem * sampleTransformItem = NULL;
        AVIF_CHECKRES(avifDecoderDataFindSampleTransformImageItem(data, &sampleTransformItem));
        if (sampleTransformItem != NULL) {
            AVIF_ASSERT_OR_RETURN(data->sampleTransformNumInputImageItems == 0);
            uint32_t numExtraInputImageItems = 0;
            for (uint32_t i = 0; i < data->meta->items.count; ++i) {
                avifDecoderItem * inputImageItem = data->meta->items.item[i];
                if (inputImageItem->dimgForID != sampleTransformItem->id) {
                    continue;
                }
                if (avifDecoderItemShouldBeSkipped(inputImageItem)) {
                    avifDiagnosticsPrintf(data->diag, "Box[sato] input item %u is not a supported image type", inputImageItem->id);
                    return AVIF_RESULT_DECODE_SAMPLE_TRANSFORM_FAILED;
                }
                // Input image item order is important because input image items are indexed according to this order.
                AVIF_CHECKERR(inputImageItem->dimgIdx == data->sampleTransformNumInputImageItems, AVIF_RESULT_NOT_IMPLEMENTED);

                AVIF_CHECKERR(data->sampleTransformNumInputImageItems < AVIF_SAMPLE_TRANSFORM_MAX_NUM_INPUT_IMAGE_ITEMS,
                              AVIF_RESULT_NOT_IMPLEMENTED);
                avifItemCategory * category = &data->sampleTransformInputImageItems[data->sampleTransformNumInputImageItems];
                avifBool foundItem = AVIF_FALSE;
                avifItemCategory alphaCategory = AVIF_ITEM_CATEGORY_COUNT;
                for (int c = AVIF_ITEM_COLOR; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
                    if (mainItems[c] && inputImageItem->id == mainItems[c]->id) {
                        *category = c;
                        AVIF_CHECKERR(*category == AVIF_ITEM_COLOR, AVIF_RESULT_NOT_IMPLEMENTED);
                        alphaCategory = AVIF_ITEM_ALPHA;
                        foundItem = AVIF_TRUE;
                        break;
                    }
                }
                if (!foundItem) {
                    AVIF_CHECKERR(numExtraInputImageItems < AVIF_SAMPLE_TRANSFORM_MAX_NUM_EXTRA_INPUT_IMAGE_ITEMS,
                                  AVIF_RESULT_NOT_IMPLEMENTED);
                    *category = (avifItemCategory)(AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_COLOR + numExtraInputImageItems);
                    alphaCategory = (avifItemCategory)(AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_ALPHA + numExtraInputImageItems);
                    mainItems[*category] = inputImageItem;
                    ++numExtraInputImageItems;

                    AVIF_CHECKRES(avifDecoderItemReadAndParse(decoder,
                                                              inputImageItem,
                                                              /*isItemInInput=*/AVIF_TRUE,
                                                              &data->tileInfos[*category].grid,
                                                              &codecType[*category]));

                    // Optional alpha auxiliary item
                    avifBool isAlphaInputImageItemInInput = AVIF_FALSE;
                    AVIF_CHECKRES(avifMetaFindAlphaItem(data->meta,
                                                        mainItems[*category],
                                                        &data->tileInfos[*category],
                                                        &mainItems[alphaCategory],
                                                        &data->tileInfos[alphaCategory],
                                                        &isAlphaInputImageItemInInput));

                    AVIF_CHECKERR(!mainItems[alphaCategory] == !mainItems[AVIF_ITEM_ALPHA], AVIF_RESULT_NOT_IMPLEMENTED);
                    if (mainItems[alphaCategory] != NULL) {
                        AVIF_CHECKERR(isAlphaInputImageItemInInput == isAlphaItemInInput, AVIF_RESULT_NOT_IMPLEMENTED);
                        AVIF_CHECKERR((mainItems[*category]->premByID == mainItems[alphaCategory]->id) ==
                                          (mainItems[AVIF_ITEM_COLOR]->premByID == mainItems[AVIF_ITEM_ALPHA]->id),
                                      AVIF_RESULT_NOT_IMPLEMENTED);
                        AVIF_CHECKRES(avifDecoderItemReadAndParse(decoder,
                                                                  mainItems[alphaCategory],
                                                                  isAlphaInputImageItemInInput,
                                                                  &data->tileInfos[alphaCategory].grid,
                                                                  &codecType[alphaCategory]));
                    }
                }

                ++data->sampleTransformNumInputImageItems;
            }

            AVIF_ASSERT_OR_RETURN(data->meta->sampleTransformExpression.tokens == NULL);
            avifROData satoData;
            AVIF_CHECKRES(avifDecoderItemRead(sampleTransformItem, decoder->io, &satoData, 0, 0, data->diag));
            AVIF_CHECKRES(avifParseSampleTransformImageBox(satoData.data,
                                                           satoData.size,
                                                           data->sampleTransformNumInputImageItems,
                                                           &data->meta->sampleTransformExpression,
                                                           data->diag));
            AVIF_CHECKRES(avifDecoderSampleTransformItemValidateProperties(sampleTransformItem, data->diag));
            const avifProperty * pixiProp = avifPropertyArrayFind(&sampleTransformItem->properties, "pixi");
            AVIF_ASSERT_OR_RETURN(pixiProp != NULL);
            data->meta->sampleTransformDepth = pixiProp->u.pixi.planeDepths[0];
        }
#endif // AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM

        // Find Exif and/or XMP metadata, if any
        AVIF_CHECKRES(avifDecoderFindMetadata(decoder, data->meta, decoder->image, mainItems[AVIF_ITEM_COLOR]->id));

        // Set all counts and timing to safe-but-uninteresting values
        decoder->imageIndex = -1;
        decoder->imageCount = 1;
        decoder->imageTiming.timescale = 1;
        decoder->imageTiming.pts = 0;
        decoder->imageTiming.ptsInTimescales = 0;
        decoder->imageTiming.duration = 1;
        decoder->imageTiming.durationInTimescales = 1;
        decoder->timescale = 1;
        decoder->duration = 1;
        decoder->durationInTimescales = 1;

        for (int c = AVIF_ITEM_COLOR; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
            if (!mainItems[c]) {
                continue;
            }

#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
            if (decoder->ignoreColorAndAlpha && (c == AVIF_ITEM_COLOR || c == AVIF_ITEM_ALPHA)) {
                continue;
            }
#endif
            if (avifIsAlpha((avifItemCategory)c) && !mainItems[c]->width && !mainItems[c]->height) {
                // NON-STANDARD: Alpha subimage does not have an ispe property; adopt width/height from color item
                AVIF_ASSERT_OR_RETURN(!(decoder->strictFlags & AVIF_STRICT_ALPHA_ISPE_REQUIRED));
                mainItems[c]->width = mainItems[AVIF_ITEM_COLOR]->width;
                mainItems[c]->height = mainItems[AVIF_ITEM_COLOR]->height;
            }

            AVIF_CHECKRES(avifDecoderGenerateImageTiles(decoder, &data->tileInfos[c], mainItems[c], (avifItemCategory)c));

            avifStrictFlags strictFlags = decoder->strictFlags;
            if (avifIsAlpha((avifItemCategory)c) && !isAlphaItemInInput) {
                // In this case, the made up grid item will not have an associated pixi property. So validate everything else
                // but the pixi property.
                strictFlags &= ~(avifStrictFlags)AVIF_STRICT_PIXI_REQUIRED;
            }
            AVIF_CHECKRES(
                avifDecoderItemValidateProperties(mainItems[c], avifGetConfigurationPropertyName(codecType[c]), &decoder->diag, strictFlags));
        }

        if (mainItems[AVIF_ITEM_COLOR]->progressive) {
            decoder->progressiveState = AVIF_PROGRESSIVE_STATE_AVAILABLE;
            // data->tileInfos[AVIF_ITEM_COLOR].firstTileIndex is not yet defined but will be set to 0 a few lines below.
            const avifTile * colorTile = &data->tiles.tile[0];
            if (colorTile->input->samples.count > 1) {
                decoder->progressiveState = AVIF_PROGRESSIVE_STATE_ACTIVE;
                decoder->imageCount = (int)colorTile->input->samples.count;
            }
        }

        decoder->image->width = mainItems[AVIF_ITEM_COLOR]->width;
        decoder->image->height = mainItems[AVIF_ITEM_COLOR]->height;
        decoder->alphaPresent = (mainItems[AVIF_ITEM_ALPHA] != NULL);
        decoder->image->alphaPremultiplied = decoder->alphaPresent &&
                                             (mainItems[AVIF_ITEM_COLOR]->premByID == mainItems[AVIF_ITEM_ALPHA]->id);

#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
        if (mainItems[AVIF_ITEM_GAIN_MAP]) {
            AVIF_ASSERT_OR_RETURN(decoder->image->gainMap && decoder->image->gainMap->image);
            decoder->image->gainMap->image->width = mainItems[AVIF_ITEM_GAIN_MAP]->width;
            decoder->image->gainMap->image->height = mainItems[AVIF_ITEM_GAIN_MAP]->height;
            decoder->gainMapPresent = AVIF_TRUE;
            // Must be called after avifDecoderGenerateImageTiles() which among other things copies the
            // codec config property from the first tile of a grid to the grid item (when grids are used).
            AVIF_CHECKRES(avifReadCodecConfigProperty(decoder->image->gainMap->image,
                                                      &mainItems[AVIF_ITEM_GAIN_MAP]->properties,
                                                      codecType[AVIF_ITEM_GAIN_MAP]));
            gainMapProperties = &mainItems[AVIF_ITEM_GAIN_MAP]->properties;
        }
#endif
    }

    uint32_t firstTileIndex = 0;
    for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
        data->tileInfos[c].firstTileIndex = firstTileIndex;
        firstTileIndex += data->tileInfos[c].tileCount;
    }

    // Sanity check tiles
    for (uint32_t tileIndex = 0; tileIndex < data->tiles.count; ++tileIndex) {
        avifTile * tile = &data->tiles.tile[tileIndex];
        for (uint32_t sampleIndex = 0; sampleIndex < tile->input->samples.count; ++sampleIndex) {
            avifDecodeSample * sample = &tile->input->samples.sample[sampleIndex];
            if (!sample->size) {
                // Every sample must have some data
                return AVIF_RESULT_BMFF_PARSE_FAILED;
            }

            if (tile->input->itemCategory == AVIF_ITEM_COLOR) {
                decoder->ioStats.colorOBUSize += sample->size;
            } else if (tile->input->itemCategory == AVIF_ITEM_ALPHA) {
                decoder->ioStats.alphaOBUSize += sample->size;
            }
        }
    }

    AVIF_CHECKRES(avifReadColorProperties(decoder->io,
                                          colorProperties,
                                          &decoder->image->icc,
                                          &decoder->image->colorPrimaries,
                                          &decoder->image->transferCharacteristics,
                                          &decoder->image->matrixCoefficients,
                                          &decoder->image->yuvRange,
                                          &data->cicpSet));

    const avifProperty * clliProp = avifPropertyArrayFind(colorProperties, "clli");
    if (clliProp) {
        decoder->image->clli = clliProp->u.clli;
    }

    // Transformations
    const avifProperty * paspProp = avifPropertyArrayFind(colorProperties, "pasp");
    if (paspProp) {
        decoder->image->transformFlags |= AVIF_TRANSFORM_PASP;
        decoder->image->pasp = paspProp->u.pasp;
    }
    const avifProperty * clapProp = avifPropertyArrayFind(colorProperties, "clap");
    if (clapProp) {
        decoder->image->transformFlags |= AVIF_TRANSFORM_CLAP;
        decoder->image->clap = clapProp->u.clap;
    }
    const avifProperty * irotProp = avifPropertyArrayFind(colorProperties, "irot");
    if (irotProp) {
        decoder->image->transformFlags |= AVIF_TRANSFORM_IROT;
        decoder->image->irot = irotProp->u.irot;
    }
    const avifProperty * imirProp = avifPropertyArrayFind(colorProperties, "imir");
    if (imirProp) {
        decoder->image->transformFlags |= AVIF_TRANSFORM_IMIR;
        decoder->image->imir = imirProp->u.imir;
    }
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
    if (gainMapProperties != NULL) {
        AVIF_CHECKRES(aviDecoderCheckGainMapProperties(decoder, gainMapProperties));
    }
#endif

    if (!data->cicpSet && (data->tiles.count > 0)) {
        avifTile * firstTile = &data->tiles.tile[0];
        if (firstTile->input->samples.count > 0) {
            avifDecodeSample * sample = &firstTile->input->samples.sample[0];

            // Harvest CICP from the AV1's sequence header, which should be very close to the front
            // of the first sample. Read in successively larger chunks until we successfully parse the sequence.
            static const size_t searchSampleChunkIncrement = 64;
            static const size_t searchSampleSizeMax = 4096;
            size_t searchSampleSize = 0;
            do {
                searchSampleSize += searchSampleChunkIncrement;
                if (searchSampleSize > sample->size) {
                    searchSampleSize = sample->size;
                }

                avifResult prepareResult = avifDecoderPrepareSample(decoder, sample, searchSampleSize);
                if (prepareResult != AVIF_RESULT_OK) {
                    return prepareResult;
                }

                avifSequenceHeader sequenceHeader;
                if (avifSequenceHeaderParse(&sequenceHeader, &sample->data, firstTile->codecType)) {
                    data->cicpSet = AVIF_TRUE;
                    decoder->image->colorPrimaries = sequenceHeader.colorPrimaries;
                    decoder->image->transferCharacteristics = sequenceHeader.transferCharacteristics;
                    decoder->image->matrixCoefficients = sequenceHeader.matrixCoefficients;
                    decoder->image->yuvRange = sequenceHeader.range;
                    break;
                }
            } while (searchSampleSize != sample->size && searchSampleSize < searchSampleSizeMax);
        }
    }

    AVIF_CHECKRES(avifReadCodecConfigProperty(decoder->image, colorProperties, colorCodecType));

    return AVIF_RESULT_OK;
}

static avifResult avifDecoderPrepareTiles(avifDecoder * decoder, uint32_t nextImageIndex, const avifTileInfo * info)
{
    for (unsigned int tileIndex = info->decodedTileCount; tileIndex < info->tileCount; ++tileIndex) {
        avifTile * tile = &decoder->data->tiles.tile[info->firstTileIndex + tileIndex];

        if (nextImageIndex >= tile->input->samples.count) {
            return AVIF_RESULT_NO_IMAGES_REMAINING;
        }

        avifDecodeSample * sample = &tile->input->samples.sample[nextImageIndex];
        avifResult prepareResult = avifDecoderPrepareSample(decoder, sample, 0);
        if (prepareResult != AVIF_RESULT_OK) {
            return prepareResult;
        }
    }
    return AVIF_RESULT_OK;
}

static avifResult avifImageLimitedToFullAlpha(avifImage * image)
{
    if (image->imageOwnsAlphaPlane) {
        return AVIF_RESULT_NOT_IMPLEMENTED;
    }

    const uint8_t * alphaPlane = image->alphaPlane;
    const uint32_t alphaRowBytes = image->alphaRowBytes;

    // We cannot do the range conversion in place since it will modify the
    // codec's internal frame buffers. Allocate memory for the conversion.
    image->alphaPlane = NULL;
    image->alphaRowBytes = 0;
    const avifResult allocationResult = avifImageAllocatePlanes(image, AVIF_PLANES_A);
    if (allocationResult != AVIF_RESULT_OK) {
        return allocationResult;
    }

    if (image->depth > 8) {
        for (uint32_t j = 0; j < image->height; ++j) {
            const uint8_t * srcRow = &alphaPlane[j * alphaRowBytes];
            uint8_t * dstRow = &image->alphaPlane[j * image->alphaRowBytes];
            for (uint32_t i = 0; i < image->width; ++i) {
                int srcAlpha = *((const uint16_t *)&srcRow[i * 2]);
                int dstAlpha = avifLimitedToFullY(image->depth, srcAlpha);
                *((uint16_t *)&dstRow[i * 2]) = (uint16_t)dstAlpha;
            }
        }
    } else {
        for (uint32_t j = 0; j < image->height; ++j) {
            const uint8_t * srcRow = &alphaPlane[j * alphaRowBytes];
            uint8_t * dstRow = &image->alphaPlane[j * image->alphaRowBytes];
            for (uint32_t i = 0; i < image->width; ++i) {
                int srcAlpha = srcRow[i];
                int dstAlpha = avifLimitedToFullY(image->depth, srcAlpha);
                dstRow[i] = (uint8_t)dstAlpha;
            }
        }
    }
    return AVIF_RESULT_OK;
}

static avifResult avifGetErrorForItemCategory(avifItemCategory itemCategory)
{
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
    if (itemCategory == AVIF_ITEM_GAIN_MAP) {
        return AVIF_RESULT_DECODE_GAIN_MAP_FAILED;
    }
#endif
#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
    if (itemCategory >= AVIF_SAMPLE_TRANSFORM_MIN_CATEGORY && itemCategory <= AVIF_SAMPLE_TRANSFORM_MAX_CATEGORY) {
        return AVIF_RESULT_DECODE_SAMPLE_TRANSFORM_FAILED;
    }
#endif
    return avifIsAlpha(itemCategory) ? AVIF_RESULT_DECODE_ALPHA_FAILED : AVIF_RESULT_DECODE_COLOR_FAILED;
}

static avifResult avifDecoderDecodeTiles(avifDecoder * decoder, uint32_t nextImageIndex, avifTileInfo * info)
{
    const unsigned int oldDecodedTileCount = info->decodedTileCount;
    for (unsigned int tileIndex = oldDecodedTileCount; tileIndex < info->tileCount; ++tileIndex) {
        avifTile * tile = &decoder->data->tiles.tile[info->firstTileIndex + tileIndex];

        const avifDecodeSample * sample = &tile->input->samples.sample[nextImageIndex];
        if (sample->data.size < sample->size) {
            AVIF_ASSERT_OR_RETURN(decoder->allowIncremental);
            // Data is missing but there is no error yet. Output available pixel rows.
            return AVIF_RESULT_OK;
        }

        avifBool isLimitedRangeAlpha = AVIF_FALSE;
        tile->codec->maxThreads = decoder->maxThreads;
        tile->codec->imageSizeLimit = decoder->imageSizeLimit;
        if (!tile->codec->getNextImage(tile->codec, sample, avifIsAlpha(tile->input->itemCategory), &isLimitedRangeAlpha, tile->image)) {
            avifDiagnosticsPrintf(&decoder->diag, "tile->codec->getNextImage() failed");
            return avifGetErrorForItemCategory(tile->input->itemCategory);
        }

        // Section 2.3.4 of AV1 Codec ISO Media File Format Binding v1.2.0 says:
        //   the full_range_flag in the colr box shall match the color_range
        //   flag in the Sequence Header OBU.
        // See https://aomediacodec.github.io/av1-isobmff/v1.2.0.html#av1codecconfigurationbox-semantics.
        // If a 'colr' box of colour_type 'nclx' was parsed, a mismatch between
        // the 'colr' decoder->image->yuvRange and the AV1 OBU
        // tile->image->yuvRange should be treated as an error.
        // However codec_svt.c was not encoding the color_range field for
        // multiple years, so there probably are files in the wild that will
        // fail decoding if this is enforced. Thus this pattern is allowed.
        // Section 12.1.5.1 of ISO 14496-12 (ISOBMFF) says:
        //   If colour information is supplied in both this [colr] box, and also
        //   in the video bitstream, this box takes precedence, and over-rides
        //   the information in the bitstream.
        // So decoder->image->yuvRange is kept because it was either the 'colr'
        // value set when the 'colr' box was parsed, or it was the AV1 OBU value
        // extracted from the sequence header OBU of the first tile of the first
        // frame (if no 'colr' box of colour_type 'nclx' was found).

        // Alpha plane with limited range is not allowed by the latest revision
        // of the specification. However, it was allowed in version 1.0.0 of the
        // specification. To allow such files, simply convert the alpha plane to
        // full range.
        if (avifIsAlpha(tile->input->itemCategory) && isLimitedRangeAlpha) {
            avifResult result = avifImageLimitedToFullAlpha(tile->image);
            if (result != AVIF_RESULT_OK) {
                avifDiagnosticsPrintf(&decoder->diag, "avifImageLimitedToFullAlpha failed");
                return result;
            }
        }

        // Scale the decoded image so that it corresponds to this tile's output dimensions
        if ((tile->width != tile->image->width) || (tile->height != tile->image->height)) {
            if (avifImageScaleWithLimit(tile->image,
                                        tile->width,
                                        tile->height,
                                        decoder->imageSizeLimit,
                                        decoder->imageDimensionLimit,
                                        &decoder->diag) != AVIF_RESULT_OK) {
                return avifGetErrorForItemCategory(tile->input->itemCategory);
            }
        }

        ++info->decodedTileCount;

        const avifBool isGrid = (info->grid.rows > 0) && (info->grid.columns > 0);
        avifBool stealPlanes = !isGrid;
#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
        if (decoder->data->meta->sampleTransformExpression.count > 0) {
            // Keep everything as a copy for now.
            stealPlanes = AVIF_FALSE;
        }
        if (tile->input->itemCategory >= AVIF_SAMPLE_TRANSFORM_MIN_CATEGORY &&
            tile->input->itemCategory <= AVIF_SAMPLE_TRANSFORM_MAX_CATEGORY) {
            // Keep Sample Transform input image item samples in tiles.
            // The expression will be applied in avifDecoderNextImage() below instead, once all the tiles are available.
            continue;
        }
#endif

        if (!stealPlanes) {
            avifImage * dstImage = decoder->image;
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
            if (tile->input->itemCategory == AVIF_ITEM_GAIN_MAP) {
                AVIF_ASSERT_OR_RETURN(dstImage->gainMap && dstImage->gainMap->image);
                dstImage = dstImage->gainMap->image;
            }
#endif
            if (tileIndex == 0) {
                AVIF_CHECKRES(avifDecoderDataAllocateImagePlanes(decoder->data, info, dstImage));
            }
            AVIF_CHECKRES(avifDecoderDataCopyTileToImage(decoder->data, info, dstImage, tile, tileIndex));
        } else {
            AVIF_ASSERT_OR_RETURN(info->tileCount == 1);
            AVIF_ASSERT_OR_RETURN(tileIndex == 0);
            avifImage * src = tile->image;

            switch (tile->input->itemCategory) {
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
                case AVIF_ITEM_GAIN_MAP:
                    AVIF_ASSERT_OR_RETURN(decoder->image->gainMap && decoder->image->gainMap->image);
                    decoder->image->gainMap->image->width = src->width;
                    decoder->image->gainMap->image->height = src->height;
                    decoder->image->gainMap->image->depth = src->depth;
                    break;
#endif
                default:
                    if ((decoder->image->width != src->width) || (decoder->image->height != src->height) ||
                        (decoder->image->depth != src->depth)) {
                        if (avifIsAlpha(tile->input->itemCategory)) {
                            avifDiagnosticsPrintf(&decoder->diag,
                                                  "The color image item does not match the alpha image item in width, height, or bit depth");
                            return AVIF_RESULT_DECODE_ALPHA_FAILED;
                        }
                        avifImageFreePlanes(decoder->image, AVIF_PLANES_ALL);

                        decoder->image->width = src->width;
                        decoder->image->height = src->height;
                        decoder->image->depth = src->depth;
                    }
                    break;
            }

            if (avifIsAlpha(tile->input->itemCategory)) {
                avifImageStealPlanes(decoder->image, src, AVIF_PLANES_A);
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
            } else if (tile->input->itemCategory == AVIF_ITEM_GAIN_MAP) {
                AVIF_ASSERT_OR_RETURN(decoder->image->gainMap && decoder->image->gainMap->image);
                avifImageStealPlanes(decoder->image->gainMap->image, src, AVIF_PLANES_YUV);
#endif
            } else { // AVIF_ITEM_COLOR
                avifImageStealPlanes(decoder->image, src, AVIF_PLANES_YUV);
            }
        }
    }
    return AVIF_RESULT_OK;
}

// Returns AVIF_FALSE if there is currently a partially decoded frame.
static avifBool avifDecoderDataFrameFullyDecoded(const avifDecoderData * data)
{
    for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
        if (data->tileInfos[c].decodedTileCount != data->tileInfos[c].tileCount) {
            return AVIF_FALSE;
        }
    }
    return AVIF_TRUE;
}

#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
static avifResult avifDecoderApplySampleTransform(const avifDecoder * decoder, avifImage * dstImage)
{
    if (dstImage->depth != decoder->data->meta->sampleTransformDepth) {
        AVIF_ASSERT_OR_RETURN(dstImage->yuvPlanes[0] != NULL);
        AVIF_ASSERT_OR_RETURN(dstImage->imageOwnsYUVPlanes);

        // Use a temporary buffer because dstImage may point to decoder->image, which could be an input image.
        avifImage * dstImageWithCorrectDepth =
            avifImageCreate(dstImage->width, dstImage->height, decoder->data->meta->sampleTransformDepth, dstImage->yuvFormat);
        AVIF_CHECKERR(dstImageWithCorrectDepth != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        avifResult result =
            avifImageAllocatePlanes(dstImageWithCorrectDepth, dstImage->alphaPlane != NULL ? AVIF_PLANES_ALL : AVIF_PLANES_YUV);
        if (result == AVIF_RESULT_OK) {
            result = avifDecoderApplySampleTransform(decoder, dstImageWithCorrectDepth);
            if (result == AVIF_RESULT_OK) {
                // Keep the same dstImage object rather than swapping decoder->image, in case the user already accessed it.
                avifImageFreePlanes(dstImage, AVIF_PLANES_ALL);
                dstImage->depth = dstImageWithCorrectDepth->depth;
                avifImageStealPlanes(dstImage, dstImageWithCorrectDepth, AVIF_PLANES_ALL);
            }
        }
        avifImageDestroy(dstImageWithCorrectDepth);
        return result;
    }

    for (avifBool alpha = AVIF_FALSE; alpha <= decoder->alphaPresent ? AVIF_TRUE : AVIF_FALSE; ++alpha) {
        AVIF_ASSERT_OR_RETURN(decoder->data->sampleTransformNumInputImageItems <= AVIF_SAMPLE_TRANSFORM_MAX_NUM_INPUT_IMAGE_ITEMS);
        const avifImage * inputImages[AVIF_SAMPLE_TRANSFORM_MAX_NUM_INPUT_IMAGE_ITEMS];
        for (uint32_t i = 0; i < decoder->data->sampleTransformNumInputImageItems; ++i) {
            avifItemCategory category = decoder->data->sampleTransformInputImageItems[i];
            if (category == AVIF_ITEM_COLOR) {
                inputImages[i] = decoder->image;
            } else {
                AVIF_ASSERT_OR_RETURN(category >= AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_COLOR &&
                                      category < AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_COLOR +
                                                     AVIF_SAMPLE_TRANSFORM_MAX_NUM_EXTRA_INPUT_IMAGE_ITEMS);
                if (alpha) {
                    category += AVIF_SAMPLE_TRANSFORM_MAX_NUM_EXTRA_INPUT_IMAGE_ITEMS;
                }
                const avifTileInfo * tileInfo = &decoder->data->tileInfos[category];
                AVIF_CHECKERR(tileInfo->tileCount == 1, AVIF_RESULT_NOT_IMPLEMENTED); // TODO(yguyon): Implement Sample Transform grids
                inputImages[i] = decoder->data->tiles.tile[tileInfo->firstTileIndex].image;
                AVIF_ASSERT_OR_RETURN(inputImages[i] != NULL);
            }
        }
        AVIF_CHECKRES(avifImageApplyExpression(dstImage,
                                               AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_32,
                                               &decoder->data->meta->sampleTransformExpression,
                                               decoder->data->sampleTransformNumInputImageItems,
                                               inputImages,
                                               alpha ? AVIF_PLANES_A : AVIF_PLANES_YUV));
    }
    return AVIF_RESULT_OK;
}
#endif // AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM

avifResult avifDecoderNextImage(avifDecoder * decoder)
{
    avifDiagnosticsClearError(&decoder->diag);

    if (!decoder->data || decoder->data->tiles.count == 0) {
        // Nothing has been parsed yet
        return AVIF_RESULT_NO_CONTENT;
    }

    if (!decoder->io || !decoder->io->read) {
        return AVIF_RESULT_IO_NOT_SET;
    }

    if (avifDecoderDataFrameFullyDecoded(decoder->data)) {
        // A frame was decoded during the last avifDecoderNextImage() call.
        for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
            decoder->data->tileInfos[c].decodedTileCount = 0;
        }
    }

    AVIF_ASSERT_OR_RETURN(decoder->data->tiles.count == (decoder->data->tileInfos[AVIF_ITEM_CATEGORY_COUNT - 1].firstTileIndex +
                                                         decoder->data->tileInfos[AVIF_ITEM_CATEGORY_COUNT - 1].tileCount));

    const uint32_t nextImageIndex = (uint32_t)(decoder->imageIndex + 1);

    // Ensure that we have created the codecs before proceeding with the decoding.
    if (!decoder->data->tiles.tile[0].codec) {
        AVIF_CHECKRES(avifDecoderCreateCodecs(decoder));
    }

    // Acquire all sample data for the current image first, allowing for any read call to bail out
    // with AVIF_RESULT_WAITING_ON_IO harmlessly / idempotently, unless decoder->allowIncremental.
    avifResult prepareTileResult[AVIF_ITEM_CATEGORY_COUNT];
    for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
        prepareTileResult[c] = avifDecoderPrepareTiles(decoder, nextImageIndex, &decoder->data->tileInfos[c]);
        if (!decoder->allowIncremental || (prepareTileResult[c] != AVIF_RESULT_WAITING_ON_IO)) {
            AVIF_CHECKRES(prepareTileResult[c]);
        }
    }

    // Decode all available color tiles now, then all available alpha tiles, then all available bit
    // depth extension tiles. The order of appearance of the tiles in the bitstream is left to the
    // encoder's choice, and decoding as many as possible of each category in parallel is beneficial
    // for incremental decoding, as pixel rows need all channels to be decoded before being
    // accessible to the user.
    for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
        AVIF_CHECKRES(avifDecoderDecodeTiles(decoder, nextImageIndex, &decoder->data->tileInfos[c]));
    }

    if (!avifDecoderDataFrameFullyDecoded(decoder->data)) {
        AVIF_ASSERT_OR_RETURN(decoder->allowIncremental);
        // The image is not completely decoded. There should be no error unrelated to missing bytes,
        // and at least some missing bytes.
        avifResult firstNonOkResult = AVIF_RESULT_OK;
        for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
            AVIF_ASSERT_OR_RETURN(prepareTileResult[c] == AVIF_RESULT_OK || prepareTileResult[c] == AVIF_RESULT_WAITING_ON_IO);
            if (firstNonOkResult == AVIF_RESULT_OK) {
                firstNonOkResult = prepareTileResult[c];
            }
        }
        AVIF_ASSERT_OR_RETURN(firstNonOkResult != AVIF_RESULT_OK);
        // Return the "not enough bytes" status now instead of moving on to the next frame.
        return AVIF_RESULT_WAITING_ON_IO;
    }
    for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
        AVIF_ASSERT_OR_RETURN(prepareTileResult[c] == AVIF_RESULT_OK);
    }

#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
    if (decoder->data->meta->sampleTransformExpression.count > 0) {
        // TODO(yguyon): Add a field in avifDecoder and only perform sample transformations upon request.
        AVIF_CHECKRES(avifDecoderApplySampleTransform(decoder, decoder->image));
    }
#endif // AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM

    // Only advance decoder->imageIndex once the image is completely decoded, so that
    // avifDecoderNthImage(decoder, decoder->imageIndex + 1) is equivalent to avifDecoderNextImage(decoder)
    // if the previous call to avifDecoderNextImage() returned AVIF_RESULT_WAITING_ON_IO.
    decoder->imageIndex = (int)nextImageIndex;
    // The decoded tile counts will be reset to 0 the next time avifDecoderNextImage() is called,
    // for avifDecoderDecodedRowCount() to work until then.
    if (decoder->data->sourceSampleTable) {
        // Decoding from a track! Provide timing information.

        avifResult timingResult = avifDecoderNthImageTiming(decoder, decoder->imageIndex, &decoder->imageTiming);
        if (timingResult != AVIF_RESULT_OK) {
            return timingResult;
        }
    }
    return AVIF_RESULT_OK;
}

avifResult avifDecoderNthImageTiming(const avifDecoder * decoder, uint32_t frameIndex, avifImageTiming * outTiming)
{
    if (!decoder->data) {
        // Nothing has been parsed yet
        return AVIF_RESULT_NO_CONTENT;
    }

    if ((frameIndex > INT_MAX) || ((int)frameIndex >= decoder->imageCount)) {
        // Impossible index
        return AVIF_RESULT_NO_IMAGES_REMAINING;
    }

    if (!decoder->data->sourceSampleTable) {
        // There isn't any real timing associated with this decode, so
        // just hand back the defaults chosen in avifDecoderReset().
        *outTiming = decoder->imageTiming;
        return AVIF_RESULT_OK;
    }

    outTiming->timescale = decoder->timescale;
    outTiming->ptsInTimescales = 0;
    for (uint32_t imageIndex = 0; imageIndex < frameIndex; ++imageIndex) {
        outTiming->ptsInTimescales += avifSampleTableGetImageDelta(decoder->data->sourceSampleTable, imageIndex);
    }
    outTiming->durationInTimescales = avifSampleTableGetImageDelta(decoder->data->sourceSampleTable, frameIndex);

    if (outTiming->timescale > 0) {
        outTiming->pts = (double)outTiming->ptsInTimescales / (double)outTiming->timescale;
        outTiming->duration = (double)outTiming->durationInTimescales / (double)outTiming->timescale;
    } else {
        outTiming->pts = 0.0;
        outTiming->duration = 0.0;
    }
    return AVIF_RESULT_OK;
}

avifResult avifDecoderNthImage(avifDecoder * decoder, uint32_t frameIndex)
{
    avifDiagnosticsClearError(&decoder->diag);

    if (!decoder->data) {
        // Nothing has been parsed yet
        return AVIF_RESULT_NO_CONTENT;
    }

    if ((frameIndex > INT_MAX) || ((int)frameIndex >= decoder->imageCount)) {
        // Impossible index
        return AVIF_RESULT_NO_IMAGES_REMAINING;
    }

    int requestedIndex = (int)frameIndex;
    if (requestedIndex == (decoder->imageIndex + 1)) {
        // It's just the next image (already partially decoded or not at all), nothing special here
        return avifDecoderNextImage(decoder);
    }

    if (requestedIndex == decoder->imageIndex) {
        if (avifDecoderDataFrameFullyDecoded(decoder->data)) {
            // The current fully decoded image (decoder->imageIndex) is requested, nothing to do
            return AVIF_RESULT_OK;
        }
        // The next image (decoder->imageIndex + 1) is partially decoded but
        // the previous image (decoder->imageIndex) is requested.
        // Fall through to resetting the decoder data and start decoding from
        // the nearest key frame.
    }

    int nearestKeyFrame = (int)avifDecoderNearestKeyframe(decoder, frameIndex);
    if ((nearestKeyFrame > (decoder->imageIndex + 1)) || (requestedIndex <= decoder->imageIndex)) {
        // If we get here, we need to start decoding from the nearest key frame.
        // So discard the unused decoder state and its previous frames. This
        // will force the setup of new AV1 decoder (avifCodec) instances in
        // avifDecoderNextImage().
        decoder->imageIndex = nearestKeyFrame - 1; // prepare to read nearest keyframe
        avifDecoderDataResetCodec(decoder->data);
    }
    for (;;) {
        avifResult result = avifDecoderNextImage(decoder);
        if (result != AVIF_RESULT_OK) {
            return result;
        }

        if (requestedIndex == decoder->imageIndex) {
            break;
        }
    }
    return AVIF_RESULT_OK;
}

avifBool avifDecoderIsKeyframe(const avifDecoder * decoder, uint32_t frameIndex)
{
    if (!decoder->data || (decoder->data->tiles.count == 0)) {
        // Nothing has been parsed yet
        return AVIF_FALSE;
    }

    // *All* tiles for the requested frameIndex must be keyframes in order for
    //  avifDecoderIsKeyframe() to return true, otherwise we may seek to a frame in which the color
    //  planes are a keyframe but the alpha plane isn't a keyframe, which will cause an alpha plane
    //  decode failure.
    for (unsigned int i = 0; i < decoder->data->tiles.count; ++i) {
        const avifTile * tile = &decoder->data->tiles.tile[i];
        if ((frameIndex >= tile->input->samples.count) || !tile->input->samples.sample[frameIndex].sync) {
            return AVIF_FALSE;
        }
    }
    return AVIF_TRUE;
}

uint32_t avifDecoderNearestKeyframe(const avifDecoder * decoder, uint32_t frameIndex)
{
    if (!decoder->data) {
        // Nothing has been parsed yet
        return 0;
    }

    for (; frameIndex != 0; --frameIndex) {
        if (avifDecoderIsKeyframe(decoder, frameIndex)) {
            break;
        }
    }
    return frameIndex;
}

// Returns the number of available rows in decoder->image given a color or alpha subimage.
static uint32_t avifGetDecodedRowCount(const avifDecoder * decoder, const avifTileInfo * info, const avifImage * image)
{
    if (info->decodedTileCount == info->tileCount) {
        return image->height;
    }
    if (info->decodedTileCount == 0) {
        return 0;
    }

#if defined(AVIF_ENABLE_EXPERIMENTAL_SAMPLE_TRANSFORM)
    if (decoder->data->meta->sampleTransformExpression.count > 0) {
        // TODO(yguyon): Support incremental Sample Transforms
        return 0;
    }
#endif

    if ((info->grid.rows > 0) && (info->grid.columns > 0)) {
        // Grid of AVIF tiles (not to be confused with AV1 tiles).
        const uint32_t tileHeight = decoder->data->tiles.tile[info->firstTileIndex].height;
        return AVIF_MIN((info->decodedTileCount / info->grid.columns) * tileHeight, image->height);
    } else {
        // Non-grid image.
        return image->height;
    }
}

uint32_t avifDecoderDecodedRowCount(const avifDecoder * decoder)
{
    uint32_t minRowCount = decoder->image->height;
    for (int c = 0; c < AVIF_ITEM_CATEGORY_COUNT; ++c) {
#if defined(AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP)
        if (c == AVIF_ITEM_GAIN_MAP) {
            const avifImage * const gainMap = decoder->image->gainMap ? decoder->image->gainMap->image : NULL;
            if (decoder->gainMapPresent && decoder->enableDecodingGainMap && gainMap != NULL && gainMap->height != 0) {
                uint32_t gainMapRowCount = avifGetDecodedRowCount(decoder, &decoder->data->tileInfos[AVIF_ITEM_GAIN_MAP], gainMap);
                if (gainMap->height != decoder->image->height) {
                    const uint32_t scaledGainMapRowCount =
                        (uint32_t)floorf((float)gainMapRowCount / gainMap->height * decoder->image->height);
                    // Make sure it matches the formula described in the comment of avifDecoderDecodedRowCount() in avif.h.
                    AVIF_CHECKERR((uint32_t)lround((double)scaledGainMapRowCount / decoder->image->height *
                                                   decoder->image->gainMap->image->height) <= gainMapRowCount,
                                  0);
                    gainMapRowCount = scaledGainMapRowCount;
                }
                minRowCount = AVIF_MIN(minRowCount, gainMapRowCount);
            }
            continue;
        }
#endif
        const uint32_t rowCount = avifGetDecodedRowCount(decoder, &decoder->data->tileInfos[c], decoder->image);
        minRowCount = AVIF_MIN(minRowCount, rowCount);
    }
    return minRowCount;
}

avifResult avifDecoderRead(avifDecoder * decoder, avifImage * image)
{
    avifResult result = avifDecoderParse(decoder);
    if (result != AVIF_RESULT_OK) {
        return result;
    }
    result = avifDecoderNextImage(decoder);
    if (result != AVIF_RESULT_OK) {
        return result;
    }
    // If decoder->image->imageOwnsYUVPlanes is true and decoder->image is not used after this call,
    // the ownership of the planes in decoder->image could be transferred here instead of copied.
    // However most codec_*.c implementations allocate the output buffer themselves and return a
    // view, unless some postprocessing is applied (container-level grid reconstruction for
    // example), so the first condition rarely holds.
    // The second condition does not hold either: it is not required by the documentation in avif.h.
    return avifImageCopy(image, decoder->image, AVIF_PLANES_ALL);
}

avifResult avifDecoderReadMemory(avifDecoder * decoder, avifImage * image, const uint8_t * data, size_t size)
{
    avifDiagnosticsClearError(&decoder->diag);
    avifResult result = avifDecoderSetIOMemory(decoder, data, size);
    if (result != AVIF_RESULT_OK) {
        return result;
    }
    return avifDecoderRead(decoder, image);
}

avifResult avifDecoderReadFile(avifDecoder * decoder, avifImage * image, const char * filename)
{
    avifDiagnosticsClearError(&decoder->diag);
    avifResult result = avifDecoderSetIOFile(decoder, filename);
    if (result != AVIF_RESULT_OK) {
        return result;
    }
    return avifDecoderRead(decoder, image);
}
