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

#include "avif/internal.h"

#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <time.h>

// Section 8.11.14.2 of ISO/IEC 14496-12 (ItemPropertyAssociationBox 'ipma' syntax):
//   if (flags & 1)
//     unsigned int(15) property_index;
//   else
//     unsigned int(7) property_index;
//
// libavif writes 'ipma' with flags set to 0.
#define MAX_PROPERTY_INDEX ((1 << 7) - 1)

// The indices of the properties associated with an item.
typedef struct avifItemPropertyAssociation
{
    uint8_t property_index; // 1-indexed
    avifBool essential;
} avifItemPropertyAssociation;
AVIF_ARRAY_DECLARE(avifItemPropertyAssociationArray, avifItemPropertyAssociation, association);

// Used to store offsets in meta boxes which need to point at mdat offsets that
// aren't known yet. When an item's mdat payload is written, all registered fixups
// will have this now-known offset "fixed up".
typedef struct avifOffsetFixup
{
    size_t offset;
} avifOffsetFixup;
AVIF_ARRAY_DECLARE(avifOffsetFixupArray, avifOffsetFixup, fixup);

static const char alphaURN[] = AVIF_URN_ALPHA0;
static const size_t alphaURNSize = sizeof(alphaURN);

static const char xmpContentType[] = AVIF_CONTENT_TYPE_XMP;
static const size_t xmpContentTypeSize = sizeof(xmpContentType);

static avifResult writeCodecConfig(avifRWStream * s, const avifCodecConfigurationBox * cfg);
static avifResult writeConfigBox(avifRWStream * s, const avifCodecConfigurationBox * cfg, const char * configPropName);

// ---------------------------------------------------------------------------
// avifSetTileConfiguration

static int floorLog2(uint32_t n)
{
    assert(n > 0);
    int count = 0;
    while (n != 0) {
        ++count;
        n >>= 1;
    }
    return count - 1;
}

// Splits tilesLog2 into *tileDim1Log2 and *tileDim2Log2, considering the ratio of dim1 to dim2.
//
// Precondition:
//     dim1 >= dim2
// Postcondition:
//     tilesLog2 == *tileDim1Log2 + *tileDim2Log2
//     *tileDim1Log2 >= *tileDim2Log2
static void splitTilesLog2(uint32_t dim1, uint32_t dim2, int tilesLog2, int * tileDim1Log2, int * tileDim2Log2)
{
    assert(dim1 >= dim2);
    uint32_t ratio = dim1 / dim2;
    int diffLog2 = floorLog2(ratio);
    int subtract = tilesLog2 - diffLog2;
    if (subtract < 0) {
        subtract = 0;
    }
    *tileDim2Log2 = subtract / 2;
    *tileDim1Log2 = tilesLog2 - *tileDim2Log2;
    assert(*tileDim1Log2 >= *tileDim2Log2);
}

// Set the tile configuration: the number of tiles and the tile size.
//
// Tiles improve encoding and decoding speeds when multiple threads are available. However, for
// image coding, the total tile boundary length affects the compression efficiency because intra
// prediction can't go across tile boundaries. So the more tiles there are in an image, the worse
// the compression ratio is. For a given number of tiles, making the tile size close to a square
// tends to reduce the total tile boundary length inside the image. Use more tiles along the longer
// dimension of the image to make the tile size closer to a square.
void avifSetTileConfiguration(int threads, uint32_t width, uint32_t height, int * tileRowsLog2, int * tileColsLog2)
{
    *tileRowsLog2 = 0;
    *tileColsLog2 = 0;
    if (threads > 1) {
        // Avoid small tiles because they are particularly bad for image coding.
        //
        // Use no more tiles than the number of threads. Aim for one tile per thread. Using more
        // than one thread inside one tile could be less efficient. Using more tiles than the
        // number of threads would result in a compression penalty without much benefit.
        const uint32_t kMinTileArea = 512 * 512;
        const uint32_t kMaxTiles = 32;
        // AV1 requires width <= 65536 and height <= 65536, so their product fits
        // in uint64_t and the resulting tile count fits in uint32_t.
        const uint64_t imageArea = (uint64_t)width * height;
        uint32_t tiles = (uint32_t)((imageArea + kMinTileArea - 1) / kMinTileArea);
        if (tiles > kMaxTiles) {
            tiles = kMaxTiles;
        }
        if (tiles > (uint32_t)threads) {
            tiles = threads;
        }
        int tilesLog2 = floorLog2(tiles);
        // If the image's width is greater than the height, use more tile columns than tile rows.
        if (width >= height) {
            splitTilesLog2(width, height, tilesLog2, tileColsLog2, tileRowsLog2);
        } else {
            splitTilesLog2(height, width, tilesLog2, tileRowsLog2, tileColsLog2);
        }
    }
}

// ---------------------------------------------------------------------------
// avifCodecEncodeOutput

avifCodecEncodeOutput * avifCodecEncodeOutputCreate(void)
{
    avifCodecEncodeOutput * encodeOutput = (avifCodecEncodeOutput *)avifAlloc(sizeof(avifCodecEncodeOutput));
    if (encodeOutput == NULL) {
        return NULL;
    }
    memset(encodeOutput, 0, sizeof(avifCodecEncodeOutput));
    if (!avifArrayCreate(&encodeOutput->samples, sizeof(avifEncodeSample), 1)) {
        avifCodecEncodeOutputDestroy(encodeOutput);
        return NULL;
    }
    return encodeOutput;
}

avifResult avifCodecEncodeOutputAddSample(avifCodecEncodeOutput * encodeOutput, const uint8_t * data, size_t len, avifBool sync)
{
    avifEncodeSample * sample = (avifEncodeSample *)avifArrayPush(&encodeOutput->samples);
    AVIF_CHECKERR(sample, AVIF_RESULT_OUT_OF_MEMORY);
    const avifResult result = avifRWDataSet(&sample->data, data, len);
    if (result != AVIF_RESULT_OK) {
        avifArrayPop(&encodeOutput->samples);
        return result;
    }
    sample->sync = sync;
    return AVIF_RESULT_OK;
}

void avifCodecEncodeOutputDestroy(avifCodecEncodeOutput * encodeOutput)
{
    for (uint32_t sampleIndex = 0; sampleIndex < encodeOutput->samples.count; ++sampleIndex) {
        avifRWDataFree(&encodeOutput->samples.sample[sampleIndex].data);
    }
    avifArrayDestroy(&encodeOutput->samples);
    avifFree(encodeOutput);
}

// ---------------------------------------------------------------------------
// avifEncoderItem

// one "item" worth for encoder
typedef struct avifEncoderItem
{
    uint32_t id;
    uint8_t type[4];                      // 4-character 'item_type' field in the 'infe' (item info entry) box
    avifCodec * codec;                    // only present on image items
    avifCodecEncodeOutput * encodeOutput; // AV1 sample data
    avifRWData metadataPayload;           // Exif/XMP data
    avifCodecConfigurationBox av1C;       // Harvested in avifEncoderFinish(), if encodeOutput has samples
                                          // TODO(yguyon): Rename or add av2C
    uint32_t cellIndex;                   // Which row-major cell index corresponds to this item. only present on image items
    avifItemCategory itemCategory;        // Category of item being encoded
    avifBool hiddenImage;                 // A hidden image item has (flags & 1) equal to 1 in its ItemInfoEntry.

    const char * infeName;
    size_t infeNameSize;
    const char * infeContentType;
    size_t infeContentTypeSize;
    avifOffsetFixupArray mdatFixups;

    uint32_t irefToID; // if non-zero, make an iref from this id -> irefToID
    const char * irefType;

    uint32_t gridCols; // if non-zero (legal range [1-256]), this is a grid item
    uint32_t gridRows; // if non-zero (legal range [1-256]), this is a grid item

    // the reconstructed image of a grid item will be trimmed to these dimensions (only present on grid items)
    uint32_t gridWidth;
    uint32_t gridHeight;

    uint32_t extraLayerCount; // if non-zero (legal range [1-(AVIF_MAX_AV1_LAYER_COUNT-1)]), this is a layered AV1 image

    uint32_t dimgFromID; // if non-zero, make an iref from dimgFromID -> this id

    avifItemPropertyAssociationArray associations; // 'ipma'
} avifEncoderItem;
AVIF_ARRAY_DECLARE(avifEncoderItemArray, avifEncoderItem, item);

// ---------------------------------------------------------------------------
// avifEncoderItemReference

// pointer to one "item" interested in
typedef avifEncoderItem * avifEncoderItemReference;
AVIF_ARRAY_DECLARE(avifEncoderItemReferenceArray, avifEncoderItemReference, ref);

// ---------------------------------------------------------------------------
// avifEncoderFrame

typedef struct avifEncoderFrame
{
    uint64_t durationInTimescales;
} avifEncoderFrame;
AVIF_ARRAY_DECLARE(avifEncoderFrameArray, avifEncoderFrame, frame);

// ---------------------------------------------------------------------------
// avifEncoderData

AVIF_ARRAY_DECLARE(avifEncoderItemIdArray, uint32_t, itemID);

typedef struct avifEncoderData
{
    avifEncoderItemArray items;
    avifEncoderFrameArray frames;
    // quality values for the image, alpha, and gain map
    // Note: these three fields are the actual quality values after the default values are resolved
    int quality;
    int qualityAlpha;
    int qualityGainMap;
    // tileRowsLog2 and tileColsLog2 are the actual tiling values after automatic tiling is handled
    int tileRowsLog2;
    int tileColsLog2;
    avifEncoder lastEncoder; // Shallow state at last avifEncoderAddImageInternal() call.
    // lastQuality and lastQualityAlpha are the quality and qualityAlpha values used last time
    // Note: Gain maps are supported for still images only, so we don't need a "lastQualityGainMap"
    int lastQuality;
    int lastQualityAlpha;
    // lastTileRowsLog2 and lastTileColsLog2 are the actual tiling values used last time
    int lastTileRowsLog2;
    int lastTileColsLog2;
    // Holds metadata about the base image
    avifImage * imageMetadata;
    // Holds metadata derived from the avifGainMap struct (when present) about the alternate image
    avifImage * altImageMetadata;
    uint32_t lastItemID;
    uint32_t primaryItemID;
    avifEncoderItemIdArray alternativeItemIDs; // list of item ids for an 'altr' box (group of alternatives to each other)
    avifBool singleImage; // if true, the AVIF_ADD_IMAGE_FLAG_SINGLE flag was set on the first call to avifEncoderAddImage()
    avifBool alphaPresent;
    size_t gainMapSizeBytes;
    // Fields specific to AV1/AV2
    const char * imageItemType;  // "av01" for AV1 ("av02" for AV2 if AVIF_CODEC_AVM)
    const char * configPropName; // "av1C" for AV1 ("av2C" for AV2 if AVIF_CODEC_AVM)
} avifEncoderData;

static void avifEncoderDataDestroy(avifEncoderData * data);

// Returns NULL if a memory allocation failed.
static avifEncoderData * avifEncoderDataCreate(void)
{
    avifEncoderData * data = (avifEncoderData *)avifAlloc(sizeof(avifEncoderData));
    if (!data) {
        return NULL;
    }
    memset(data, 0, sizeof(avifEncoderData));
    data->imageMetadata = avifImageCreateEmpty();
    if (!data->imageMetadata) {
        goto error;
    }
    data->altImageMetadata = avifImageCreateEmpty();
    if (!data->altImageMetadata) {
        goto error;
    }
    if (!avifArrayCreate(&data->items, sizeof(avifEncoderItem), 8)) {
        goto error;
    }
    if (!avifArrayCreate(&data->frames, sizeof(avifEncoderFrame), 1)) {
        goto error;
    }
    if (!avifArrayCreate(&data->alternativeItemIDs, sizeof(uint32_t), 1)) {
        goto error;
    }
    return data;

error:
    avifEncoderDataDestroy(data);
    return NULL;
}

// Returns AVIF_RESULT_OUT_OF_MEMORY if a memory allocation failed, or AVIF_RESULT_INTERNAL_ERROR
// if no item ID is left (item IDs span a 32-bit space, so the latter would require more than
// 4 billion items).
static avifResult avifEncoderDataCreateItem(avifEncoderData * data,
                                            const char * type,
                                            const char * infeName,
                                            size_t infeNameSize,
                                            uint32_t cellIndex,
                                            avifEncoderItem ** itemPtr)
{
    // All item IDs are taken. This is unreachable in practice but avoid a wrap-around of
    // item IDs, which would silently truncate or duplicate them.
    AVIF_ASSERT_OR_RETURN(data->lastItemID != UINT32_MAX);

    avifEncoderItem * item = (avifEncoderItem *)avifArrayPush(&data->items);
    AVIF_CHECKERR(item != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    ++data->lastItemID;
    item->id = data->lastItemID;
    memcpy(item->type, type, sizeof(item->type));
    item->infeName = infeName;
    item->infeNameSize = infeNameSize;
    item->encodeOutput = avifCodecEncodeOutputCreate();
    if (item->encodeOutput == NULL) {
        goto error;
    }
    item->cellIndex = cellIndex;
    if (!avifArrayCreate(&item->mdatFixups, sizeof(avifOffsetFixup), 4)) {
        goto error;
    }
    if (!avifArrayCreate(&item->associations, sizeof(avifItemPropertyAssociation), 4)) {
        goto error;
    }
    *itemPtr = item;
    return AVIF_RESULT_OK;

error:
    if (item->encodeOutput != NULL) {
        avifCodecEncodeOutputDestroy(item->encodeOutput);
    }
    avifArrayDestroy(&item->mdatFixups);
    --data->lastItemID;
    avifArrayPop(&data->items);
    return AVIF_RESULT_OUT_OF_MEMORY;
}

static avifEncoderItem * avifEncoderDataFindItemByID(avifEncoderData * data, uint32_t id)
{
    for (uint32_t itemIndex = 0; itemIndex < data->items.count; ++itemIndex) {
        avifEncoderItem * item = &data->items.item[itemIndex];
        if (item->id == id) {
            return item;
        }
    }
    return NULL;
}

static void avifEncoderDataDestroy(avifEncoderData * data)
{
    for (uint32_t i = 0; i < data->items.count; ++i) {
        avifEncoderItem * item = &data->items.item[i];
        if (item->codec) {
            avifCodecDestroy(item->codec);
        }
        avifCodecEncodeOutputDestroy(item->encodeOutput);
        avifRWDataFree(&item->metadataPayload);
        avifArrayDestroy(&item->mdatFixups);
        avifArrayDestroy(&item->associations);
    }
    if (data->imageMetadata) {
        avifImageDestroy(data->imageMetadata);
    }
    if (data->altImageMetadata) {
        avifImageDestroy(data->altImageMetadata);
    }
    avifArrayDestroy(&data->items);
    avifArrayDestroy(&data->frames);
    avifArrayDestroy(&data->alternativeItemIDs);
    avifFree(data);
}

static avifResult avifEncoderItemAddMdatFixup(avifEncoderItem * item, const avifRWStream * s)
{
    avifOffsetFixup * fixup = (avifOffsetFixup *)avifArrayPush(&item->mdatFixups);
    AVIF_CHECKERR(fixup != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    fixup->offset = avifRWStreamOffset(s);
    return AVIF_RESULT_OK;
}

// ---------------------------------------------------------------------------
// avifItemPropertyDedup - Provides ipco deduplication

typedef struct avifItemProperty
{
    uint8_t index;
    size_t offset;
    size_t size;
} avifItemProperty;
AVIF_ARRAY_DECLARE(avifItemPropertyArray, avifItemProperty, property);

typedef struct avifItemPropertyDedup
{
    avifItemPropertyArray properties;
    avifRWStream s;    // Temporary stream for each new property, checked against already-written boxes for deduplications
    avifRWData buffer; // Temporary storage for 's'
    uint8_t nextIndex; // 1-indexed, incremented every time another unique property is finished
} avifItemPropertyDedup;

static avifItemPropertyDedup * avifItemPropertyDedupCreate(void)
{
    avifItemPropertyDedup * dedup = (avifItemPropertyDedup *)avifAlloc(sizeof(avifItemPropertyDedup));
    if (dedup == NULL) {
        return NULL;
    }
    memset(dedup, 0, sizeof(avifItemPropertyDedup));
    if (!avifArrayCreate(&dedup->properties, sizeof(avifItemProperty), 8)) {
        avifFree(dedup);
        return NULL;
    }
    if (avifRWDataRealloc(&dedup->buffer, 2048) != AVIF_RESULT_OK) {
        avifArrayDestroy(&dedup->properties);
        avifFree(dedup);
        return NULL;
    }
    return dedup;
}

static void avifItemPropertyDedupDestroy(avifItemPropertyDedup * dedup)
{
    avifArrayDestroy(&dedup->properties);
    avifRWDataFree(&dedup->buffer);
    avifFree(dedup);
}

// Resets the dedup's temporary write stream in preparation for a single item property's worth of writing
static void avifItemPropertyDedupStart(avifItemPropertyDedup * dedup)
{
    avifRWStreamStart(&dedup->s, &dedup->buffer);
}

// This compares the newly written item property (in the dedup's temporary storage buffer) to
// already-written properties (whose offsets/sizes in outputStream are recorded in the dedup). If a
// match is found, the previous property's index is used. If this new property is unique, it is
// assigned the next available property index, written to the output stream, and its offset/size in
// the output stream is recorded in the dedup for future comparisons.
//
// On success, this function adds to the given ipma box a property association linking the reused
// or newly created property with the item.
static avifResult avifItemPropertyDedupFinish(avifItemPropertyDedup * dedup,
                                              avifRWStream * outputStream,
                                              avifItemPropertyAssociationArray * associations,
                                              avifBool essential)
{
    uint8_t propertyIndex = 0;
    const size_t newPropertySize = avifRWStreamOffset(&dedup->s);

    for (size_t i = 0; i < dedup->properties.count; ++i) {
        avifItemProperty * property = &dedup->properties.property[i];
        if ((property->size == newPropertySize) &&
            !memcmp(&outputStream->raw->data[property->offset], dedup->buffer.data, newPropertySize)) {
            // We've already written this exact property, reuse it
            propertyIndex = property->index;
            AVIF_ASSERT_OR_RETURN(propertyIndex != 0);
            break;
        }
    }

    if (propertyIndex == 0) {
        // Write a new property, and remember its location in the output stream for future deduplication
        avifItemProperty * property = (avifItemProperty *)avifArrayPush(&dedup->properties);
        AVIF_CHECKERR(property != NULL, AVIF_RESULT_OUT_OF_MEMORY);
        AVIF_CHECKERR(dedup->nextIndex < MAX_PROPERTY_INDEX, AVIF_RESULT_INVALID_ARGUMENT);
        property->index = ++dedup->nextIndex; // preincrement so the first new index is 1 (as ipma is 1-indexed)
        property->size = newPropertySize;
        property->offset = avifRWStreamOffset(outputStream);
        AVIF_CHECKRES(avifRWStreamWrite(outputStream, dedup->buffer.data, newPropertySize));
        propertyIndex = property->index;
    }

    avifItemPropertyAssociation * association = (avifItemPropertyAssociation *)avifArrayPush(associations);
    AVIF_CHECKERR(association != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    association->property_index = propertyIndex;
    association->essential = essential;
    return AVIF_RESULT_OK;
}

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

static const avifScalingMode noScaling = { { 1, 1 }, { 1, 1 } };

static avifBool avifEncoderSizeIsSet(const avifEncoder * encoder)
{
    return (encoder->width != 0) || (encoder->height != 0);
}

static avifBool avifScalingModeIsNoScaling(const avifScalingMode * scalingMode)
{
    return (scalingMode->horizontal.n == scalingMode->horizontal.d) && (scalingMode->vertical.n == scalingMode->vertical.d);
}

static avifBool avifImageHasEquivalentTransformProperties(const avifImage * lhs, const avifImage * rhs)
{
    const uint32_t lhsTransformFlags = lhs->transformFlags &
                                       (AVIF_TRANSFORM_PASP | AVIF_TRANSFORM_CLAP | AVIF_TRANSFORM_IROT | AVIF_TRANSFORM_IMIR);
    const uint32_t rhsTransformFlags = rhs->transformFlags &
                                       (AVIF_TRANSFORM_PASP | AVIF_TRANSFORM_CLAP | AVIF_TRANSFORM_IROT | AVIF_TRANSFORM_IMIR);
    if (lhsTransformFlags != rhsTransformFlags) {
        return AVIF_FALSE;
    }
    if ((lhsTransformFlags & AVIF_TRANSFORM_PASP) &&
        ((lhs->pasp.hSpacing != rhs->pasp.hSpacing) || (lhs->pasp.vSpacing != rhs->pasp.vSpacing))) {
        return AVIF_FALSE;
    }
    if ((lhsTransformFlags & AVIF_TRANSFORM_CLAP) &&
        ((lhs->clap.widthN != rhs->clap.widthN) || (lhs->clap.widthD != rhs->clap.widthD) ||
         (lhs->clap.heightN != rhs->clap.heightN) || (lhs->clap.heightD != rhs->clap.heightD) ||
         (lhs->clap.horizOffN != rhs->clap.horizOffN) || (lhs->clap.horizOffD != rhs->clap.horizOffD) ||
         (lhs->clap.vertOffN != rhs->clap.vertOffN) || (lhs->clap.vertOffD != rhs->clap.vertOffD))) {
        return AVIF_FALSE;
    }
    if ((lhsTransformFlags & AVIF_TRANSFORM_IROT) && (lhs->irot.angle != rhs->irot.angle)) {
        return AVIF_FALSE;
    }
    if ((lhsTransformFlags & AVIF_TRANSFORM_IMIR) && (lhs->imir.axis != rhs->imir.axis)) {
        return AVIF_FALSE;
    }
    return AVIF_TRUE;
}

avifEncoder * avifEncoderCreate(void)
{
    avifEncoder * encoder = (avifEncoder *)avifAlloc(sizeof(avifEncoder));
    if (!encoder) {
        return NULL;
    }
    memset(encoder, 0, sizeof(avifEncoder));
    encoder->codecChoice = AVIF_CODEC_CHOICE_AUTO;
    encoder->maxThreads = 1;
    encoder->speed = AVIF_SPEED_DEFAULT;
    encoder->keyframeInterval = 0;
    encoder->timescale = 1;
    encoder->repetitionCount = AVIF_REPETITION_COUNT_INFINITE;
    encoder->quality = AVIF_QUALITY_DEFAULT;
    encoder->qualityAlpha = AVIF_QUALITY_DEFAULT;
    encoder->qualityGainMap = AVIF_QUALITY_DEFAULT;
    encoder->minQuantizer = AVIF_QUANTIZER_BEST_QUALITY;
    encoder->maxQuantizer = AVIF_QUANTIZER_WORST_QUALITY;
    encoder->minQuantizerAlpha = AVIF_QUANTIZER_BEST_QUALITY;
    encoder->maxQuantizerAlpha = AVIF_QUANTIZER_WORST_QUALITY;
    encoder->tileRowsLog2 = 0;
    encoder->tileColsLog2 = 0;
    encoder->autoTiling = AVIF_FALSE;
    encoder->scalingMode = noScaling;
    encoder->data = avifEncoderDataCreate();
    encoder->csOptions = avifCodecSpecificOptionsCreate();
    if (!encoder->data || !encoder->csOptions) {
        avifEncoderDestroy(encoder);
        return NULL;
    }
    encoder->headerFormat = AVIF_HEADER_DEFAULT;
    encoder->creationTime = 0;
    encoder->modificationTime = 0;
    encoder->sampleTransformRecipe = AVIF_SAMPLE_TRANSFORM_NONE;
    encoder->width = 0;
    encoder->height = 0;
    return encoder;
}

void avifEncoderDestroy(avifEncoder * encoder)
{
    if (encoder->csOptions) {
        avifCodecSpecificOptionsDestroy(encoder->csOptions);
    }
    if (encoder->data) {
        avifEncoderDataDestroy(encoder->data);
    }
    avifFree(encoder);
}

avifResult avifEncoderSetCodecSpecificOption(avifEncoder * encoder, const char * key, const char * value)
{
    return avifCodecSpecificOptionsSet(encoder->csOptions, key, value);
}

static void avifEncoderBackupSettings(avifEncoder * encoder)
{
    avifEncoder * lastEncoder = &encoder->data->lastEncoder;

    // lastEncoder->data is only used to mark that lastEncoder is initialized. lastEncoder->data
    // must not be dereferenced.
    lastEncoder->data = encoder->data;
    lastEncoder->codecChoice = encoder->codecChoice;
    lastEncoder->maxThreads = encoder->maxThreads;
    lastEncoder->speed = encoder->speed;
    lastEncoder->keyframeInterval = encoder->keyframeInterval;
    lastEncoder->timescale = encoder->timescale;
    lastEncoder->repetitionCount = encoder->repetitionCount;
    lastEncoder->extraLayerCount = encoder->extraLayerCount;
    lastEncoder->minQuantizer = encoder->minQuantizer;
    lastEncoder->maxQuantizer = encoder->maxQuantizer;
    lastEncoder->minQuantizerAlpha = encoder->minQuantizerAlpha;
    lastEncoder->maxQuantizerAlpha = encoder->maxQuantizerAlpha;
    encoder->data->lastQuality = encoder->data->quality;
    encoder->data->lastQualityAlpha = encoder->data->qualityAlpha;
    encoder->data->lastTileRowsLog2 = encoder->data->tileRowsLog2;
    encoder->data->lastTileColsLog2 = encoder->data->tileColsLog2;
    lastEncoder->scalingMode = encoder->scalingMode;
    lastEncoder->sampleTransformRecipe = encoder->sampleTransformRecipe;
    lastEncoder->width = encoder->width;
    lastEncoder->height = encoder->height;
}

// This function detects changes made on avifEncoder. It returns true on success (i.e., if every
// change is valid), or false on failure (i.e., if any setting that can't change was changed). It
// reports a bitwise-OR of detected changes in encoderChanges.
static avifBool avifEncoderDetectChanges(const avifEncoder * encoder, avifEncoderChanges * encoderChanges)
{
    const avifEncoder * lastEncoder = &encoder->data->lastEncoder;
    *encoderChanges = 0;

    if (!lastEncoder->data) {
        // lastEncoder is not initialized.
        return AVIF_TRUE;
    }

    if ((lastEncoder->codecChoice != encoder->codecChoice) || (lastEncoder->maxThreads != encoder->maxThreads) ||
        (lastEncoder->speed != encoder->speed) || (lastEncoder->keyframeInterval != encoder->keyframeInterval) ||
        (lastEncoder->timescale != encoder->timescale) || (lastEncoder->repetitionCount != encoder->repetitionCount) ||
        (lastEncoder->extraLayerCount != encoder->extraLayerCount) || (lastEncoder->width != encoder->width) ||
        (lastEncoder->height != encoder->height)) {
        return AVIF_FALSE;
    }

    if (encoder->data->lastQuality != encoder->data->quality) {
        *encoderChanges |= AVIF_ENCODER_CHANGE_QUALITY;
    }
    if (encoder->data->lastQualityAlpha != encoder->data->qualityAlpha) {
        *encoderChanges |= AVIF_ENCODER_CHANGE_QUALITY_ALPHA;
    }
    if (lastEncoder->minQuantizer != encoder->minQuantizer) {
        *encoderChanges |= AVIF_ENCODER_CHANGE_MIN_QUANTIZER;
    }
    if (lastEncoder->maxQuantizer != encoder->maxQuantizer) {
        *encoderChanges |= AVIF_ENCODER_CHANGE_MAX_QUANTIZER;
    }
    if (lastEncoder->minQuantizerAlpha != encoder->minQuantizerAlpha) {
        *encoderChanges |= AVIF_ENCODER_CHANGE_MIN_QUANTIZER_ALPHA;
    }
    if (lastEncoder->maxQuantizerAlpha != encoder->maxQuantizerAlpha) {
        *encoderChanges |= AVIF_ENCODER_CHANGE_MAX_QUANTIZER_ALPHA;
    }
    if (encoder->data->lastTileRowsLog2 != encoder->data->tileRowsLog2) {
        *encoderChanges |= AVIF_ENCODER_CHANGE_TILE_ROWS_LOG2;
    }
    if (encoder->data->lastTileColsLog2 != encoder->data->tileColsLog2) {
        *encoderChanges |= AVIF_ENCODER_CHANGE_TILE_COLS_LOG2;
    }
    if (memcmp(&lastEncoder->scalingMode, &encoder->scalingMode, sizeof(avifScalingMode)) != 0) {
        *encoderChanges |= AVIF_ENCODER_CHANGE_SCALING_MODE;
    }
    if (encoder->csOptions->count > 0) {
        *encoderChanges |= AVIF_ENCODER_CHANGE_CODEC_SPECIFIC;
    }

    if (lastEncoder->sampleTransformRecipe != encoder->sampleTransformRecipe) {
        return AVIF_FALSE;
    }

    return AVIF_TRUE;
}

// Same as 'avifEncoderWriteColorProperties' but for the colr nclx box only.
static avifResult avifEncoderWriteNclxProperty(avifRWStream * dedupStream,
                                               avifRWStream * outputStream,
                                               const avifImage * imageMetadata,
                                               avifItemPropertyAssociationArray * associations,
                                               avifItemPropertyDedup * dedup)
{
    if (dedup) {
        avifItemPropertyDedupStart(dedup);
    }
    avifBoxMarker colr;
    AVIF_CHECKRES(avifRWStreamWriteBox(dedupStream, "colr", AVIF_BOX_SIZE_TBD, &colr));
    AVIF_CHECKRES(avifRWStreamWriteChars(dedupStream, "nclx", 4));                   // unsigned int(32) colour_type;
    AVIF_CHECKRES(avifRWStreamWriteU16(dedupStream, imageMetadata->colorPrimaries)); // unsigned int(16) colour_primaries;
    AVIF_CHECKRES(avifRWStreamWriteU16(dedupStream, imageMetadata->transferCharacteristics)); // unsigned int(16) transfer_characteristics;
    AVIF_CHECKRES(avifRWStreamWriteU16(dedupStream, imageMetadata->matrixCoefficients)); // unsigned int(16) matrix_coefficients;
    AVIF_CHECKRES(avifRWStreamWriteBits(dedupStream, (imageMetadata->yuvRange == AVIF_RANGE_FULL) ? 1 : 0, /*bitCount=*/1)); // unsigned int(1) full_range_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(dedupStream, 0, /*bitCount=*/7)); // unsigned int(7) reserved = 0;
    AVIF_CHECKRES(avifRWStreamFinishBox(dedupStream, colr));
    if (dedup) {
        AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, outputStream, associations, /*essential=*/AVIF_FALSE));
    }
    return AVIF_RESULT_OK;
}

static avifResult avifEncoderWritePaspProperty(avifRWStream * dedupStream,
                                               avifRWStream * outputStream,
                                               const avifImage * imageMetadata,
                                               avifItemPropertyAssociationArray * associations,
                                               avifItemPropertyDedup * dedup);
static avifResult avifEncoderWriteTransformativeProperties(avifRWStream * dedupStream,
                                                           avifRWStream * outputStream,
                                                           const avifImage * imageMetadata,
                                                           avifItemPropertyAssociationArray * associations,
                                                           avifItemPropertyDedup * dedup);

// This function is used in two codepaths:
// * writing color *item* properties
// * writing color *track* properties
//
// Item properties must have property associations with them and can be deduplicated (by reusing
// these associations), so this function leverages the ipma and dedup arguments to do this.
//
// Track properties, however, are implicitly associated by the track in which they are contained, so
// there is no need to build a property association box (ipma), and no way to deduplicate/reuse a
// property. In this case, the ipma and dedup properties should/will be set to NULL, and this
// function will avoid using them.
static avifResult avifEncoderWriteColorProperties(avifRWStream * outputStream,
                                                  const avifImage * imageMetadata,
                                                  avifItemPropertyAssociationArray * associations,
                                                  avifItemPropertyDedup * dedup)
{
    // outputStream is the final bitstream that will be output by the libavif encoder API.
    // dedupStream is either equal to outputStream or to &dedup->s which is a temporary stream used
    // to store parts of the final bitstream; these parts may be discarded if they are a duplicate
    // of an already stored property.
    avifRWStream * dedupStream = outputStream;
    if (dedup) {
        AVIF_ASSERT_OR_RETURN(associations);

        // Use the dedup's temporary stream for box writes.
        dedupStream = &dedup->s;
    }

    if (imageMetadata->icc.size > 0) {
        if (dedup) {
            avifItemPropertyDedupStart(dedup);
        }
        avifBoxMarker colr;
        AVIF_CHECKRES(avifRWStreamWriteBox(dedupStream, "colr", AVIF_BOX_SIZE_TBD, &colr));
        AVIF_CHECKRES(avifRWStreamWriteChars(dedupStream, "prof", 4)); // unsigned int(32) colour_type;
        AVIF_CHECKRES(avifRWStreamWrite(dedupStream, imageMetadata->icc.data, imageMetadata->icc.size));
        AVIF_CHECKRES(avifRWStreamFinishBox(dedupStream, colr));
        if (dedup) {
            AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, outputStream, associations, /*essential=*/AVIF_FALSE));
        }
    }

    // HEIF 6.5.5.1, from Amendment 3 allows multiple colr boxes: "at most one for a given value of colour type"
    // Therefore, *always* writing an nclx box, even if a prof box was already written above.
    AVIF_CHECKRES(avifEncoderWriteNclxProperty(dedupStream, outputStream, imageMetadata, associations, dedup));

    AVIF_CHECKRES(avifEncoderWritePaspProperty(dedupStream, outputStream, imageMetadata, associations, dedup));

    return AVIF_RESULT_OK;
}

