// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause

#include "avif/internal.h"

#include "avm/avm_decoder.h"
#include "avm/avm_encoder.h"
#include "avm/avmcx.h"
#include "avm/avmdx.h"

#include <assert.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#define TWO_LAYER_ALL_INTRA_QUALITY_THRESHOLD 10

struct avifCodecInternal
{
    avifBool decoderInitialized;
    avm_codec_ctx_t decoder;
    avm_codec_iter_t iter;
    avm_image_t * image;

    avifBool encoderInitialized;
    avm_codec_ctx_t encoder;
    struct avm_codec_enc_cfg cfg;
    avifPixelFormatInfo formatInfo;
    avm_img_fmt_t avmFormat;
    avifBool monochromeEnabled;
    // Whether 'tuning' (of the specified distortion metric) was set with an
    // avifEncoderSetCodecSpecificOption(encoder, "tune", value) call.
    avifBool tuningSet;
    uint32_t currentLayer;
};

static void avmCodecDestroyInternal(avifCodec * codec)
{
    if (codec->internal->decoderInitialized) {
        avm_codec_destroy(&codec->internal->decoder);
    }

    if (codec->internal->encoderInitialized) {
        avm_codec_destroy(&codec->internal->encoder);
    }

    avifFree(codec->internal);
}

static avifBool avmCodecGetNextImage(struct avifCodec * codec,
                                     const avifDecodeSample * sample,
                                     avifBool alpha,
                                     avifBool * isLimitedRangeAlpha,
                                     avifImage * image)
{
    assert(sample);

    if (!codec->internal->decoderInitialized) {
        avm_codec_dec_cfg_t cfg;
        memset(&cfg, 0, sizeof(avm_codec_dec_cfg_t));
        cfg.threads = codec->maxThreads;

        avm_codec_iface_t * decoder_interface = avm_codec_av2_dx();
        if (avm_codec_dec_init(&codec->internal->decoder, decoder_interface, &cfg, 0)) {
            return AVIF_FALSE;
        }
        codec->internal->decoderInitialized = AVIF_TRUE;

        if (avm_codec_control(&codec->internal->decoder, AV2D_SET_OUTPUT_ALL_LAYERS, codec->allLayers)) {
            return AVIF_FALSE;
        }
        if (codec->operatingPoint != 0) {
            // Not implemented.
            return AVIF_FALSE;
        }

        codec->internal->iter = NULL;
    }

    avm_image_t * nextFrame = NULL;
    uint8_t spatialID = AVIF_SPATIAL_ID_UNSET;
    for (;;) {
        nextFrame = avm_codec_get_frame(&codec->internal->decoder, &codec->internal->iter);
        if (nextFrame) {
            if (spatialID != AVIF_SPATIAL_ID_UNSET) {
                if (spatialID == nextFrame->mlayer_id) {
                    // Found the correct spatial_id.
                    break;
                }
            } else {
                // Got an image!
                break;
            }
        } else if (sample) {
            codec->internal->iter = NULL;
            if (avm_codec_decode(&codec->internal->decoder, sample->data.data, sample->data.size, NULL)) {
                return AVIF_FALSE;
            }
            spatialID = sample->spatialID;
            sample = NULL;
        } else {
            break;
        }
    }

    if (nextFrame) {
        codec->internal->image = nextFrame;
    } else {
        if (alpha && codec->internal->image) {
            // Special case: reuse last alpha frame
        } else {
            return AVIF_FALSE;
        }
    }

    avifBool isColor = !alpha;
    if (isColor) {
        // Color (YUV) planes - set image to correct size / format, fill color

        avifPixelFormat yuvFormat = AVIF_PIXEL_FORMAT_NONE;
        switch (codec->internal->image->fmt) {
            case AVM_IMG_FMT_I420:
            case AVM_IMG_FMT_I42016:
                yuvFormat = AVIF_PIXEL_FORMAT_YUV420;
                break;
            case AVM_IMG_FMT_I422:
            case AVM_IMG_FMT_I42216:
                yuvFormat = AVIF_PIXEL_FORMAT_YUV422;
                break;
            case AVM_IMG_FMT_I444:
            case AVM_IMG_FMT_I44416:
                yuvFormat = AVIF_PIXEL_FORMAT_YUV444;
                break;
            case AVM_IMG_FMT_NONE:
            case AVM_IMG_FMT_YV12:
            case AVM_IMG_FMT_YV1216:
            default:
                return AVIF_FALSE;
        }
        if (codec->internal->image->monochrome) {
            yuvFormat = AVIF_PIXEL_FORMAT_YUV400;
        }

        image->width = codec->internal->image->d_w;
        image->height = codec->internal->image->d_h;
        image->depth = codec->internal->image->bit_depth;

        image->yuvFormat = yuvFormat;
        image->yuvRange = (codec->internal->image->range == AVM_CR_STUDIO_RANGE) ? AVIF_RANGE_LIMITED : AVIF_RANGE_FULL;
        if (codec->internal->image->csp == AVM_CSP_LEFT) {
            // CSP_LEFT: Horizontal offset 0, vertical offset 0.5
            image->yuvChromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_VERTICAL;
        } else if (codec->internal->image->csp == AVM_CSP_CENTER) {
            // CSP_CENTER: Horizontal offset 0.5, vertical offset 0.5
            image->yuvChromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
        } else if (codec->internal->image->csp == AVM_CSP_TOPLEFT) {
            // CSP_TOPLEFT: Horizontal offset 0, vertical offset 0
            image->yuvChromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_COLOCATED;
        } else {
            image->yuvChromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
        }

        image->colorPrimaries = (avifColorPrimaries)codec->internal->image->cp;
        image->transferCharacteristics = (avifTransferCharacteristics)codec->internal->image->tc;
        image->matrixCoefficients = (avifMatrixCoefficients)codec->internal->image->mc;

        avifImageFreePlanes(image, AVIF_PLANES_YUV);
        int yuvPlaneCount = (yuvFormat == AVIF_PIXEL_FORMAT_YUV400) ? 1 : 3;

        // avifImage assumes that a depth of 8 bits means an 8-bit buffer.
        // avm_image does not. The buffer depth depends on fmt|AVM_IMG_FMT_HIGHBITDEPTH, even for 8-bit values.
        if (!avifImageUsesU16(image) && (codec->internal->image->fmt & AVM_IMG_FMT_HIGHBITDEPTH)) {
            AVIF_CHECK(avifImageAllocatePlanes(image, AVIF_PLANES_YUV) == AVIF_RESULT_OK);
            for (int yuvPlane = 0; yuvPlane < yuvPlaneCount; ++yuvPlane) {
                const uint32_t planeWidth = avifImagePlaneWidth(image, yuvPlane);
                const uint32_t planeHeight = avifImagePlaneHeight(image, yuvPlane);
                const uint8_t * srcRow = codec->internal->image->planes[yuvPlane];
                uint8_t * dstRow = avifImagePlane(image, yuvPlane);
                const uint32_t dstRowBytes = avifImagePlaneRowBytes(image, yuvPlane);
                for (uint32_t y = 0; y < planeHeight; ++y) {
                    const uint16_t * srcRow16 = (const uint16_t *)srcRow;
                    for (uint32_t x = 0; x < planeWidth; ++x) {
                        dstRow[x] = (uint8_t)srcRow16[x];
                    }
                    srcRow += codec->internal->image->stride[yuvPlane];
                    dstRow += dstRowBytes;
                }
            }
        } else {
            // Steal the pointers from the decoder's image directly
            for (int yuvPlane = 0; yuvPlane < yuvPlaneCount; ++yuvPlane) {
                image->yuvPlanes[yuvPlane] = codec->internal->image->planes[yuvPlane];
                image->yuvRowBytes[yuvPlane] = codec->internal->image->stride[yuvPlane];
            }
            image->imageOwnsYUVPlanes = AVIF_FALSE;
        }
    } else {
        // Alpha plane - set image to correct size, fill alpha

        image->width = codec->internal->image->d_w;
        image->height = codec->internal->image->d_h;
        image->depth = codec->internal->image->bit_depth;

        avifImageFreePlanes(image, AVIF_PLANES_A);

        if (!avifImageUsesU16(image) && (codec->internal->image->fmt & AVM_IMG_FMT_HIGHBITDEPTH)) {
            AVIF_CHECK(avifImageAllocatePlanes(image, AVIF_PLANES_A) == AVIF_RESULT_OK);
            const uint8_t * srcRow = codec->internal->image->planes[0];
            uint8_t * dstRow = image->alphaPlane;
            for (uint32_t y = 0; y < image->height; ++y) {
                const uint16_t * srcRow16 = (const uint16_t *)srcRow;
                for (uint32_t x = 0; x < image->width; ++x) {
                    dstRow[x] = (uint8_t)srcRow16[x];
                }
                srcRow += codec->internal->image->stride[0];
                dstRow += image->alphaRowBytes;
            }
        } else {
            image->alphaPlane = codec->internal->image->planes[0];
            image->alphaRowBytes = codec->internal->image->stride[0];
            image->imageOwnsAlphaPlane = AVIF_FALSE;
        }
        *isLimitedRangeAlpha = (codec->internal->image->range == AVM_CR_STUDIO_RANGE);
    }

    return AVIF_TRUE;
}

