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

#include "avif/internal.h"

#include <string.h>

#define MAX_ASSOCIATIONS 16
struct ipmaArray
{
    uint8_t associations[MAX_ASSOCIATIONS];
    avifBool essential[MAX_ASSOCIATIONS];
    uint8_t count;
};
static void ipmaPush(struct ipmaArray * ipma, uint8_t assoc, avifBool essential)
{
    ipma->associations[ipma->count] = assoc;
    ipma->essential[ipma->count] = essential;
    ++ipma->count;
}

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

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

static avifBool avifImageIsOpaque(avifImage * image);
static void fillConfigBox(avifCodec * codec, avifImage * image, avifBool alpha);
static void writeConfigBox(avifRWStream * s, avifCodecConfigurationBox * cfg);

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

// one "item" worth for encoder
typedef struct avifEncoderItem
{
    uint16_t id;
    uint8_t type[4];
    avifImage * image;  // avifImage* to use when encoding or populating ipma for this item (unowned)
    avifCodec * codec;  // only present on type==av01
    avifRWData content; // OBU data on av01, metadata payload for Exif/XMP
    avifBool alpha;

    const char * infeName;
    size_t infeNameSize;
    const char * infeContentType;
    size_t infeContentTypeSize;
    size_t infeOffsetOffset; // Stream offset where infe offset was written, so it can be properly set after mdat is written

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

    struct ipmaArray ipma;
} avifEncoderItem;
AVIF_ARRAY_DECLARE(avifEncoderItemArray, avifEncoderItem, item);

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

typedef struct avifEncoderData
{
    avifEncoderItemArray items;
    uint16_t lastItemID;
    uint16_t primaryItemID;
} avifEncoderData;

static avifEncoderData * avifEncoderDataCreate()
{
    avifEncoderData * data = (avifEncoderData *)avifAlloc(sizeof(avifEncoderData));
    memset(data, 0, sizeof(avifEncoderData));
    avifArrayCreate(&data->items, sizeof(avifEncoderItem), 8);
    return data;
}

static avifEncoderItem * avifEncoderDataCreateItem(avifEncoderData * data, const char * type, const char * infeName, size_t infeNameSize)
{
    avifEncoderItem * item = (avifEncoderItem *)avifArrayPushPtr(&data->items);
    ++data->lastItemID;
    item->id = data->lastItemID;
    memcpy(item->type, type, sizeof(item->type));
    item->infeName = infeName;
    item->infeNameSize = infeNameSize;
    return item;
}

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);
        }
        avifRWDataFree(&item->content);
    }
    avifArrayDestroy(&data->items);
    avifFree(data);
}

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

avifEncoder * avifEncoderCreate(void)
{
    avifEncoder * encoder = (avifEncoder *)avifAlloc(sizeof(avifEncoder));
    memset(encoder, 0, sizeof(avifEncoder));
    encoder->maxThreads = 1;
    encoder->minQuantizer = AVIF_QUANTIZER_LOSSLESS;
    encoder->maxQuantizer = AVIF_QUANTIZER_LOSSLESS;
    encoder->minQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS;
    encoder->maxQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS;
    encoder->tileRowsLog2 = 0;
    encoder->tileColsLog2 = 0;
    encoder->speed = AVIF_SPEED_DEFAULT;
    encoder->data = avifEncoderDataCreate();
    return encoder;
}

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