static avifResult avifEncoderWriteContentLightLevelInformation(avifRWStream * outputStream,
                                                               const avifContentLightLevelInformationBox * clli)
{
    AVIF_CHECKRES(avifRWStreamWriteBits(outputStream, clli->maxCLL, 16));  // unsigned int(16) max_content_light_level;
    AVIF_CHECKRES(avifRWStreamWriteBits(outputStream, clli->maxPALL, 16)); // unsigned int(16) max_pic_average_light_level;
    return AVIF_RESULT_OK;
}

// Same as 'avifEncoderWriteColorProperties' but for properties related to High Dynamic Range only.
static avifResult avifEncoderWriteHDRProperties(avifRWStream * dedupStream,
                                                avifRWStream * outputStream,
                                                const avifImage * imageMetadata,
                                                avifItemPropertyAssociationArray * associations,
                                                avifItemPropertyDedup * dedup)
{
    // Write Content Light Level Information, if present
    if (imageMetadata->clli.maxCLL || imageMetadata->clli.maxPALL) {
        if (dedup) {
            avifItemPropertyDedupStart(dedup);
        }
        avifBoxMarker clli;
        AVIF_CHECKRES(avifRWStreamWriteBox(dedupStream, "clli", AVIF_BOX_SIZE_TBD, &clli));
        AVIF_CHECKRES(avifEncoderWriteContentLightLevelInformation(dedupStream, &imageMetadata->clli));
        AVIF_CHECKRES(avifRWStreamFinishBox(dedupStream, clli));
        if (dedup) {
            AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, outputStream, associations, /*essential=*/AVIF_FALSE));
        }
    }

    // TODO(maryla): add other HDR boxes: mdcv, cclv, etc. (in avifEncoderWriteMiniHDRProperties() too)

    return AVIF_RESULT_OK;
}

#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
static avifResult avifEncoderWriteMiniHDRProperties(avifRWStream * outputStream, const avifImage * imageMetadata)
{
    const avifBool hasClli = imageMetadata->clli.maxCLL != 0 || imageMetadata->clli.maxPALL != 0;
    const avifBool hasMdcv = AVIF_FALSE;
    const avifBool hasCclv = AVIF_FALSE;
    const avifBool hasAmve = AVIF_FALSE;
    const avifBool hasReve = AVIF_FALSE;
    const avifBool hasNdwt = AVIF_FALSE;
    AVIF_CHECKRES(avifRWStreamWriteBits(outputStream, hasClli, 1)); // bit(1) clli_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(outputStream, hasMdcv, 1)); // bit(1) mdcv_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(outputStream, hasCclv, 1)); // bit(1) cclv_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(outputStream, hasAmve, 1)); // bit(1) amve_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(outputStream, hasReve, 1)); // bit(1) reve_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(outputStream, hasNdwt, 1)); // bit(1) ndwt_flag;

    if (hasClli) {
        // ContentLightLevel clli;
        AVIF_CHECKRES(avifEncoderWriteContentLightLevelInformation(outputStream, &imageMetadata->clli));
    }
    if (hasMdcv) {
        // MasteringDisplayColourVolume mdcv;
    }
    if (hasCclv) {
        // ContentColourVolume cclv;
    }
    if (hasAmve) {
        // AmbientViewingEnvironment amve;
    }
    if (hasReve) {
        // ReferenceViewingEnvironment reve;
    }
    if (hasNdwt) {
        // NominalDiffuseWhite ndwt;
    }
    return AVIF_RESULT_OK;
}
#endif // AVIF_ENABLE_EXPERIMENTAL_MINI

static avifResult avifEncoderWritePaspProperty(avifRWStream * dedupStream,
                                               avifRWStream * outputStream,
                                               const avifImage * imageMetadata,
                                               avifItemPropertyAssociationArray * associations,
                                               avifItemPropertyDedup * dedup)
{
    if (imageMetadata->transformFlags & AVIF_TRANSFORM_PASP) {
        if (dedup) {
            avifItemPropertyDedupStart(dedup);
        }
        avifBoxMarker pasp;
        AVIF_CHECKRES(avifRWStreamWriteBox(dedupStream, "pasp", AVIF_BOX_SIZE_TBD, &pasp));
        AVIF_CHECKRES(avifRWStreamWriteU32(dedupStream, imageMetadata->pasp.hSpacing)); // unsigned int(32) hSpacing;
        AVIF_CHECKRES(avifRWStreamWriteU32(dedupStream, imageMetadata->pasp.vSpacing)); // unsigned int(32) vSpacing;
        AVIF_CHECKRES(avifRWStreamFinishBox(dedupStream, pasp));
        if (dedup) {
            AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, outputStream, associations, /*essential=*/AVIF_FALSE));
        }
    }
    return AVIF_RESULT_OK;
}

static avifResult avifEncoderWriteTransformativeProperties(avifRWStream * dedupStream,
                                                           avifRWStream * outputStream,
                                                           const avifImage * imageMetadata,
                                                           avifItemPropertyAssociationArray * associations,
                                                           avifItemPropertyDedup * dedup)
{
    if (imageMetadata->transformFlags & AVIF_TRANSFORM_CLAP) {
        if (dedup) {
            avifItemPropertyDedupStart(dedup);
        }
        avifBoxMarker clap;
        AVIF_CHECKRES(avifRWStreamWriteBox(dedupStream, "clap", AVIF_BOX_SIZE_TBD, &clap));
        AVIF_CHECKRES(avifRWStreamWriteU32(dedupStream, imageMetadata->clap.widthN));    // unsigned int(32) cleanApertureWidthN;
        AVIF_CHECKRES(avifRWStreamWriteU32(dedupStream, imageMetadata->clap.widthD));    // unsigned int(32) cleanApertureWidthD;
        AVIF_CHECKRES(avifRWStreamWriteU32(dedupStream, imageMetadata->clap.heightN));   // unsigned int(32) cleanApertureHeightN;
        AVIF_CHECKRES(avifRWStreamWriteU32(dedupStream, imageMetadata->clap.heightD));   // unsigned int(32) cleanApertureHeightD;
        AVIF_CHECKRES(avifRWStreamWriteU32(dedupStream, imageMetadata->clap.horizOffN)); // unsigned int(32) horizOffN;
        AVIF_CHECKRES(avifRWStreamWriteU32(dedupStream, imageMetadata->clap.horizOffD)); // unsigned int(32) horizOffD;
        AVIF_CHECKRES(avifRWStreamWriteU32(dedupStream, imageMetadata->clap.vertOffN));  // unsigned int(32) vertOffN;
        AVIF_CHECKRES(avifRWStreamWriteU32(dedupStream, imageMetadata->clap.vertOffD));  // unsigned int(32) vertOffD;
        AVIF_CHECKRES(avifRWStreamFinishBox(dedupStream, clap));
        if (dedup) {
            AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, outputStream, associations, /*essential=*/AVIF_TRUE));
        }
    }
    if (imageMetadata->transformFlags & AVIF_TRANSFORM_IROT) {
        if (dedup) {
            avifItemPropertyDedupStart(dedup);
        }
        avifBoxMarker irot;
        AVIF_CHECKRES(avifRWStreamWriteBox(dedupStream, "irot", AVIF_BOX_SIZE_TBD, &irot));
        AVIF_CHECKRES(avifRWStreamWriteBits(dedupStream, 0, /*bitCount=*/6)); // unsigned int (6) reserved = 0;
        AVIF_CHECKRES(avifRWStreamWriteBits(dedupStream, imageMetadata->irot.angle & 0x3, /*bitCount=*/2)); // unsigned int (2) angle;
        AVIF_CHECKRES(avifRWStreamFinishBox(dedupStream, irot));
        if (dedup) {
            AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, outputStream, associations, /*essential=*/AVIF_TRUE));
        }
    }
    if (imageMetadata->transformFlags & AVIF_TRANSFORM_IMIR) {
        if (dedup) {
            avifItemPropertyDedupStart(dedup);
        }
        avifBoxMarker imir;
        AVIF_CHECKRES(avifRWStreamWriteBox(dedupStream, "imir", AVIF_BOX_SIZE_TBD, &imir));
        AVIF_CHECKRES(avifRWStreamWriteBits(dedupStream, 0, /*bitCount=*/7)); // unsigned int(7) reserved = 0;
        AVIF_CHECKRES(avifRWStreamWriteBits(dedupStream, imageMetadata->imir.axis ? 1 : 0, /*bitCount=*/1)); // unsigned int(1) axis;
        AVIF_CHECKRES(avifRWStreamFinishBox(dedupStream, imir));
        if (dedup) {
            AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, outputStream, associations, /*essential=*/AVIF_TRUE));
        }
    }
    return AVIF_RESULT_OK;
}

static avifResult avifRWStreamWriteHandlerBox(avifRWStream * s, const char handlerType[4])
{
    avifBoxMarker hdlr;
    AVIF_CHECKRES(avifRWStreamWriteFullBox(s, "hdlr", AVIF_BOX_SIZE_TBD, 0, 0, &hdlr));
    AVIF_CHECKRES(avifRWStreamWriteU32(s, 0));                // unsigned int(32) pre_defined = 0;
    AVIF_CHECKRES(avifRWStreamWriteChars(s, handlerType, 4)); // unsigned int(32) handler_type;
    AVIF_CHECKRES(avifRWStreamWriteZeros(s, 12));             // const unsigned int(32)[3] reserved = 0;
    AVIF_CHECKRES(avifRWStreamWriteChars(s, "", 1));          // string name; (writing null terminator)
    AVIF_CHECKRES(avifRWStreamFinishBox(s, hdlr));
    return AVIF_RESULT_OK;
}

// Write unassociated metadata items (EXIF, XMP) to a small meta box inside of a trak box.
// These items are implicitly associated with the track they are contained within.
static avifResult avifEncoderWriteTrackMetaBox(avifEncoder * encoder, avifRWStream * s)
{
    // Count how many non-image items (such as EXIF/XMP) are being written
    uint32_t metadataItemCount = 0;
    avifBool largeItemIDs = AVIF_FALSE; // Are any of the metadata item IDs, or the metadata item count, too large for a 16-bit field?
    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        if (memcmp(item->type, encoder->data->imageItemType, 4) != 0) {
            ++metadataItemCount;
            largeItemIDs |= (item->id > UINT16_MAX);
        }
    }
    // The 'iloc' and 'iinf' variants below are also needed if the metadata item count does not
    // fit in a 16-bit field.
    largeItemIDs |= (metadataItemCount > UINT16_MAX);
    if (metadataItemCount == 0) {
        // Don't even bother writing the trak meta box
        return AVIF_RESULT_OK;
    }

    avifBoxMarker meta;
    AVIF_CHECKRES(avifRWStreamWriteFullBox(s, "meta", AVIF_BOX_SIZE_TBD, 0, 0, &meta));

    AVIF_CHECKRES(avifRWStreamWriteHandlerBox(s, "pict"));

    avifBoxMarker iloc;
    AVIF_CHECKRES(avifRWStreamWriteFullBox(s, "iloc", AVIF_BOX_SIZE_TBD, largeItemIDs ? 2 : 0, 0, &iloc));
    AVIF_CHECKRES(avifRWStreamWriteBits(s, 4, /*bitCount=*/4)); // unsigned int(4) offset_size;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, 4, /*bitCount=*/4)); // unsigned int(4) length_size;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, /*bitCount=*/4)); // unsigned int(4) base_offset_size;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, /*bitCount=*/4)); // unsigned int(4) index_size, or reserved if version < 1;
    if (largeItemIDs) {
        AVIF_CHECKRES(avifRWStreamWriteU32(s, metadataItemCount)); // unsigned int(32) item_count;
    } else {
        AVIF_CHECKRES(avifRWStreamWriteU16(s, (uint16_t)metadataItemCount)); // unsigned int(16) item_count;
    }
    for (uint32_t trakItemIndex = 0; trakItemIndex < encoder->data->items.count; ++trakItemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[trakItemIndex];
        if (memcmp(item->type, encoder->data->imageItemType, 4) == 0) {
            // Skip over all non-metadata items
            continue;
        }

        if (largeItemIDs) {
            AVIF_CHECKRES(avifRWStreamWriteU32(s, item->id));            // unsigned int(32) item_ID;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, /*bitCount=*/12)); // unsigned int(12) reserved = 0;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, /*bitCount=*/4));  // unsigned int(4) construction_method = 0 (file offset);
        } else {
            AVIF_CHECKRES(avifRWStreamWriteU16(s, (uint16_t)item->id)); // unsigned int(16) item_ID;
        }
        AVIF_CHECKRES(avifRWStreamWriteU16(s, 0));                 // unsigned int(16) data_reference_index;
        AVIF_CHECKRES(avifRWStreamWriteU16(s, 1));                 // unsigned int(16) extent_count;
        AVIF_CHECKRES(avifEncoderItemAddMdatFixup(item, s));       //
        AVIF_CHECKRES(avifRWStreamWriteU32(s, 0 /* set later */)); // unsigned int(offset_size*8) extent_offset;
        AVIF_CHECKRES(avifRWStreamWriteU32(s, (uint32_t)item->metadataPayload.size)); // unsigned int(length_size*8) extent_length;
    }
    AVIF_CHECKRES(avifRWStreamFinishBox(s, iloc));

    avifBoxMarker iinf;
    AVIF_CHECKRES(avifRWStreamWriteFullBox(s, "iinf", AVIF_BOX_SIZE_TBD, largeItemIDs ? 1 : 0, 0, &iinf));
    if (largeItemIDs) {
        AVIF_CHECKRES(avifRWStreamWriteU32(s, metadataItemCount)); //  unsigned int(32) entry_count;
    } else {
        AVIF_CHECKRES(avifRWStreamWriteU16(s, (uint16_t)metadataItemCount)); //  unsigned int(16) entry_count;
    }
    for (uint32_t trakItemIndex = 0; trakItemIndex < encoder->data->items.count; ++trakItemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[trakItemIndex];
        if (memcmp(item->type, encoder->data->imageItemType, 4) == 0) {
            continue;
        }

        AVIF_ASSERT_OR_RETURN(!item->hiddenImage);
        avifBoxMarker infe;
        // 'infe' version 3 contains a 32-bit item_ID field, whereas version 2 contains a 16-bit item_ID field.
        AVIF_CHECKRES(avifRWStreamWriteFullBox(s, "infe", AVIF_BOX_SIZE_TBD, largeItemIDs ? 3 : 2, 0, &infe));
        if (largeItemIDs) {
            AVIF_CHECKRES(avifRWStreamWriteU32(s, item->id)); // unsigned int(32) item_ID;
        } else {
            AVIF_CHECKRES(avifRWStreamWriteU16(s, (uint16_t)item->id)); // unsigned int(16) item_ID;
        }
        AVIF_CHECKRES(avifRWStreamWriteU16(s, 0));                                    // unsigned int(16) item_protection_index;
        AVIF_CHECKRES(avifRWStreamWrite(s, item->type, 4));                           // unsigned int(32) item_type;
        AVIF_CHECKRES(avifRWStreamWriteChars(s, item->infeName, item->infeNameSize)); // string item_name; (writing null terminator)
        if (item->infeContentType && item->infeContentTypeSize) { // string content_type; (writing null terminator)
            AVIF_CHECKRES(avifRWStreamWriteChars(s, item->infeContentType, item->infeContentTypeSize));
        }
        AVIF_CHECKRES(avifRWStreamFinishBox(s, infe));
    }
    AVIF_CHECKRES(avifRWStreamFinishBox(s, iinf));

    AVIF_CHECKRES(avifRWStreamFinishBox(s, meta));
    return AVIF_RESULT_OK;
}

static avifResult avifWriteGridPayload(avifRWData * data, uint32_t gridCols, uint32_t gridRows, uint32_t gridWidth, uint32_t gridHeight)
{
    // ISO/IEC 23008-12 6.6.2.3.2
    // aligned(8) class ImageGrid {
    //     unsigned int(8) version = 0;
    //     unsigned int(8) flags;
    //     FieldLength = ((flags & 1) + 1) * 16;
    //     unsigned int(8) rows_minus_one;
    //     unsigned int(8) columns_minus_one;
    //     unsigned int(FieldLength) output_width;
    //     unsigned int(FieldLength) output_height;
    // }

    uint8_t gridFlags = ((gridWidth > 65535) || (gridHeight > 65535)) ? 1 : 0;

    avifRWStream s;
    avifRWStreamStart(&s, data);
    AVIF_CHECKRES(avifRWStreamWriteU8(&s, 0));                       // unsigned int(8) version = 0;
    AVIF_CHECKRES(avifRWStreamWriteU8(&s, gridFlags));               // unsigned int(8) flags;
    AVIF_CHECKRES(avifRWStreamWriteU8(&s, (uint8_t)(gridRows - 1))); // unsigned int(8) rows_minus_one;
    AVIF_CHECKRES(avifRWStreamWriteU8(&s, (uint8_t)(gridCols - 1))); // unsigned int(8) columns_minus_one;
    if (gridFlags & 1) {
        AVIF_CHECKRES(avifRWStreamWriteU32(&s, gridWidth));  // unsigned int(FieldLength) output_width;
        AVIF_CHECKRES(avifRWStreamWriteU32(&s, gridHeight)); // unsigned int(FieldLength) output_height;
    } else {
        uint16_t tmpWidth = (uint16_t)gridWidth;
        uint16_t tmpHeight = (uint16_t)gridHeight;
        AVIF_CHECKRES(avifRWStreamWriteU16(&s, tmpWidth));  // unsigned int(FieldLength) output_width;
        AVIF_CHECKRES(avifRWStreamWriteU16(&s, tmpHeight)); // unsigned int(FieldLength) output_height;
    }
    avifRWStreamFinishWrite(&s);
    return AVIF_RESULT_OK;
}

static avifBool avifGainMapIdenticalChannels(const avifGainMap * gainMap)
{
    return gainMap->gainMapMin[0].n == gainMap->gainMapMin[1].n && gainMap->gainMapMin[0].n == gainMap->gainMapMin[2].n &&
           gainMap->gainMapMin[0].d == gainMap->gainMapMin[1].d && gainMap->gainMapMin[0].d == gainMap->gainMapMin[2].d &&
           gainMap->gainMapMax[0].n == gainMap->gainMapMax[1].n && gainMap->gainMapMax[0].n == gainMap->gainMapMax[2].n &&
           gainMap->gainMapMax[0].d == gainMap->gainMapMax[1].d && gainMap->gainMapMax[0].d == gainMap->gainMapMax[2].d &&
           gainMap->gainMapGamma[0].n == gainMap->gainMapGamma[1].n && gainMap->gainMapGamma[0].n == gainMap->gainMapGamma[2].n &&
           gainMap->gainMapGamma[0].d == gainMap->gainMapGamma[1].d && gainMap->gainMapGamma[0].d == gainMap->gainMapGamma[2].d &&
           gainMap->baseOffset[0].n == gainMap->baseOffset[1].n && gainMap->baseOffset[0].n == gainMap->baseOffset[2].n &&
           gainMap->baseOffset[0].d == gainMap->baseOffset[1].d && gainMap->baseOffset[0].d == gainMap->baseOffset[2].d &&
           gainMap->alternateOffset[0].n == gainMap->alternateOffset[1].n &&
           gainMap->alternateOffset[0].n == gainMap->alternateOffset[2].n &&
           gainMap->alternateOffset[0].d == gainMap->alternateOffset[1].d &&
           gainMap->alternateOffset[0].d == gainMap->alternateOffset[2].d;
}

// Returns the number of bytes written by avifWriteGainmapMetadata().
static uint32_t avifGainMapMetadataSize(const avifGainMap * gainMap)
{
    const uint8_t channelCount = avifGainMapIdenticalChannels(gainMap) ? 1u : 3u;
    return (uint32_t)(sizeof(uint16_t) * 2 + sizeof(uint8_t) + sizeof(uint32_t) * 4 + channelCount * sizeof(uint32_t) * 10);
}

static avifResult avifWriteGainmapMetadata(avifRWStream * s, const avifGainMap * gainMap, avifDiagnostics * diag)
{
    AVIF_CHECKRES(avifGainMapValidateMetadata(gainMap, diag));
    const size_t offset = avifRWStreamOffset(s);

    // GainMapMetadata syntax as per clause C.2.2 of ISO 21496-1:

    // GainMapVersion syntax as per clause C.2.2 of ISO 21496-1:
    const uint16_t minimumVersion = 0;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, minimumVersion, 16)); // unsigned int(16) minimum_version;
    const uint16_t writerVersion = 0;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, writerVersion, 16)); // unsigned int(16) writer_version;

    if (minimumVersion == 0) {
        const uint8_t channelCount = avifGainMapIdenticalChannels(gainMap) ? 1u : 3u;
        AVIF_CHECKRES(avifRWStreamWriteBits(s, channelCount == 3, 1));          // unsigned int(1) is_multichannel;
        AVIF_CHECKRES(avifRWStreamWriteBits(s, gainMap->useBaseColorSpace, 1)); // unsigned int(1) use_base_colour_space;
        AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, 6));                          // unsigned int(6) reserved;

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

        // GainMapChannel channels[channel_count];
        for (int c = 0; c < channelCount; ++c) {
            // GainMapChannel syntax as per clause C.2.2 of ISO 21496-1:
            AVIF_CHECKRES(avifRWStreamWriteBits(s, (uint32_t)gainMap->gainMapMin[c].n, 32)); // int(32) gain_map_min_numerator;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainMap->gainMapMin[c].d, 32)); // unsigned int(32) gain_map_min_denominator;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, (uint32_t)gainMap->gainMapMax[c].n, 32)); // int(32) gain_map_max_numerator;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainMap->gainMapMax[c].d, 32));   // unsigned int(32) gain_map_max_denominator;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainMap->gainMapGamma[c].n, 32)); // unsigned int(32) gamma_numerator;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainMap->gainMapGamma[c].d, 32)); // unsigned int(32) gamma_denominator;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, (uint32_t)gainMap->baseOffset[c].n, 32)); // int(32) base_offset_numerator;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainMap->baseOffset[c].d, 32)); // unsigned int(32) base_offset_denominator;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, (uint32_t)gainMap->alternateOffset[c].n, 32)); // int(32) alternate_offset_numerator;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainMap->alternateOffset[c].d, 32)); // unsigned int(32) alternate_offset_denominator;
        }
    }

    AVIF_ASSERT_OR_RETURN(avifRWStreamOffset(s) == offset + avifGainMapMetadataSize(gainMap));
    return AVIF_RESULT_OK;
}

static avifResult avifWriteToneMappedImagePayload(avifRWData * data, const avifGainMap * gainMap, avifDiagnostics * diag)
{
    avifRWStream s;
    avifRWStreamStart(&s, data);
    // ToneMapImage syntax as per section 6.6.2.4.2 of ISO/IEC 23008-12:2024
    // amendment "Support for tone map derived image items and other improvements":
    const uint8_t version = 0;
    AVIF_CHECKRES(avifRWStreamWriteU8(&s, version)); // unsigned int(8) version = 0;
    if (version == 0) {
        AVIF_CHECKRES(avifWriteGainmapMetadata(&s, gainMap, diag)); // GainMapMetadata;
    }
    avifRWStreamFinishWrite(&s);
    return AVIF_RESULT_OK;
}

size_t avifEncoderGetGainMapSizeBytes(avifEncoder * encoder)
{
    return encoder->data->gainMapSizeBytes;
}