static avm_img_fmt_t avifImageCalcAVMFmt(const avifImage * image, avifBool alpha)
{
    avm_img_fmt_t fmt;
    if (alpha) {
        // We're going monochrome, who cares about chroma quality
        fmt = AVM_IMG_FMT_I420;
    } else {
        switch (image->yuvFormat) {
            case AVIF_PIXEL_FORMAT_YUV444:
                fmt = AVM_IMG_FMT_I444;
                break;
            case AVIF_PIXEL_FORMAT_YUV422:
                fmt = AVM_IMG_FMT_I422;
                break;
            case AVIF_PIXEL_FORMAT_YUV420:
            case AVIF_PIXEL_FORMAT_YUV400:
                fmt = AVM_IMG_FMT_I420;
                break;
            case AVIF_PIXEL_FORMAT_NONE:
            case AVIF_PIXEL_FORMAT_COUNT:
            default:
                return AVM_IMG_FMT_NONE;
        }
    }

    if (image->depth > 8) {
        fmt |= AVM_IMG_FMT_HIGHBITDEPTH;
    }

    return fmt;
}

struct avmOptionEnumList
{
    const char * name;
    int val;
};

static avifBool avmOptionParseEnum(const char * str, const struct avmOptionEnumList * enums, int * val)
{
    const struct avmOptionEnumList * listptr;
    long int rawval;
    char * endptr;

    // First see if the value can be parsed as a raw value.
    rawval = strtol(str, &endptr, 10);
    if (str[0] != '\0' && endptr[0] == '\0') {
        // Got a raw value, make sure it's valid.
        for (listptr = enums; listptr->name; listptr++)
            if (listptr->val == rawval) {
                *val = (int)rawval;
                return AVIF_TRUE;
            }
    }

    // Next see if it can be parsed as a string.
    for (listptr = enums; listptr->name; listptr++) {
        if (!strcmp(str, listptr->name)) {
            *val = listptr->val;
            return AVIF_TRUE;
        }
    }

    return AVIF_FALSE;
}

static const struct avmOptionEnumList endUsageEnum[] = { //
    { "vbr", AVM_VBR },                                  // Variable Bit Rate (VBR) mode
    { "cbr", AVM_CBR },                                  // Constant Bit Rate (CBR) mode
    { "cq", AVM_CQ },                                    // Constrained Quality (CQ) mode
    { "q", AVM_Q },                                      // Constant Quality (Q) mode
    { NULL, 0 }
};

// Returns true if <key> equals <name> or <prefix><name>, where <prefix> is "color:" or "alpha:"
// or the abbreviated form "c:" or "a:".
static avifBool avifKeyEqualsName(const char * key, const char * name, avifBool alpha)
{
    const char * prefix = alpha ? "alpha:" : "color:";
    size_t prefixLen = 6;
    const char * shortPrefix = alpha ? "a:" : "c:";
    size_t shortPrefixLen = 2;
    return !strcmp(key, name) || (!strncmp(key, prefix, prefixLen) && !strcmp(key + prefixLen, name)) ||
           (!strncmp(key, shortPrefix, shortPrefixLen) && !strcmp(key + shortPrefixLen, name));
}