avifResult avifEncoderWrite(avifEncoder * encoder, avifImage * image, avifRWData * output)
{
    if ((image->depth != 8) && (image->depth != 10) && (image->depth != 12)) {
        return AVIF_RESULT_UNSUPPORTED_DEPTH;
    }

    avifResult result = AVIF_RESULT_UNKNOWN_ERROR;

    avifEncoderItem * colorItem = avifEncoderDataCreateItem(encoder->data, "av01", "Color", 6);
    colorItem->image = image;
    colorItem->codec = avifCodecCreate(encoder->codecChoice, AVIF_CODEC_FLAG_CAN_ENCODE);
    if (!colorItem->codec) {
        // Just bail out early, we're not surviving this function without an encoder compiled in
        return AVIF_RESULT_NO_CODEC_AVAILABLE;
    }
    encoder->data->primaryItemID = colorItem->id;

    avifBool imageIsOpaque = avifImageIsOpaque(image);
    if (!imageIsOpaque) {
        avifEncoderItem * alphaItem = avifEncoderDataCreateItem(encoder->data, "av01", "Alpha", 6);
        alphaItem->image = image;
        alphaItem->codec = avifCodecCreate(encoder->codecChoice, AVIF_CODEC_FLAG_CAN_ENCODE);
        if (!alphaItem->codec) {
            return AVIF_RESULT_NO_CODEC_AVAILABLE;
        }
        alphaItem->alpha = AVIF_TRUE;
        alphaItem->irefToID = encoder->data->primaryItemID;
        alphaItem->irefType = "auxl";
    }

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

    if (image->exif.size > 0) {
        // Validate Exif payload (if any) and find TIFF header offset
        uint32_t exifTiffHeaderOffset = 0;
        if (image->exif.size > 0) {
            if (image->exif.size < 4) {
                // Can't even fit the TIFF header, something is wrong
                return AVIF_RESULT_INVALID_EXIF_PAYLOAD;
            }

            const uint8_t tiffHeaderBE[4] = { 'M', 'M', 0, 42 };
            const uint8_t tiffHeaderLE[4] = { 'I', 'I', 42, 0 };
            for (; exifTiffHeaderOffset < (image->exif.size - 4); ++exifTiffHeaderOffset) {
                if (!memcmp(&image->exif.data[exifTiffHeaderOffset], tiffHeaderBE, sizeof(tiffHeaderBE))) {
                    break;
                }
                if (!memcmp(&image->exif.data[exifTiffHeaderOffset], tiffHeaderLE, sizeof(tiffHeaderLE))) {
                    break;
                }
            }

            if (exifTiffHeaderOffset >= image->exif.size - 4) {
                // Couldn't find the TIFF header
                return AVIF_RESULT_INVALID_EXIF_PAYLOAD;
            }
        }

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

        avifRWDataRealloc(&exifItem->content, sizeof(uint32_t) + image->exif.size);
        exifTiffHeaderOffset = avifHTONL(exifTiffHeaderOffset);
        memcpy(exifItem->content.data, &exifTiffHeaderOffset, sizeof(uint32_t));
        memcpy(exifItem->content.data + sizeof(uint32_t), image->exif.data, image->exif.size);
    }

    if (image->xmp.size > 0) {
        avifEncoderItem * xmpItem = avifEncoderDataCreateItem(encoder->data, "mime", "XMP", 4);
        xmpItem->irefToID = encoder->data->primaryItemID;
        xmpItem->irefType = "cdsc";

        xmpItem->infeContentType = xmpContentType;
        xmpItem->infeContentTypeSize = xmpContentTypeSize;
        avifRWDataSet(&xmpItem->content, image->xmp.data, image->xmp.size);
    }

    // -----------------------------------------------------------------------
    // Pre-fill config boxes based on image (codec can query/update later)

    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        if (item->codec && item->image) {
            fillConfigBox(item->codec, item->image, item->alpha);
        }
    }

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

    avifRWStream s;
    avifRWStreamStart(&s, output);

    // -----------------------------------------------------------------------
    // Validate image

    if (!image->width || !image->height || !image->yuvPlanes[AVIF_CHAN_Y]) {
        result = AVIF_RESULT_NO_CONTENT;
        goto writeCleanup;
    }

    if (image->yuvFormat == AVIF_PIXEL_FORMAT_NONE) {
        result = AVIF_RESULT_NO_YUV_FORMAT_SELECTED;
        goto writeCleanup;
    }

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

    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        if (item->codec && item->image) {
            if (!item->codec->encodeImage(item->codec, item->image, encoder, &item->content, item->alpha)) {
                result = item->alpha ? AVIF_RESULT_ENCODE_ALPHA_FAILED : AVIF_RESULT_ENCODE_COLOR_FAILED;
                goto writeCleanup;
            }

            // TODO: rethink this if/when image grid encoding support is added
            if (item->alpha) {
                encoder->ioStats.alphaOBUSize = item->content.size;
            } else {
                encoder->ioStats.colorOBUSize = item->content.size;
            }
        }
    }

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

    avifBoxMarker ftyp = avifRWStreamWriteBox(&s, "ftyp", -1, 0);
    avifRWStreamWriteChars(&s, "avif", 4);                         // unsigned int(32) major_brand;
    avifRWStreamWriteU32(&s, 0);                                   // unsigned int(32) minor_version;
    avifRWStreamWriteChars(&s, "avif", 4);                         // unsigned int(32) compatible_brands[];
    avifRWStreamWriteChars(&s, "mif1", 4);                         // ... compatible_brands[]
    avifRWStreamWriteChars(&s, "miaf", 4);                         // ... compatible_brands[]
    if ((image->depth == 8) || (image->depth == 10)) {             //
        if (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV420) {        //
            avifRWStreamWriteChars(&s, "MA1B", 4);                 // ... compatible_brands[]
        } else if (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV444) { //
            avifRWStreamWriteChars(&s, "MA1A", 4);                 // ... compatible_brands[]
        }
    }
    avifRWStreamFinishBox(&s, ftyp);

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

    avifBoxMarker meta = avifRWStreamWriteBox(&s, "meta", 0, 0);

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

    avifBoxMarker hdlr = avifRWStreamWriteBox(&s, "hdlr", 0, 0);
    avifRWStreamWriteU32(&s, 0);              // unsigned int(32) pre_defined = 0;
    avifRWStreamWriteChars(&s, "pict", 4);    // unsigned int(32) handler_type;
    avifRWStreamWriteZeros(&s, 12);           // const unsigned int(32)[3] reserved = 0;
    avifRWStreamWriteChars(&s, "libavif", 8); // string name; (writing null terminator)
    avifRWStreamFinishBox(&s, hdlr);

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

    if (encoder->data->primaryItemID != 0) {
        avifRWStreamWriteBox(&s, "pitm", 0, sizeof(uint16_t));
        avifRWStreamWriteU16(&s, encoder->data->primaryItemID); //  unsigned int(16) item_ID;
    }

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

    avifBoxMarker iloc = avifRWStreamWriteBox(&s, "iloc", 0, 0);

    uint8_t offsetSizeAndLengthSize = (4 << 4) + (4 << 0);          // unsigned int(4) offset_size;
                                                                    // unsigned int(4) length_size;
    avifRWStreamWrite(&s, &offsetSizeAndLengthSize, 1);             //
    avifRWStreamWriteZeros(&s, 1);                                  // unsigned int(4) base_offset_size;
                                                                    // unsigned int(4) reserved;
    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];
        avifRWStreamWriteU16(&s, item->id);                     // unsigned int(16) item_ID;
        avifRWStreamWriteU16(&s, 0);                            // unsigned int(16) data_reference_index;
        avifRWStreamWriteU16(&s, 1);                            // unsigned int(16) extent_count;
        item->infeOffsetOffset = avifRWStreamOffset(&s);        //
        avifRWStreamWriteU32(&s, 0 /* set later */);            // unsigned int(offset_size*8) extent_offset;
        avifRWStreamWriteU32(&s, (uint32_t)item->content.size); // unsigned int(length_size*8) extent_length;
    }

    avifRWStreamFinishBox(&s, iloc);

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

    avifBoxMarker iinf = avifRWStreamWriteBox(&s, "iinf", 0, 0);
    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];

        avifBoxMarker infe = avifRWStreamWriteBox(&s, "infe", 2, 0);
        avifRWStreamWriteU16(&s, item->id);                             // unsigned int(16) item_ID;
        avifRWStreamWriteU16(&s, 0);                                    // unsigned int(16) item_protection_index;
        avifRWStreamWrite(&s, item->type, 4);                           // unsigned int(32) item_type;
        avifRWStreamWriteChars(&s, item->infeName, item->infeNameSize); // string item_name; (writing null terminator)
        if (item->infeContentType && item->infeContentTypeSize) {       // string content_type; (writing null terminator)
            avifRWStreamWriteChars(&s, item->infeContentType, item->infeContentTypeSize);
        }
        avifRWStreamFinishBox(&s, infe);
    }

    avifRWStreamFinishBox(&s, iinf);

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

    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        if (item->irefToID != 0) {
            avifBoxMarker iref = avifRWStreamWriteBox(&s, "iref", 0, 0);
            avifBoxMarker refType = avifRWStreamWriteBox(&s, item->irefType, -1, 0);
            avifRWStreamWriteU16(&s, item->id);       // unsigned int(16) from_item_ID;
            avifRWStreamWriteU16(&s, 1);              // unsigned int(16) reference_count;
            avifRWStreamWriteU16(&s, item->irefToID); // unsigned int(16) to_item_ID;
            avifRWStreamFinishBox(&s, refType);
            avifRWStreamFinishBox(&s, iref);
        }
    }

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

    avifBoxMarker iprp = avifRWStreamWriteBox(&s, "iprp", -1, 0);

    uint8_t itemPropertyIndex = 0;
    avifBoxMarker ipco = avifRWStreamWriteBox(&s, "ipco", -1, 0);
    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        memset(&item->ipma, 0, sizeof(item->ipma));
        if (!item->image || !item->codec) {
            // No ipma to write for this item
            continue;
        }

        // Properties all av01 items need

        avifBoxMarker ispe = avifRWStreamWriteBox(&s, "ispe", 0, 0);
        avifRWStreamWriteU32(&s, item->image->width);  // unsigned int(32) image_width;
        avifRWStreamWriteU32(&s, item->image->height); // unsigned int(32) image_height;
        avifRWStreamFinishBox(&s, ispe);
        ipmaPush(&item->ipma, ++itemPropertyIndex, AVIF_FALSE); // ipma is 1-indexed, doing this afterwards is correct

        uint8_t channelCount = item->alpha ? 1 : 3; // TODO: write the correct value here when adding monochrome support
        avifBoxMarker pixi = avifRWStreamWriteBox(&s, "pixi", 0, 0);
        avifRWStreamWriteU8(&s, channelCount); // unsigned int (8) num_channels;
        for (uint8_t chan = 0; chan < channelCount; ++chan) {
            avifRWStreamWriteU8(&s, (uint8_t)item->image->depth); // unsigned int (8) bits_per_channel;
        }
        avifRWStreamFinishBox(&s, pixi);
        ipmaPush(&item->ipma, ++itemPropertyIndex, AVIF_FALSE);

        writeConfigBox(&s, &item->codec->configBox);
        ipmaPush(&item->ipma, ++itemPropertyIndex, AVIF_TRUE);

        if (item->alpha) {
            // Alpha specific properties

            avifBoxMarker auxC = avifRWStreamWriteBox(&s, "auxC", 0, 0);
            avifRWStreamWriteChars(&s, alphaURN, alphaURNSize); //  string aux_type;
            avifRWStreamFinishBox(&s, auxC);
            ipmaPush(&item->ipma, ++itemPropertyIndex, AVIF_FALSE);
        } else {
            // Color specific properties

            if (item->image->profileFormat == AVIF_PROFILE_FORMAT_NCLX) {
                avifBoxMarker colr = avifRWStreamWriteBox(&s, "colr", -1, 0);
                avifRWStreamWriteChars(&s, "nclx", 4);                                 // unsigned int(32) colour_type;
                avifRWStreamWriteU16(&s, (uint16_t)item->image->nclx.colourPrimaries); // unsigned int(16) colour_primaries;
                avifRWStreamWriteU16(&s, (uint16_t)item->image->nclx.transferCharacteristics); // unsigned int(16) transfer_characteristics;
                avifRWStreamWriteU16(&s, (uint16_t)item->image->nclx.matrixCoefficients); // unsigned int(16) matrix_coefficients;
                avifRWStreamWriteU8(&s, item->image->nclx.range & 0x80);                  // unsigned int(1) full_range_flag;
                                                                                          // unsigned int(7) reserved = 0;
                avifRWStreamFinishBox(&s, colr);
                ipmaPush(&item->ipma, ++itemPropertyIndex, AVIF_FALSE);
            } else if ((item->image->profileFormat == AVIF_PROFILE_FORMAT_ICC) && item->image->icc.data && (item->image->icc.size > 0)) {
                avifBoxMarker colr = avifRWStreamWriteBox(&s, "colr", -1, 0);
                avifRWStreamWriteChars(&s, "prof", 4); // unsigned int(32) colour_type;
                avifRWStreamWrite(&s, item->image->icc.data, item->image->icc.size);
                avifRWStreamFinishBox(&s, colr);
                ipmaPush(&item->ipma, ++itemPropertyIndex, AVIF_FALSE);
            }

            // Write (Optional) Transformations
            if (item->image->transformFlags & AVIF_TRANSFORM_PASP) {
                avifBoxMarker pasp = avifRWStreamWriteBox(&s, "pasp", -1, 0);
                avifRWStreamWriteU32(&s, item->image->pasp.hSpacing); // unsigned int(32) hSpacing;
                avifRWStreamWriteU32(&s, item->image->pasp.vSpacing); // unsigned int(32) vSpacing;
                avifRWStreamFinishBox(&s, pasp);
                ipmaPush(&item->ipma, ++itemPropertyIndex, AVIF_FALSE);
            }
            if (item->image->transformFlags & AVIF_TRANSFORM_CLAP) {
                avifBoxMarker clap = avifRWStreamWriteBox(&s, "clap", -1, 0);
                avifRWStreamWriteU32(&s, item->image->clap.widthN);    // unsigned int(32) cleanApertureWidthN;
                avifRWStreamWriteU32(&s, item->image->clap.widthD);    // unsigned int(32) cleanApertureWidthD;
                avifRWStreamWriteU32(&s, item->image->clap.heightN);   // unsigned int(32) cleanApertureHeightN;
                avifRWStreamWriteU32(&s, item->image->clap.heightD);   // unsigned int(32) cleanApertureHeightD;
                avifRWStreamWriteU32(&s, item->image->clap.horizOffN); // unsigned int(32) horizOffN;
                avifRWStreamWriteU32(&s, item->image->clap.horizOffD); // unsigned int(32) horizOffD;
                avifRWStreamWriteU32(&s, item->image->clap.vertOffN);  // unsigned int(32) vertOffN;
                avifRWStreamWriteU32(&s, item->image->clap.vertOffD);  // unsigned int(32) vertOffD;
                avifRWStreamFinishBox(&s, clap);
                ipmaPush(&item->ipma, ++itemPropertyIndex, AVIF_TRUE);
            }
            if (item->image->transformFlags & AVIF_TRANSFORM_IROT) {
                avifBoxMarker irot = avifRWStreamWriteBox(&s, "irot", -1, 0);
                uint8_t angle = item->image->irot.angle & 0x3;
                avifRWStreamWrite(&s, &angle, 1); // unsigned int (6) reserved = 0; unsigned int (2) angle;
                avifRWStreamFinishBox(&s, irot);
                ipmaPush(&item->ipma, ++itemPropertyIndex, AVIF_TRUE);
            }
            if (item->image->transformFlags & AVIF_TRANSFORM_IMIR) {
                avifBoxMarker imir = avifRWStreamWriteBox(&s, "imir", -1, 0);
                uint8_t axis = item->image->imir.axis & 0x1;
                avifRWStreamWrite(&s, &axis, 1); // unsigned int (7) reserved = 0; unsigned int (1) axis;
                avifRWStreamFinishBox(&s, imir);
                ipmaPush(&item->ipma, ++itemPropertyIndex, AVIF_TRUE);
            }
        }
    }
    avifRWStreamFinishBox(&s, ipco);

    avifBoxMarker ipma = avifRWStreamWriteBox(&s, "ipma", 0, 0);
    {
        int ipmaCount = 0;
        for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
            avifEncoderItem * item = &encoder->data->items.item[itemIndex];
            if (item->ipma.count > 0) {
                ++ipmaCount;
            }
        }
        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->ipma.count == 0) {
                continue;
            }

            avifRWStreamWriteU16(&s, item->id);          // unsigned int(16) item_ID;
            avifRWStreamWriteU8(&s, item->ipma.count);   // unsigned int(8) association_count;
            for (int i = 0; i < item->ipma.count; ++i) { //
                uint8_t essentialAndIndex = item->ipma.associations[i];
                if (item->ipma.essential[i]) {
                    essentialAndIndex |= 0x80;
                }
                avifRWStreamWriteU8(&s, essentialAndIndex); // bit(1) essential; unsigned int(7) property_index;
            }
        }
    }
    avifRWStreamFinishBox(&s, ipma);

    avifRWStreamFinishBox(&s, iprp);

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

    avifRWStreamFinishBox(&s, meta);

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

    avifBoxMarker mdat = avifRWStreamWriteBox(&s, "mdat", -1, 0);
    for (uint32_t itemIndex = 0; itemIndex < encoder->data->items.count; ++itemIndex) {
        avifEncoderItem * item = &encoder->data->items.item[itemIndex];
        if (item->content.size == 0) {
            continue;
        }

        uint32_t infeOffset = (uint32_t)s.offset;
        avifRWStreamWrite(&s, item->content.data, item->content.size);

        if (item->infeOffsetOffset != 0) {
            size_t prevOffset = avifRWStreamOffset(&s);
            avifRWStreamSetOffset(&s, item->infeOffsetOffset);
            avifRWStreamWriteU32(&s, infeOffset);
            avifRWStreamSetOffset(&s, prevOffset);
        }
    }
    avifRWStreamFinishBox(&s, mdat);

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

    avifRWStreamFinishWrite(&s);

    // -----------------------------------------------------------------------
    // Set result and cleanup

    result = AVIF_RESULT_OK;