// Sets altImageMetadata's metadata values to represent the "alternate" image as if applying the gain map to the base image.
// For grid images, imageWithGainMap is the metadata of the first cell. gridWidth and gridHeight are the dimensions of the
// full image.
static avifResult avifImageCopyAltImageMetadata(avifImage * altImageMetadata, const avifImage * imageWithGainMap, uint32_t gridWidth, uint32_t gridHeight)
{
    altImageMetadata->width = gridWidth;
    altImageMetadata->height = gridHeight;
    AVIF_CHECKRES(avifRWDataSet(&altImageMetadata->icc, imageWithGainMap->gainMap->altICC.data, imageWithGainMap->gainMap->altICC.size));
    altImageMetadata->colorPrimaries = imageWithGainMap->gainMap->altColorPrimaries;
    altImageMetadata->transferCharacteristics = imageWithGainMap->gainMap->altTransferCharacteristics;
    altImageMetadata->matrixCoefficients = imageWithGainMap->gainMap->altMatrixCoefficients;
    altImageMetadata->yuvRange = imageWithGainMap->gainMap->altYUVRange;
    altImageMetadata->depth = imageWithGainMap->gainMap->altDepth
                                  ? imageWithGainMap->gainMap->altDepth
                                  : AVIF_MAX(imageWithGainMap->depth, imageWithGainMap->gainMap->image->depth);
    altImageMetadata->yuvFormat = (imageWithGainMap->gainMap->altPlaneCount == 1) ? AVIF_PIXEL_FORMAT_YUV400 : AVIF_PIXEL_FORMAT_YUV444;
    altImageMetadata->clli = imageWithGainMap->gainMap->altCLLI;
    return AVIF_RESULT_OK;
}

static avifResult avifEncoderWriteSampleTransformTokens(avifRWStream * s, const avifSampleTransformExpression * expression)
{
    AVIF_ASSERT_OR_RETURN(expression->count <= 255);
    AVIF_CHECKRES(avifRWStreamWriteU8(s, (uint8_t)expression->count)); // unsigned int(8) token_count;

    for (uint32_t t = 0; t < expression->count; ++t) {
        const avifSampleTransformToken * token = &expression->tokens[t];

        if (token->type == AVIF_SAMPLE_TRANSFORM_CONSTANT) {
            AVIF_CHECKRES(avifRWStreamWriteU8(s, token->type)); // unsigned int(8) token;
            const uint32_t constant = (uint32_t)token->constant;
            AVIF_CHECKRES(avifRWStreamWriteU32(s, constant)); // signed int(1<<(bit_depth+3)) constant;
        } else if (token->type == AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX) {
            AVIF_CHECKRES(avifRWStreamWriteU8(s, token->inputImageItemIndex)); // unsigned int(8) token;
        } else {
            // Operator.
            AVIF_CHECKRES(avifRWStreamWriteU8(s, token->type)); // unsigned int(8) token;
        }
    }
    return AVIF_RESULT_OK;
}

static avifResult avifEncoderWriteSampleTransformPayload(avifEncoder * encoder, avifRWData * data)
{
    avifRWStream s;
    avifRWStreamStart(&s, data);
    AVIF_CHECKRES(avifRWStreamWriteBits(&s, 0, /*bitCount=*/2)); // unsigned int(2) version = 0;
    AVIF_CHECKRES(avifRWStreamWriteBits(&s, 0, /*bitCount=*/4)); // unsigned int(4) reserved;
    // AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_32 is necessary because the two input images
    // once combined use 16-bit unsigned values, but intermediate results are stored in signed integers.
    AVIF_CHECKRES(avifRWStreamWriteBits(&s, AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_32, /*bitCount=*/2)); // unsigned int(2) bit_depth;

    avifSampleTransformExpression expression = { 0 };
    AVIF_CHECKRES(avifSampleTransformRecipeToExpression(encoder->sampleTransformRecipe, &expression));
    const avifResult result = avifEncoderWriteSampleTransformTokens(&s, &expression);
    avifArrayDestroy(&expression);
    if (result != AVIF_RESULT_OK) {
        avifDiagnosticsPrintf(&encoder->diag, "Failed to write sample transform metadata for recipe %d", (int)encoder->sampleTransformRecipe);
        return result;
    }

    avifRWStreamFinishWrite(&s);
    return AVIF_RESULT_OK;
}

static avifResult avifEncoderDataCreateExifItem(avifEncoderData * data, const avifRWData * exif)
{
    size_t exifTiffHeaderOffset;
    const avifResult result = avifGetExifTiffHeaderOffset(exif->data, exif->size, &exifTiffHeaderOffset);
    if (result != AVIF_RESULT_OK) {
        // Couldn't find the TIFF header
        return result;
    }

    avifEncoderItem * exifItem;
    AVIF_CHECKRES(avifEncoderDataCreateItem(data, "Exif", "Exif", 5, 0, &exifItem));
    exifItem->irefToID = data->primaryItemID;
    exifItem->irefType = "cdsc";

    const uint32_t offset32bit = avifHTONL((uint32_t)exifTiffHeaderOffset);
    AVIF_CHECKRES(avifRWDataRealloc(&exifItem->metadataPayload, sizeof(offset32bit) + exif->size));
    memcpy(exifItem->metadataPayload.data, &offset32bit, sizeof(offset32bit));
    memcpy(exifItem->metadataPayload.data + sizeof(offset32bit), exif->data, exif->size);
    return AVIF_RESULT_OK;
}

static avifResult avifEncoderDataCreateXMPItem(avifEncoderData * data, const avifRWData * xmp)
{
    avifEncoderItem * xmpItem;
    AVIF_CHECKRES(avifEncoderDataCreateItem(data, "mime", "XMP", 4, 0, &xmpItem));
    xmpItem->irefToID = data->primaryItemID;
    xmpItem->irefType = "cdsc";

    xmpItem->infeContentType = xmpContentType;
    xmpItem->infeContentTypeSize = xmpContentTypeSize;
    AVIF_CHECKRES(avifRWDataSet(&xmpItem->metadataPayload, xmp->data, xmp->size));
    return AVIF_RESULT_OK;
}

// Same as avifImageCopy() but pads the dstImage with border pixel values to reach dstWidth and dstHeight.
static avifResult avifImageCopyAndPad(avifImage * const dstImage, const avifImage * srcImage, uint32_t dstWidth, uint32_t dstHeight)
{
    AVIF_ASSERT_OR_RETURN(dstImage);
    AVIF_ASSERT_OR_RETURN(!dstImage->width && !dstImage->height); // dstImage is not set yet.
    AVIF_ASSERT_OR_RETURN(dstWidth >= srcImage->width);
    AVIF_ASSERT_OR_RETURN(dstHeight >= srcImage->height);

    // Copy all fields but do not allocate the planes.
    AVIF_CHECKRES(avifImageCopy(dstImage, srcImage, (avifPlanesFlag)0));
    dstImage->width = dstWidth;
    dstImage->height = dstHeight;

    if (srcImage->yuvPlanes[AVIF_CHAN_Y]) {
        AVIF_CHECKRES(avifImageAllocatePlanes(dstImage, AVIF_PLANES_YUV));
    }
    if (srcImage->alphaPlane) {
        AVIF_CHECKRES(avifImageAllocatePlanes(dstImage, AVIF_PLANES_A));
    }
    const avifBool usesU16 = avifImageUsesU16(srcImage);
    for (int plane = AVIF_CHAN_Y; plane <= AVIF_CHAN_A; ++plane) {
        const uint8_t * srcRow = avifImagePlane(srcImage, plane);
        const uint32_t srcRowBytes = avifImagePlaneRowBytes(srcImage, plane);
        const uint32_t srcPlaneWidth = avifImagePlaneWidth(srcImage, plane);
        const uint32_t srcPlaneHeight = avifImagePlaneHeight(srcImage, plane); // 0 for A if no alpha and 0 for UV if 4:0:0.
        const size_t srcPlaneWidthBytes = (size_t)srcPlaneWidth << usesU16;

        uint8_t * dstRow = avifImagePlane(dstImage, plane);
        const uint32_t dstRowBytes = avifImagePlaneRowBytes(dstImage, plane);
        const uint32_t dstPlaneWidth = avifImagePlaneWidth(dstImage, plane);
        const uint32_t dstPlaneHeight = avifImagePlaneHeight(dstImage, plane); // 0 for A if no alpha and 0 for UV if 4:0:0.
        const size_t dstPlaneWidthBytes = (size_t)dstPlaneWidth << usesU16;

        for (uint32_t j = 0; j < srcPlaneHeight; ++j) {
            memcpy(dstRow, srcRow, srcPlaneWidthBytes);

            // Pad columns.
            if (dstPlaneWidth > srcPlaneWidth) {
                if (usesU16) {
                    uint16_t * dstRow16 = (uint16_t *)dstRow;
                    for (uint32_t x = srcPlaneWidth; x < dstPlaneWidth; ++x) {
                        dstRow16[x] = dstRow16[srcPlaneWidth - 1];
                    }
                } else {
                    memset(&dstRow[srcPlaneWidth], dstRow[srcPlaneWidth - 1], dstPlaneWidth - srcPlaneWidth);
                }
            }
            srcRow += srcRowBytes;
            dstRow += dstRowBytes;
        }

        // Pad rows.
        for (uint32_t j = srcPlaneHeight; j < dstPlaneHeight; ++j) {
            memcpy(dstRow, dstRow - dstRowBytes, dstPlaneWidthBytes);
            dstRow += dstRowBytes;
        }
    }
    return AVIF_RESULT_OK;
}

static int avifGetQuality(int quality, int minQuantizer, int maxQuantizer)
{
    int quantizer;

    if (quality == AVIF_QUALITY_DEFAULT) {
        // In older libavif releases, avifEncoder didn't have the quality and qualityAlpha fields.
        // Supply a default value for quality.
        quantizer = (minQuantizer + maxQuantizer) / 2;
        quantizer = AVIF_CLAMP(quantizer, 0, 63);
        quality = ((63 - quantizer) * 100 + 31) / 63;
    } else {
        quality = AVIF_CLAMP(quality, 0, 100);
    }

    return quality;
}

static const char infeNameColor[] = "Color";
static const char infeNameAlpha[] = "Alpha";
static const char infeNameGainMap[] = "GMap";
static const char infeNameSampleTransform[] = "SampleTransform";

static const char * getInfeName(avifItemCategory itemCategory)
{
    if (avifIsAlpha(itemCategory)) {
        return infeNameAlpha;
    }
    if (itemCategory == AVIF_ITEM_GAIN_MAP) {
        return infeNameGainMap;
    }
    if (itemCategory >= AVIF_SAMPLE_TRANSFORM_MIN_CATEGORY && itemCategory <= AVIF_SAMPLE_TRANSFORM_MAX_CATEGORY) {
        return infeNameSampleTransform;
    }
    return infeNameColor;
}

// Adds the items for a single cell or a grid of cells. Outputs the topLevelItemID which is
// the only item if there is exactly one cell, or the grid item for multiple cells.
// Note: The topLevelItemID output argument has the type uint32_t* instead of avifEncoderItem** because
//       the avifEncoderItem pointer may be invalidated by a call to avifEncoderDataCreateItem().
static avifResult avifEncoderAddImageItems(avifEncoder * encoder,
                                           uint32_t gridCols,
                                           uint32_t gridRows,
                                           uint32_t gridWidth,
                                           uint32_t gridHeight,
                                           avifItemCategory itemCategory,
                                           uint32_t * topLevelItemID)
{
    const uint32_t cellCount = gridCols * gridRows;
    const char * infeName = getInfeName(itemCategory);
    const size_t infeNameSize = strlen(infeName) + 1;

    if (cellCount > 1) {
        avifEncoderItem * gridItem;
        AVIF_CHECKRES(avifEncoderDataCreateItem(encoder->data, "grid", infeName, infeNameSize, 0, &gridItem));
        AVIF_CHECKRES(avifWriteGridPayload(&gridItem->metadataPayload, gridCols, gridRows, gridWidth, gridHeight));
        gridItem->itemCategory = itemCategory;
        gridItem->gridCols = gridCols;
        gridItem->gridRows = gridRows;
        gridItem->gridWidth = gridWidth;
        gridItem->gridHeight = gridHeight;
        *topLevelItemID = gridItem->id;
    }

    for (uint32_t cellIndex = 0; cellIndex < cellCount; ++cellIndex) {
        avifEncoderItem * item;
        AVIF_CHECKRES(avifEncoderDataCreateItem(encoder->data, encoder->data->imageItemType, infeName, infeNameSize, cellIndex, &item));
        AVIF_CHECKRES(avifCodecCreate(encoder->codecChoice, AVIF_CODEC_FLAG_CAN_ENCODE, &item->codec));
        item->codec->csOptions = encoder->csOptions;
        item->codec->diag = &encoder->diag;
        item->itemCategory = itemCategory;
        item->extraLayerCount = encoder->extraLayerCount;

        if (cellCount > 1) {
            item->dimgFromID = *topLevelItemID;
            item->hiddenImage = AVIF_TRUE;
        } else {
            *topLevelItemID = item->id;
        }
    }
    return AVIF_RESULT_OK;
}

static avifResult avifEncoderCreateBitDepthExtensionItems(avifEncoder * encoder,
                                                          uint32_t gridCols,
                                                          uint32_t gridRows,
                                                          uint32_t gridWidth,
                                                          uint32_t gridHeight,
                                                          uint32_t colorItemID)
{
    AVIF_ASSERT_OR_RETURN(encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_8B_8B ||
                          encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_4B ||
                          encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_8B_OVERLAP_4B);

    // There are multiple possible ISOBMFF box hierarchies for translucent images,
    // using 'sato' (Sample Transform) derived image items:
    //  - a primary 'sato' item uses a main color coded item and a hidden color coded item; each color coded
    //    item has an auxiliary alpha coded item; the main color coded item and the 'sato' item are in
    //    an 'altr' group (backward-compatible, implemented)
    //  - a primary 'sato' item uses a main color coded item and a hidden color coded item; the primary
    //    'sato' item has an auxiliary alpha 'sato' item using two alpha coded items (backward-incompatible)
    // Likewise, there are multiple possible ISOBMFF box hierarchies for bit-depth-extended grids,
    // using 'sato' (Sample Transform) derived image items:
    //  - a primary color 'grid', an auxiliary alpha 'grid', a hidden color 'grid', a hidden auxiliary alpha 'grid'
    //    and a 'sato' using the two color 'grid's as input items in this order; the primary color item
    //    and the 'sato' item being in an 'altr' group (backward-compatible, implemented)
    //  - a primary 'grid' of 'sato' cells and an auxiliary alpha 'grid' of 'sato' cells (backward-incompatible)
    avifEncoderItem * sampleTransformItem;
    AVIF_CHECKRES(avifEncoderDataCreateItem(encoder->data,
                                            "sato",
                                            infeNameSampleTransform,
                                            /*infeNameSize=*/strlen(infeNameSampleTransform) + 1,
                                            /*cellIndex=*/0,
                                            &sampleTransformItem));
    AVIF_CHECKRES(avifEncoderWriteSampleTransformPayload(encoder, &sampleTransformItem->metadataPayload));
    sampleTransformItem->itemCategory = AVIF_ITEM_SAMPLE_TRANSFORM;
    uint32_t sampleTransformItemID = sampleTransformItem->id;
    // 'altr' group
    AVIF_ASSERT_OR_RETURN(encoder->data->alternativeItemIDs.count == 0);
    uint32_t * alternativeItemID = (uint32_t *)avifArrayPush(&encoder->data->alternativeItemIDs);
    AVIF_CHECKERR(alternativeItemID != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    *alternativeItemID = sampleTransformItem->id;
    alternativeItemID = (uint32_t *)avifArrayPush(&encoder->data->alternativeItemIDs);
    AVIF_CHECKERR(alternativeItemID != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    *alternativeItemID = colorItemID;

    uint32_t bitDepthExtensionColorItemId;
    AVIF_CHECKRES(
        avifEncoderAddImageItems(encoder, gridCols, gridRows, gridWidth, gridHeight, AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_COLOR, &bitDepthExtensionColorItemId));
    avifEncoderItem * bitDepthExtensionColorItem = avifEncoderDataFindItemByID(encoder->data, bitDepthExtensionColorItemId);
    assert(bitDepthExtensionColorItem);
    bitDepthExtensionColorItem->hiddenImage = AVIF_TRUE;

    // Set the color and bit depth extension items' dimgFromID value to point to the sample transform item.
    // The color item shall be first, and the bit depth extension item second. avifEncoderFinish() writes the
    // dimg item references in item id order, so as long as colorItemID < bitDepthExtensionColorItemId, the order
    // will be correct.
    AVIF_ASSERT_OR_RETURN(colorItemID < bitDepthExtensionColorItemId);
    avifEncoderItem * colorItem = avifEncoderDataFindItemByID(encoder->data, colorItemID);
    AVIF_ASSERT_OR_RETURN(colorItem != NULL);
    AVIF_ASSERT_OR_RETURN(colorItem->dimgFromID == 0); // The internal API only allows one dimg value per item.
    colorItem->dimgFromID = sampleTransformItemID;
    bitDepthExtensionColorItem->dimgFromID = sampleTransformItemID;

    if (encoder->data->alphaPresent) {
        uint32_t bitDepthExtensionAlphaItemId;
        AVIF_CHECKRES(
            avifEncoderAddImageItems(encoder, gridCols, gridRows, gridWidth, gridHeight, AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_ALPHA, &bitDepthExtensionAlphaItemId));
        avifEncoderItem * bitDepthExtensionAlphaItem = avifEncoderDataFindItemByID(encoder->data, bitDepthExtensionAlphaItemId);
        assert(bitDepthExtensionAlphaItem);
        bitDepthExtensionAlphaItem->irefType = "auxl";
        bitDepthExtensionAlphaItem->irefToID = bitDepthExtensionColorItemId;
        if (encoder->data->imageMetadata->alphaPremultiplied) {
            // The reference may have changed; fetch it again.
            bitDepthExtensionColorItem = avifEncoderDataFindItemByID(encoder->data, bitDepthExtensionColorItemId);
            assert(bitDepthExtensionColorItem);
            bitDepthExtensionColorItem->irefType = "prem";
            bitDepthExtensionColorItem->irefToID = bitDepthExtensionAlphaItemId;
        }
    }
    return AVIF_RESULT_OK;
}

// Same as avifImageApplyExpression() but for the expression (inputImageItem [op] constant).
// Convenience function.
static avifResult avifImageApplyImgOpConst(avifImage * result,
                                           const avifImage * inputImageItem,
                                           avifSampleTransformTokenType op,
                                           int32_t constant,
                                           avifPlanesFlags planes)
{
    // Postfix notation.
    const avifSampleTransformToken tokens[] = { { AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX, 0, /*inputImageItemIndex=*/1 },
                                                { AVIF_SAMPLE_TRANSFORM_CONSTANT, constant, 0 },
                                                { (uint8_t)op, 0, 0 } };
    return avifImageApplyOperations(result, AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_32, /*numTokens=*/3, tokens, /*numInputImageItems=*/1, &inputImageItem, planes);
}

static avifResult avifImageCreateAllocate(avifImage ** sampleTransformedImage, const avifImage * reference, uint32_t numBits, avifPlanesFlag planes)
{
    *sampleTransformedImage = avifImageCreate(reference->width, reference->height, numBits, reference->yuvFormat);
    AVIF_CHECKERR(*sampleTransformedImage != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    return avifImageAllocatePlanes(*sampleTransformedImage, planes);
}

// Finds the encoded base image and decodes it. Callers of this function must free
// *codec and *decodedBaseImage if not null, whether the function succeeds or not.
static avifResult avifEncoderDecodeSatoBaseImage(avifEncoder * encoder,
                                                 uint32_t cellIndex,
                                                 const avifImage * original,
                                                 uint32_t numBits,
                                                 avifPlanesFlag planes,
                                                 avifCodec ** codec,
                                                 avifImage ** decodedBaseImage)
{
    avifDecodeSample sample;
    memset(&sample, 0, sizeof(sample));
    sample.spatialID = AVIF_SPATIAL_ID_UNSET;

    // Find the encoded bytes of the base image item.
    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        if (item->codec == NULL) {
            continue; // Non-image item such as metadata.
        }
        if ((item->itemCategory != AVIF_ITEM_COLOR || planes != AVIF_PLANES_YUV) &&
            (item->itemCategory != AVIF_ITEM_ALPHA || planes != AVIF_PLANES_A)) {
            continue;
        }
        if (item->cellIndex != cellIndex) {
            continue;
        }

        AVIF_ASSERT_OR_RETURN(item->encodeOutput != NULL);
        AVIF_ASSERT_OR_RETURN(item->encodeOutput->samples.count == 1);
        AVIF_ASSERT_OR_RETURN(item->encodeOutput->samples.sample[0].data.size != 0);
        AVIF_ASSERT_OR_RETURN(sample.data.size == 0); // There should be only one base item.
        sample.data.data = item->encodeOutput->samples.sample[0].data.data;
        sample.data.size = item->encodeOutput->samples.sample[0].data.size;
    }
    AVIF_ASSERT_OR_RETURN(sample.data.size != 0); // There should be at least one base item.

    AVIF_CHECKRES(avifCodecCreate(AVIF_CODEC_CHOICE_AUTO, AVIF_CODEC_FLAG_CAN_DECODE, codec));
    (*codec)->diag = &encoder->diag;
    (*codec)->maxThreads = encoder->maxThreads;
    (*codec)->imageSizeLimit = AVIF_DEFAULT_IMAGE_SIZE_LIMIT;
    (*codec)->imageDimensionLimit = AVIF_DEFAULT_IMAGE_DIMENSION_LIMIT;
    AVIF_CHECKRES(avifImageCreateAllocate(decodedBaseImage, original, numBits, planes));
    avifBool isLimitedRangeAlpha = AVIF_FALSE; // Ignored.
    AVIF_CHECKERR((*codec)->getNextImage(*codec, &sample, planes == AVIF_PLANES_A, &isLimitedRangeAlpha, *decodedBaseImage),
                  AVIF_RESULT_ENCODE_SAMPLE_TRANSFORM_FAILED);
    return AVIF_RESULT_OK;
}

static avifResult avifEncoderCreateSatoImage(avifEncoder * encoder,
                                             const avifEncoderItem * item,
                                             avifBool itemWillBeEncodedLosslessly,
                                             const avifImage * image,
                                             avifImage ** sampleTransformedImage)
{
    const avifPlanesFlag planes = avifIsAlpha(item->itemCategory) ? AVIF_PLANES_A : AVIF_PLANES_YUV;
    // The first image item used as input to the 'sato' Sample Transform derived image item.
    avifBool isBase = item->itemCategory == AVIF_ITEM_COLOR || item->itemCategory == AVIF_ITEM_ALPHA;
    if (!isBase) {
        // The second image item used as input to the 'sato' Sample Transform derived image item.
        AVIF_ASSERT_OR_RETURN(item->itemCategory >= AVIF_SAMPLE_TRANSFORM_MIN_CATEGORY &&
                              item->itemCategory <= AVIF_SAMPLE_TRANSFORM_MAX_CATEGORY);
    }

    if (encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_8B_8B) {
        if (isBase) {
            AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 8, planes));
            AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_QUOTIENT, 256, planes));
        } else {
            AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 8, planes));
            AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_AND, 255, planes));
        }
    } else if (encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_4B) {
        if (isBase) {
            AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 12, planes));
            AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_QUOTIENT, 16, planes));
        } else {
            AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 8, planes));
            AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_AND, 15, planes));
            // AVIF only supports 8, 10 or 12-bit image items. Scale the samples to fit the range.
            // Note: The samples could be encoded as is without being shifted left before encoding,
            //       but they would not be shifted right after decoding either. Right shifting after
            //       decoding provides a guarantee on the range of values and on the lack of integer
            //       overflow, so it is safer to do these extra steps.
            //       It also makes more sense from a compression point-of-view to use the full range.
            // Transform in-place.
            AVIF_CHECKRES(
                avifImageApplyImgOpConst(*sampleTransformedImage, *sampleTransformedImage, AVIF_SAMPLE_TRANSFORM_PRODUCT, 16, planes));
            if (!itemWillBeEncodedLosslessly) {
                // Small loss at encoding could be amplified by the truncation caused by the right
                // shift after decoding. Offset sample values now, before encoding, to round rather
                // than floor the samples shifted after decoding.
                // Note: Samples were just left shifted by numShiftedBits, so adding less than
                //       (1<<numShiftedBits) will not trigger any integer overflow.
                // Transform in-place.
                AVIF_CHECKRES(
                    avifImageApplyImgOpConst(*sampleTransformedImage, *sampleTransformedImage, AVIF_SAMPLE_TRANSFORM_SUM, 7, planes));
            }
        }
    } else {
        AVIF_CHECKERR(encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_8B_OVERLAP_4B,
                      AVIF_RESULT_NOT_IMPLEMENTED);
        if (isBase) {
            AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 12, planes));
            AVIF_CHECKRES(avifImageApplyImgOpConst(*sampleTransformedImage, image, AVIF_SAMPLE_TRANSFORM_QUOTIENT, 16, planes));
        } else {
            AVIF_CHECKRES(avifImageCreateAllocate(sampleTransformedImage, image, 8, planes));
            avifCodec * codec = NULL;
            avifImage * decodedBaseImage = NULL;
            avifResult result = avifEncoderDecodeSatoBaseImage(encoder, item->cellIndex, image, 12, planes, &codec, &decodedBaseImage);
            if (result == AVIF_RESULT_OK) {
                // decoded = main*16+hidden-128 so hidden = clamp_8b(original-main*16+128). Postfix notation.
                const avifSampleTransformToken tokens[] = { { AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX, 0, /*inputImageItemIndex=*/1 },
                                                            { AVIF_SAMPLE_TRANSFORM_INPUT_IMAGE_ITEM_INDEX, 0, /*inputImageItemIndex=*/2 },
                                                            { AVIF_SAMPLE_TRANSFORM_CONSTANT, /*constant=*/16, 0 },
                                                            { AVIF_SAMPLE_TRANSFORM_PRODUCT, 0, 0 },
                                                            { AVIF_SAMPLE_TRANSFORM_DIFFERENCE, 0, 0 },
                                                            { AVIF_SAMPLE_TRANSFORM_CONSTANT, /*constant=*/128, 0 },
                                                            { AVIF_SAMPLE_TRANSFORM_SUM, 0, 0 } };
                // image is "original" (index 1) and decodedBaseImage is "main" (index 2) in the formula above.
                const avifImage * inputImageItems[] = { image, decodedBaseImage };
                result = avifImageApplyOperations(*sampleTransformedImage,
                                                  AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_32,
                                                  /*numTokens=*/7,
                                                  tokens,
                                                  /*numInputImageItems=*/2,
                                                  inputImageItems,
                                                  planes);
            }
            if (decodedBaseImage) {
                avifImageDestroy(decodedBaseImage);
            }
            if (codec) {
                avifCodecDestroy(codec);
            }
            AVIF_CHECKRES(result);
        }
    }
    return AVIF_RESULT_OK;
}

static avifResult avifEncoderCreateBitDepthExtensionImage(avifEncoder * encoder,
                                                          const avifEncoderItem * item,
                                                          avifBool itemWillBeEncodedLosslessly,
                                                          const avifImage * image,
                                                          avifImage ** sampleTransformedImage)
{
    AVIF_ASSERT_OR_RETURN(image->depth == 16); // Other bit depths could be supported but for now it is 16-bit only.
    *sampleTransformedImage = NULL;
    const avifResult result = avifEncoderCreateSatoImage(encoder, item, itemWillBeEncodedLosslessly, image, sampleTransformedImage);
    if (result != AVIF_RESULT_OK && *sampleTransformedImage != NULL) {
        avifImageDestroy(*sampleTransformedImage);
    }
    return result;
}

static avifCodecType avifEncoderGetCodecType(const avifEncoder * encoder)
{
    // This asserts that images cannot be encoded with AVM unless AVIF_CODEC_CHOICE_AVM is explicitly selected.
    assert((encoder->codecChoice != AVIF_CODEC_CHOICE_AUTO) ||
           (strcmp(avifCodecName(encoder->codecChoice, AVIF_CODEC_FLAG_CAN_ENCODE), "avm") != 0));
    return avifCodecTypeFromChoice(encoder->codecChoice, AVIF_CODEC_FLAG_CAN_ENCODE);
}