static avifBool avifProcessAVMOptionsPreInit(avifCodec * codec, avifBool alpha, struct avm_codec_enc_cfg * cfg)
{
    for (uint32_t i = 0; i < codec->csOptions->count; ++i) {
        const avifCodecSpecificOption * entry = &codec->csOptions->entries[i];
        int val;
        if (avifKeyEqualsName(entry->key, "end-usage", alpha)) { // Rate control mode
            if (!avmOptionParseEnum(entry->value, endUsageEnum, &val)) {
                avifDiagnosticsPrintf(codec->diag, "Invalid value for end-usage: %s", entry->value);
                return AVIF_FALSE;
            }
            cfg->rc_end_usage = val;
        }
    }
    return AVIF_TRUE;
}

static avifBool avifProcessAVMOptionsPostInit(avifCodec * codec, avifBool alpha)
{
    for (uint32_t i = 0; i < codec->csOptions->count; ++i) {
        const avifCodecSpecificOption * entry = &codec->csOptions->entries[i];
        // Skip options for the other kind of plane.
        const char * otherPrefix = alpha ? "color:" : "alpha:";
        size_t otherPrefixLen = 6;
        const char * otherShortPrefix = alpha ? "c:" : "a:";
        size_t otherShortPrefixLen = 2;
        if (!strncmp(entry->key, otherPrefix, otherPrefixLen) || !strncmp(entry->key, otherShortPrefix, otherShortPrefixLen)) {
            continue;
        }

        // Skip options processed by avifProcessAVMOptionsPreInit.
        if (avifKeyEqualsName(entry->key, "end-usage", alpha)) {
            continue;
        }

        const char * prefix = alpha ? "alpha:" : "color:";
        size_t prefixLen = 6;
        const char * shortPrefix = alpha ? "a:" : "c:";
        size_t shortPrefixLen = 2;
        const char * key = entry->key;
        if (!strncmp(key, prefix, prefixLen)) {
            key += prefixLen;
        } else if (!strncmp(key, shortPrefix, shortPrefixLen)) {
            key += shortPrefixLen;
        }
        if (avm_codec_set_option(&codec->internal->encoder, key, entry->value) != AVM_CODEC_OK) {
            avifDiagnosticsPrintf(codec->diag,
                                  "avm_codec_set_option(\"%s\", \"%s\") failed: %s: %s",
                                  key,
                                  entry->value,
                                  avm_codec_error(&codec->internal->encoder),
                                  avm_codec_error_detail(&codec->internal->encoder));
            return AVIF_FALSE;
        }
        if (!strcmp(key, "tune")) {
            codec->internal->tuningSet = AVIF_TRUE;
        }
    }
    return AVIF_TRUE;
}

struct avmScalingModeMapList
{
    avifFraction avifMode;
    AVM_SCALING_MODE avmMode;
};

static const struct avmScalingModeMapList scalingModeMap[] = {
    { { 1, 1 }, AVME_NORMAL },    { { 1, 2 }, AVME_ONETWO },    { { 1, 4 }, AVME_ONEFOUR },  { { 1, 8 }, AVME_ONEEIGHT },
    { { 3, 4 }, AVME_THREEFOUR }, { { 3, 5 }, AVME_THREEFIVE }, { { 4, 5 }, AVME_FOURFIVE },
};

static const int scalingModeMapSize = sizeof(scalingModeMap) / sizeof(scalingModeMap[0]);

static avifBool avifFindAVMScalingMode(const avifFraction * avifMode, AVM_SCALING_MODE * avmMode)
{
    avifFraction simplifiedFraction = *avifMode;
    avifFractionSimplify(&simplifiedFraction);
    for (int i = 0; i < scalingModeMapSize; ++i) {
        if (scalingModeMap[i].avifMode.n == simplifiedFraction.n && scalingModeMap[i].avifMode.d == simplifiedFraction.d) {
            *avmMode = scalingModeMap[i].avmMode;
            return AVIF_TRUE;
        }
    }

    return AVIF_FALSE;
}

// Scales from aom's [0:63] to avm's [M:255], where M=0/-48/-96 for 8/10/12 bit.
// See --min-qp help in
// https://gitlab.com/AOMediaCodec/avm/-/blob/main/apps/avmenc.c
static int avmScaleQuantizer(int quantizer, uint32_t depth)
{
    if (depth == 10) {
        return AVIF_CLAMP((quantizer * (255 + 48) + 31) / 63 - 48, -48, 255);
    }
    if (depth == 12) {
        return AVIF_CLAMP((quantizer * (255 + 96) + 31) / 63 - 96, -96, 255);
    }
    assert(depth == 8);
    return AVIF_CLAMP((quantizer * 255 + 31) / 63, 0, 255);
}

// Converts quality to avm's quantizer in the range of [M:255], where M=0/-48/-96 for 8/10/12 bit.
// See --min-qp help in
// https://gitlab.com/AOMediaCodec/avm/-/blob/main/apps/avmenc.c
static int avmQualityToQuantizer(int quality, uint32_t depth)
{
    if (depth == 10) {
        return 255 - (quality * (255 + 48) + 50) / 100;
    }
    if (depth == 12) {
        return 255 - (quality * (255 + 96) + 50) / 100;
    }
    assert(depth == 8);
    return 255 - (quality * 255 + 50) / 100;
}

static avifBool avmCodecEncodeFinish(avifCodec * codec, avifCodecEncodeOutput * output);