writeCleanup:
    return result;
}

static avifBool avifImageIsOpaque(avifImage * image)
{
    if (!image->alphaPlane) {
        return AVIF_TRUE;
    }

    int maxChannel = (1 << image->depth) - 1;
    if (avifImageUsesU16(image)) {
        for (uint32_t j = 0; j < image->height; ++j) {
            for (uint32_t i = 0; i < image->width; ++i) {
                uint16_t * p = (uint16_t *)&image->alphaPlane[(i * 2) + (j * image->alphaRowBytes)];
                if (*p != maxChannel) {
                    return AVIF_FALSE;
                }
            }
        }
    } else {
        for (uint32_t j = 0; j < image->height; ++j) {
            for (uint32_t i = 0; i < image->width; ++i) {
                if (image->alphaPlane[i + (j * image->alphaRowBytes)] != maxChannel) {
                    return AVIF_FALSE;
                }
            }
        }
    }
    return AVIF_TRUE;
}

static void fillConfigBox(avifCodec * codec, avifImage * image, avifBool alpha)
{
    avifPixelFormatInfo formatInfo;
    avifGetPixelFormatInfo(image->yuvFormat, &formatInfo);

    // Profile 0.  8-bit and 10-bit 4:2:0 and 4:0:0 only.
    // Profile 1.  8-bit and 10-bit 4:4:4
    // Profile 2.  8-bit and 10-bit 4:2:2
    //            12-bit  4:0:0, 4:2:2 and 4:4:4
    uint8_t seqProfile = 0;
    if (image->depth == 12) {
        // Only seqProfile 2 can handle 12 bit
        seqProfile = 2;
    } else {
        // 8-bit or 10-bit

        if (alpha) {
            seqProfile = 0;
        } else {
            switch (image->yuvFormat) {
                case AVIF_PIXEL_FORMAT_YUV444:
                    seqProfile = 1;
                    break;
                case AVIF_PIXEL_FORMAT_YUV422:
                    seqProfile = 2;
                    break;
                case AVIF_PIXEL_FORMAT_YUV420:
                    seqProfile = 0;
                    break;
                case AVIF_PIXEL_FORMAT_YV12:
                    seqProfile = 0;
                    break;
                case AVIF_PIXEL_FORMAT_NONE:
                default:
                    break;
            }
        }
    }

    // TODO: Choose correct value from Annex A.3 table: https://aomediacodec.github.io/av1-spec/av1-spec.pdf
    uint8_t seqLevelIdx0 = 31;
    if ((image->width <= 8192) && (image->height <= 4352) && ((image->width * image->height) <= 8912896)) {
        // Image is 5.1 compatible
        seqLevelIdx0 = 13; // 5.1
    }

    memset(&codec->configBox, 0, sizeof(avifCodecConfigurationBox));
    codec->configBox.seqProfile = seqProfile;
    codec->configBox.seqLevelIdx0 = seqLevelIdx0;
    codec->configBox.seqTier0 = 0;
    codec->configBox.highBitdepth = (image->depth > 8) ? 1 : 0;
    codec->configBox.twelveBit = (image->depth == 12) ? 1 : 0;
    codec->configBox.monochrome = alpha ? 1 : 0;
    codec->configBox.chromaSubsamplingX = (uint8_t)formatInfo.chromaShiftX;
    codec->configBox.chromaSubsamplingY = (uint8_t)formatInfo.chromaShiftY;

    // TODO: choose the correct one from below:
    //   * 0 - CSP_UNKNOWN   Unknown (in this case the source video transfer function must be signaled outside the AV1 bitstream)
    //   * 1 - CSP_VERTICAL  Horizontally co-located with (0, 0) luma sample, vertical position in the middle between two luma samples
    //   * 2 - CSP_COLOCATED co-located with (0, 0) luma sample
    //   * 3 - CSP_RESERVED
    codec->configBox.chromaSamplePosition = 0;
}