static avifResult avifEncoderValidateSize(avifEncoder * encoder, uint32_t gridCols, uint32_t gridRows, const avifImage * firstCell)
{
    if (!avifEncoderSizeIsSet(encoder)) {
        // First image, encoder->data->imageMetadata not initialized yet, nothing to check against.
        if (encoder->data->items.count == 0) {
            return AVIF_RESULT_OK;
        }

        // For animation, the encoder verifies the input size never changes, so this check is redundant.
        // But for a layered image, the encoder relaxes the check to allow layers to have different sizes.
        // We support 2 ways to produce different sized layers:
        // 1. Send full sized inputs and let the encoder scale them via scalingMode
        // 2. Declare the full size via width/height and send pre-scaled inputs
        // To avoid confusion, we require the user to consistently use only one of the 2 ways,
        // and this check blocks the attempt to start with method 1 and try to switch to method 2.
        if ((firstCell->width != encoder->data->imageMetadata->width) || (firstCell->height != encoder->data->imageMetadata->height)) {
            avifDiagnosticsPrintf(&encoder->diag, "All images must have the same width/height unless avifEncoder.width/height is set");
            return AVIF_RESULT_INVALID_ARGUMENT;
        }

        // According to section 2.2.2 of AV1 Image File Format specification v1.2.0:
        //   [...] the values of image_width and image_height shall respectively equal the values of
        //   UpscaledWidth and FrameHeight as defined in [AV1] but for a specific frame in the item
        //   payload. [...]
        //   In the absence of a 'lsel' property associated with the item, or if it is present and its
        //   layer_id value is set to 0xFFFF:
        //     If no OperatingPointSelectorProperty is associated with the item, the 'ispe' property
        //     shall document the dimensions of the last frame decoded when processing the operating
        //     point whose index is 0.
        //   NOTE: The dimensions of possible intermediate output images might not match the ones given
        //   in the 'ispe' property. If renderers display these intermediate images, they are expected
        //   to scale the output image to match the 'ispe' property.
        // See https://aomediacodec.github.io/av1-avif/v1.2.0.html#image-spatial-extents-property.
        //
        // Therefore the last layer must not have any scaling.
        if ((encoder->data->frames.count == encoder->extraLayerCount) && !avifScalingModeIsNoScaling(&encoder->scalingMode)) {
            avifDiagnosticsPrintf(&encoder->diag,
                                  "The last layer must not be scaled, but got scalingMode=(%d/%d, %d/%d)",
                                  encoder->scalingMode.horizontal.n,
                                  encoder->scalingMode.horizontal.d,
                                  encoder->scalingMode.vertical.n,
                                  encoder->scalingMode.vertical.d);
            return AVIF_RESULT_INVALID_ARGUMENT;
        }
        return AVIF_RESULT_OK;
    }

    if ((encoder->width == 0) || (encoder->height == 0)) {
        avifDiagnosticsPrintf(&encoder->diag, "avifEncoder.width and avifEncoder.height must either both be zero or both be nonzero");
        return AVIF_RESULT_INVALID_ARGUMENT;
    }

    if ((gridCols > 1) || (gridRows > 1)) {
        avifDiagnosticsPrintf(&encoder->diag, "avifEncoder.width/height cannot be set with grid images");
        return AVIF_RESULT_NOT_IMPLEMENTED;
    }

    // This blocks the attempt to use both ways to produce different sized layers together,
    // or start with method 2 and try to switch to method 1,
    // so the result is INVALID_ARGUMENT. See the comment above for the detail.
    if (!avifScalingModeIsNoScaling(&encoder->scalingMode)) {
        avifDiagnosticsPrintf(&encoder->diag, "avifEncoder.width/height cannot be set together with encoder->scalingMode");
        return AVIF_RESULT_INVALID_ARGUMENT;
    }

    if (encoder->sampleTransformRecipe != AVIF_SAMPLE_TRANSFORM_NONE) {
        avifDiagnosticsPrintf(&encoder->diag, "avifEncoder.width/height cannot be set with sample transforms");
        return AVIF_RESULT_NOT_IMPLEMENTED;
    }

    if (firstCell->gainMap && firstCell->gainMap->image) {
        avifDiagnosticsPrintf(&encoder->diag, "avifEncoder.width/height cannot be set with gain maps");
        return AVIF_RESULT_NOT_IMPLEMENTED;
    }

    // These 3 checks below are based on section 2.2.2 of AV1 Image File Format specification v1.2.0.
    // See the comment above for the detail.
    // Only a layered image can have frames of different sizes, so reject otherwise.
    if (encoder->extraLayerCount == 0) {
        avifDiagnosticsPrintf(&encoder->diag, "avifEncoder.width/height can only be set for layered images (extraLayerCount > 0)");
        return AVIF_RESULT_INVALID_ARGUMENT;
    }

    // The spec allows arbitrary sizes. We tighten the rule to "earlier layers shall be smaller" due to encoder restrictions.
    if ((encoder->width < firstCell->width) || (encoder->height < firstCell->height)) {
        avifDiagnosticsPrintf(&encoder->diag,
                              "avifEncoder.width/height %ux%u must be at least the coded image size %ux%u",
                              encoder->width,
                              encoder->height,
                              firstCell->width,
                              firstCell->height);
        return AVIF_RESULT_INCOMPATIBLE_IMAGE;
    }

    // The declared width/height must exactly match the coded size of the last layer.
    if ((encoder->data->frames.count == encoder->extraLayerCount) &&
        ((encoder->width != firstCell->width) || (encoder->height != firstCell->height))) {
        avifDiagnosticsPrintf(&encoder->diag,
                              "avifEncoder.width/height %ux%u must exactly match the coded size %ux%u of the last layer",
                              encoder->width,
                              encoder->height,
                              firstCell->width,
                              firstCell->height);
        return AVIF_RESULT_INCOMPATIBLE_IMAGE;
    }

    if (firstCell->transformFlags & AVIF_TRANSFORM_CLAP) {
        avifCropRect cropRect;
        if (!avifCropRectFromCleanApertureBox(&cropRect, &firstCell->clap, encoder->width, encoder->height, &encoder->diag)) {
            return AVIF_RESULT_INVALID_ARGUMENT;
        }
    }

    if ((encoder->data->items.count > 0) && (encoder->extraLayerCount > 0) &&
        !avifImageHasEquivalentTransformProperties(firstCell, encoder->data->imageMetadata)) {
        avifDiagnosticsPrintf(&encoder->diag,
                              "When avifEncoder.width/height is set, 'pasp', 'clap', 'irot' and 'imir' must match across layers");
        return AVIF_RESULT_INCOMPATIBLE_IMAGE;
    }

    return AVIF_RESULT_OK;
}

// This function is called after every color frame is encoded. It returns AVIF_TRUE if a keyframe needs to be forced for the next
// alpha frame to be encoded, AVIF_FALSE otherwise.
static avifBool avifEncoderDataShouldForceKeyframeForAlpha(const avifEncoderData * data,
                                                           const avifEncoderItem * colorItem,
                                                           avifAddImageFlags addImageFlags)
{
    if (!data->alphaPresent) {
        // There is no alpha plane.
        return AVIF_FALSE;
    }
    if (addImageFlags & AVIF_ADD_IMAGE_FLAG_SINGLE) {
        // Not an animated image.
        return AVIF_FALSE;
    }
    if (data->frames.count == 0) {
        // data->frames.count is the number of frames that have been encoded so far by previous calls to avifEncoderAddImage. If
        // this is the first frame, there is no need to force keyframe.
        return AVIF_FALSE;
    }
    const uint32_t colorFramesOutputSoFar = colorItem->encodeOutput->samples.count;
    const avifBool isLaggedOutput = (data->frames.count + 1) != colorFramesOutputSoFar;
    if (isLaggedOutput) {
        // If the encoder is operating with lag, then there is no way to determine if the last encoded frame was a keyframe until
        // the encoder outputs it (after the lag). So do not force keyframe for alpha channel in this case.
        return AVIF_FALSE;
    }
    return colorItem->encodeOutput->samples.sample[colorFramesOutputSoFar - 1].sync;
}

static avifResult avifGetErrorForItemCategory(avifItemCategory itemCategory)
{
    if (itemCategory == AVIF_ITEM_GAIN_MAP) {
        return AVIF_RESULT_ENCODE_GAIN_MAP_FAILED;
    }
    if (itemCategory == AVIF_ITEM_SAMPLE_TRANSFORM ||
        (itemCategory >= AVIF_SAMPLE_TRANSFORM_MIN_CATEGORY && itemCategory <= AVIF_SAMPLE_TRANSFORM_MAX_CATEGORY)) {
        return AVIF_RESULT_ENCODE_SAMPLE_TRANSFORM_FAILED;
    }
    return avifIsAlpha(itemCategory) ? AVIF_RESULT_ENCODE_ALPHA_FAILED : AVIF_RESULT_ENCODE_COLOR_FAILED;
}

static uint32_t avifGridWidth(uint32_t gridCols, const avifImage * firstCell, const avifImage * bottomRightCell)
{
    return (gridCols - 1) * firstCell->width + bottomRightCell->width;
}

static uint32_t avifGridHeight(uint32_t gridRows, const avifImage * firstCell, const avifImage * bottomRightCell)
{
    return (gridRows - 1) * firstCell->height + bottomRightCell->height;
}

static avifResult avifValidateGrid(uint32_t gridCols,
                                   uint32_t gridRows,
                                   const avifImage * const * cellImages,
                                   avifBool validateGainMap,
                                   avifDiagnostics * diag)
{
    const uint32_t cellCount = gridCols * gridRows;
    const avifImage * firstCell = cellImages[0];
    const avifImage * bottomRightCell = cellImages[cellCount - 1];
    if (validateGainMap) {
        AVIF_ASSERT_OR_RETURN(firstCell->gainMap && firstCell->gainMap->image);
        firstCell = firstCell->gainMap->image;
        AVIF_ASSERT_OR_RETURN(bottomRightCell->gainMap && bottomRightCell->gainMap->image);
        bottomRightCell = bottomRightCell->gainMap->image;
    }
    const uint32_t tileWidth = firstCell->width;
    const uint32_t tileHeight = firstCell->height;
    if ((tileWidth > 65536) || (tileHeight > 65536)) {
        avifDiagnosticsPrintf(diag,
                              "the first %s cell has invalid dimensions for AV1 and AV2: %ux%u",
                              validateGainMap ? "gain map" : "image",
                              tileWidth,
                              tileHeight);
        return AVIF_RESULT_INVALID_ARGUMENT;
    }
    for (uint32_t cellIndex = 0; cellIndex < cellCount; ++cellIndex) {
        const avifImage * cellImage = cellImages[cellIndex];
        if (validateGainMap) {
            AVIF_ASSERT_OR_RETURN(cellImage->gainMap && cellImage->gainMap->image);
            cellImage = cellImage->gainMap->image;
        }
        const uint32_t expectedCellWidth = ((cellIndex + 1) % gridCols) ? tileWidth : bottomRightCell->width;
        const uint32_t expectedCellHeight = (cellIndex < (cellCount - gridCols)) ? tileHeight : bottomRightCell->height;
        if ((cellImage->width != expectedCellWidth) || (cellImage->height != expectedCellHeight)) {
            avifDiagnosticsPrintf(diag,
                                  "%s cell %u has invalid dimensions: expected %ux%u found %ux%u",
                                  validateGainMap ? "gain map" : "image",
                                  cellIndex,
                                  expectedCellWidth,
                                  expectedCellHeight,
                                  cellImage->width,
                                  cellImage->height);
            return AVIF_RESULT_INVALID_IMAGE_GRID;
        }

        // 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, chroma sampling format, and the
        //   same decoder configuration (see 7.3.6.2).
        if ((cellImage->depth != firstCell->depth) || (cellImage->yuvFormat != firstCell->yuvFormat) ||
            (cellImage->yuvRange != firstCell->yuvRange) || (cellImage->colorPrimaries != firstCell->colorPrimaries) ||
            (cellImage->transferCharacteristics != firstCell->transferCharacteristics) ||
            (cellImage->matrixCoefficients != firstCell->matrixCoefficients) || (!!cellImage->alphaPlane != !!firstCell->alphaPlane) ||
            (cellImage->alphaPremultiplied != firstCell->alphaPremultiplied)) {
            avifDiagnosticsPrintf(diag,
                                  "all grid cells should have the same value for: depth, yuvFormat, yuvRange, colorPrimaries, "
                                  "transferCharacteristics, matrixCoefficients, alphaPlane presence, alphaPremultiplied");
            return AVIF_RESULT_INVALID_IMAGE_GRID;
        }

        // AV1 (Version 1.0.0 with Errata 1), Section 6.4.2. Color config semantics
        //   If matrix_coefficients is equal to MC_IDENTITY, it is a requirement of bitstream conformance that
        //   subsampling_x is equal to 0 and subsampling_y is equal to 0.
        // Although matrix_coefficients in the Sequence Header OBU is set to Undefined (2), the requirement
        // is still enforced here between what is written in the ColourInformationProperty of colour_type 'nclx'
        // and the subsampling information in the Sequence Header OBU.
        if (cellImage->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_IDENTITY && cellImage->yuvFormat != AVIF_PIXEL_FORMAT_YUV444) {
            avifDiagnosticsPrintf(diag, "subsampling must be 0 (4:4:4) with identity matrix coefficients");
            return AVIF_RESULT_INVALID_ARGUMENT;
        }

        if (!cellImage->yuvPlanes[AVIF_CHAN_Y]) {
            return AVIF_RESULT_NO_CONTENT;
        }
    }

    if ((bottomRightCell->width > tileWidth) || (bottomRightCell->height > tileHeight)) {
        avifDiagnosticsPrintf(diag,
                              "the last %s cell can be smaller but not larger than the other cells which are %ux%u, found %ux%u",
                              validateGainMap ? "gain map" : "image",
                              tileWidth,
                              tileHeight,
                              bottomRightCell->width,
                              bottomRightCell->height);
        return AVIF_RESULT_INVALID_IMAGE_GRID;
    }
    const uint32_t gridWidth = avifGridWidth(gridCols, firstCell, bottomRightCell);
    const uint32_t gridHeight = avifGridHeight(gridRows, firstCell, bottomRightCell);
    if ((cellCount > 1) && !avifAreGridDimensionsValid(firstCell->yuvFormat, gridWidth, gridHeight, tileWidth, tileHeight, diag)) {
        return AVIF_RESULT_INVALID_IMAGE_GRID;
    }

    return AVIF_RESULT_OK;
}

static avifResult avifEncoderAddImageInternal(avifEncoder * encoder,
                                              uint32_t gridCols,
                                              uint32_t gridRows,
                                              const avifImage * const * cellImages,
                                              uint64_t durationInTimescales,
                                              avifAddImageFlags addImageFlags)
{
    // -----------------------------------------------------------------------
    // Verify encoding is possible

    if (!avifCodecName(encoder->codecChoice, AVIF_CODEC_FLAG_CAN_ENCODE)) {
        return AVIF_RESULT_NO_CODEC_AVAILABLE;
    }

    if (encoder->extraLayerCount >= AVIF_MAX_AV1_LAYER_COUNT) {
        avifDiagnosticsPrintf(&encoder->diag, "extraLayerCount [%u] must be less than %d", encoder->extraLayerCount, AVIF_MAX_AV1_LAYER_COUNT);
        return AVIF_RESULT_INVALID_ARGUMENT;
    }

    // -----------------------------------------------------------------------
    // Validate images

    const uint32_t cellCount = gridCols * gridRows;
    if (cellCount == 0) {
        return AVIF_RESULT_INVALID_ARGUMENT;
    }

    const avifImage * firstCell = cellImages[0];
    const avifImage * bottomRightCell = cellImages[cellCount - 1];
    AVIF_CHECKERR(firstCell->depth == 8 || firstCell->depth == 10 || firstCell->depth == 12 ||
                      (firstCell->depth == 16 && encoder->sampleTransformRecipe != AVIF_SAMPLE_TRANSFORM_NONE),
                  AVIF_RESULT_UNSUPPORTED_DEPTH);
    AVIF_CHECKERR(firstCell->yuvFormat != AVIF_PIXEL_FORMAT_NONE, AVIF_RESULT_NO_YUV_FORMAT_SELECTED);
    if (!firstCell->width || !firstCell->height || !bottomRightCell->width || !bottomRightCell->height) {
        return AVIF_RESULT_NO_CONTENT;
    }

    AVIF_CHECKRES(avifEncoderValidateSize(encoder, gridCols, gridRows, firstCell));

    AVIF_CHECKRES(avifValidateGrid(gridCols, gridRows, cellImages, /*validateGainMap=*/AVIF_FALSE, &encoder->diag));

    const avifBool hasGainMap = (firstCell->gainMap && firstCell->gainMap->image != NULL);

    // Check that either all cells have a gain map, or none of them do.
    // If a gain map is present, check that they all have the same gain map metadata.
    for (uint32_t cellIndex = 0; cellIndex < cellCount; ++cellIndex) {
        const avifImage * cellImage = cellImages[cellIndex];
        const avifBool cellHasGainMap = (cellImage->gainMap && cellImage->gainMap->image);
        if (cellHasGainMap != hasGainMap) {
            avifDiagnosticsPrintf(&encoder->diag, "cells should either all have a gain map image, or none of them should, found a mix");
            return AVIF_RESULT_INVALID_IMAGE_GRID;
        }
        if (hasGainMap) {
            if (!avifSameGainMapAltMetadata(firstCell->gainMap, cellImage->gainMap)) {
                avifDiagnosticsPrintf(&encoder->diag, "all cells should have the same alternate image metadata in the gain map");
                return AVIF_RESULT_INVALID_IMAGE_GRID;
            }
            if (!avifSameGainMapMetadata(firstCell->gainMap, cellImage->gainMap)) {
                avifDiagnosticsPrintf(&encoder->diag, "all cells should have the same gain map metadata");
                return AVIF_RESULT_INVALID_IMAGE_GRID;
            }
        }
    }

    if (hasGainMap) {
        // AVIF supports 16-bit images through sample transforms used as bit depth extensions,
        // but this is not implemented for gain maps for now. Stick to at most 12 bits.
        AVIF_CHECKERR(firstCell->gainMap->image->depth == 8 || firstCell->gainMap->image->depth == 10 ||
                          firstCell->gainMap->image->depth == 12,
                      AVIF_RESULT_UNSUPPORTED_DEPTH);
        AVIF_CHECKERR(firstCell->gainMap->image->yuvFormat != AVIF_PIXEL_FORMAT_NONE, AVIF_RESULT_NO_YUV_FORMAT_SELECTED);
        AVIF_CHECKRES(avifValidateGrid(gridCols, gridRows, cellImages, /*validateGainMap=*/AVIF_TRUE, &encoder->diag));
        if (firstCell->gainMap->image->colorPrimaries != AVIF_COLOR_PRIMARIES_UNSPECIFIED ||
            firstCell->gainMap->image->transferCharacteristics != AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED) {
            avifDiagnosticsPrintf(&encoder->diag, "the gain map image must have colorPrimaries = 2 and transferCharacteristics = 2");
            return AVIF_RESULT_INVALID_ARGUMENT;
        }
    }

    // -----------------------------------------------------------------------
    // Validate flags

    if (encoder->data->singleImage) {
        // The previous call to avifEncoderAddImage() set AVIF_ADD_IMAGE_FLAG_SINGLE.
        // avifEncoderAddImage() cannot be called again for this encode.
        return AVIF_RESULT_ENCODE_COLOR_FAILED;
    }

    if (addImageFlags & AVIF_ADD_IMAGE_FLAG_SINGLE) {
        encoder->data->singleImage = AVIF_TRUE;

        if (encoder->extraLayerCount > 0) {
            // AVIF_ADD_IMAGE_FLAG_SINGLE may not be set for a layered image.
            return AVIF_RESULT_INVALID_ARGUMENT;
        }

        if (encoder->data->items.count > 0) {
            // AVIF_ADD_IMAGE_FLAG_SINGLE may only be set on the first and only image.
            return AVIF_RESULT_INVALID_ARGUMENT;
        }
    }

    // -----------------------------------------------------------------------
    // Choose AV1 or AV2

    const avifCodecType codecType = avifEncoderGetCodecType(encoder);
    switch (codecType) {
        case AVIF_CODEC_TYPE_AV1:
            encoder->data->imageItemType = "av01";
            encoder->data->configPropName = "av1C";
            break;
#if defined(AVIF_CODEC_AVM)
        case AVIF_CODEC_TYPE_AV2:
            encoder->data->imageItemType = "av02";
            encoder->data->configPropName = "av2C";
            break;
#endif
        default:
            return AVIF_RESULT_NO_CODEC_AVAILABLE;
    }

    // -----------------------------------------------------------------------
    // Populate encoder data (color) quality, qualityAlpha and qualityGainMap.
    encoder->data->quality = avifGetQuality(encoder->quality, encoder->minQuantizer, encoder->maxQuantizer);

    // If alpha quality, and min and max alpha quantizer have their default values, default to the same quality as color.
    if (encoder->qualityAlpha == AVIF_QUALITY_DEFAULT && encoder->minQuantizerAlpha == AVIF_QUANTIZER_BEST_QUALITY &&
        encoder->maxQuantizerAlpha == AVIF_QUANTIZER_WORST_QUALITY) {
        encoder->data->qualityAlpha = encoder->data->quality;
    } else {
        encoder->data->qualityAlpha = avifGetQuality(encoder->qualityAlpha, encoder->minQuantizerAlpha, encoder->maxQuantizerAlpha);
    }
    if (encoder->qualityGainMap == AVIF_QUALITY_DEFAULT) {
        encoder->data->qualityGainMap = encoder->data->quality; // Default to the same quality as color.
    } else {
        encoder->data->qualityGainMap =
            avifGetQuality(encoder->qualityGainMap, AVIF_QUANTIZER_BEST_QUALITY, AVIF_QUANTIZER_WORST_QUALITY);
    }

    // -----------------------------------------------------------------------
    // Handle automatic tiling

    encoder->data->tileRowsLog2 = AVIF_CLAMP(encoder->tileRowsLog2, 0, 6);
    encoder->data->tileColsLog2 = AVIF_CLAMP(encoder->tileColsLog2, 0, 6);
    if (encoder->autoTiling) {
        // Use as many tiles as allowed by the minimum tile area requirement and impose a maximum
        // of 8 tiles.
        const int threads = 8;
        avifSetTileConfiguration(threads, firstCell->width, firstCell->height, &encoder->data->tileRowsLog2, &encoder->data->tileColsLog2);
    }

    // -----------------------------------------------------------------------
    // All encoder settings are known now. Detect changes.

    avifEncoderChanges encoderChanges;
    if (!avifEncoderDetectChanges(encoder, &encoderChanges)) {
        return AVIF_RESULT_CANNOT_CHANGE_SETTING;
    }
    avifEncoderBackupSettings(encoder);

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

    if (durationInTimescales == 0) {
        durationInTimescales = 1;
    }

    if (encoder->data->items.count == 0) {
        // Make a copy of the first image's metadata (sans pixels) for future writing/validation
        AVIF_CHECKRES(avifImageCopy(encoder->data->imageMetadata, firstCell, 0));
        if (avifEncoderSizeIsSet(encoder)) {
            encoder->data->imageMetadata->width = encoder->width;
            encoder->data->imageMetadata->height = encoder->height;
        }

        const uint32_t gridWidth = avifGridWidth(gridCols, firstCell, bottomRightCell);
        const uint32_t gridHeight = avifGridHeight(gridRows, firstCell, bottomRightCell);

        if (hasGainMap) {
            AVIF_CHECKRES(
                avifImageCopyAltImageMetadata(encoder->data->altImageMetadata, encoder->data->imageMetadata, gridWidth, gridHeight));
        }

        // Prepare all AV1 items
        uint32_t colorItemID;
        AVIF_CHECKRES(avifEncoderAddImageItems(encoder, gridCols, gridRows, gridWidth, gridHeight, AVIF_ITEM_COLOR, &colorItemID));
        encoder->data->primaryItemID = colorItemID;

        encoder->data->alphaPresent = (firstCell->alphaPlane != NULL);
        if (encoder->data->alphaPresent && (addImageFlags & AVIF_ADD_IMAGE_FLAG_SINGLE)) {
            // If encoding a single image in which the alpha plane exists but is entirely opaque,
            // simply skip writing an alpha AV1 payload entirely, as it'll be interpreted as opaque
            // and is less bytes.
            //
            // However, if encoding an image sequence, the first frame's alpha plane being entirely
            // opaque could be a false positive for removing the alpha AV1 payload, as it might simply
            // be a fade out later in the sequence. This is why avifImageIsOpaque() is only called
            // when encoding a single image.

            encoder->data->alphaPresent = AVIF_FALSE;
            for (uint32_t cellIndex = 0; cellIndex < cellCount; ++cellIndex) {
                const avifImage * cellImage = cellImages[cellIndex];
                if (!avifImageIsOpaque(cellImage)) {
                    encoder->data->alphaPresent = AVIF_TRUE;
                    break;
                }
            }
        }

        if (encoder->data->alphaPresent) {
            uint32_t alphaItemID;
            AVIF_CHECKRES(avifEncoderAddImageItems(encoder, gridCols, gridRows, gridWidth, gridHeight, AVIF_ITEM_ALPHA, &alphaItemID));
            avifEncoderItem * alphaItem = avifEncoderDataFindItemByID(encoder->data, alphaItemID);
            AVIF_ASSERT_OR_RETURN(alphaItem);
            alphaItem->irefType = "auxl";
            alphaItem->irefToID = colorItemID;
            if (encoder->data->imageMetadata->alphaPremultiplied) {
                avifEncoderItem * colorItem = avifEncoderDataFindItemByID(encoder->data, colorItemID);
                AVIF_ASSERT_OR_RETURN(colorItem);
                colorItem->irefType = "prem";
                colorItem->irefToID = alphaItemID;
            }
        }

        if (firstCell->gainMap && firstCell->gainMap->image) {
            avifEncoderItem * toneMappedItem;
            AVIF_CHECKRES(avifEncoderDataCreateItem(encoder->data,
                                                    "tmap",
                                                    infeNameGainMap,
                                                    /*infeNameSize=*/strlen(infeNameGainMap) + 1,
                                                    /*cellIndex=*/0,
                                                    &toneMappedItem));
            AVIF_CHECKRES(avifWriteToneMappedImagePayload(&toneMappedItem->metadataPayload, firstCell->gainMap, &encoder->diag));
            // Even though the 'tmap' item is related to the gain map, it represents a color image and its metadata is more similar to the color item.
            toneMappedItem->itemCategory = AVIF_ITEM_COLOR;
            uint32_t toneMappedItemID = toneMappedItem->id;

            AVIF_ASSERT_OR_RETURN(encoder->data->alternativeItemIDs.count == 0);
            uint32_t * alternativeItemID = (uint32_t *)avifArrayPush(&encoder->data->alternativeItemIDs);
            AVIF_CHECKERR(alternativeItemID != NULL, AVIF_RESULT_OUT_OF_MEMORY);
            *alternativeItemID = toneMappedItemID;

            alternativeItemID = (uint32_t *)avifArrayPush(&encoder->data->alternativeItemIDs);
            AVIF_CHECKERR(alternativeItemID != NULL, AVIF_RESULT_OUT_OF_MEMORY);
            *alternativeItemID = colorItemID;

            const uint32_t gainMapGridWidth =
                avifGridWidth(gridCols, cellImages[0]->gainMap->image, cellImages[gridCols * gridRows - 1]->gainMap->image);
            const uint32_t gainMapGridHeight =
                avifGridHeight(gridRows, cellImages[0]->gainMap->image, cellImages[gridCols * gridRows - 1]->gainMap->image);

            uint32_t gainMapItemID;
            AVIF_CHECKRES(
                avifEncoderAddImageItems(encoder, gridCols, gridRows, gainMapGridWidth, gainMapGridHeight, AVIF_ITEM_GAIN_MAP, &gainMapItemID));
            avifEncoderItem * gainMapItem = avifEncoderDataFindItemByID(encoder->data, gainMapItemID);
            AVIF_ASSERT_OR_RETURN(gainMapItem);
            gainMapItem->hiddenImage = AVIF_TRUE;

            // Set the color item and gain map item's dimgFromID value to point to the tone mapped item.
            // The color item shall be first, and the gain map second. avifEncoderFinish() writes the
            // dimg item references in item id order, so as long as colorItemID < gainMapItemID, the order
            // will be correct.
            AVIF_ASSERT_OR_RETURN(colorItemID < gainMapItemID);
            avifEncoderItem * colorItem = avifEncoderDataFindItemByID(encoder->data, colorItemID);
            AVIF_ASSERT_OR_RETURN(colorItem);
            AVIF_ASSERT_OR_RETURN(colorItem->dimgFromID == 0); // Our internal API only allows one dimg value per item.
            colorItem->dimgFromID = toneMappedItemID;
            gainMapItem->dimgFromID = toneMappedItemID;
        }

        if (encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_8B_8B ||
            encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_4B ||
            encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_8B_OVERLAP_4B) {
            // For now, only 16-bit depth is supported.
            AVIF_CHECKERR(firstCell->depth == 16, AVIF_RESULT_NOT_IMPLEMENTED);
            // For now, gain maps are not supported in the same file as Sample Transforms ('altr' group conflict).
            AVIF_CHECKERR(!firstCell->gainMap, AVIF_RESULT_NOT_IMPLEMENTED);
            AVIF_CHECKRES(avifEncoderCreateBitDepthExtensionItems(encoder, gridCols, gridRows, gridWidth, gridHeight, colorItemID));
        } else {
            AVIF_CHECKERR(encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_NONE, AVIF_RESULT_NOT_IMPLEMENTED);
        }

        // -----------------------------------------------------------------------
        // Create metadata items (Exif, XMP)

        if (firstCell->exif.size > 0) {
            const avifResult result = avifEncoderDataCreateExifItem(encoder->data, &firstCell->exif);
            if (result != AVIF_RESULT_OK) {
                return result;
            }
        }

        if (firstCell->xmp.size > 0) {
            const avifResult result = avifEncoderDataCreateXMPItem(encoder->data, &firstCell->xmp);
            if (result != AVIF_RESULT_OK) {
                return result;
            }
        }
    } else {
        // Another frame in an image sequence, or layer in a layered image

        if (hasGainMap) {
            avifDiagnosticsPrintf(&encoder->diag, "gain maps are not supported for image sequences or layered images");
            return AVIF_RESULT_NOT_IMPLEMENTED;
        }

        const avifImage * imageMetadata = encoder->data->imageMetadata;
        // Image metadata that are copied to the configuration property and nclx boxes are not allowed to change.
        // If the first image in the sequence had an alpha plane (even if fully opaque), all
        // subsequent images must have alpha as well.
        if ((imageMetadata->depth != firstCell->depth) || (imageMetadata->yuvFormat != firstCell->yuvFormat) ||
            (imageMetadata->yuvRange != firstCell->yuvRange) ||
            (imageMetadata->yuvChromaSamplePosition != firstCell->yuvChromaSamplePosition) ||
            (imageMetadata->colorPrimaries != firstCell->colorPrimaries) ||
            (imageMetadata->transferCharacteristics != firstCell->transferCharacteristics) ||
            (imageMetadata->matrixCoefficients != firstCell->matrixCoefficients) ||
            (imageMetadata->alphaPremultiplied != firstCell->alphaPremultiplied) ||
            (encoder->data->alphaPresent && !firstCell->alphaPlane)) {
            return AVIF_RESULT_INCOMPATIBLE_IMAGE;
        }
    }

    if (encoder->data->frames.count == 1) {
        // We will be writing an image sequence. When writing the AV1SampleEntry (derived from
        // VisualSampleEntry) in the stsd box, we need to cast imageMetadata->width and
        // imageMetadata->height to uint16_t:
        //     class VisualSampleEntry(codingname) extends SampleEntry (codingname){
        //        ...
        //        unsigned int(16) width;
        //        unsigned int(16) height;
        //        ...
        //     }
        // Check whether it is safe to cast width and height to uint16_t. The maximum width and
        // height of an AV1 frame are 65536, which just exceeds uint16_t.
        AVIF_ASSERT_OR_RETURN(encoder->data->items.count > 0);
        const avifImage * imageMetadata = encoder->data->imageMetadata;
        AVIF_CHECKERR(imageMetadata->width <= 65535 && imageMetadata->height <= 65535, AVIF_RESULT_INVALID_ARGUMENT);
    }

    // -----------------------------------------------------------------------
    // Encode AV1 OBUs

    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        if (item->codec) {
            const avifImage * cellImage = cellImages[item->cellIndex];
            avifImage * cellImagePlaceholder = NULL; // May be used as a temporary, modified cellImage. Left as NULL otherwise.
            const avifImage * firstCellImage = firstCell;

            if (item->itemCategory == AVIF_ITEM_GAIN_MAP) {
                AVIF_ASSERT_OR_RETURN(cellImage->gainMap && cellImage->gainMap->image);
                cellImage = cellImage->gainMap->image;
                AVIF_ASSERT_OR_RETURN(firstCell->gainMap && firstCell->gainMap->image);
                firstCellImage = firstCell->gainMap->image;
            }

            if ((cellImage->width != firstCellImage->width) || (cellImage->height != firstCellImage->height)) {
                // Pad the right-most and/or bottom-most tiles so that all tiles share the same dimensions.
                cellImagePlaceholder = avifImageCreateEmpty();
                AVIF_CHECKERR(cellImagePlaceholder, AVIF_RESULT_OUT_OF_MEMORY);
                const avifResult result =
                    avifImageCopyAndPad(cellImagePlaceholder, cellImage, firstCellImage->width, firstCellImage->height);
                if (result != AVIF_RESULT_OK) {
                    avifImageDestroy(cellImagePlaceholder);
                    return result;
                }
                cellImage = cellImagePlaceholder;
            }

            const avifBool isAlpha = avifIsAlpha(item->itemCategory);
            int quality = isAlpha                                      ? encoder->data->qualityAlpha
                          : (item->itemCategory == AVIF_ITEM_GAIN_MAP) ? encoder->data->qualityGainMap
                                                                       : encoder->data->quality;

            // Remember original quantizer values in case they change, to reset them afterwards.
            int * encoderMinQuantizer = isAlpha ? &encoder->minQuantizerAlpha : &encoder->minQuantizer;
            int * encoderMaxQuantizer = isAlpha ? &encoder->maxQuantizerAlpha : &encoder->maxQuantizer;
            const int originalMinQuantizer = *encoderMinQuantizer;
            const int originalMaxQuantizer = *encoderMaxQuantizer;

            if (encoder->sampleTransformRecipe != AVIF_SAMPLE_TRANSFORM_NONE) {
                if ((encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_8B_8B ||
                     encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_4B) &&
                    (item->itemCategory == AVIF_ITEM_COLOR || item->itemCategory == AVIF_ITEM_ALPHA)) {
                    // Encoding the least significant bits of a sample does not make any sense if the
                    // other bits are lossily compressed. Encode the most significant bits losslessly.
                    quality = AVIF_QUALITY_LOSSLESS;
                    *encoderMinQuantizer = AVIF_QUANTIZER_LOSSLESS;
                    *encoderMaxQuantizer = AVIF_QUANTIZER_LOSSLESS;
                    if (!avifEncoderDetectChanges(encoder, &encoderChanges)) {
                        assert(AVIF_FALSE);
                    }
                }

                // Replace cellImage by the first or second input to the AVIF_ITEM_SAMPLE_TRANSFORM derived image item.
                const avifBool itemWillBeEncodedLosslessly = (quality == AVIF_QUALITY_LOSSLESS);
                avifImage * sampleTransformedImage = NULL;
                if (cellImagePlaceholder) {
                    avifImageDestroy(cellImagePlaceholder); // Replaced by sampleTransformedImage.
                    cellImagePlaceholder = NULL;
                }
                AVIF_CHECKRES(
                    avifEncoderCreateBitDepthExtensionImage(encoder, item, itemWillBeEncodedLosslessly, cellImage, &sampleTransformedImage));
                assert(cellImagePlaceholder == NULL);
                cellImagePlaceholder = sampleTransformedImage; // Transfer ownership.
                cellImage = cellImagePlaceholder;
            }

            // If alpha channel is present, set disableLaggedOutput to AVIF_TRUE. If the encoder supports it, this enables
            // avifEncoderDataShouldForceKeyframeForAlpha to force a keyframe in the alpha channel whenever a keyframe has been
            // encoded in the color channel for animated images.
            avifResult encodeResult = item->codec->encodeImage(item->codec,
                                                               encoder,
                                                               cellImage,
                                                               isAlpha,
                                                               encoder->data->tileRowsLog2,
                                                               encoder->data->tileColsLog2,
                                                               quality,
                                                               encoderChanges,
                                                               /*disableLaggedOutput=*/encoder->data->alphaPresent,
                                                               addImageFlags,
                                                               item->encodeOutput);
            // Revert quality settings if they changed.
            if (*encoderMinQuantizer != originalMinQuantizer || *encoderMaxQuantizer != originalMaxQuantizer) {
                avifEncoderBackupSettings(encoder); // Remember last encoding settings for next avifEncoderDetectChanges().
                *encoderMinQuantizer = originalMinQuantizer;
                *encoderMaxQuantizer = originalMaxQuantizer;
            }
            if (cellImagePlaceholder) {
                avifImageDestroy(cellImagePlaceholder);
            }
            if (encodeResult == AVIF_RESULT_UNKNOWN_ERROR) {
                encodeResult = avifGetErrorForItemCategory(item->itemCategory);
            }
            AVIF_CHECKRES(encodeResult);
            if (itemIndex == 0 && avifEncoderDataShouldForceKeyframeForAlpha(encoder->data, item, addImageFlags)) {
                addImageFlags |= AVIF_ADD_IMAGE_FLAG_FORCE_KEYFRAME;
            }
        }
    }

    avifEncoderFrame * frame = (avifEncoderFrame *)avifArrayPush(&encoder->data->frames);
    AVIF_CHECKERR(frame != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    frame->durationInTimescales = durationInTimescales;
    avifCodecSpecificOptionsClear(encoder->csOptions);
    return AVIF_RESULT_OK;
}