static avifResult avmCodecEncodeImage(avifCodec * codec,
                                      avifEncoder * encoder,
                                      const avifImage * image,
                                      avifBool alpha,
                                      int tileRowsLog2,
                                      int tileColsLog2,
                                      int quality,
                                      avifEncoderChanges encoderChanges,
                                      avifBool disableLaggedOutput,
                                      avifAddImageFlags addImageFlags,
                                      avifCodecEncodeOutput * output)
{
    struct avm_codec_enc_cfg * cfg = &codec->internal->cfg;
    avifBool quantizerUpdated = AVIF_FALSE;
    const int quantizer = avmQualityToQuantizer(quality, image->depth);

    // For encoder->scalingMode.horizontal and encoder->scalingMode.vertical to take effect in AV2
    // encoder, config should be applied for each frame, so we don't care about changes on these
    // two fields.
    encoderChanges &= ~AVIF_ENCODER_CHANGE_SCALING_MODE;

    if (!codec->internal->encoderInitialized) {
        int avmCpuUsed = -1;
        if (encoder->speed != AVIF_SPEED_DEFAULT) {
            avmCpuUsed = AVIF_CLAMP(encoder->speed, 0, 9);
        }

        codec->internal->avmFormat = avifImageCalcAVMFmt(image, alpha);
        if (codec->internal->avmFormat == AVM_IMG_FMT_NONE) {
            return AVIF_RESULT_UNKNOWN_ERROR;
        }

        avifGetPixelFormatInfo(image->yuvFormat, &codec->internal->formatInfo);

        avm_codec_iface_t * encoderInterface = avm_codec_av2_cx();
        avm_codec_err_t err = avm_codec_enc_config_default(encoderInterface, cfg, AVM_USAGE_GOOD_QUALITY);
        if (err != AVM_CODEC_OK) {
            avifDiagnosticsPrintf(codec->diag, "avm_codec_enc_config_default() failed: %s", avm_codec_err_to_string(err));
            return AVIF_RESULT_UNKNOWN_ERROR;
        }

        // avm's default is AVM_VBR. Change the default to AVM_Q since we don't need to hit a certain target bit rate.
        // It's easier to control the worst quality in Q mode.
        cfg->rc_end_usage = AVM_Q;

        // 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:0, 4:2:2 and 4:4:4
        uint8_t seqProfile = 0;
        if (image->depth != 8 && image->depth != 10) {
            avifDiagnosticsPrintf(codec->diag, "%d-bit is not supported in AV2 encoder.", image->depth);
            return AVIF_RESULT_INVALID_ARGUMENT;
        }
        // Based on AV2 spec Section A.3 Profiles.
        if (alpha) {
            seqProfile = 1; // Main_420_10_IP1
        } else {
            switch (image->yuvFormat) {
                case AVIF_PIXEL_FORMAT_YUV444:
                    seqProfile = 4; // Main_444_10_IP1
                    break;
                case AVIF_PIXEL_FORMAT_YUV422:
                    seqProfile = 3; // Main_422_10_IP1
                    break;
                case AVIF_PIXEL_FORMAT_YUV420:
                    seqProfile = 1; // Main_420_10_IP1
                    break;
                case AVIF_PIXEL_FORMAT_YUV400:
                    seqProfile = 1; // Main_420_10_IP1
                    break;
                case AVIF_PIXEL_FORMAT_NONE:
                case AVIF_PIXEL_FORMAT_COUNT:
                default:
                    break;
            }
        }

        cfg->g_profile = seqProfile;
        cfg->g_bit_depth = image->depth;
        cfg->g_input_bit_depth = image->depth;
        cfg->g_w = image->width;
        cfg->g_h = image->height;
        if (addImageFlags & AVIF_ADD_IMAGE_FLAG_SINGLE) {
            // Set the maximum number of frames to encode to 1. This instructs
            // libavm to set still_picture and reduced_still_picture_header to
            // 1 in AV2 sequence headers.
            cfg->g_limit = 1;
        }

        // Determine whether the encoder should be configured to use intra frames only, by manually configuring the encoder so all
        // frames will be key frames.

        // All-intra encoding is beneficial when encoding a two-layer image item and the quality of the first layer is very low.
        // Switching to all-intra encoding comes with the following benefits:
        // - The first layer will be smaller than the second layer (which is often not the case with inter encoding)
        // - Outputs have predictable file sizes: the sum of the first layer (quality <= 10) plus the second layer (quality set by the caller)
        // - Because the first layer is very small, layered encoding overhead is also smaller and more stable (about 5-8% for quality 40 and 2-4% for quality 60)
        avifBool useAllIntraForLayered = encoder->extraLayerCount == 1 && quality <= TWO_LAYER_ALL_INTRA_QUALITY_THRESHOLD;
        avifBool useAllIntra = (addImageFlags & AVIF_ADD_IMAGE_FLAG_SINGLE) || useAllIntraForLayered;

        if (useAllIntra) {
            // Use the default settings of libaom's AOM_USAGE_ALL_INTRA (added
            // in https://crbug.com/aomedia/2959).
            //
            // Set g_lag_in_frames to 0 to reduce the number of frame buffers
            // (from 20 to 2) in libavm's lookahead structure. This reduces
            // memory consumption when encoding a single image.
            cfg->g_lag_in_frames = 0;
            // Disable automatic placement of key frames by the encoder.
            cfg->kf_mode = AVM_KF_DISABLED;
            // Tell libavm that all frames will be key frames.
            cfg->kf_max_dist = 0;
        }
        if (encoder->extraLayerCount > 0) {
            cfg->g_limit = encoder->extraLayerCount + 1;
            // For layered image, disable lagged encoding to always get output
            // frame for each input frame.
            cfg->g_lag_in_frames = 0;
        }
        if (disableLaggedOutput) {
            cfg->g_lag_in_frames = 0;
        }
        if (encoder->maxThreads > 1) {
            // libavm fails if cfg->g_threads is greater than 64 threads. See MAX_NUM_THREADS in
            // avm/avm_util/avm_thread.h.
            cfg->g_threads = AVIF_MIN(encoder->maxThreads, 64);
        }

        codec->internal->monochromeEnabled = AVIF_FALSE;
        if (alpha || (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400)) {
            codec->internal->monochromeEnabled = AVIF_TRUE;
            cfg->monochrome = 1;
        }

        if (!avifProcessAVMOptionsPreInit(codec, alpha, cfg)) {
            return AVIF_RESULT_INVALID_CODEC_SPECIFIC_OPTION;
        }

        int minQuantizer;
        int maxQuantizer;
        if (alpha) {
            minQuantizer = encoder->minQuantizerAlpha;
            maxQuantizer = encoder->maxQuantizerAlpha;
        } else {
            minQuantizer = encoder->minQuantizer;
            maxQuantizer = encoder->maxQuantizer;
        }
        minQuantizer = avmScaleQuantizer(minQuantizer, image->depth);
        maxQuantizer = avmScaleQuantizer(maxQuantizer, image->depth);
        if ((cfg->rc_end_usage == AVM_VBR) || (cfg->rc_end_usage == AVM_CBR)) {
            // cq-level is ignored in these two end-usage modes, so adjust minQuantizer and
            // maxQuantizer to the target quantizer.
            if (quantizer == AVIF_QUANTIZER_LOSSLESS) {
                minQuantizer = AVIF_QUANTIZER_LOSSLESS;
                maxQuantizer = AVIF_QUANTIZER_LOSSLESS;
            } else {
                minQuantizer = AVIF_MAX(quantizer - 4, minQuantizer);
                maxQuantizer = AVIF_MIN(quantizer + 4, maxQuantizer);
            }
        }
        cfg->rc_min_quantizer = minQuantizer;
        cfg->rc_max_quantizer = maxQuantizer;
        quantizerUpdated = AVIF_TRUE;

        if (avm_codec_enc_init(&codec->internal->encoder, encoderInterface, cfg, /*flags=*/0) != AVM_CODEC_OK) {
            avifDiagnosticsPrintf(codec->diag,
                                  "avm_codec_enc_init() failed: %s: %s",
                                  avm_codec_error(&codec->internal->encoder),
                                  avm_codec_error_detail(&codec->internal->encoder));
            return AVIF_RESULT_UNKNOWN_ERROR;
        }
        codec->internal->encoderInitialized = AVIF_TRUE;

        if ((cfg->rc_end_usage == AVM_CQ) || (cfg->rc_end_usage == AVM_Q)) {
            avm_codec_control(&codec->internal->encoder, AVME_SET_QP, quantizer);
        }
        avifBool lossless = (quantizer == AVIF_QUANTIZER_LOSSLESS);
        if (lossless) {
            avm_codec_control(&codec->internal->encoder, AV2E_SET_LOSSLESS, 1);
        }
        if (encoder->maxThreads > 1) {
            avm_codec_control(&codec->internal->encoder, AV2E_SET_ROW_MT, 1);
        }
        if (tileRowsLog2 != 0) {
            avm_codec_control(&codec->internal->encoder, AV2E_SET_TILE_ROWS, tileRowsLog2);
        }
        if (tileColsLog2 != 0) {
            avm_codec_control(&codec->internal->encoder, AV2E_SET_TILE_COLUMNS, tileColsLog2);
        }
        if (encoder->extraLayerCount > 0) {
            int layerCount = encoder->extraLayerCount + 1;
            if (avm_codec_control(&codec->internal->encoder, AVME_SET_NUMBER_MLAYERS, layerCount) != AVM_CODEC_OK) {
                return AVIF_RESULT_UNKNOWN_ERROR;
            }
        }
        if (avmCpuUsed != -1) {
            if (avm_codec_control(&codec->internal->encoder, AVME_SET_CPUUSED, avmCpuUsed) != AVM_CODEC_OK) {
                return AVIF_RESULT_UNKNOWN_ERROR;
            }
        }

        // Set color_config() in the sequence header OBU.
        if (alpha) {
            // AV1-AVIF specification, Section 4 "Auxiliary Image Items and Sequences":
            //   The color_range field in the Sequence Header OBU shall be set to 1.
            avm_codec_control(&codec->internal->encoder, AV2E_SET_COLOR_RANGE, AVM_CR_FULL_RANGE);

            // Keep the default AVM_CSP_UNKNOWN value.

            // CICP (CP/TC/MC) does not apply to the alpha auxiliary image.
            // Keep default Unspecified (2) colour primaries, transfer characteristics,
            // and matrix coefficients.
        } else {
            // libavm's defaults are AVM_CSP_UNKNOWN and 0 (studio/limited range).
            // Call avm_codec_control() only if the values are not the defaults.

            // AV1-AVIF specification, Section 2.2.1. "AV1 Item Configuration Property":
            //   The values of the fields in the AV1CodecConfigurationBox shall match those
            //   of the Sequence Header OBU in the AV1 Image Item Data.
            if (image->yuvChromaSamplePosition != AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN) {
                avm_codec_control(&codec->internal->encoder, AV2E_SET_CHROMA_SAMPLE_POSITION, (int)image->yuvChromaSamplePosition);
            }

            // AV1-ISOBMFF specification, Section 2.3.4:
            //   The value of full_range_flag in the 'colr' box SHALL match the color_range
            //   flag in the Sequence Header OBU.
            if (image->yuvRange != AVIF_RANGE_LIMITED) {
                avm_codec_control(&codec->internal->encoder, AV2E_SET_COLOR_RANGE, (int)image->yuvRange);
            }

            // Section 2.3.4 of AV1-ISOBMFF says 'colr' with 'nclx' should be present and shall match CICP
            // values in the Sequence Header OBU, unless the latter has 2/2/2 (Unspecified).
            // So set CICP values to 2/2/2 (Unspecified) in the Sequence Header OBU for simplicity.
            // libavm's defaults are AVM_CICP_CP_UNSPECIFIED, AVM_CICP_TC_UNSPECIFIED, and
            // AVM_CICP_MC_UNSPECIFIED. No need to call avm_codec_control().
            // avm_image_t::cp, avm_image_t::tc and avm_image_t::mc are ignored by avm_codec_encode().
        }

        if (!avifProcessAVMOptionsPostInit(codec, alpha)) {
            return AVIF_RESULT_INVALID_CODEC_SPECIFIC_OPTION;
        }
        // Disabling these two gives 1.19% PSNR YUV loss in All-Intra config, but encode will be ~4X faster.
        if (avm_codec_set_option(&codec->internal->encoder, "enable-ext-partitions", "0") != AVM_CODEC_OK ||
            avm_codec_set_option(&codec->internal->encoder, "enable-uneven-4way-partitions", "0") != AVM_CODEC_OK) {
            return AVIF_RESULT_UNKNOWN_ERROR;
        }
        if (!codec->internal->tuningSet) {
            if (avm_codec_control(&codec->internal->encoder, AVME_SET_TUNING, AVM_TUNE_SSIM) != AVM_CODEC_OK) {
                return AVIF_RESULT_UNKNOWN_ERROR;
            }
        }
    } else {
        avifBool dimensionsChanged = AVIF_FALSE;
        if ((cfg->g_w != image->width) || (cfg->g_h != image->height)) {
            // We are not ready for dimension change for now.
            return AVIF_RESULT_NOT_IMPLEMENTED;
        }
        if (alpha) {
            if (encoderChanges & (AVIF_ENCODER_CHANGE_MIN_QUANTIZER_ALPHA | AVIF_ENCODER_CHANGE_MAX_QUANTIZER_ALPHA)) {
                cfg->rc_min_quantizer = avmScaleQuantizer(encoder->minQuantizerAlpha, image->depth);
                cfg->rc_max_quantizer = avmScaleQuantizer(encoder->maxQuantizerAlpha, image->depth);
                quantizerUpdated = AVIF_TRUE;
            }
        } else {
            if (encoderChanges & (AVIF_ENCODER_CHANGE_MIN_QUANTIZER | AVIF_ENCODER_CHANGE_MAX_QUANTIZER)) {
                cfg->rc_min_quantizer = avmScaleQuantizer(encoder->minQuantizer, image->depth);
                cfg->rc_max_quantizer = avmScaleQuantizer(encoder->maxQuantizer, image->depth);
                quantizerUpdated = AVIF_TRUE;
            }
        }
        const int qualityChangedBit = alpha ? AVIF_ENCODER_CHANGE_QUALITY_ALPHA : AVIF_ENCODER_CHANGE_QUALITY;
        if (encoderChanges & qualityChangedBit) {
            if ((cfg->rc_end_usage == AVM_VBR) || (cfg->rc_end_usage == AVM_CBR)) {
                // cq-level is ignored in these two end-usage modes, so adjust minQuantizer and
                // maxQuantizer to the target quantizer.
                if (quantizer == AVIF_QUANTIZER_LOSSLESS) {
                    cfg->rc_min_quantizer = AVIF_QUANTIZER_LOSSLESS;
                    cfg->rc_max_quantizer = AVIF_QUANTIZER_LOSSLESS;
                } else {
                    int minQuantizer;
                    int maxQuantizer;
                    if (alpha) {
                        minQuantizer = encoder->minQuantizerAlpha;
                        maxQuantizer = encoder->maxQuantizerAlpha;
                    } else {
                        minQuantizer = encoder->minQuantizer;
                        maxQuantizer = encoder->maxQuantizer;
                    }
                    minQuantizer = avmScaleQuantizer(minQuantizer, image->depth);
                    maxQuantizer = avmScaleQuantizer(maxQuantizer, image->depth);
                    cfg->rc_min_quantizer = AVIF_MAX(quantizer - 4, minQuantizer);
                    cfg->rc_max_quantizer = AVIF_MIN(quantizer + 4, maxQuantizer);
                }
                quantizerUpdated = AVIF_TRUE;
            }
        }
        if (quantizerUpdated || dimensionsChanged) {
            avm_codec_err_t err = avm_codec_enc_config_set(&codec->internal->encoder, cfg);
            if (err != AVM_CODEC_OK) {
                avifDiagnosticsPrintf(codec->diag,
                                      "avm_codec_enc_config_set() failed: %s: %s",
                                      avm_codec_error(&codec->internal->encoder),
                                      avm_codec_error_detail(&codec->internal->encoder));
                return AVIF_RESULT_UNKNOWN_ERROR;
            }
        }
        if (encoderChanges & AVIF_ENCODER_CHANGE_TILE_ROWS_LOG2) {
            avm_codec_control(&codec->internal->encoder, AV2E_SET_TILE_ROWS, tileRowsLog2);
        }
        if (encoderChanges & AVIF_ENCODER_CHANGE_TILE_COLS_LOG2) {
            avm_codec_control(&codec->internal->encoder, AV2E_SET_TILE_COLUMNS, tileColsLog2);
        }
        if (encoderChanges & qualityChangedBit) {
            if ((cfg->rc_end_usage == AVM_CQ) || (cfg->rc_end_usage == AVM_Q)) {
                avm_codec_control(&codec->internal->encoder, AVME_SET_QP, quantizer);
            }
            avifBool lossless = (quantizer == AVIF_QUANTIZER_LOSSLESS);
            avm_codec_control(&codec->internal->encoder, AV2E_SET_LOSSLESS, lossless);
        }
        if (encoderChanges & AVIF_ENCODER_CHANGE_CODEC_SPECIFIC) {
            if (!avifProcessAVMOptionsPostInit(codec, alpha)) {
                return AVIF_RESULT_INVALID_CODEC_SPECIFIC_OPTION;
            }
        }
    }

    if (codec->internal->currentLayer > encoder->extraLayerCount) {
        avifDiagnosticsPrintf(codec->diag,
                              "Too many layers sent. Expected %u layers, but got %u layers.",
                              encoder->extraLayerCount + 1,
                              codec->internal->currentLayer + 1);
        return AVIF_RESULT_INVALID_ARGUMENT;
    }
    if (encoder->extraLayerCount > 0) {
        avm_codec_control(&codec->internal->encoder, AVME_SET_MLAYER_ID, codec->internal->currentLayer);
    }

    avm_scaling_mode_t avmScalingMode;
    if (!avifFindAVMScalingMode(&encoder->scalingMode.horizontal, &avmScalingMode.h_scaling_mode)) {
        return AVIF_RESULT_NOT_IMPLEMENTED;
    }
    if (!avifFindAVMScalingMode(&encoder->scalingMode.vertical, &avmScalingMode.v_scaling_mode)) {
        return AVIF_RESULT_NOT_IMPLEMENTED;
    }
    if ((avmScalingMode.h_scaling_mode != AVME_NORMAL) || (avmScalingMode.v_scaling_mode != AVME_NORMAL)) {
        // AVME_SET_SCALEMODE only applies to next frame (layer), so we have to set it every time.
        avm_codec_control(&codec->internal->encoder, AVME_SET_SCALEMODE, &avmScalingMode);
    }

    avm_image_t avmImage;
    // We prefer to simply set the avmImage.planes[] pointers to the plane buffers in 'image'. When
    // doing this, we set avmImage.w equal to avmImage.d_w and avmImage.h equal to avmImage.d_h and
    // do not "align" avmImage.w and avmImage.h. Unfortunately this exposes a libaom bug in libavm
    // (https://crbug.com/aomedia/3113) if chroma is subsampled and image->width or image->height is
    // equal to 1. To work around this libavm bug, we allocate the avmImage.planes[] buffers and
    // copy the image YUV data if image->width or image->height is equal to 1. This bug has been
    // fixed in libaom v3.1.3 but not in libavm.
    //
    // Note: The exact condition for the bug is
    //   ((image->width == 1) && (chroma is subsampled horizontally)) ||
    //   ((image->height == 1) && (chroma is subsampled vertically))
    // Since an image width or height of 1 is uncommon in practice, we test an inexact but simpler
    // condition.
    avifBool avmImageAllocated = (image->width == 1) || (image->height == 1);
    if (avmImageAllocated) {
        avm_img_alloc(&avmImage, codec->internal->avmFormat, image->width, image->height, 16);
    } else {
        memset(&avmImage, 0, sizeof(avmImage));
        avmImage.fmt = codec->internal->avmFormat;
        avmImage.bit_depth = (image->depth > 8) ? 16 : 8;
        avmImage.w = image->width;
        avmImage.h = image->height;
        avmImage.d_w = image->width;
        avmImage.d_h = image->height;
        // Get sample size for this format.
        unsigned int bps;
        if (codec->internal->avmFormat == AVM_IMG_FMT_I420) {
            bps = 12;
        } else if (codec->internal->avmFormat == AVM_IMG_FMT_I422) {
            bps = 16;
        } else if (codec->internal->avmFormat == AVM_IMG_FMT_I444) {
            bps = 24;
        } else if (codec->internal->avmFormat == AVM_IMG_FMT_I42016) {
            bps = 24;
        } else if (codec->internal->avmFormat == AVM_IMG_FMT_I42216) {
            bps = 32;
        } else if (codec->internal->avmFormat == AVM_IMG_FMT_I44416) {
            bps = 48;
        } else {
            bps = 16;
        }
        avmImage.bps = bps;
        // See avifImageCalcAVMFmt(). libavm doesn't have AVM_IMG_FMT_I400, so we use AVM_IMG_FMT_I420 as a substitute for monochrome.
        avmImage.x_chroma_shift = (alpha || codec->internal->formatInfo.monochrome) ? 1 : codec->internal->formatInfo.chromaShiftX;
        avmImage.y_chroma_shift = (alpha || codec->internal->formatInfo.monochrome) ? 1 : codec->internal->formatInfo.chromaShiftY;
    }

    avifBool monochromeRequested = AVIF_FALSE;

    if (alpha) {
        // AV1-AVIF specification, Section 4 "Auxiliary Image Items and Sequences":
        //   The color_range field in the Sequence Header OBU shall be set to 1.
        avmImage.range = AVM_CR_FULL_RANGE;

        // AV1-AVIF specification, Section 4 "Auxiliary Image Items and Sequences":
        //   The mono_chrome field in the Sequence Header OBU shall be set to 1.
        // Some encoders do not support 4:0:0 and encode alpha as 4:2:0 so it is not always respected.
        monochromeRequested = AVIF_TRUE;
        if (avmImageAllocated) {
            const uint32_t bytesPerRow = ((image->depth > 8) ? 2 : 1) * image->width;
            for (uint32_t j = 0; j < image->height; ++j) {
                const uint8_t * srcAlphaRow = &image->alphaPlane[(size_t)j * image->alphaRowBytes];
                uint8_t * dstAlphaRow = &avmImage.planes[0][(size_t)j * avmImage.stride[0]];
                memcpy(dstAlphaRow, srcAlphaRow, bytesPerRow);
            }
        } else {
            avmImage.planes[0] = image->alphaPlane;
            avmImage.stride[0] = image->alphaRowBytes;
        }

        // Ignore UV planes when monochrome. Keep the default AVM_CSP_UNKNOWN value.
    } else {
        int yuvPlaneCount = 3;
        if (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) {
            yuvPlaneCount = 1; // Ignore UV planes when monochrome
            monochromeRequested = AVIF_TRUE;
        }
        if (avmImageAllocated) {
            uint32_t bytesPerPixel = (image->depth > 8) ? 2 : 1;
            for (int yuvPlane = 0; yuvPlane < yuvPlaneCount; ++yuvPlane) {
                uint32_t planeWidth = avifImagePlaneWidth(image, yuvPlane);
                uint32_t planeHeight = avifImagePlaneHeight(image, yuvPlane);
                uint32_t bytesPerRow = bytesPerPixel * planeWidth;

                for (uint32_t j = 0; j < planeHeight; ++j) {
                    const uint8_t * srcRow = &image->yuvPlanes[yuvPlane][(size_t)j * image->yuvRowBytes[yuvPlane]];
                    uint8_t * dstRow = &avmImage.planes[yuvPlane][(size_t)j * avmImage.stride[yuvPlane]];
                    memcpy(dstRow, srcRow, bytesPerRow);
                }
            }
        } else {
            for (int yuvPlane = 0; yuvPlane < yuvPlaneCount; ++yuvPlane) {
                avmImage.planes[yuvPlane] = image->yuvPlanes[yuvPlane];
                avmImage.stride[yuvPlane] = image->yuvRowBytes[yuvPlane];
            }
        }

        // AV1-AVIF specification, Section 2.2.1. "AV1 Item Configuration Property":
        //   The values of the fields in the AV1CodecConfigurationBox shall match those
        //   of the Sequence Header OBU in the AV1 Image Item Data.
        if (image->yuvChromaSamplePosition == AVIF_CHROMA_SAMPLE_POSITION_VERTICAL) {
            // CSP_LEFT: Horizontal offset 0, vertical offset 0.5
            avmImage.csp = AVM_CSP_LEFT;
        } else if (image->yuvChromaSamplePosition == AVIF_CHROMA_SAMPLE_POSITION_COLOCATED) {
            // CSP_TOPLEFT: Horizontal offset 0, vertical offset 0
            avmImage.csp = AVM_CSP_TOPLEFT;
        } else if (image->yuvChromaSamplePosition == AVIF_CHROMA_SAMPLE_POSITION_RESERVED) {
            // CSP_CENTER: Horizontal offset 0.5, vertical offset 0.5
            avmImage.csp = AVM_CSP_CENTER;
        } else { // AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN or invalid values
            avmImage.csp = AVM_CSP_UNSPECIFIED;
        }

        // AV1-ISOBMFF specification, Section 2.3.4:
        //   The value of full_range_flag in the 'colr' box SHALL match the color_range
        //   flag in the Sequence Header OBU.
        avmImage.range = (avm_color_range_t)image->yuvRange;
    }

    unsigned char * monoUVPlane = NULL;
    if (monochromeRequested) {
        if (codec->internal->monochromeEnabled) {
            avmImage.monochrome = 1;
        } else {
            // The user requested monochrome (via alpha or YUV400) but libavm does not support
            // monochrome. Manually set UV planes to 0.5.

            // avmImage is always 420 when we're monochrome
            uint32_t monoUVWidth = (image->width + 1) >> 1;
            uint32_t monoUVHeight = (image->height + 1) >> 1;

            // Allocate the U plane if necessary.
            if (!avmImageAllocated) {
                uint32_t channelSize = avifImageUsesU16(image) ? 2 : 1;
                uint32_t monoUVRowBytes = channelSize * monoUVWidth;
                size_t monoUVSize = (size_t)monoUVHeight * monoUVRowBytes;

                monoUVPlane = avifAlloc(monoUVSize);
                AVIF_CHECKERR(monoUVPlane != NULL, AVIF_RESULT_OUT_OF_MEMORY); // No need for avm_img_free() because !avmImageAllocated
                avmImage.planes[1] = monoUVPlane;
                avmImage.stride[1] = monoUVRowBytes;
            }
            // Set the U plane to 0.5.
            if (image->depth > 8) {
                const uint16_t half = 1 << (image->depth - 1);
                for (uint32_t j = 0; j < monoUVHeight; ++j) {
                    uint16_t * dstRow = (uint16_t *)&avmImage.planes[1][(size_t)j * avmImage.stride[1]];
                    for (uint32_t i = 0; i < monoUVWidth; ++i) {
                        dstRow[i] = half;
                    }
                }
            } else {
                const uint8_t half = 128;
                size_t planeSize = (size_t)monoUVHeight * avmImage.stride[1];
                memset(avmImage.planes[1], half, planeSize);
            }
            // Make the V plane the same as the U plane.
            avmImage.planes[2] = avmImage.planes[1];
            avmImage.stride[2] = avmImage.stride[1];
        }
    }

    avm_enc_frame_flags_t encodeFlags = 0;
    if (addImageFlags & AVIF_ADD_IMAGE_FLAG_FORCE_KEYFRAME) {
        encodeFlags |= AVM_EFLAG_FORCE_KF;
    }
    if (codec->internal->currentLayer > 0) {
        encodeFlags |= AVM_EFLAG_NO_REF_GF | AVM_EFLAG_NO_REF_ARF | AVM_EFLAG_NO_REF_BWD | AVM_EFLAG_NO_REF_ARF2 | AVM_EFLAG_NO_UPD_ALL;
    }
    avm_codec_err_t encodeErr = avm_codec_encode(&codec->internal->encoder, &avmImage, 0, 1, encodeFlags);
    avifFree(monoUVPlane);
    if (avmImageAllocated) {
        avm_img_free(&avmImage);
    }
    if (encodeErr != AVM_CODEC_OK) {
        avifDiagnosticsPrintf(codec->diag,
                              "avm_codec_encode() failed: %s: %s",
                              avm_codec_error(&codec->internal->encoder),
                              avm_codec_error_detail(&codec->internal->encoder));
        return AVIF_RESULT_UNKNOWN_ERROR;
    }

    avm_codec_iter_t iter = NULL;
    for (;;) {
        const avm_codec_cx_pkt_t * pkt = avm_codec_get_cx_data(&codec->internal->encoder, &iter);
        if (pkt == NULL) {
            break;
        }
        if (pkt->kind == AVM_CODEC_CX_FRAME_PKT) {
            AVIF_CHECKRES(
                avifCodecEncodeOutputAddSample(output, pkt->data.frame.buf, pkt->data.frame.sz, (pkt->data.frame.flags & AVM_FRAME_IS_KEY)));
        }
    }

    if ((addImageFlags & AVIF_ADD_IMAGE_FLAG_SINGLE) ||
        ((encoder->extraLayerCount > 0) && (encoder->extraLayerCount == codec->internal->currentLayer))) {
        // Flush and clean up encoder resources early to save on overhead when encoding alpha or grid images,
        // as encoding is finished now. For layered image, encoding finishes when the last layer is encoded.

        if (!avmCodecEncodeFinish(codec, output)) {
            return AVIF_RESULT_UNKNOWN_ERROR;
        }
        avm_codec_destroy(&codec->internal->encoder);
        codec->internal->encoderInitialized = AVIF_FALSE;
    }
    if (encoder->extraLayerCount > 0) {
        ++codec->internal->currentLayer;
    }
    return AVIF_RESULT_OK;
}