static void writeConfigBox(avifRWStream * s, avifCodecConfigurationBox * cfg)
{
    avifBoxMarker av1C = avifRWStreamWriteBox(s, "av1C", -1, 0);

    // unsigned int (1) marker = 1;
    // unsigned int (7) version = 1;
    avifRWStreamWriteU8(s, 0x80 | 0x1);

    // unsigned int (3) seq_profile;
    // unsigned int (5) seq_level_idx_0;
    avifRWStreamWriteU8(s, (uint8_t)((cfg->seqProfile & 0x7) << 5) | (uint8_t)(cfg->seqLevelIdx0 & 0x1f));

    uint8_t bits = 0;
    bits |= (cfg->seqTier0 & 0x1) << 7;           // unsigned int (1) seq_tier_0;
    bits |= (cfg->highBitdepth & 0x1) << 6;       // unsigned int (1) high_bitdepth;
    bits |= (cfg->twelveBit & 0x1) << 5;          // unsigned int (1) twelve_bit;
    bits |= (cfg->monochrome & 0x1) << 4;         // unsigned int (1) monochrome;
    bits |= (cfg->chromaSubsamplingX & 0x1) << 3; // unsigned int (1) chroma_subsampling_x;
    bits |= (cfg->chromaSubsamplingY & 0x1) << 2; // unsigned int (1) chroma_subsampling_y;
    bits |= (cfg->chromaSamplePosition & 0x3);    // unsigned int (2) chroma_sample_position;
    avifRWStreamWriteU8(s, bits);

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

    avifRWStreamFinishBox(s, av1C);
}