avifResult avifEncoderAddImage(avifEncoder * encoder, const avifImage * image, uint64_t durationInTimescales, avifAddImageFlags addImageFlags)
{
    avifDiagnosticsClearError(&encoder->diag);
    return avifEncoderAddImageInternal(encoder, 1, 1, &image, durationInTimescales, addImageFlags);
}

avifResult avifEncoderAddImageGrid(avifEncoder * encoder,
                                   uint32_t gridCols,
                                   uint32_t gridRows,
                                   const avifImage * const * cellImages,
                                   avifAddImageFlags addImageFlags)
{
    avifDiagnosticsClearError(&encoder->diag);
    // Each cell is referenced by a 'dimg' item reference whose reference_count field is
    // 16-bit regardless of the 'iref' box version (ISO/IEC 14496-12 Section 8.11.12), so a
    // grid cannot contain more than 65535 cells.
    if ((gridCols == 0) || (gridCols > 256) || (gridRows == 0) || (gridRows > 256) || (gridCols * gridRows > 65535)) {
        return AVIF_RESULT_INVALID_IMAGE_GRID;
    }
    if (gridCols * gridRows > 65535) {
        // Section 8.11.12.1 of ISO/IEC 14496-12: "All the references for one item of a specific type
        // are collected into a single item type reference box", whose reference_count field is
        // unsigned int(16) whatever the 'iref' version (Section 8.11.12.2). Moreover, ISO/IEC 23008-12
        // (HEIF) Section 6.6.1 states that "The number of SingleItemTypeReferenceBoxes with the box
        // type 'dimg' and with the same value of from_item_ID shall not be greater than 1".
        // A grid item therefore cannot reference more than 65535 cell items, so a 256x256-cell grid
        // cannot be encoded in a conformant way, whatever the item ID width.
        avifDiagnosticsPrintf(&encoder->diag,
                              "avifEncoderAddImageGrid() failed because a grid cannot have more than 65535 cells due to the 16-bit 'dimg' reference_count field (%u columns x %u rows)",
                              gridCols,
                              gridRows);
        return AVIF_RESULT_INVALID_IMAGE_GRID;
    }
    if (encoder->extraLayerCount == 0) {
        addImageFlags |= AVIF_ADD_IMAGE_FLAG_SINGLE; // image grids cannot be image sequences
    }
    return avifEncoderAddImageInternal(encoder, gridCols, gridRows, cellImages, 1, addImageFlags);
}

static size_t avifEncoderFindExistingChunk(avifRWStream * s, size_t mdatStartOffset, const uint8_t * data, size_t size)
{
    const size_t mdatCurrentOffset = avifRWStreamOffset(s);
    const size_t mdatSearchSize = mdatCurrentOffset - mdatStartOffset;
    if (mdatSearchSize < size) {
        return 0;
    }
    const size_t mdatEndSearchOffset = mdatCurrentOffset - size;
    for (size_t searchOffset = mdatStartOffset; searchOffset <= mdatEndSearchOffset; ++searchOffset) {
        if (!memcmp(data, &s->raw->data[searchOffset], size)) {
            return searchOffset;
        }
    }
    return 0;
}

static avifResult avifEncoderWriteMediaDataBox(avifEncoder * encoder,
                                               avifRWStream * s,
                                               avifEncoderItemReferenceArray * layeredColorItems,
                                               avifEncoderItemReferenceArray * layeredAlphaItems)
{
    encoder->ioStats.colorOBUSize = 0;
    encoder->ioStats.alphaOBUSize = 0;
    encoder->data->gainMapSizeBytes = 0;

    avifBoxMarker mdat;
    AVIF_CHECKRES(avifRWStreamWriteBox(s, "mdat", AVIF_BOX_SIZE_TBD, &mdat));
    const size_t mdatStartOffset = avifRWStreamOffset(s);
    for (uint32_t itemPasses = 0; itemPasses < 3; ++itemPasses) {
        // Use multiple passes to pack in the following order:
        //   * Pass 0: metadata (Exif/XMP/gain map metadata)
        //   * Pass 1: alpha, gain map image (AV1)
        //   * Pass 2: all other item data (AV1 color)
        //
        // See here for the discussion on alpha coming before color:
        // https://github.com/AOMediaCodec/libavif/issues/287
        //
        // Exif and XMP are packed first as they're required to be fully available
        // by avifDecoderParse() before it returns AVIF_RESULT_OK, unless ignoreXMP
        // and ignoreExif are enabled.
        //
        const avifBool metadataPass = (itemPasses == 0);
        const avifBool alphaAndGainMapPass = (itemPasses == 1);

        for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
            avifEncoderItem * item = &encoder->data->items.item[itemIndex];
            if ((item->metadataPayload.size == 0) && (item->encodeOutput->samples.count == 0)) {
                // this item has nothing for the mdat box
                continue;
            }
            const avifBool isMetadata = !memcmp(item->type, "mime", 4) || !memcmp(item->type, "Exif", 4) ||
                                        !memcmp(item->type, "tmap", 4);
            if (metadataPass != isMetadata) {
                // only process metadata (XMP/Exif) payloads when metadataPass is true
                continue;
            }
            const avifBool isAlpha = avifIsAlpha(item->itemCategory);
            const avifBool isAlphaOrGainMap = isAlpha || item->itemCategory == AVIF_ITEM_GAIN_MAP;
            if (alphaAndGainMapPass != isAlphaOrGainMap) {
                // only process alpha payloads when alphaPass is true
                continue;
            }

            if ((encoder->extraLayerCount > 0) && (item->encodeOutput->samples.count > 0)) {
                // Interleave - Pick out AV1 items and interleave them later.
                // We always interleave all AV1 items for layered images.
                AVIF_ASSERT_OR_RETURN(item->encodeOutput->samples.count == item->mdatFixups.count);

                avifEncoderItemReference * ref =
                    (avifEncoderItemReference *)avifArrayPush(isAlpha ? layeredAlphaItems : layeredColorItems);
                AVIF_CHECKERR(ref != NULL, AVIF_RESULT_OUT_OF_MEMORY);
                *ref = item;
                continue;
            }

            size_t chunkOffset = 0;

            // Deduplication - See if an identical chunk to this has already been written.
            // Doing it when item->encodeOutput->samples.count > 1 would require contiguous memory.
            if (item->encodeOutput->samples.count == 1) {
                avifEncodeSample * sample = &item->encodeOutput->samples.sample[0];
                chunkOffset = avifEncoderFindExistingChunk(s, mdatStartOffset, sample->data.data, sample->data.size);
            } else if (item->encodeOutput->samples.count == 0) {
                chunkOffset = avifEncoderFindExistingChunk(s, mdatStartOffset, item->metadataPayload.data, item->metadataPayload.size);
            }

            if (!chunkOffset) {
                // We've never seen this chunk before; write it out
                chunkOffset = avifRWStreamOffset(s);
                if (item->encodeOutput->samples.count > 0) {
                    for (uint32_t sampleIndex = 0; sampleIndex < item->encodeOutput->samples.count; ++sampleIndex) {
                        avifEncodeSample * sample = &item->encodeOutput->samples.sample[sampleIndex];
                        AVIF_CHECKRES(avifRWStreamWrite(s, sample->data.data, sample->data.size));

                        if (isAlpha) {
                            encoder->ioStats.alphaOBUSize += sample->data.size;
                        } else if (item->itemCategory == AVIF_ITEM_COLOR) {
                            encoder->ioStats.colorOBUSize += sample->data.size;
                        } else if (item->itemCategory == AVIF_ITEM_GAIN_MAP) {
                            encoder->data->gainMapSizeBytes += sample->data.size;
                        }
                    }
                } else {
                    AVIF_CHECKRES(avifRWStreamWrite(s, item->metadataPayload.data, item->metadataPayload.size));
                }
            }

            for (uint32_t fixupIndex = 0; fixupIndex < item->mdatFixups.count; ++fixupIndex) {
                avifOffsetFixup * fixup = &item->mdatFixups.fixup[fixupIndex];
                size_t prevOffset = avifRWStreamOffset(s);
                avifRWStreamSetOffset(s, fixup->offset);
                AVIF_CHECKRES(avifRWStreamWriteU32(s, (uint32_t)chunkOffset));
                avifRWStreamSetOffset(s, prevOffset);
            }
        }
    }

    uint32_t layeredItemCount = AVIF_MAX(layeredColorItems->count, layeredAlphaItems->count);
    if (layeredItemCount > 0) {
        // Interleave samples of all AV1 items.
        // We first write the first layer of all items,
        // in which we write first layer of each cell,
        // in which we write alpha first and then color.
        avifBool hasMoreSample;
        uint32_t layerIndex = 0;
        do {
            hasMoreSample = AVIF_FALSE;
            for (uint32_t itemIndex = 0; itemIndex < layeredItemCount; ++itemIndex) {
                for (int samplePass = 0; samplePass < 2; ++samplePass) {
                    // Alpha coming before color
                    avifEncoderItemReferenceArray * currentItems = (samplePass == 0) ? layeredAlphaItems : layeredColorItems;
                    if (itemIndex >= currentItems->count) {
                        continue;
                    }

                    // There is no way to select which grid cell should be written first for now.
                    avifEncoderItem * item = currentItems->ref[itemIndex];
                    if (item->encodeOutput->samples.count <= layerIndex) {
                        // We've already written all samples of this item
                        continue;
                    } else if (item->encodeOutput->samples.count > layerIndex + 1) {
                        hasMoreSample = AVIF_TRUE;
                    }
                    avifRWData * data = &item->encodeOutput->samples.sample[layerIndex].data;
                    size_t chunkOffset = avifEncoderFindExistingChunk(s, mdatStartOffset, data->data, data->size);
                    if (!chunkOffset) {
                        // We've never seen this chunk before; write it out
                        chunkOffset = avifRWStreamOffset(s);
                        AVIF_CHECKRES(avifRWStreamWrite(s, data->data, data->size));
                        if (samplePass == 0) {
                            encoder->ioStats.alphaOBUSize += data->size;
                        } else {
                            encoder->ioStats.colorOBUSize += data->size;
                        }
                    }

                    size_t prevOffset = avifRWStreamOffset(s);
                    avifRWStreamSetOffset(s, item->mdatFixups.fixup[layerIndex].offset);
                    AVIF_CHECKRES(avifRWStreamWriteU32(s, (uint32_t)chunkOffset));
                    avifRWStreamSetOffset(s, prevOffset);
                }
            }
            ++layerIndex;
        } while (hasMoreSample);

        AVIF_ASSERT_OR_RETURN(layerIndex <= AVIF_MAX_AV1_LAYER_COUNT);
    }
    AVIF_CHECKRES(avifRWStreamFinishBox(s, mdat));
    return AVIF_RESULT_OK;
}

static avifResult avifWriteAltrGroup(avifRWStream * s, uint32_t groupID, const avifEncoderItemIdArray * itemIDs)
{
    avifBoxMarker grpl;
    AVIF_CHECKRES(avifRWStreamWriteBox(s, "grpl", AVIF_BOX_SIZE_TBD, &grpl));

    avifBoxMarker altr;
    AVIF_CHECKRES(avifRWStreamWriteFullBox(s, "altr", AVIF_BOX_SIZE_TBD, 0, 0, &altr));

    AVIF_CHECKRES(avifRWStreamWriteU32(s, groupID));                  // unsigned int(32) group_id;
    AVIF_CHECKRES(avifRWStreamWriteU32(s, (uint32_t)itemIDs->count)); // unsigned int(32) num_entities_in_group;
    for (uint32_t i = 0; i < itemIDs->count; ++i) {
        AVIF_CHECKRES(avifRWStreamWriteU32(s, (uint32_t)itemIDs->itemID[i])); // unsigned int(32) entity_id;
    }

    AVIF_CHECKRES(avifRWStreamFinishBox(s, altr));

    AVIF_CHECKRES(avifRWStreamFinishBox(s, grpl));

    return AVIF_RESULT_OK;
}

#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
// Returns true if the image can be encoded with a MinimizedImageBox instead of a full regular MetaBox.
static avifBool avifEncoderIsMiniCompatible(const avifEncoder * encoder)
{
    // The MinimizedImageBox ("mif3" brand) only supports non-layered, still images.
    if (encoder->extraLayerCount || (encoder->data->frames.count != 1)) {
        return AVIF_FALSE;
    }

    if (encoder->sampleTransformRecipe != AVIF_SAMPLE_TRANSFORM_NONE) {
        return AVIF_FALSE;
    }

    // Check for maximum field values and maximum chunk sizes.

    // width_minus1 and height_minus1
    if (encoder->data->imageMetadata->width > (1 << 15) || encoder->data->imageMetadata->height > (1 << 15)) {
        return AVIF_FALSE;
    }
    // icc_data_size_minus1, exif_data_size_minus1 and xmp_data_size_minus1
    if (encoder->data->imageMetadata->icc.size > (1 << 20) || encoder->data->imageMetadata->exif.size > (1 << 20) ||
        encoder->data->imageMetadata->xmp.size > (1 << 20)) {
        return AVIF_FALSE;
    }
    // gainmap_width_minus1 and gainmap_height_minus1
    if (encoder->data->imageMetadata->gainMap != NULL && encoder->data->imageMetadata->gainMap->image != NULL &&
        (encoder->data->imageMetadata->gainMap->image->width > (1 << 15) ||
         encoder->data->imageMetadata->gainMap->image->height > (1 << 15))) {
        return AVIF_FALSE;
    }
    // tmap_icc_data_size_minus1
    if (encoder->data->altImageMetadata->icc.size > (1 << 20)) {
        return AVIF_FALSE;
    }
    // gainmap_metadata_size
    if (encoder->data->imageMetadata->gainMap != NULL && avifGainMapMetadataSize(encoder->data->imageMetadata->gainMap) >= (1 << 20)) {
        return AVIF_FALSE;
    }

    // 4:4:4, 4:2:2, 4:2:0 and 4:0:0 are supported by a MinimizedImageBox.
    // chroma_subsampling
    if (encoder->data->imageMetadata->yuvFormat != AVIF_PIXEL_FORMAT_YUV444 &&
        encoder->data->imageMetadata->yuvFormat != AVIF_PIXEL_FORMAT_YUV422 &&
        encoder->data->imageMetadata->yuvFormat != AVIF_PIXEL_FORMAT_YUV420 &&
        encoder->data->imageMetadata->yuvFormat != AVIF_PIXEL_FORMAT_YUV400) {
        return AVIF_FALSE;
    }
    // gainmap_chroma_subsampling
    if (encoder->data->imageMetadata->gainMap != NULL && encoder->data->imageMetadata->gainMap->image != NULL &&
        (encoder->data->imageMetadata->gainMap->image->yuvFormat != AVIF_PIXEL_FORMAT_YUV444 &&
         encoder->data->imageMetadata->gainMap->image->yuvFormat != AVIF_PIXEL_FORMAT_YUV422 &&
         encoder->data->imageMetadata->gainMap->image->yuvFormat != AVIF_PIXEL_FORMAT_YUV420 &&
         encoder->data->imageMetadata->gainMap->image->yuvFormat != AVIF_PIXEL_FORMAT_YUV400)) {
        return AVIF_FALSE;
    }

    // colour_primaries, transfer_characteristics and matrix_coefficients
    if (encoder->data->imageMetadata->colorPrimaries > 255 || encoder->data->imageMetadata->transferCharacteristics > 255 ||
        encoder->data->imageMetadata->matrixCoefficients > 255) {
        return AVIF_FALSE;
    }
    // gainmap_colour_primaries, gainmap_transfer_characteristics and gainmap_matrix_coefficients
    if (encoder->data->imageMetadata->gainMap != NULL && encoder->data->imageMetadata->gainMap->image != NULL &&
        (encoder->data->imageMetadata->gainMap->image->colorPrimaries > 255 ||
         encoder->data->imageMetadata->gainMap->image->transferCharacteristics > 255 ||
         encoder->data->imageMetadata->gainMap->image->matrixCoefficients > 255)) {
        return AVIF_FALSE;
    }
    // tmap_colour_primaries, tmap_transfer_characteristics and tmap_matrix_coefficients
    if (encoder->data->altImageMetadata->colorPrimaries > 255 || encoder->data->altImageMetadata->transferCharacteristics > 255 ||
        encoder->data->altImageMetadata->matrixCoefficients > 255) {
        return AVIF_FALSE;
    }

    const avifEncoderItem * colorItem = NULL;
    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];

        // Grids are not supported by a MinimizedImageBox.
        if (item->gridCols || item->gridRows) {
            return AVIF_FALSE;
        }

        if (item->id == encoder->data->primaryItemID) {
            assert(!colorItem);
            colorItem = item;
            // main_item_data_size_minus1
            if (item->encodeOutput->samples.count != 1 || item->encodeOutput->samples.sample[0].data.size > (1 << 28)) {
                return AVIF_FALSE;
            }
            continue; // The primary item can be stored in the MinimizedImageBox.
        }
        if (item->itemCategory == AVIF_ITEM_ALPHA && item->irefToID == encoder->data->primaryItemID) {
            // alpha_item_data_size
            if (item->encodeOutput->samples.count != 1 || item->encodeOutput->samples.sample[0].data.size >= (1 << 28)) {
                return AVIF_FALSE;
            }
            continue; // The alpha auxiliary item can be stored in the MinimizedImageBox.
        }
        if (item->itemCategory == AVIF_ITEM_GAIN_MAP) {
            // gainmap_item_data_size
            if (item->encodeOutput->samples.count != 1 || item->encodeOutput->samples.sample[0].data.size >= (1 << 28)) {
                return AVIF_FALSE;
            }
            continue; // The gainmap input image item can be stored in the MinimizedImageBox.
        }
        if (!memcmp(item->type, "tmap", 4)) {
            assert(item->itemCategory == AVIF_ITEM_COLOR); // Cannot be differentiated from the primary item by its itemCategory.
            continue; // The tone mapping derived image item can be represented in the MinimizedImageBox.
        }
        if (!memcmp(item->type, "mime", 4) && !memcmp(item->infeName, "XMP", item->infeNameSize)) {
            assert(item->metadataPayload.size == encoder->data->imageMetadata->xmp.size);
            continue; // XMP metadata can be stored in the MinimizedImageBox.
        }
        if (!memcmp(item->type, "Exif", 4) && !memcmp(item->infeName, "Exif", item->infeNameSize)) {
            assert(item->metadataPayload.size == encoder->data->imageMetadata->exif.size + 4);
            const uint32_t exif_tiff_header_offset = *(uint32_t *)item->metadataPayload.data;
            if (exif_tiff_header_offset != 0) {
                return AVIF_FALSE;
            }
            continue; // Exif metadata can be stored in the MinimizedImageBox if exif_tiff_header_offset is 0.
        }

        // Items besides the colorItem, the alphaItem, the gainmap item and Exif/XMP/ICC/HDR
        // metadata are not directly supported by the MinimizedImageBox.
        return AVIF_FALSE;
    }
    // A primary item is necessary.
    if (!colorItem) {
        return AVIF_FALSE;
    }
    return AVIF_TRUE;
}

static avifResult avifEncoderWriteMiniBox(avifEncoder * encoder, avifRWStream * s);