static avifBool avmCodecEncodeFinish(avifCodec * codec, avifCodecEncodeOutput * output)
{
    if (!codec->internal->encoderInitialized) {
        return AVIF_TRUE;
    }
    for (;;) {
        // flush encoder
        if (avm_codec_encode(&codec->internal->encoder, NULL, 0, 1, 0) != AVM_CODEC_OK) {
            avifDiagnosticsPrintf(codec->diag,
                                  "avm_codec_encode() with img=NULL failed: %s: %s",
                                  avm_codec_error(&codec->internal->encoder),
                                  avm_codec_error_detail(&codec->internal->encoder));
            return AVIF_FALSE;
        }

        avifBool gotPacket = AVIF_FALSE;
        avm_codec_iter_t iter = NULL;
        for (;;) {
            const avm_codec_cx_pkt_t * pkt = avm_codec_get_cx_data(&codec->internal->encoder, &iter);
            if (pkt == NULL) {
                break;
            }
            if (pkt->kind == AVM_CODEC_CX_FRAME_PKT) {
                gotPacket = AVIF_TRUE;
                const avifResult result = avifCodecEncodeOutputAddSample(output,
                                                                         pkt->data.frame.buf,
                                                                         pkt->data.frame.sz,
                                                                         (pkt->data.frame.flags & AVM_FRAME_IS_KEY));
                if (result != AVIF_RESULT_OK) {
                    avifDiagnosticsPrintf(codec->diag, "avifCodecEncodeOutputAddSample() failed: %s", avifResultToString(result));
                    return AVIF_FALSE;
                }
            }
        }

        if (!gotPacket) {
            break;
        }
    }
    return AVIF_TRUE;
}

const char * avifCodecVersionAVM(void)
{
    return avm_codec_version_str();
}

avifCodec * avifCodecCreateAVM(void)
{
    avifCodec * codec = (avifCodec *)avifCalloc(1, sizeof(avifCodec));
    if (codec == NULL) {
        return NULL;
    }

    codec->getNextImage = avmCodecGetNextImage;

    codec->encodeImage = avmCodecEncodeImage;
    codec->encodeFinish = avmCodecEncodeFinish;

    codec->destroyInternal = avmCodecDestroyInternal;
    codec->internal = (struct avifCodecInternal *)avifCalloc(1, sizeof(struct avifCodecInternal));
    if (codec->internal == NULL) {
        avifFree(codec);
        return NULL;
    }
    return codec;
}