static avifResult avifEncoderWriteFileTypeBoxAndMiniBox(avifEncoder * encoder, avifRWData * output)
{
    avifRWStream s;
    avifRWStreamStart(&s, output);

    avifBoxMarker ftyp;
    AVIF_CHECKRES(avifRWStreamWriteBox(&s, "ftyp", AVIF_BOX_SIZE_TBD, &ftyp));
    AVIF_CHECKRES(avifRWStreamWriteChars(&s, "mif3", 4)); // unsigned int(32) major_brand;
    AVIF_CHECKRES(avifRWStreamWriteChars(&s, "avif", 4)); // unsigned int(32) minor_version;
                                                          // unsigned int(32) compatible_brands[];
    AVIF_CHECKRES(avifRWStreamFinishBox(&s, ftyp));

    AVIF_CHECKRES(avifEncoderWriteMiniBox(encoder, &s));

    avifRWStreamFinishWrite(&s);
    return AVIF_RESULT_OK;
}

static avifResult avifEncoderWriteMiniBox(avifEncoder * encoder, avifRWStream * s)
{
    const avifEncoderItem * colorItem = NULL;
    const avifEncoderItem * alphaItem = NULL;
    const avifEncoderItem * gainmapItem = NULL;
    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        if (item->id == encoder->data->primaryItemID) {
            AVIF_ASSERT_OR_RETURN(!colorItem);
            colorItem = item;
        } else if (item->itemCategory == AVIF_ITEM_ALPHA && item->irefToID == encoder->data->primaryItemID) {
            AVIF_ASSERT_OR_RETURN(!alphaItem);
            alphaItem = item;
        }
        if (item->itemCategory == AVIF_ITEM_GAIN_MAP) {
            AVIF_ASSERT_OR_RETURN(!gainmapItem);
            gainmapItem = item;
        }
    }

    AVIF_ASSERT_OR_RETURN(colorItem);
    const avifRWData * colorData = &colorItem->encodeOutput->samples.sample[0].data;
    const avifRWData * alphaData = alphaItem ? &alphaItem->encodeOutput->samples.sample[0].data : NULL;
    const avifRWData * gainmapData = gainmapItem ? &gainmapItem->encodeOutput->samples.sample[0].data : NULL;

    const avifImage * const image = encoder->data->imageMetadata;

    const avifBool hasAlpha = alphaItem != NULL;
    const avifBool alphaIsPremultiplied = encoder->data->imageMetadata->alphaPremultiplied;
    const avifBool hasGainmap = gainmapItem != NULL;
    const avifBool hasHdr = hasGainmap; // libavif only supports gainmap-based HDR encoding for now.
    const avifBool hasIcc = image->icc.size != 0;
    const uint32_t chromaSubsampling = image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400   ? 0
                                       : image->yuvFormat == AVIF_PIXEL_FORMAT_YUV420 ? 1
                                       : image->yuvFormat == AVIF_PIXEL_FORMAT_YUV422 ? 2
                                                                                      : 3;

    const avifColorPrimaries defaultColorPrimaries = hasIcc ? AVIF_COLOR_PRIMARIES_UNSPECIFIED : AVIF_COLOR_PRIMARIES_BT709;
    const avifTransferCharacteristics defaultTransferCharacteristics = hasIcc ? AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED
                                                                              : AVIF_TRANSFER_CHARACTERISTICS_SRGB;
    const avifMatrixCoefficients defaultMatrixCoefficients = chromaSubsampling == 0 ? AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED
                                                                                    : AVIF_MATRIX_COEFFICIENTS_BT601;
    const avifBool hasExplicitCicp = image->colorPrimaries != defaultColorPrimaries ||
                                     image->transferCharacteristics != defaultTransferCharacteristics ||
                                     image->matrixCoefficients != defaultMatrixCoefficients;

    const avifBool floatFlag = AVIF_FALSE;
    const avifBool fullRange = image->yuvRange == AVIF_RANGE_FULL;

    // 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).
    if (image->yuvFormat != AVIF_PIXEL_FORMAT_YUV420 && image->yuvChromaSamplePosition != AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN) {
        avifDiagnosticsPrintf(&encoder->diag,
                              "YUV chroma sample position %d is only supported with 4:2:0 YUV format in AV1",
                              image->yuvChromaSamplePosition);
        return AVIF_RESULT_INVALID_ARGUMENT;
    }
    // For the YUV 4:2:0 format, assume centered sample position unless specified otherwise.
    // This is consistent with the behavior in read.c.
    const avifBool chromaIsHorizontallyCentered = image->yuvFormat == AVIF_PIXEL_FORMAT_YUV420 &&
                                                  image->yuvChromaSamplePosition != AVIF_CHROMA_SAMPLE_POSITION_VERTICAL &&
                                                  image->yuvChromaSamplePosition != AVIF_CHROMA_SAMPLE_POSITION_COLOCATED;
    const avifBool chromaIsVerticallyCentered = image->yuvFormat == AVIF_PIXEL_FORMAT_YUV420 &&
                                                image->yuvChromaSamplePosition != AVIF_CHROMA_SAMPLE_POSITION_COLOCATED;

    const uint32_t orientationMinus1 = avifImageIrotImirToExifOrientation(image) - 1;

    uint8_t infeType[4];
    uint8_t codecConfigType[4];
    avifBool hasExplicitCodecTypes;
    if (encoder->codecChoice == AVIF_CODEC_CHOICE_AVM) {
        memcpy(infeType, "av02", 4);
        memcpy(codecConfigType, "av2C", 4); // Same syntax as 'av1C'.
        hasExplicitCodecTypes = AVIF_TRUE;
    } else {
        memcpy(infeType, "av01", 4);
        memcpy(codecConfigType, "av1C", 4);
        // 'av01' and 'av1C' are implied by 'avif' minor_version field of FileTypeBox. No need to write them.
        hasExplicitCodecTypes = AVIF_FALSE;
    }

    // _minus1 is encoded for these fields.
    AVIF_ASSERT_OR_RETURN(image->width != 0 && image->height != 0);
    AVIF_ASSERT_OR_RETURN(colorData->size != 0);

    uint32_t largeDimensionsFlag = image->width - 1 >= (1 << 7) || image->height - 1 >= (1 << 7);
    const uint32_t codecConfigSize = 4;  // 'av1C' always uses 4 bytes.
    uint32_t alphaCodecConfigSize = 0;   // 0 if same codec config as main. Equal to codecConfigSize otherwise.
    uint32_t gainmapCodecConfigSize = 0; // 0 if same codec config as main. Equal to codecConfigSize otherwise.
    uint32_t gainmapMetadataSize = 0;
    const uint32_t largeCodecConfigFlag = codecConfigSize >= (1 << 3);
    uint32_t largeItemDataFlag = colorData->size - 1 >= (1 << 15) || (alphaData && alphaData->size >= (1 << 15));
    uint32_t largeMetadataFlag = (hasIcc && image->icc.size - 1 >= (1 << 10)) ||
                                 (image->exif.size != 0 && image->exif.size - 1 >= (1 << 10)) ||
                                 (image->xmp.size != 0 && image->xmp.size - 1 >= (1 << 10));

    if (hasGainmap) {
        AVIF_ASSERT_OR_RETURN(image->gainMap != NULL && image->gainMap->image != NULL);
        gainmapMetadataSize = avifGainMapMetadataSize(image->gainMap);
        AVIF_ASSERT_OR_RETURN(gainmapData != NULL);

        // _minus1 is encoded for these fields.
        AVIF_ASSERT_OR_RETURN(image->gainMap->image->width != 0 && image->gainMap->image->height != 0);

        largeDimensionsFlag |= image->gainMap->image->width - 1 >= (1 << 7) || image->gainMap->image->height - 1 >= (1 << 7);
        largeItemDataFlag |= gainmapData->size >= (1 << 15);
        largeMetadataFlag |=
            (encoder->data->altImageMetadata->icc.size != 0 && encoder->data->altImageMetadata->icc.size - 1 >= (1 << 10)) ||
            gainmapMetadataSize >= (1 << 10);
        // image->gainMap->image->icc is ignored.
    }

    avifBoxMarker mini;
    AVIF_CHECKRES(avifRWStreamWriteBox(s, "mini", AVIF_BOX_SIZE_TBD, &mini));
    AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, 2)); // bit(2) version = 0;

    // flags
    AVIF_CHECKRES(avifRWStreamWriteBits(s, hasExplicitCodecTypes, 1)); // bit(1) explicit_codec_types_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, floatFlag, 1));             // bit(1) float_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, fullRange, 1));             // bit(1) full_range_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, alphaItem != 0, 1));        // bit(1) alpha_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, hasExplicitCicp, 1));       // bit(1) explicit_cicp_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, hasHdr, 1));                // bit(1) hdr_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, hasIcc, 1));                // bit(1) icc_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, image->exif.size != 0, 1)); // bit(1) exif_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, image->xmp.size != 0, 1));  // bit(1) xmp_flag;

    AVIF_CHECKRES(avifRWStreamWriteBits(s, chromaSubsampling, 2)); // bit(2) chroma_subsampling;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, orientationMinus1, 3)); // bit(3) orientation_minus1;

    // Spatial extents
    AVIF_CHECKRES(avifRWStreamWriteBits(s, largeDimensionsFlag, 1));                         // bit(1) large_dimensions_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, image->width - 1, largeDimensionsFlag ? 15 : 7)); // unsigned int(large_dimensions_flag ? 15 : 7) width_minus1;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, image->height - 1, largeDimensionsFlag ? 15 : 7)); // unsigned int(large_dimensions_flag ? 15 : 7) height_minus1;

    // Pixel information
    if (chromaSubsampling == 1 || chromaSubsampling == 2) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, chromaIsHorizontallyCentered, 1)); // bit(1) chroma_is_horizontally_centered;
    }
    if (chromaSubsampling == 1) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, chromaIsVerticallyCentered, 1)); // bit(1) chroma_is_vertically_centered;
    }

    if (floatFlag) {
        // bit(2) bit_depth_log2_minus4;
        AVIF_ASSERT_NOT_REACHED_OR_RETURN;
    } else {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, image->depth > 8, 1)); // bit(1) high_bit_depth_flag;
        if (image->depth > 8) {
            AVIF_CHECKRES(avifRWStreamWriteBits(s, image->depth - 9, 3)); // bit(3) bit_depth_minus9;
        }
    }

    if (alphaItem) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, alphaIsPremultiplied, 1)); // bit(1) alpha_is_premultiplied;
    }

    // Colour properties
    if (hasExplicitCicp) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, image->colorPrimaries, 8));          // bit(8) colour_primaries;
        AVIF_CHECKRES(avifRWStreamWriteBits(s, image->transferCharacteristics, 8)); // bit(8) transfer_characteristics;
        if (chromaSubsampling != 0) {
            AVIF_CHECKRES(avifRWStreamWriteBits(s, image->matrixCoefficients, 8)); // bit(8) matrix_coefficients;
        } else {
            AVIF_CHECKERR(image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_UNSPECIFIED, AVIF_RESULT_ENCODE_COLOR_FAILED);
        }
    }

    if (hasExplicitCodecTypes) {
        // bit(32) infe_type;
        for (int i = 0; i < 4; ++i) {
            AVIF_CHECKRES(avifRWStreamWriteBits(s, infeType[i], 8));
        }
        // bit(32) codec_config_type;
        for (int i = 0; i < 4; ++i) {
            AVIF_CHECKRES(avifRWStreamWriteBits(s, codecConfigType[i], 8));
        }
    }

    // High Dynamic Range properties
    size_t tmapIccSize = 0;
    if (hasHdr) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, hasGainmap, 1)); // bit(1) gainmap_flag;
        if (hasGainmap) {
            const avifImage * tmap = encoder->data->altImageMetadata;
            const avifImage * gainmap = image->gainMap->image;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainmap->width - 1, largeDimensionsFlag ? 15 : 7)); // unsigned int(large_dimensions_flag ? 15 : 7) gainmap_width_minus1;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainmap->height - 1, largeDimensionsFlag ? 15 : 7)); // unsigned int(large_dimensions_flag ? 15 : 7) gainmap_height_minus1;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainmap->matrixCoefficients, 8)); // bit(8) gainmap_matrix_coefficients;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainmap->yuvRange == AVIF_RANGE_FULL, 1)); // bit(1) gainmap_full_range_flag;
            const uint32_t gainmapChromaSubsampling = gainmap->yuvFormat == AVIF_PIXEL_FORMAT_YUV400   ? 0
                                                      : gainmap->yuvFormat == AVIF_PIXEL_FORMAT_YUV420 ? 1
                                                      : gainmap->yuvFormat == AVIF_PIXEL_FORMAT_YUV422 ? 2
                                                                                                       : 3;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainmapChromaSubsampling, 2)); // bit(1) gainmap_chroma_subsampling;
            if (gainmapChromaSubsampling == 1 || gainmapChromaSubsampling == 2) {
                AVIF_CHECKRES(avifRWStreamWriteBits(s,
                                                    gainmap->yuvFormat == AVIF_PIXEL_FORMAT_YUV420 &&
                                                        gainmap->yuvChromaSamplePosition != AVIF_CHROMA_SAMPLE_POSITION_VERTICAL &&
                                                        gainmap->yuvChromaSamplePosition != AVIF_CHROMA_SAMPLE_POSITION_COLOCATED,
                                                    1)); // bit(1) gainmap_chroma_is_horizontally_centered;
            }
            if (gainmapChromaSubsampling == 1) {
                AVIF_CHECKRES(avifRWStreamWriteBits(s,
                                                    gainmap->yuvFormat == AVIF_PIXEL_FORMAT_YUV420 &&
                                                        gainmap->yuvChromaSamplePosition != AVIF_CHROMA_SAMPLE_POSITION_COLOCATED,
                                                    1)); // bit(1) gainmap_chroma_is_vertically_centered;
            }

            const avifBool gainmapFloatFlag = AVIF_FALSE;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, gainmapFloatFlag, 1)); // bit(1) gainmap_float_flag;
            if (gainmapFloatFlag) {
                // bit(2) gainmap_bit_depth_log2_minus4;
                AVIF_ASSERT_NOT_REACHED_OR_RETURN;
            } else {
                AVIF_CHECKRES(avifRWStreamWriteBits(s, gainmap->depth > 8, 1)); // bit(1) gainmap_high_bit_depth_flag;
                if (gainmap->depth > 8) {
                    AVIF_CHECKRES(avifRWStreamWriteBits(s, gainmap->depth - 9, 3)); // bit(3) gainmap_bit_depth_minus9;
                }
            }

            tmapIccSize = encoder->data->altImageMetadata->icc.size;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, tmapIccSize != 0, 1)); // bit(1) tmap_icc_flag;
            const avifBool tmapHasExplicitCicp = tmap->colorPrimaries != AVIF_COLOR_PRIMARIES_BT709 ||
                                                 tmap->transferCharacteristics != AVIF_TRANSFER_CHARACTERISTICS_SRGB ||
                                                 tmap->matrixCoefficients != AVIF_MATRIX_COEFFICIENTS_BT601 ||
                                                 tmap->yuvRange != AVIF_RANGE_FULL;
            AVIF_CHECKRES(avifRWStreamWriteBits(s, tmapHasExplicitCicp, 1)); // bit(1) tmap_explicit_cicp_flag;
            if (tmapHasExplicitCicp) {
                AVIF_CHECKRES(avifRWStreamWriteBits(s, tmap->colorPrimaries, 8));          // bit(8) tmap_colour_primaries;
                AVIF_CHECKRES(avifRWStreamWriteBits(s, tmap->transferCharacteristics, 8)); // bit(8) tmap_transfer_characteristics;
                AVIF_CHECKRES(avifRWStreamWriteBits(s, tmap->matrixCoefficients, 8));      // bit(8) tmap_matrix_coefficients;
                AVIF_CHECKRES(avifRWStreamWriteBits(s, tmap->yuvRange == AVIF_RANGE_FULL, 1)); // bit(8) tmap_full_range_flag;
            }
            // gainmap->icc is ignored.
        }

        AVIF_CHECKRES(avifEncoderWriteMiniHDRProperties(s, image));
        if (hasGainmap) {
            AVIF_CHECKRES(avifEncoderWriteMiniHDRProperties(s, encoder->data->altImageMetadata));
        }
    }

    // Chunk sizes
    if (hasIcc || image->exif.size || image->xmp.size || (hasHdr && hasGainmap)) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, largeMetadataFlag, 1)); // bit(1) large_metadata_flag;
    }
    AVIF_CHECKRES(avifRWStreamWriteBits(s, largeCodecConfigFlag, 1)); // bit(1) large_codec_config_flag;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, largeItemDataFlag, 1));    // bit(1) large_item_data_flag;

    if (hasIcc) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, (uint32_t)image->icc.size - 1, largeMetadataFlag ? 20 : 10)); // unsigned int(large_metadata_flag ? 20 : 10) icc_data_size_minus1;
    }
    if (hasHdr && hasGainmap && tmapIccSize != 0) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, (uint32_t)tmapIccSize - 1, largeMetadataFlag ? 20 : 10)); // unsigned int(large_metadata_flag ? 20 : 10) tmap_icc_data_size_minus1;
    }

    if (hasHdr && hasGainmap) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, gainmapMetadataSize, largeMetadataFlag ? 20 : 10)); // unsigned int(large_metadata_flag ? 20 : 10) gainmap_metadata_size;
    }
    if (hasHdr && hasGainmap) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, (uint32_t)gainmapData->size, largeItemDataFlag ? 28 : 15)); // unsigned int(large_item_data_flag ? 28 : 15) gainmap_item_data_size;
    }
    if (hasHdr && hasGainmap && gainmapData->size != 0) {
        if (!memcmp(&colorItem->av1C, &gainmapItem->av1C, sizeof(colorItem->av1C))) {
            // The gainmap codec config is copied from the main codec config.
            // This is signaled by a size of 0.
            gainmapCodecConfigSize = 0;
        } else {
            gainmapCodecConfigSize = codecConfigSize;
        }
        AVIF_CHECKRES(avifRWStreamWriteBits(s, gainmapCodecConfigSize, largeCodecConfigFlag ? 12 : 3)); // unsigned int(large_codec_config_flag ? 12 : 3) gainmap_item_codec_config_size;
    }

    AVIF_CHECKRES(avifRWStreamWriteBits(s, codecConfigSize, largeCodecConfigFlag ? 12 : 3)); // unsigned int(large_codec_config_flag ? 12 : 3) main_item_codec_config_size;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, (uint32_t)colorData->size - 1, largeItemDataFlag ? 28 : 15)); // unsigned int(large_item_data_flag ? 28 : 15) main_item_data_size_minus1;

    if (hasAlpha) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, (uint32_t)alphaData->size, largeItemDataFlag ? 28 : 15)); // unsigned int(large_item_data_flag ? 28 : 15) alpha_item_data_size;
    }
    if (hasAlpha && alphaData->size != 0) {
        if (!memcmp(&colorItem->av1C, &alphaItem->av1C, sizeof(colorItem->av1C))) {
            // The alpha codec config is copied from the main codec config.
            // This is signaled by a size of 0.
            alphaCodecConfigSize = 0;
        } else {
            alphaCodecConfigSize = codecConfigSize;
        }
        AVIF_CHECKRES(avifRWStreamWriteBits(s, alphaCodecConfigSize, largeCodecConfigFlag ? 12 : 3)); // unsigned int(large_codec_config_flag ? 12 : 3) alpha_item_codec_config_size;
    }

    if (image->exif.size || image->xmp.size) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, 1)); // unsigned int(1) exif_xmp_compressed_flag
    }
    if (image->exif.size) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, (uint32_t)image->exif.size - 1, largeMetadataFlag ? 20 : 10)); // unsigned int(large_metadata_flag ? 20 : 10) exif_data_size_minus_one;
    }
    if (image->xmp.size) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, (uint32_t)image->xmp.size - 1, largeMetadataFlag ? 20 : 10)); // unsigned int(large_metadata_flag ? 20 : 10) xmp_data_size_minus_one;
    }

    // trailing_bits(); // bit padding till byte alignment
    if (s->numUsedBitsInPartialByte != 0) {
        AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, 8 - s->numUsedBitsInPartialByte));
    }
    const size_t headerBytes = avifRWStreamOffset(s);

    // Chunks
    if (codecConfigSize > 0) {
        AVIF_CHECKRES(writeCodecConfig(s, &colorItem->av1C)); // unsigned int(8) main_item_codec_config[main_item_codec_config_size];
    }
    if (hasAlpha && alphaData->size != 0 && alphaCodecConfigSize != 0) {
        AVIF_CHECKRES(writeCodecConfig(s, &alphaItem->av1C)); // unsigned int(8) alpha_item_codec_config[alpha_item_codec_config_size];
    }
    if (hasHdr && hasGainmap && gainmapCodecConfigSize != 0) {
        AVIF_CHECKRES(writeCodecConfig(s, &gainmapItem->av1C)); // unsigned int(8) gainmap_item_codec_config[gainmap_item_codec_config_size];
    }

    if (hasIcc) {
        AVIF_CHECKRES(avifRWStreamWrite(s, image->icc.data, image->icc.size)); // unsigned int(8) icc_data[icc_data_size_minus1 + 1];
    }
    if (hasHdr && hasGainmap && tmapIccSize != 0) {
        AVIF_CHECKRES(avifRWStreamWrite(s, encoder->data->altImageMetadata->icc.data, tmapIccSize)); // unsigned int(8) tmap_icc_data[tmap_icc_data_size_minus1 + 1];
    }
    if (hasHdr && hasGainmap && gainmapMetadataSize != 0) {
        AVIF_CHECKRES(avifWriteGainmapMetadata(s, image->gainMap, &encoder->diag)); // unsigned int(8) gainmap_metadata[gainmap_metadata_size];
    }

    if (hasAlpha && alphaData->size != 0) {
        AVIF_CHECKRES(avifRWStreamWrite(s, alphaData->data, alphaData->size)); // unsigned int(8) alpha_item_data[alpha_item_data_size];
    }
    if (hasHdr && hasGainmap && gainmapData->size != 0) {
        AVIF_CHECKRES(avifRWStreamWrite(s, gainmapData->data, gainmapData->size)); // unsigned int(8) gainmap_item_data[gainmap_item_data_size];
    }

    AVIF_CHECKRES(avifRWStreamWrite(s, colorData->data, colorData->size)); // unsigned int(8) main_item_data[main_item_data_size_minus1 + 1];

    if (image->exif.size) {
        AVIF_CHECKRES(avifRWStreamWrite(s, image->exif.data, image->exif.size)); // unsigned int(8) exif_data[exif_data_size_minus1 + 1];
    }
    if (image->xmp.size) {
        AVIF_CHECKRES(avifRWStreamWrite(s, image->xmp.data, image->xmp.size)); // unsigned int(8) xmp_data[xmp_data_size_minus1 + 1];
    }

    const size_t expectedChunkBytes = codecConfigSize + alphaCodecConfigSize + gainmapCodecConfigSize + image->icc.size +
                                      tmapIccSize + gainmapMetadataSize + (hasAlpha ? alphaData->size : 0) +
                                      (hasGainmap ? gainmapData->size : 0) + colorData->size + image->exif.size + image->xmp.size;
    AVIF_ASSERT_OR_RETURN(avifRWStreamOffset(s) == headerBytes + expectedChunkBytes);
    AVIF_CHECKRES(avifRWStreamFinishBox(s, mini));
    return AVIF_RESULT_OK;
}
#endif // AVIF_ENABLE_EXPERIMENTAL_MINI

static avifResult avifRWStreamWriteProperties(avifItemPropertyDedup * const dedup,
                                              avifRWStream * const s,
                                              const avifEncoder * const encoder,
                                              const avifImage * const imageMetadata,
                                              const avifImage * const altImageMetadata)
{
    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        const avifBool isGrid = (item->gridCols > 0);
        // Whether there is ipma to write for this item.
        avifBool hasIpmaToWrite = item->codec || isGrid;
        const avifBool isToneMappedImage = !memcmp(item->type, "tmap", 4);
        if (isToneMappedImage) {
            hasIpmaToWrite = AVIF_TRUE;
        }
        const avifBool isSampleTransformImage = !memcmp(item->type, "sato", 4);
        if (isSampleTransformImage) {
            hasIpmaToWrite = AVIF_TRUE;
        }
        item->associations.count = 0;
        if (!hasIpmaToWrite) {
            continue;
        }

        if (item->dimgFromID && (item->extraLayerCount == 0)) {
            avifEncoderItem * parentItem = avifEncoderDataFindItemByID(encoder->data, item->dimgFromID);
            if (parentItem && !memcmp(parentItem->type, "grid", 4)) {
                // All image cells from a grid should share the exact same properties unless they are
                // layered image which have different al1x, so see if we've already written properties
                // out for another cell in this grid, and if so, just steal their ipma and move on.
                // This is a sneaky way to provide iprp deduplication.

                avifBool foundPreviousCell = AVIF_FALSE;
                for (uint32_t dedupIndex = 0; dedupIndex < itemIndex; ++dedupIndex) {
                    avifEncoderItem * dedupItem = &encoder->data->items.item[dedupIndex];
                    if ((item->dimgFromID == dedupItem->dimgFromID) && (dedupItem->extraLayerCount == 0)) {
                        // We've already written dedup's items out. Steal their ipma indices and move on!
                        item->associations.count = 0;
                        for (uint32_t associationIndex = 0; associationIndex < dedupItem->associations.count; ++associationIndex) {
                            avifItemPropertyAssociation * association = (avifItemPropertyAssociation *)avifArrayPush(&item->associations);
                            AVIF_CHECKERR(association != NULL, AVIF_RESULT_OUT_OF_MEMORY);
                            *association = dedupItem->associations.association[associationIndex];
                        }
                        foundPreviousCell = AVIF_TRUE;
                        break;
                    }
                }
                if (foundPreviousCell) {
                    continue;
                }
            }
        }

        const avifImage * itemMetadata = imageMetadata;
        if (isToneMappedImage) {
            itemMetadata = altImageMetadata;
        } else if (item->itemCategory == AVIF_ITEM_GAIN_MAP) {
            AVIF_ASSERT_OR_RETURN(itemMetadata->gainMap && itemMetadata->gainMap->image);
            itemMetadata = itemMetadata->gainMap->image;
        }
        uint32_t imageWidth = itemMetadata->width;
        uint32_t imageHeight = itemMetadata->height;
        if (isGrid) {
            imageWidth = item->gridWidth;
            imageHeight = item->gridHeight;
        }

        // ISO/IEC 23008-12:2024 section 6.5.1:
        //   Writers should arrange the descriptive properties specified in 6.5 prior to any other properties
        //   in the sequence associating properties with an item.
        // For each item, write the descriptive properties first (and thus associate them before the
        // transformative properties).

        // Properties all image items need (coded and derived)
        // ispe = image spatial extent (width, height)
        avifItemPropertyDedupStart(dedup);
        avifBoxMarker ispe;
        AVIF_CHECKRES(avifRWStreamWriteFullBox(&dedup->s, "ispe", AVIF_BOX_SIZE_TBD, 0, 0, &ispe));
        AVIF_CHECKRES(avifRWStreamWriteU32(&dedup->s, imageWidth));  // unsigned int(32) image_width;
        AVIF_CHECKRES(avifRWStreamWriteU32(&dedup->s, imageHeight)); // unsigned int(32) image_height;
        AVIF_CHECKRES(avifRWStreamFinishBox(&dedup->s, ispe));
        AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, s, &item->associations, /*essential=*/AVIF_FALSE));

        // pixi = pixel information (depth, channel count)
        avifBool hasPixi = AVIF_TRUE;
        // Pixi is optional for the 'tmap' item.
        if (isToneMappedImage && imageMetadata->gainMap->altDepth == 0 && imageMetadata->gainMap->altPlaneCount == 0) {
            hasPixi = AVIF_FALSE;
        }
        const avifBool isAlpha = avifIsAlpha(item->itemCategory);
        uint8_t depth = (uint8_t)itemMetadata->depth;
        if (encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_8B_8B ||
            encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_4B ||
            encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_8B_OVERLAP_4B) {
            if (item->itemCategory == AVIF_ITEM_SAMPLE_TRANSFORM) {
                AVIF_ASSERT_OR_RETURN(depth == 16); // Only 16-bit depth is supported for now.
            } else if (encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_8B_8B) {
                depth = 8;
            } else {
                if (item->itemCategory == AVIF_ITEM_COLOR || item->itemCategory == AVIF_ITEM_ALPHA) {
                    depth = 12;
                } else {
                    AVIF_ASSERT_OR_RETURN(item->itemCategory == AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_COLOR ||
                                          item->itemCategory == AVIF_ITEM_SAMPLE_TRANSFORM_INPUT_0_ALPHA);
                    // Will be shifted to 4-bit samples at decoding for AVIF_SAMPLE_TRANSFORM_BIT_DEPTH_EXTENSION_12B_4B.
                    depth = 8;
                }
            }
        } else {
            AVIF_CHECKERR(encoder->sampleTransformRecipe == AVIF_SAMPLE_TRANSFORM_NONE, AVIF_RESULT_NOT_IMPLEMENTED);
        }
        assert(isSampleTransformImage == (item->itemCategory == AVIF_ITEM_SAMPLE_TRANSFORM));

        if (hasPixi) {
            avifItemPropertyDedupStart(dedup);
            uint8_t channelCount = (isAlpha || (itemMetadata->yuvFormat == AVIF_PIXEL_FORMAT_YUV400)) ? 1 : 3;
            // See ISO/IEC 23008-12:2024/CDAM 2:2025 section 6.5.6.3.
            avifBoxMarker pixi;
            uint32_t flags = 0;
#if defined(AVIF_ENABLE_EXPERIMENTAL_EXTENDED_PIXI)
            if (encoder->headerFormat & AVIF_HEADER_EXTENDED_PIXI) {
                flags |= 1;
            }
#endif // AVIF_ENABLE_EXPERIMENTAL_EXTENDED_PIXI
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&dedup->s, "pixi", AVIF_BOX_SIZE_TBD, 0, flags, &pixi));
            AVIF_CHECKRES(avifRWStreamWriteU8(&dedup->s, channelCount)); // unsigned int (8) num_channels;
            for (uint8_t chan = 0; chan < channelCount; ++chan) {
                AVIF_CHECKRES(avifRWStreamWriteU8(&dedup->s, depth)); // unsigned int (8) bits_per_channel;
            }
#if defined(AVIF_ENABLE_EXPERIMENTAL_EXTENDED_PIXI)
            if (flags & 1) {
                AVIF_ASSERT_OR_RETURN(item->av1C.chromaSamplePosition != AVIF_CHROMA_SAMPLE_POSITION_RESERVED);
                // Do not signal any subsampling information if the sample position is unknown because the 'pixi' box
                // does not have an enum entry for "unknown subsampling location".
                const uint8_t subsampling_flag = item->av1C.chromaSamplePosition == AVIF_CHROMA_SAMPLE_POSITION_VERTICAL ||
                                                 item->av1C.chromaSamplePosition == AVIF_CHROMA_SAMPLE_POSITION_COLOCATED;
                for (uint8_t chan = 0; chan < channelCount; ++chan) {
                    AVIF_CHECKRES(avifRWStreamWriteBits(&dedup->s, 0, /*bitCount=*/3)); // unsigned int(3) channel_idc;
                    AVIF_CHECKRES(avifRWStreamWriteBits(&dedup->s, 0, /*bitCount=*/1)); // unsigned int(1) reserved;
                    AVIF_CHECKRES(avifRWStreamWriteBits(&dedup->s, 0, /*bitCount=*/2)); // unsigned int(2) component_format;
                    AVIF_CHECKRES(avifRWStreamWriteBits(&dedup->s, subsampling_flag, /*bitCount=*/1)); // unsigned int(1) subsampling_flag;
                    AVIF_CHECKRES(avifRWStreamWriteBits(&dedup->s, 0, /*bitCount=*/1)); // unsigned int(1) channel_label_flag;
                    if (subsampling_flag) {
                        const uint8_t subsamplingType = avifCodecConfigurationBoxGetSubsamplingType(&item->av1C, chan);
                        const uint8_t subsamplingLocation = subsamplingType == AVIF_PIXI_444 ? 0
                                                            : item->av1C.chromaSamplePosition == AVIF_CHROMA_SAMPLE_POSITION_VERTICAL
                                                                ? 0
                                                                : 2;
                        AVIF_CHECKRES(avifRWStreamWriteBits(&dedup->s, subsamplingType, /*bitCount=*/4)); // unsigned int(4) subsampling_type;
                        AVIF_CHECKRES(avifRWStreamWriteBits(&dedup->s, subsamplingLocation, /*bitCount=*/4)); // unsigned int(4) subsampling_location;
                    }
                }
            }
#endif // AVIF_ENABLE_EXPERIMENTAL_EXTENDED_PIXI
            AVIF_CHECKRES(avifRWStreamFinishBox(&dedup->s, pixi));
            AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, s, &item->associations, /*essential=*/AVIF_FALSE));
        }

        // Codec configuration box ('av1C' or 'av2C')
        if (item->codec) {
            avifItemPropertyDedupStart(dedup);
            AVIF_CHECKRES(writeConfigBox(&dedup->s, &item->av1C, encoder->data->configPropName));
            AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, s, &item->associations, /*essential=*/AVIF_TRUE));
        }

        if (isAlpha) {
            // Alpha specific properties

            avifItemPropertyDedupStart(dedup);
            avifBoxMarker auxC;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&dedup->s, "auxC", AVIF_BOX_SIZE_TBD, 0, 0, &auxC));
            AVIF_CHECKRES(avifRWStreamWriteChars(&dedup->s, alphaURN, alphaURNSize)); //  string aux_type;
            AVIF_CHECKRES(avifRWStreamFinishBox(&dedup->s, auxC));
            AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, s, &item->associations, /*essential=*/AVIF_FALSE));
        } else if (item->itemCategory == AVIF_ITEM_COLOR) {
            // Color specific properties
            // Note the 'tmap' (tone mapped image) item when a gain map is present also has itemCategory AVIF_ITEM_COLOR.

            AVIF_CHECKRES(avifEncoderWriteColorProperties(s, itemMetadata, &item->associations, dedup));
            AVIF_CHECKRES(avifEncoderWriteHDRProperties(&dedup->s, s, itemMetadata, &item->associations, dedup));
        } else if (item->itemCategory == AVIF_ITEM_GAIN_MAP) {
            // Gain map specific properties

            // Write the colr nclx box.
            AVIF_CHECKRES(avifEncoderWriteNclxProperty(&dedup->s, s, itemMetadata, &item->associations, dedup));

            AVIF_CHECKRES(avifEncoderWritePaspProperty(&dedup->s, s, imageMetadata, &item->associations, dedup));
        }

        if (item->extraLayerCount > 0) {
            // Layered Image Indexing Property

            avifItemPropertyDedupStart(dedup);
            avifBoxMarker a1lx;
            AVIF_CHECKRES(avifRWStreamWriteBox(&dedup->s, "a1lx", AVIF_BOX_SIZE_TBD, &a1lx));
            uint32_t layerSize[AVIF_MAX_AV1_LAYER_COUNT - 1] = { 0 };
            avifBool largeSize = AVIF_FALSE;

            for (uint32_t validLayer = 0; validLayer < item->extraLayerCount; ++validLayer) {
                uint32_t size = (uint32_t)item->encodeOutput->samples.sample[validLayer].data.size;
                layerSize[validLayer] = size;
                if (size > 0xffff) {
                    largeSize = AVIF_TRUE;
                }
            }

            AVIF_CHECKRES(avifRWStreamWriteBits(&dedup->s, 0, /*bitCount=*/7));                 // unsigned int(7) reserved = 0;
            AVIF_CHECKRES(avifRWStreamWriteBits(&dedup->s, largeSize ? 1 : 0, /*bitCount=*/1)); // unsigned int(1) large_size;

            // FieldLength = (large_size + 1) * 16;
            // unsigned int(FieldLength) layer_size[3];
            for (uint32_t layer = 0; layer < AVIF_MAX_AV1_LAYER_COUNT - 1; ++layer) {
                if (largeSize) {
                    AVIF_CHECKRES(avifRWStreamWriteU32(&dedup->s, layerSize[layer]));
                } else {
                    AVIF_CHECKRES(avifRWStreamWriteU16(&dedup->s, (uint16_t)layerSize[layer]));
                }
            }
            AVIF_CHECKRES(avifRWStreamFinishBox(&dedup->s, a1lx));
            AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, s, &item->associations, /*essential=*/AVIF_FALSE));

            // We don't add an 'lsel' property since many decoders do not support it and will reject the image,
            // see https://github.com/AOMediaCodec/libavif/pull/2429.
            // Firefox 155 or later will support an 'lsel' property whose layer_id is 0xFFFF,
            // see https://bugzilla.mozilla.org/show_bug.cgi?id=2055813.
        }

        // Write out any opaque properties from avifImageAddOpaqueProperty() or avifImageAddUUIDProperty().
        for (size_t i = 0; i < itemMetadata->numProperties; i++) {
            avifItemPropertyDedupStart(dedup);
            const avifImageItemProperty * prop = &itemMetadata->properties[i];
            avifBoxMarker propMarker;
            AVIF_CHECKRES(avifRWStreamWriteBox(&dedup->s, (const char *)prop->boxtype, AVIF_BOX_SIZE_TBD, &propMarker));
            if (memcmp(prop->boxtype, "uuid", 4) == 0) {
                AVIF_CHECKRES(avifRWStreamWrite(&dedup->s, prop->usertype, 16));
            }
            AVIF_CHECKRES(avifRWStreamWrite(&dedup->s, prop->boxPayload.data, prop->boxPayload.size));
            AVIF_CHECKRES(avifRWStreamFinishBox(&dedup->s, propMarker));
            AVIF_CHECKRES(avifItemPropertyDedupFinish(dedup, s, &item->associations, /*essential=*/AVIF_FALSE));
        }

        // Also write the transformative properties.

        if (item->itemCategory == AVIF_ITEM_COLOR) {
            // Color specific properties
            // Note the 'tmap' (tone mapped image) item when a gain map is present also has itemCategory AVIF_ITEM_COLOR.
            AVIF_CHECKRES(avifEncoderWriteTransformativeProperties(&dedup->s, s, itemMetadata, &item->associations, dedup));
        } else if (item->itemCategory == AVIF_ITEM_ALPHA) {
            // Cropping, rotation and mirroring must also be applied to alpha auxiliary items.
            AVIF_CHECKRES(avifEncoderWriteTransformativeProperties(&dedup->s, s, itemMetadata, &item->associations, dedup));
        } else if (item->itemCategory == AVIF_ITEM_GAIN_MAP) {
            // Gain map specific properties

            // For the orientation, it could be done in multiple ways:
            // - Bake the orientation in the base and gain map images.
            //   This does not allow for orientation changes without recompression.
            // - Associate 'irot'/'imir' with the 'tmap' derived image item only.
            //   If so, decoding only the base image would give a different orientation than
            //   decoding the tone-mapped image.
            // - Wrap the base image in an 'iden' derived image item and associate 'irot'/'imir'
            //   with the 'tmap' and 'iden' derived image items. 'iden' is not currently supported
            //   by libavif, reducing the backward compatibility of this solution.
            // - Associate 'irot'/'imir' with the base and gain map image items.
            //   Do not associate 'irot'/'imir' with the 'tmap' derived image item.
            //   These transformative properties are supposed to be applied at decoding on
            //   image items before these are used as input to a derived image item.
            //   libavif uses this pattern at encoding and requires it at decoding.
            //   As of today, this is forbidden by the AVIF specification:
            //     https://aomediacodec.github.io/av1-avif/v1.1.0.html#file-constraints
            //   That rule was written before 'tmap' was proposed and may be relaxed for 'tmap'.

            // 'clap' is treated as 'irot'/'imir', although it could differ between the base and
            // gain map image items if these have different dimensions.
            if (imageMetadata->transformFlags & AVIF_TRANSFORM_CLAP) {
                AVIF_CHECKERR(imageMetadata->width != itemMetadata->width || imageMetadata->height != itemMetadata->height,
                              AVIF_RESULT_NOT_IMPLEMENTED);
            }

            // 'pasp' is not a transformative property (despite AVIF_TRANSFORM_PASP being part of
            // avifTransformFlag) but it is assumed to apply to the gain map in the same way as
            // the transformative properties above.

            // Based on the explanation above, 'clap', 'irot', 'imir' and 'pasp' have to match between the base and
            // gain map image items in the container part of the encoded file.
            // To enforce that, the transformative and 'pasp' properties of the gain map cannot be set explicitly in the API.
            AVIF_CHECKERR(itemMetadata->transformFlags == AVIF_TRANSFORM_NONE, AVIF_RESULT_ENCODE_GAIN_MAP_FAILED);
            AVIF_CHECKRES(avifEncoderWriteTransformativeProperties(&dedup->s, s, imageMetadata, &item->associations, dedup));
        }
    }
    return AVIF_RESULT_OK;
}

avifResult avifEncoderFinish(avifEncoder * encoder, avifRWData * output)
{
    avifDiagnosticsClearError(&encoder->diag);
    if (encoder->data->items.count == 0) {
        return AVIF_RESULT_NO_CONTENT;
    }

    const avifCodecType codecType = avifEncoderGetCodecType(encoder);
    if (codecType == AVIF_CODEC_TYPE_UNKNOWN) {
        return AVIF_RESULT_NO_CODEC_AVAILABLE;
    }

    // -----------------------------------------------------------------------
    // Finish up encoding

    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        if (item->codec) {
            if (!item->codec->encodeFinish(item->codec, item->encodeOutput)) {
                return avifGetErrorForItemCategory(item->itemCategory);
            }

            if (item->encodeOutput->samples.count != encoder->data->frames.count) {
                return avifGetErrorForItemCategory(item->itemCategory);
            }

            if ((item->extraLayerCount > 0) && (item->encodeOutput->samples.count != item->extraLayerCount + 1)) {
                // Check whether user has sent enough frames to encoder.
                avifDiagnosticsPrintf(&encoder->diag,
                                      "Expected %u frames given to avifEncoderAddImage() to encode this layered image according to extraLayerCount, but got %u frames.",
                                      item->extraLayerCount + 1,
                                      item->encodeOutput->samples.count);
                return AVIF_RESULT_INVALID_ARGUMENT;
            }
        }
    }

    // -----------------------------------------------------------------------
    // Harvest configuration properties from sequence headers

    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        if (item->encodeOutput->samples.count > 0) {
            const avifEncodeSample * firstSample = &item->encodeOutput->samples.sample[0];
            avifSequenceHeader sequenceHeader;
            AVIF_CHECKERR(avifSequenceHeaderParse(&sequenceHeader, (const avifROData *)&firstSample->data, codecType),
                          avifGetErrorForItemCategory(item->itemCategory));
            item->av1C = sequenceHeader.av1C;
        }
    }

    // -----------------------------------------------------------------------
    // Begin write stream

#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
    // Decide whether to go for a reduced MinimizedImageBox or a full regular MetaBox.
    if ((encoder->headerFormat & AVIF_HEADER_MINI) && avifEncoderIsMiniCompatible(encoder)) {
        AVIF_CHECKRES(avifEncoderWriteFileTypeBoxAndMiniBox(encoder, output));
        return AVIF_RESULT_OK;
    }
#endif // AVIF_ENABLE_EXPERIMENTAL_MINI

    const avifImage * imageMetadata = encoder->data->imageMetadata;
    uint64_t now = (uint64_t)time(NULL);
    uint64_t modificationTime = (encoder->modificationTime != 0) ? encoder->modificationTime : now;
    uint64_t creationTime = (encoder->creationTime != 0) ? encoder->creationTime : modificationTime;
    // The epoch for creation_time and modification_time is midnight, Jan. 1,
    // 1904, in UTC time. Add the number of seconds between that epoch and the
    // Unix epoch.
    creationTime += 2082844800;
    modificationTime += 2082844800;

    avifRWStream s;
    avifRWStreamStart(&s, output);

    // -----------------------------------------------------------------------
    // Write ftyp

    // Layered sequence is not supported for now.
    const avifBool isSequence = (encoder->extraLayerCount == 0) && (encoder->data->frames.count > 1);

    const char * majorBrand = "avif";
    if (isSequence) {
        majorBrand = "avis";
    }

    uint32_t minorVersion = 0;
#if defined(AVIF_CODEC_AVM)
    if (codecType == AVIF_CODEC_TYPE_AV2) {
        // TODO(yguyon): Experimental AV2-AVIF is AVIF version 2 for now (change once it is ratified).
        minorVersion = 2;
    }
#endif

    // According to section 5.2 of AV1 Image File Format specification v1.1.0:
    //   If the primary item or all the items referenced by the primary item are AV1 image items made only
    //   of Intra Frames, the brand "avio" should be used in the compatible_brands field of the FileTypeBox.
    // See https://aomediacodec.github.io/av1-avif/v1.1.0.html#image-and-image-collection-brand.
    // This rule corresponds to using the "avio" brand in all cases except for layered images, because:
    //  - Non-layered still images are always Intra Frames, even with grids;
    //  - Sequences cannot be combined with layers or grids, and the first frame of the sequence
    //    (referred to by the primary image item) is always an Intra Frame.
    avifBool useAvioBrand;
    if (isSequence) {
        // According to section 5.3 of AV1 Image File Format specification v1.1.0:
        //   Additionally, if a file contains AV1 image sequences and the brand avio is used in the
        //   compatible_brands field of the FileTypeBox, the item constraints for this brand shall be met
        //   and at least one of the AV1 image sequences shall be made only of AV1 Samples marked as sync.
        // See https://aomediacodec.github.io/av1-avif/v1.1.0.html#image-sequence-brand.
        useAvioBrand = AVIF_FALSE;
        for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
            avifEncoderItem * item = &encoder->data->items.item[itemIndex];
            if (item->encodeOutput->samples.count == 0) {
                continue; // Not a track.
            }
            avifBool onlySyncSamples = AVIF_TRUE;
            for (uint32_t sampleIndex = 0; sampleIndex < item->encodeOutput->samples.count; ++sampleIndex) {
                if (!item->encodeOutput->samples.sample[sampleIndex].sync) {
                    onlySyncSamples = AVIF_FALSE;
                    break;
                }
            }
            if (onlySyncSamples) {
                useAvioBrand = AVIF_TRUE; // at least one of the AV1 image sequences is made only of sync samples
                break;
            }
        }
    } else {
        // The gpac/ComplianceWarden tool only warns about the lack of the "avio" brand for sequences,
        // and the specification says the brand "should" be used, not "shall". Leverage that opportunity
        // to save four bytes for still images.
        useAvioBrand = AVIF_FALSE; // Should be (encoder->extraLayerCount == 0) to be fully compliant.
    }

    avifBoxMarker ftyp;
    AVIF_CHECKRES(avifRWStreamWriteBox(&s, "ftyp", AVIF_BOX_SIZE_TBD, &ftyp));
    AVIF_CHECKRES(avifRWStreamWriteChars(&s, majorBrand, 4)); // unsigned int(32) major_brand;
    AVIF_CHECKRES(avifRWStreamWriteU32(&s, minorVersion));    // unsigned int(32) minor_version;
    AVIF_CHECKRES(avifRWStreamWriteChars(&s, "avif", 4));     // unsigned int(32) compatible_brands[];
    if (useAvioBrand) {
        AVIF_CHECKRES(avifRWStreamWriteChars(&s, "avio", 4)); // ... compatible_brands[]
    }
    if (isSequence) {
        AVIF_CHECKRES(avifRWStreamWriteChars(&s, "avis", 4)); // ... compatible_brands[]
        AVIF_CHECKRES(avifRWStreamWriteChars(&s, "msf1", 4)); // ... compatible_brands[]
        AVIF_CHECKRES(avifRWStreamWriteChars(&s, "iso8", 4)); // ... compatible_brands[]
    }
    AVIF_CHECKRES(avifRWStreamWriteChars(&s, "mif1", 4));                  // ... compatible_brands[]
    AVIF_CHECKRES(avifRWStreamWriteChars(&s, "miaf", 4));                  // ... compatible_brands[]
    if ((imageMetadata->depth == 8) || (imageMetadata->depth == 10)) {     //
        if (imageMetadata->yuvFormat == AVIF_PIXEL_FORMAT_YUV420) {        //
            AVIF_CHECKRES(avifRWStreamWriteChars(&s, "MA1B", 4));          // ... compatible_brands[]
        } else if (imageMetadata->yuvFormat == AVIF_PIXEL_FORMAT_YUV444) { //
            AVIF_CHECKRES(avifRWStreamWriteChars(&s, "MA1A", 4));          // ... compatible_brands[]
        }
    }
    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        if (!memcmp(encoder->data->items.item[itemIndex].type, "tmap", 4)) {
            // ISO/IEC 23008-12:2024/AMD 1:2024(E)
            // 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.
            AVIF_CHECKRES(avifRWStreamWriteChars(&s, "tmap", 4)); // ... compatible_brands[]
            break;
        }
    }
    AVIF_CHECKRES(avifRWStreamFinishBox(&s, ftyp));

    // -----------------------------------------------------------------------
    // Start meta

    avifBoxMarker meta;
    AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "meta", AVIF_BOX_SIZE_TBD, 0, 0, &meta));

    // -----------------------------------------------------------------------
    // Write hdlr

    AVIF_CHECKRES(avifRWStreamWriteHandlerBox(&s, "pict"));

    // -----------------------------------------------------------------------
    // Write pitm

    // Use the 32-bit item ID variants of the 'pitm', 'iloc', 'iinf', 'infe', 'iref' and
    // 'ipma' boxes below if any item ID or the item count exceeds the 16-bit space, i.e. if
    // there are more than 65535 items (item IDs are sequential and start at 1).
    const avifBool largeItemIDs = encoder->data->lastItemID > UINT16_MAX || encoder->data->items.count > UINT16_MAX;

    if (encoder->data->primaryItemID != 0) {
        if (largeItemIDs) {
            // 'pitm' version 1 contains a 32-bit item_ID field, whereas version 0 contains a 16-bit item_ID field.
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "pitm", sizeof(uint32_t), 1, 0, /*marker=*/NULL));
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, encoder->data->primaryItemID)); //  unsigned int(32) item_ID;
        } else {
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "pitm", sizeof(uint16_t), 0, 0, /*marker=*/NULL));
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)encoder->data->primaryItemID)); //  unsigned int(16) item_ID;
        }
    }

    // -----------------------------------------------------------------------
    // Write iloc

    avifBoxMarker iloc;
    AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "iloc", AVIF_BOX_SIZE_TBD, largeItemIDs ? 2 : 0, 0, &iloc));
    AVIF_CHECKRES(avifRWStreamWriteBits(&s, 4, /*bitCount=*/4)); // unsigned int(4) offset_size;
    AVIF_CHECKRES(avifRWStreamWriteBits(&s, 4, /*bitCount=*/4)); // unsigned int(4) length_size;
    AVIF_CHECKRES(avifRWStreamWriteBits(&s, 0, /*bitCount=*/4)); // unsigned int(4) base_offset_size;
    AVIF_CHECKRES(avifRWStreamWriteBits(&s, 0, /*bitCount=*/4)); // unsigned int(4) index_size, or reserved if version < 1;
    if (largeItemIDs) {
        // 'iloc' version 2 contains a 32-bit item_count field, whereas versions 0 and 1 contain a 16-bit item_count field.
        AVIF_CHECKRES(avifRWStreamWriteU32(&s, encoder->data->items.count)); // unsigned int(32) item_count;
    } else {
        AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)encoder->data->items.count)); // unsigned int(16) item_count;
    }

    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        if (largeItemIDs) {
            // 'iloc' version 2 contains a 32-bit item_ID field, whereas versions 0 and 1 contain a 16-bit item_ID field.
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, item->id));            // unsigned int(32) item_ID;
            AVIF_CHECKRES(avifRWStreamWriteBits(&s, 0, /*bitCount=*/12)); // unsigned int(12) reserved = 0;
            AVIF_CHECKRES(avifRWStreamWriteBits(&s, 0, /*bitCount=*/4)); // unsigned int(4) construction_method = 0 (file offset);
        } else {
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)item->id)); // unsigned int(16) item_ID;
        }
        AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0)); // unsigned int(16) data_reference_index;

        // Layered Image, write location for all samples
        if (item->extraLayerCount > 0) {
            uint32_t layerCount = item->extraLayerCount + 1;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)layerCount)); // unsigned int(16) extent_count;
            for (uint32_t i = 0; i < layerCount; ++i) {
                AVIF_CHECKRES(avifEncoderItemAddMdatFixup(item, &s));
                AVIF_CHECKRES(avifRWStreamWriteU32(&s, 0 /* set later */)); // unsigned int(offset_size*8) extent_offset;
                AVIF_CHECKRES(avifRWStreamWriteU32(&s, (uint32_t)item->encodeOutput->samples.sample[i].data.size)); // unsigned int(length_size*8) extent_length;
            }
            continue;
        }

        uint32_t contentSize = (uint32_t)item->metadataPayload.size;
        if (item->encodeOutput->samples.count > 0) {
            // This is choosing sample 0's size as there are two cases here:
            // * This is a single image, in which case this is correct
            // * This is an image sequence, but this file should still be a valid single-image avif,
            //   so there must still be a primary item pointing at a sync sample. Since the first
            //   frame of the image sequence is guaranteed to be a sync sample, it is chosen here.
            contentSize = (uint32_t)item->encodeOutput->samples.sample[0].data.size;
        }

        AVIF_CHECKRES(avifRWStreamWriteU16(&s, 1));                     // unsigned int(16) extent_count;
        AVIF_CHECKRES(avifEncoderItemAddMdatFixup(item, &s));           //
        AVIF_CHECKRES(avifRWStreamWriteU32(&s, 0 /* set later */));     // unsigned int(offset_size*8) extent_offset;
        AVIF_CHECKRES(avifRWStreamWriteU32(&s, (uint32_t)contentSize)); // unsigned int(length_size*8) extent_length;
    }

    AVIF_CHECKRES(avifRWStreamFinishBox(&s, iloc));

    // -----------------------------------------------------------------------
    // Write iinf

    // Section 8.11.6.2 of ISO/IEC 14496-12.
    avifBoxMarker iinf;
    // 'iinf' version 1 contains a 32-bit entry_count field, whereas version 0 contains a 16-bit entry_count field.
    AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "iinf", AVIF_BOX_SIZE_TBD, largeItemIDs ? 1 : 0, 0, &iinf));
    if (largeItemIDs) {
        AVIF_CHECKRES(avifRWStreamWriteU32(&s, encoder->data->items.count)); //  unsigned int(32) entry_count;
    } else {
        AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)encoder->data->items.count)); //  unsigned int(16) entry_count;
    }

    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];

        uint32_t flags = item->hiddenImage ? 1 : 0;
        avifBoxMarker infe;
        // 'infe' version 3 contains a 32-bit item_ID field, whereas version 2 contains a 16-bit item_ID field.
        AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "infe", AVIF_BOX_SIZE_TBD, largeItemIDs ? 3 : 2, flags, &infe));
        if (largeItemIDs) {
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, item->id)); // unsigned int(32) item_ID;
        } else {
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)item->id)); // unsigned int(16) item_ID;
        }
        AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0));                                    // unsigned int(16) item_protection_index;
        AVIF_CHECKRES(avifRWStreamWrite(&s, item->type, 4));                           // unsigned int(32) item_type;
        AVIF_CHECKRES(avifRWStreamWriteChars(&s, item->infeName, item->infeNameSize)); // utf8string item_name; (writing null terminator)
        if (!memcmp(item->type, "mime", 4)) {
            AVIF_CHECKRES(avifRWStreamWriteChars(&s, item->infeContentType, item->infeContentTypeSize)); // utf8string content_type; (writing null terminator)
            // utf8string content_encoding; //optional
        } else if (!memcmp(item->type, "uri ", 4)) {
            // utf8string item_uri_type;
            return AVIF_RESULT_NOT_IMPLEMENTED;
        }
        AVIF_CHECKRES(avifRWStreamFinishBox(&s, infe));
    }

    AVIF_CHECKRES(avifRWStreamFinishBox(&s, iinf));

    // -----------------------------------------------------------------------
    // Write iref boxes

    avifBoxMarker iref = 0;
    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];

        // Count how many other items refer to this item with dimgFromID
        uint16_t dimgCount = 0;
        for (uint32_t dimgIndex = 0; dimgIndex < encoder->data->items.count; ++dimgIndex) {
            avifEncoderItem * dimgItem = &encoder->data->items.item[dimgIndex];
            if (dimgItem->dimgFromID == item->id) {
                ++dimgCount;
            }
        }

        if (dimgCount > 0) {
            if (!iref) {
                // 'iref' version 1 contains 32-bit item_ID fields, whereas version 0 contains 16-bit item_ID fields.
                AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "iref", AVIF_BOX_SIZE_TBD, largeItemIDs ? 1 : 0, 0, &iref));
            }
            avifBoxMarker refType;
            AVIF_CHECKRES(avifRWStreamWriteBox(&s, "dimg", AVIF_BOX_SIZE_TBD, &refType));
            if (largeItemIDs) {
                AVIF_CHECKRES(avifRWStreamWriteU32(&s, item->id)); // unsigned int(32) from_item_ID;
            } else {
                AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)item->id)); // unsigned int(16) from_item_ID;
            }
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, dimgCount)); // unsigned int(16) reference_count;
            for (uint32_t dimgIndex = 0; dimgIndex < encoder->data->items.count; ++dimgIndex) {
                avifEncoderItem * dimgItem = &encoder->data->items.item[dimgIndex];
                if (dimgItem->dimgFromID == item->id) {
                    if (largeItemIDs) {
                        AVIF_CHECKRES(avifRWStreamWriteU32(&s, dimgItem->id)); // unsigned int(32) to_item_ID;
                    } else {
                        AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)dimgItem->id)); // unsigned int(16) to_item_ID;
                    }
                }
            }
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, refType));
        }

        if (item->irefToID != 0) {
            if (!iref) {
                // 'iref' version 1 contains 32-bit item_ID fields, whereas version 0 contains 16-bit item_ID fields.
                AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "iref", AVIF_BOX_SIZE_TBD, largeItemIDs ? 1 : 0, 0, &iref));
            }
            avifBoxMarker refType;
            AVIF_CHECKRES(avifRWStreamWriteBox(&s, item->irefType, AVIF_BOX_SIZE_TBD, &refType));
            if (largeItemIDs) {
                AVIF_CHECKRES(avifRWStreamWriteU32(&s, item->id));       // unsigned int(32) from_item_ID;
                AVIF_CHECKRES(avifRWStreamWriteU16(&s, 1));              // unsigned int(16) reference_count;
                AVIF_CHECKRES(avifRWStreamWriteU32(&s, item->irefToID)); // unsigned int(32) to_item_ID;
            } else {
                AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)item->id));       // unsigned int(16) from_item_ID;
                AVIF_CHECKRES(avifRWStreamWriteU16(&s, 1));                        // unsigned int(16) reference_count;
                AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)item->irefToID)); // unsigned int(16) to_item_ID;
            }
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, refType));
        }
    }
    if (iref) {
        AVIF_CHECKRES(avifRWStreamFinishBox(&s, iref));
    }

    // -----------------------------------------------------------------------
    // Write iprp -> ipco/ipma

    avifBoxMarker iprp;
    AVIF_CHECKRES(avifRWStreamWriteBox(&s, "iprp", AVIF_BOX_SIZE_TBD, &iprp));

    avifItemPropertyDedup * dedup = avifItemPropertyDedupCreate();
    AVIF_CHECKERR(dedup != NULL, AVIF_RESULT_OUT_OF_MEMORY);
    avifBoxMarker ipco;
    AVIF_CHECKRES(avifRWStreamWriteBox(&s, "ipco", AVIF_BOX_SIZE_TBD, &ipco));
    avifImage * altImageMetadata = NULL;
    altImageMetadata = encoder->data->altImageMetadata;
    avifResult result = avifRWStreamWriteProperties(dedup, &s, encoder, imageMetadata, altImageMetadata);
    avifItemPropertyDedupDestroy(dedup);
    dedup = NULL;
    AVIF_CHECKRES(result);
    AVIF_CHECKRES(avifRWStreamFinishBox(&s, ipco));

    avifBoxMarker ipma;
    // 'ipma' version 1 contains a 32-bit item_ID field, whereas version 0 contains a 16-bit item_ID field.
    // Note: the flags remain 0, meaning the property_index fields stay 7-bit wide.
    AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "ipma", AVIF_BOX_SIZE_TBD, largeItemIDs ? 1 : 0, 0, &ipma));
    {
        uint32_t ipmaCount = 0;
        for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
            avifEncoderItem * item = &encoder->data->items.item[itemIndex];
            if (item->associations.count > 0) {
                AVIF_CHECKERR(ipmaCount < UINT32_MAX, AVIF_RESULT_INVALID_ARGUMENT);
                ++ipmaCount;
            }
        }
        AVIF_CHECKRES(avifRWStreamWriteU32(&s, ipmaCount)); // unsigned int(32) entry_count;

        for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
            avifEncoderItem * item = &encoder->data->items.item[itemIndex];
            if (item->associations.count == 0) {
                continue;
            }

            if (largeItemIDs) {
                AVIF_CHECKRES(avifRWStreamWriteU32(&s, item->id)); // unsigned int(32) item_ID;
            } else {
                AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)item->id)); // unsigned int(16) item_ID;
            }
            AVIF_ASSERT_OR_RETURN(item->associations.count < (1 << 8));
            AVIF_CHECKRES(avifRWStreamWriteU8(&s, (uint8_t)item->associations.count)); // unsigned int(8) association_count;
            for (uint32_t i = 0; i < item->associations.count; ++i) {
                const avifItemPropertyAssociation * association = &item->associations.association[i];
                AVIF_CHECKRES(avifRWStreamWriteBits(&s, association->essential ? 1 : 0, /*bitCount=*/1)); // bit(1) essential;
                AVIF_ASSERT_OR_RETURN(association->property_index <= MAX_PROPERTY_INDEX);
                AVIF_CHECKRES(avifRWStreamWriteBits(&s, association->property_index, /*bitCount=*/7)); // unsigned int(7) property_index;
            }
        }
    }
    AVIF_CHECKRES(avifRWStreamFinishBox(&s, ipma));

    AVIF_CHECKRES(avifRWStreamFinishBox(&s, iprp));

    // -----------------------------------------------------------------------
    // Write grpl/altr box

    if (encoder->data->alternativeItemIDs.count) {
        // Section 8.18.3.3 of ISO 14496-12 (ISOBMFF) says:
        //   group_id is a non-negative integer assigned to the particular grouping that shall not be equal to any
        //   group_id value of any other EntityToGroupBox, any item_ID value of the hierarchy level
        //   (file, movie. or track) that contains the GroupsListBox, or any track_ID value (when the
        //   GroupsListBox is contained in the file level).
        AVIF_ASSERT_OR_RETURN(encoder->data->lastItemID < UINT32_MAX);
        ++encoder->data->lastItemID;
        const uint32_t groupID = encoder->data->lastItemID;
        AVIF_CHECKRES(avifWriteAltrGroup(&s, groupID, &encoder->data->alternativeItemIDs));
    }

    // -----------------------------------------------------------------------
    // Finish meta box

    AVIF_CHECKRES(avifRWStreamFinishBox(&s, meta));

    // -----------------------------------------------------------------------
    // Write tracks (if an image sequence)

    if (isSequence) {
        static const uint8_t unityMatrix[9][4] = {
            /* clang-format off */
            { 0x00, 0x01, 0x00, 0x00 },
            { 0 },
            { 0 },
            { 0 },
            { 0x00, 0x01, 0x00, 0x00 },
            { 0 },
            { 0 },
            { 0 },
            { 0x40, 0x00, 0x00, 0x00 } /* clang-format on */
        };

        if (encoder->repetitionCount < 0 && encoder->repetitionCount != AVIF_REPETITION_COUNT_INFINITE) {
            return AVIF_RESULT_INVALID_ARGUMENT;
        }

        uint64_t framesDurationInTimescales = 0;
        for (uint32_t frameIndex = 0; frameIndex < encoder->data->frames.count; ++frameIndex) {
            const avifEncoderFrame * frame = &encoder->data->frames.frame[frameIndex];
            framesDurationInTimescales += frame->durationInTimescales;
        }
        uint64_t durationInTimescales;
        if (encoder->repetitionCount == AVIF_REPETITION_COUNT_INFINITE) {
            durationInTimescales = AVIF_INDEFINITE_DURATION64;
        } else {
            uint64_t loopCount = encoder->repetitionCount + 1;
            AVIF_ASSERT_OR_RETURN(framesDurationInTimescales != 0);
            if (loopCount > UINT64_MAX / framesDurationInTimescales) {
                // The multiplication will overflow uint64_t.
                return AVIF_RESULT_INVALID_ARGUMENT;
            }
            durationInTimescales = framesDurationInTimescales * loopCount;
        }

        // -------------------------------------------------------------------
        // Start moov

        avifBoxMarker moov;
        AVIF_CHECKRES(avifRWStreamWriteBox(&s, "moov", AVIF_BOX_SIZE_TBD, &moov));

        avifBoxMarker mvhd;
        AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "mvhd", AVIF_BOX_SIZE_TBD, 1, 0, &mvhd));
        AVIF_CHECKRES(avifRWStreamWriteU64(&s, creationTime));                 // unsigned int(64) creation_time;
        AVIF_CHECKRES(avifRWStreamWriteU64(&s, modificationTime));             // unsigned int(64) modification_time;
        AVIF_CHECKRES(avifRWStreamWriteU32(&s, (uint32_t)encoder->timescale)); // unsigned int(32) timescale;
        AVIF_CHECKRES(avifRWStreamWriteU64(&s, durationInTimescales));         // unsigned int(64) duration;
        AVIF_CHECKRES(avifRWStreamWriteU32(&s, 0x00010000)); // template int(32) rate = 0x00010000; // typically 1.0
        AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0x0100));     // template int(16) volume = 0x0100; // typically, full volume
        AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0));          // const bit(16) reserved = 0;
        AVIF_CHECKRES(avifRWStreamWriteZeros(&s, 8));        // const unsigned int(32)[2] reserved = 0;
        AVIF_CHECKRES(avifRWStreamWrite(&s, unityMatrix, sizeof(unityMatrix)));
        AVIF_CHECKRES(avifRWStreamWriteZeros(&s, 24));                       // bit(32)[6] pre_defined = 0;
        AVIF_CHECKRES(avifRWStreamWriteU32(&s, encoder->data->items.count)); // unsigned int(32) next_track_ID;
        AVIF_CHECKRES(avifRWStreamFinishBox(&s, mvhd));

        // -------------------------------------------------------------------
        // Write tracks

        for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
            avifEncoderItem * item = &encoder->data->items.item[itemIndex];
            if (item->encodeOutput->samples.count == 0) {
                continue;
            }

            uint32_t syncSamplesCount = 0;
            for (uint32_t sampleIndex = 0; sampleIndex < item->encodeOutput->samples.count; ++sampleIndex) {
                avifEncodeSample * sample = &item->encodeOutput->samples.sample[sampleIndex];
                if (sample->sync) {
                    ++syncSamplesCount;
                }
            }

            avifBoxMarker trak;
            AVIF_CHECKRES(avifRWStreamWriteBox(&s, "trak", AVIF_BOX_SIZE_TBD, &trak));

            avifBoxMarker tkhd;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "tkhd", AVIF_BOX_SIZE_TBD, 1, 1, &tkhd));
            AVIF_CHECKRES(avifRWStreamWriteU64(&s, creationTime));           // unsigned int(64) creation_time;
            AVIF_CHECKRES(avifRWStreamWriteU64(&s, modificationTime));       // unsigned int(64) modification_time;
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, itemIndex + 1));          // unsigned int(32) track_ID;
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 0));                      // const unsigned int(32) reserved = 0;
            AVIF_CHECKRES(avifRWStreamWriteU64(&s, durationInTimescales));   // unsigned int(64) duration;
            AVIF_CHECKRES(avifRWStreamWriteZeros(&s, sizeof(uint32_t) * 2)); // const unsigned int(32)[2] reserved = 0;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0));                      // template int(16) layer = 0;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0));                      // template int(16) alternate_group = 0;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0)); // template int(16) volume = {if track_is_audio 0x0100 else 0};
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0)); // const unsigned int(16) reserved = 0;
            AVIF_CHECKRES(avifRWStreamWrite(&s, unityMatrix, sizeof(unityMatrix))); // template int(32)[9] matrix= // { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 };
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, imageMetadata->width << 16));  // unsigned int(32) width;
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, imageMetadata->height << 16)); // unsigned int(32) height;
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, tkhd));

            if (item->irefToID != 0) {
                avifBoxMarker tref;
                AVIF_CHECKRES(avifRWStreamWriteBox(&s, "tref", AVIF_BOX_SIZE_TBD, &tref));
                avifBoxMarker refType;
                AVIF_CHECKRES(avifRWStreamWriteBox(&s, item->irefType, AVIF_BOX_SIZE_TBD, &refType));
                AVIF_CHECKRES(avifRWStreamWriteU32(&s, (uint32_t)item->irefToID));
                AVIF_CHECKRES(avifRWStreamFinishBox(&s, refType));
                AVIF_CHECKRES(avifRWStreamFinishBox(&s, tref));
            }

            avifBoxMarker edts;
            AVIF_CHECKRES(avifRWStreamWriteBox(&s, "edts", AVIF_BOX_SIZE_TBD, &edts));
            uint32_t elstFlags = (encoder->repetitionCount != 0);
            avifBoxMarker elst;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "elst", AVIF_BOX_SIZE_TBD, 1, elstFlags, &elst));
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 1));                          // unsigned int(32) entry_count;
            AVIF_CHECKRES(avifRWStreamWriteU64(&s, framesDurationInTimescales)); // unsigned int(64) segment_duration;
            AVIF_CHECKRES(avifRWStreamWriteU64(&s, 0));                          // int(64) media_time;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 1));                          // int(16) media_rate_integer;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0));                          // int(16) media_rate_fraction = 0;
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, elst));
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, edts));

            if (item->itemCategory != AVIF_ITEM_ALPHA) {
                AVIF_CHECKRES(avifEncoderWriteTrackMetaBox(encoder, &s));
            }

            avifBoxMarker mdia;
            AVIF_CHECKRES(avifRWStreamWriteBox(&s, "mdia", AVIF_BOX_SIZE_TBD, &mdia));

            avifBoxMarker mdhd;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "mdhd", AVIF_BOX_SIZE_TBD, 1, 0, &mdhd));
            AVIF_CHECKRES(avifRWStreamWriteU64(&s, creationTime));                 // unsigned int(64) creation_time;
            AVIF_CHECKRES(avifRWStreamWriteU64(&s, modificationTime));             // unsigned int(64) modification_time;
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, (uint32_t)encoder->timescale)); // unsigned int(32) timescale;
            AVIF_CHECKRES(avifRWStreamWriteU64(&s, framesDurationInTimescales));   // unsigned int(64) duration;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 21956)); // bit(1) pad = 0; unsigned int(5)[3] language; ("und")
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0));     // unsigned int(16) pre_defined = 0;
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, mdhd));

            AVIF_CHECKRES(avifRWStreamWriteHandlerBox(&s, (item->itemCategory == AVIF_ITEM_ALPHA) ? "auxv" : "pict"));

            avifBoxMarker minf;
            AVIF_CHECKRES(avifRWStreamWriteBox(&s, "minf", AVIF_BOX_SIZE_TBD, &minf));

            avifBoxMarker vmhd;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "vmhd", AVIF_BOX_SIZE_TBD, 0, 1, &vmhd));
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0)); // template unsigned int(16) graphicsmode = 0; (copy over the existing image)
            AVIF_CHECKRES(avifRWStreamWriteZeros(&s, 6)); // template unsigned int(16)[3] opcolor = {0, 0, 0};
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, vmhd));

            avifBoxMarker dinf;
            AVIF_CHECKRES(avifRWStreamWriteBox(&s, "dinf", AVIF_BOX_SIZE_TBD, &dinf));
            avifBoxMarker dref;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "dref", AVIF_BOX_SIZE_TBD, 0, 0, &dref));
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 1)); // unsigned int(32) entry_count;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "url ", /*contentSize=*/0, 0, 1, /*marker=*/NULL)); // flags:1 means data is in this file
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, dref));
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, dinf));

            // The boxes within the "stbl" box are ordered using the following recommendation in ISO/IEC 14496-12, Section 6.2.3:
            // 4) It is recommended that the boxes within the Sample Table Box be in the following order: Sample Description
            // (stsd), Time to Sample (stts), Sample to Chunk (stsc), Sample Size (stsz), Chunk Offset (stco).
            //
            // Any boxes not listed in the above line are placed in the end (after the "stco" box).
            avifBoxMarker stbl;
            AVIF_CHECKRES(avifRWStreamWriteBox(&s, "stbl", AVIF_BOX_SIZE_TBD, &stbl));

            avifBoxMarker stsd;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "stsd", AVIF_BOX_SIZE_TBD, 0, 0, &stsd));
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 1)); // unsigned int(32) entry_count;
            avifBoxMarker imageItem;
            AVIF_CHECKRES(avifRWStreamWriteBox(&s, encoder->data->imageItemType, AVIF_BOX_SIZE_TBD, &imageItem));
            AVIF_CHECKRES(avifRWStreamWriteZeros(&s, 6));                             // const unsigned int(8)[6] reserved = 0;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 1));                               // unsigned int(16) data_reference_index;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0));                               // unsigned int(16) pre_defined = 0;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0));                               // const unsigned int(16) reserved = 0;
            AVIF_CHECKRES(avifRWStreamWriteZeros(&s, sizeof(uint32_t) * 3));          // unsigned int(32)[3] pre_defined = 0;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)imageMetadata->width));  // unsigned int(16) width;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)imageMetadata->height)); // unsigned int(16) height;
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 0x00480000));                      // template unsigned int(32) horizresolution
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 0x00480000));                      // template unsigned int(32) vertresolution
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 0));                               // const unsigned int(32) reserved = 0;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 1));                      // template unsigned int(16) frame_count = 1;
            AVIF_CHECKRES(avifRWStreamWriteChars(&s, "\012AOM Coding", 11)); // string[32] compressorname;
            AVIF_CHECKRES(avifRWStreamWriteZeros(&s, 32 - 11));              //
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, 0x0018));                 // template unsigned int(16) depth = 0x0018;
            AVIF_CHECKRES(avifRWStreamWriteU16(&s, (uint16_t)0xffff));       // int(16) pre_defined = -1;
            AVIF_CHECKRES(writeConfigBox(&s, &item->av1C, encoder->data->configPropName));
            if (item->itemCategory == AVIF_ITEM_COLOR) {
                AVIF_CHECKRES(avifEncoderWriteColorProperties(&s, imageMetadata, NULL, NULL));
                AVIF_CHECKRES(avifEncoderWriteHDRProperties(NULL, &s, imageMetadata, NULL, NULL));
                AVIF_CHECKRES(avifEncoderWriteTransformativeProperties(NULL, &s, imageMetadata, NULL, NULL));
            }

            avifBoxMarker ccst;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "ccst", AVIF_BOX_SIZE_TBD, 0, 0, &ccst));
            AVIF_CHECKRES(avifRWStreamWriteBits(&s, 0, /*bitCount=*/1));  // unsigned int(1) all_ref_pics_intra;
            AVIF_CHECKRES(avifRWStreamWriteBits(&s, 1, /*bitCount=*/1));  // unsigned int(1) intra_pred_used;
            AVIF_CHECKRES(avifRWStreamWriteBits(&s, 15, /*bitCount=*/4)); // unsigned int(4) max_ref_per_pic;
            AVIF_CHECKRES(avifRWStreamWriteBits(&s, 0, /*bitCount=*/26)); // unsigned int(26) reserved;
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, ccst));

            if (item->itemCategory == AVIF_ITEM_ALPHA) {
                avifBoxMarker auxi;
                AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "auxi", AVIF_BOX_SIZE_TBD, 0, 0, &auxi));
                AVIF_CHECKRES(avifRWStreamWriteChars(&s, alphaURN, alphaURNSize)); //  string aux_track_type;
                AVIF_CHECKRES(avifRWStreamFinishBox(&s, auxi));
            }

            AVIF_CHECKRES(avifRWStreamFinishBox(&s, imageItem));
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, stsd));

            avifBoxMarker stts;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "stts", AVIF_BOX_SIZE_TBD, 0, 0, &stts));
            size_t sttsEntryCountOffset = avifRWStreamOffset(&s);
            uint32_t sttsEntryCount = 0;
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 0)); // unsigned int(32) entry_count;
            for (uint32_t sampleCount = 0, frameIndex = 0; frameIndex < encoder->data->frames.count; ++frameIndex) {
                avifEncoderFrame * frame = &encoder->data->frames.frame[frameIndex];
                ++sampleCount;
                if (frameIndex < (encoder->data->frames.count - 1)) {
                    avifEncoderFrame * nextFrame = &encoder->data->frames.frame[frameIndex + 1];
                    if (frame->durationInTimescales == nextFrame->durationInTimescales) {
                        continue;
                    }
                }
                AVIF_CHECKRES(avifRWStreamWriteU32(&s, sampleCount));                           // unsigned int(32) sample_count;
                AVIF_CHECKRES(avifRWStreamWriteU32(&s, (uint32_t)frame->durationInTimescales)); // unsigned int(32) sample_delta;
                sampleCount = 0;
                ++sttsEntryCount;
            }
            size_t prevOffset = avifRWStreamOffset(&s);
            avifRWStreamSetOffset(&s, sttsEntryCountOffset);
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, sttsEntryCount));
            avifRWStreamSetOffset(&s, prevOffset);
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, stts));

            avifBoxMarker stsc;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "stsc", AVIF_BOX_SIZE_TBD, 0, 0, &stsc));
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 1));                                 // unsigned int(32) entry_count;
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 1));                                 // unsigned int(32) first_chunk;
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, item->encodeOutput->samples.count)); // unsigned int(32) samples_per_chunk;
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 1)); // unsigned int(32) sample_description_index;
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, stsc));

            avifBoxMarker stsz;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "stsz", AVIF_BOX_SIZE_TBD, 0, 0, &stsz));
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 0));                                 // unsigned int(32) sample_size;
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, item->encodeOutput->samples.count)); // unsigned int(32) sample_count;
            for (uint32_t sampleIndex = 0; sampleIndex < item->encodeOutput->samples.count; ++sampleIndex) {
                avifEncodeSample * sample = &item->encodeOutput->samples.sample[sampleIndex];
                AVIF_CHECKRES(avifRWStreamWriteU32(&s, (uint32_t)sample->data.size)); // unsigned int(32) entry_size;
            }
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, stsz));

            avifBoxMarker stco;
            AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "stco", AVIF_BOX_SIZE_TBD, 0, 0, &stco));
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 1));           // unsigned int(32) entry_count;
            AVIF_CHECKRES(avifEncoderItemAddMdatFixup(item, &s)); //
            AVIF_CHECKRES(avifRWStreamWriteU32(&s, 1));           // unsigned int(32) chunk_offset; (set later)
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, stco));

            avifBool hasNonSyncSample = AVIF_FALSE;
            for (uint32_t sampleIndex = 0; sampleIndex < item->encodeOutput->samples.count; ++sampleIndex) {
                if (!item->encodeOutput->samples.sample[sampleIndex].sync) {
                    hasNonSyncSample = AVIF_TRUE;
                    break;
                }
            }
            // ISO/IEC 14496-12, Section 8.6.2.1:
            //   If the SyncSampleBox is not present, every sample is a sync sample.
            if (hasNonSyncSample) {
                avifBoxMarker stss;
                AVIF_CHECKRES(avifRWStreamWriteFullBox(&s, "stss", AVIF_BOX_SIZE_TBD, 0, 0, &stss));
                AVIF_CHECKRES(avifRWStreamWriteU32(&s, syncSamplesCount)); // unsigned int(32) entry_count;
                for (uint32_t sampleIndex = 0; sampleIndex < item->encodeOutput->samples.count; ++sampleIndex) {
                    avifEncodeSample * sample = &item->encodeOutput->samples.sample[sampleIndex];
                    if (sample->sync) {
                        AVIF_CHECKRES(avifRWStreamWriteU32(&s, sampleIndex + 1)); // unsigned int(32) sample_number;
                    }
                }
                AVIF_CHECKRES(avifRWStreamFinishBox(&s, stss));
            }

            AVIF_CHECKRES(avifRWStreamFinishBox(&s, stbl));

            AVIF_CHECKRES(avifRWStreamFinishBox(&s, minf));
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, mdia));
            AVIF_CHECKRES(avifRWStreamFinishBox(&s, trak));
        }

        // -------------------------------------------------------------------
        // Finish moov box

        AVIF_CHECKRES(avifRWStreamFinishBox(&s, moov));
    }

    // -----------------------------------------------------------------------
    // Write mdat

    avifEncoderItemReferenceArray layeredColorItems;
    avifEncoderItemReferenceArray layeredAlphaItems;
    if (!avifArrayCreate(&layeredColorItems, sizeof(avifEncoderItemReference), 1)) {
        result = AVIF_RESULT_OUT_OF_MEMORY;
    }
    if (!avifArrayCreate(&layeredAlphaItems, sizeof(avifEncoderItemReference), 1)) {
        result = AVIF_RESULT_OUT_OF_MEMORY;
    }
    if (result == AVIF_RESULT_OK) {
        result = avifEncoderWriteMediaDataBox(encoder, &s, &layeredColorItems, &layeredAlphaItems);
    }
    avifArrayDestroy(&layeredColorItems);
    avifArrayDestroy(&layeredAlphaItems);
    AVIF_CHECKRES(result);

    // -----------------------------------------------------------------------
    // Finish up stream

    avifRWStreamFinishWrite(&s);

#if defined(AVIF_ENABLE_COMPLIANCE_WARDEN)
    AVIF_CHECKRES(avifIsCompliant(output->data, output->size));
#endif

    return AVIF_RESULT_OK;
}

avifResult avifEncoderWrite(avifEncoder * encoder, const avifImage * image, avifRWData * output)
{
    avifResult addImageResult = avifEncoderAddImage(encoder, image, 1, AVIF_ADD_IMAGE_FLAG_SINGLE);
    if (addImageResult != AVIF_RESULT_OK) {
        return addImageResult;
    }
    return avifEncoderFinish(encoder, output);
}

// 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 avifResult writeCodecConfig(avifRWStream * s, const avifCodecConfigurationBox * cfg)
{
    const size_t av1COffset = s->offset;

    AVIF_CHECKRES(avifRWStreamWriteBits(s, 1, /*bitCount=*/1)); // unsigned int (1) marker = 1;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, 1, /*bitCount=*/7)); // unsigned int (7) version = 1;

    AVIF_CHECKRES(avifRWStreamWriteBits(s, cfg->seqProfile, /*bitCount=*/3));   // unsigned int (3) seq_profile;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, cfg->seqLevelIdx0, /*bitCount=*/5)); // unsigned int (5) seq_level_idx_0;

    AVIF_CHECKRES(avifRWStreamWriteBits(s, cfg->seqTier0, /*bitCount=*/1));             // unsigned int (1) seq_tier_0;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, cfg->highBitdepth, /*bitCount=*/1));         // unsigned int (1) high_bitdepth;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, cfg->twelveBit, /*bitCount=*/1));            // unsigned int (1) twelve_bit;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, cfg->monochrome, /*bitCount=*/1));           // unsigned int (1) monochrome;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, cfg->chromaSubsamplingX, /*bitCount=*/1));   // unsigned int (1) chroma_subsampling_x;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, cfg->chromaSubsamplingY, /*bitCount=*/1));   // unsigned int (1) chroma_subsampling_y;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, cfg->chromaSamplePosition, /*bitCount=*/2)); // unsigned int (2) chroma_sample_position;

    AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, /*bitCount=*/3)); // unsigned int (3) reserved = 0;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, /*bitCount=*/1)); // unsigned int (1) initial_presentation_delay_present;
    AVIF_CHECKRES(avifRWStreamWriteBits(s, 0, /*bitCount=*/4)); // unsigned int (4) reserved = 0;

    // According to section 2.2.1 of AV1 Image File Format specification v1.1.0,
    // there is no need to write any OBU here.
    // See https://aomediacodec.github.io/av1-avif/v1.1.0.html#av1-configuration-item-property.
    // unsigned int (8) configOBUs[];

    AVIF_ASSERT_OR_RETURN(s->offset - av1COffset == 4); // Make sure writeCodecConfig() writes exactly 4 bytes.
    return AVIF_RESULT_OK;
}

static avifResult writeConfigBox(avifRWStream * s, const avifCodecConfigurationBox * cfg, const char * configPropName)
{
    avifBoxMarker configBox;
    AVIF_CHECKRES(avifRWStreamWriteBox(s, configPropName, AVIF_BOX_SIZE_TBD, &configBox));
    AVIF_CHECKRES(writeCodecConfig(s, cfg));
    AVIF_CHECKRES(avifRWStreamFinishBox(s, configBox));
    return AVIF_RESULT_OK;
}
