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

#include "avif/avif.h"

#include "avifjpeg.h"
#include "avifpng.h"
#include "avifutil.h"
#include "y4m.h"

#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_WIN32)
// for setmode()
#include <fcntl.h>
#include <io.h>
#endif

#define NEXTARG()                                                     \
    if (((argIndex + 1) == argc) || (argv[argIndex + 1][0] == '-')) { \
        fprintf(stderr, "%s requires an argument.", arg);             \
        goto cleanup;                                                 \
    }                                                                 \
    arg = argv[++argIndex]

typedef struct
{
    avifCodecChoice codecChoice;
    int jobs;
    int targetSize;
    avifBool qualityIsConstrained;      // true if quality explicitly set by the user
    avifBool qualityAlphaIsConstrained; // true if qualityAlpha explicitly set by the user
    int overrideQuality;
    int overrideQualityAlpha;
    avifBool progressive; // automatic layered encoding (progressive) with single input
    avifBool layered;     // manual layered encoding by specifying each layer
    int layers;
    int speed;
    avifHeaderFormatFlags headerFormat;

    avifBool paspPresent;
    uint32_t paspValues[2];
    avifBool clapValid; // clapValues may contain 4 crop values and need conversion. In this case clapValid is also false.
    uint32_t clapValues[8];
    avifBool gridDimsPresent;
    uint32_t gridDims[2];
    avifBool clliPresent;
    uint32_t clliValues[2];

    int repetitionCount;
    int keyframeInterval;
    avifBool ignoreExif;
    avifBool ignoreXMP;
    avifBool ignoreColorProfile;

    // These settings are only relevant when compiled with AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION.
    avifBool qualityGainMapIsConstrained; // true if qualityGainMap explicitly set by the user
    int qualityGainMap;
    avifBool ignoreGainMap; // ignore any gain map present in the input file.

    // This holds the output timing for image sequences. The timescale member in this struct will
    // become the timescale set on avifEncoder, and the duration member will be the default duration
    // for any frame that doesn't have a specific duration set on the commandline. See the
    // declaration of avifAppSourceTiming for more documentation.
    avifAppSourceTiming outputTiming;

    avifBool cicpExplicitlySet;
    avifColorPrimaries colorPrimaries;
    avifTransferCharacteristics transferCharacteristics;
    avifMatrixCoefficients matrixCoefficients;
    avifChromaDownsampling chromaDownsampling;
    avifAppFileFormat inputFormat;
} avifSettings;

typedef struct
{
    char ** keys;
    char ** values;
    int count;
} avifCodecSpecificOptions;

typedef struct avifSettingsEntryInt
{
    int value;
    avifBool set;
} avifSettingsEntryInt;

static avifSettingsEntryInt intSettingsEntryOf(int value)
{
    avifSettingsEntryInt entry = { value, AVIF_TRUE };
    return entry;
}

typedef avifSettingsEntryInt avifSettingsEntryBool;

static avifSettingsEntryBool boolSettingsEntryOf(avifBool value)
{
    return intSettingsEntryOf(value);
}

typedef struct avifSettingsEntryScalingMode
{
    avifScalingMode value;
    avifBool set;
} avifSettingsEntryScalingMode;

static avifSettingsEntryScalingMode scalingModeSettingsEntryOf(uint32_t n, uint32_t d)
{
    avifFraction mode = { (int32_t)n, (int32_t)d };
    avifSettingsEntryScalingMode entry = { { mode, mode }, AVIF_TRUE };
    return entry;
}

// Each entry records an "update" action to the corresponding field in avifEncoder.
// Fields in avifEncoder are not reset after encoding an image,
// so updates naturally apply to all following inputs,
// and is only recorded once on the first applicable input.
typedef struct avifInputFileSettings
{
    avifSettingsEntryInt quality;
    avifSettingsEntryInt qualityAlpha;
    avifSettingsEntryInt minQuantizer;
    avifSettingsEntryInt maxQuantizer;
    avifSettingsEntryInt minQuantizerAlpha;
    avifSettingsEntryInt maxQuantizerAlpha;
    avifSettingsEntryInt tileRowsLog2;
    avifSettingsEntryInt tileColsLog2;
    avifSettingsEntryBool autoTiling;
    avifSettingsEntryScalingMode scalingMode;

    avifCodecSpecificOptions codecSpecificOptions;
} avifInputFileSettings;

#define AVIF_FILENAME_STDIN NULL
static const char * avifPrettyFilename(const char * filename)
{
    if (filename == AVIF_FILENAME_STDIN) {
        return "(stdin)";
    }
    return filename;
}

typedef struct avifInputFile
{
    const char * filename; // If AVIF_FILENAME_STDIN, use stdin
    uint64_t duration;     // If 0, use the default duration
    avifInputFileSettings settings;
} avifInputFile;

typedef struct
{
    int fileIndex;
    avifImage * image;
    const avifInputFileSettings * settings;
    uint32_t fileBitDepth;
    avifBool fileIsRGB;
    avifAppSourceTiming sourceTiming;
} avifInputCacheEntry;

typedef struct avifInput
{
    avifInputFile * files;
    int filesCount;
    int fileIndex;
    struct y4mFrameIterator * frameIter;
    avifPixelFormat requestedFormat;
    int requestedDepth;

    avifBool cacheEnabled;
    avifInputCacheEntry * cache;
    int cacheCount;
} avifInput;

typedef struct avifEncodedByteSizes
{
    size_t colorSizeBytes;
    size_t alphaSizeBytes;
    size_t gainMapSizeBytes;
} avifEncodedByteSizes;

static void syntaxShort(void)
{
    printf("Syntax: avifenc [options] -q quality input.[jpg|jpeg|png|y4m] output.avif\n");
    printf("where quality is between %d (worst quality) and %d (lossless).\n", AVIF_QUALITY_WORST, AVIF_QUALITY_LOSSLESS);
    printf("Typical value is 60-80.\n\n");
    printf("Try -h for an exhaustive list of options.\n");
}

static void syntaxLong(void)
{
    printf("Syntax: avifenc [options] input.[jpg|jpeg|png|y4m] output.avif\n");
    printf("Standard options:\n");
    printf("    -h,--help                         : Show syntax help (this page)\n");
    printf("    -V,--version                      : Show the version number\n");
    printf("\n");
    printf("Basic options:\n");
    printf("    -q,--qcolor Q                     : Quality for color in %d..%d where %d is lossless\n",
           AVIF_QUALITY_WORST,
           AVIF_QUALITY_BEST,
           AVIF_QUALITY_LOSSLESS);
    printf("    --qalpha Q                        : Quality for alpha in %d..%d where %d is lossless\n",
           AVIF_QUALITY_WORST,
           AVIF_QUALITY_BEST,
           AVIF_QUALITY_LOSSLESS);
    printf("    -s,--speed S                      : Encoder speed in %d..%d where 0 is the slowest, 10 is the fastest. Or 'default' or 'd' for codec internal defaults. (Default: 6)\n",
           AVIF_SPEED_SLOWEST,
           AVIF_SPEED_FASTEST);
    printf("\n");
    printf("Advanced options:\n");
    printf("    -j,--jobs J                       : Number of jobs (worker threads), or 'all' to potentially use as many cores as possible. (Default: all)\n");
    printf("    --no-overwrite                    : Never overwrite existing output file\n");
    printf("    -o,--output FILENAME              : Instead of using the last filename given as output, use this filename\n");
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
    printf("    --mini                            : EXPERIMENTAL: Use reduced header if possible (backward-incompatible)\n");
#endif
    printf("    -l,--lossless                     : Set all defaults to encode losslessly, and emit warnings when settings/input don't allow for it\n");
    printf("    -d,--depth D                      : Output depth, one of 8, 10 or 12. (JPEG/PNG only; For y4m or stdin, depth is retained)\n");
    printf("    -y,--yuv FORMAT                   : Output format, one of 'auto' (default), 444, 422, 420 or 400. Ignored for y4m or stdin (y4m format is retained)\n");
    printf("                                        For JPEG, auto honors the JPEG's internal format, if possible. For grayscale PNG, auto defaults to 400. For all other cases, auto defaults to 444\n");
    printf("    -p,--premultiply                  : Premultiply color by the alpha channel and signal this in the AVIF\n");
    printf("    --sharpyuv                        : Use sharp RGB to YUV420 conversion (if supported). Ignored for y4m or if output is not 420.\n");
    printf("    --stdin                           : Read input from stdin instead of file paths. No other input is allowed. The input format is assumed to be y4m unless --input-format is specified. The output file path must still be provided.\n");
    printf("    --input-format FORMAT             : File format of the input data. One of: jpeg/png/y4m/auto. (Default: auto, except for stdin where auto is not supported and the default is y4m)\n");
    printf("    --cicp,--nclx P/T/M               : Set CICP values (nclx colr box) (3 raw numbers, use -r to set range flag)\n");
    printf("                                        P = color primaries\n");
    printf("                                        T = transfer characteristics\n");
    printf("                                        M = matrix coefficients\n");
    printf("                                        Use 2 for any you wish to leave unspecified\n");
    printf("    -r,--range RANGE                  : YUV range, one of 'limited' or 'l', 'full' or 'f'. (JPEG/PNG only, default: full; For y4m or stdin, range is retained)\n");
    printf("    --target-size S                   : Set target file size in bytes (up to 7 times slower)\n");
    printf("    --progressive                     : EXPERIMENTAL: Automatically set parameters to encode a simple layered image supporting progressive rendering from a single input frame.\n");
    printf("    --layered                         : EXPERIMENTAL: Encode a layered AVIF. Each input is encoded as one layer and at most %d layers can be encoded.\n",
           AVIF_MAX_AV1_LAYER_COUNT);
    printf("    -g,--grid MxN                     : Encode a single-image grid AVIF with M cols & N rows. Either supply MxN identical W/H/D images, or a single\n");
    printf("                                        image that can be evenly split into the MxN grid and follow AVIF grid image restrictions. The grid will adopt\n");
    printf("                                        the color profile of the first image supplied.\n");
    printf("    -c,--codec C                      : Codec to use (choose from versions list below)\n");
    printf("    --exif FILENAME                   : Provide an Exif metadata payload to be associated with the primary item (implies --ignore-exif)\n");
    printf("    --xmp FILENAME                    : Provide an XMP metadata payload to be associated with the primary item (implies --ignore-xmp)\n");
    printf("    --icc FILENAME                    : Provide an ICC profile payload to be associated with the primary item (implies --ignore-icc)\n");
    printf("    --timescale,--fps V               : Timescale for image sequences. If all frames are 1 timescale in length, this is equivalent to frames per second. (Default: 30)\n");
    printf("                                        If neither duration nor timescale are set, avifenc will attempt to use the framerate stored in a y4m header, if present.\n");
    printf("    -k,--keyframe INTERVAL            : Maximum keyframe interval for image sequences (any set of INTERVAL consecutive frames will have at least one keyframe). Set to 0 to disable (default).\n");
    printf("    --ignore-exif                     : If the input file contains embedded Exif metadata, ignore it (no-op if absent)\n");
    printf("    --ignore-xmp                      : If the input file contains embedded XMP metadata, ignore it (no-op if absent)\n");
    printf("    --ignore-profile,--ignore-icc     : If the input file contains an embedded color profile, ignore it (no-op if absent)\n");
#if defined(AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION)
    printf("    --ignore-gain-map                 : If the input file contains an embedded gain map, ignore it (no-op if absent)\n");
    printf("    --qgain-map Q                     : Quality for the gain map in %d..%d where %d is lossless\n",
           AVIF_QUALITY_WORST,
           AVIF_QUALITY_BEST,
           AVIF_QUALITY_LOSSLESS);
#endif
    printf("    --pasp H,V                        : Add pasp property (aspect ratio). H=horizontal spacing, V=vertical spacing\n");
    printf("    --crop CROPX,CROPY,CROPW,CROPH    : Add clap property (clean aperture), but calculated from a crop rectangle\n");
    printf("    --clap WN,WD,HN,HD,HON,HOD,VON,VOD: Add clap property (clean aperture). Width, Height, HOffset, VOffset (in numerator/denominator pairs)\n");
    printf("    --irot ANGLE                      : Add irot property (rotation), in 0..3. Makes (90 * ANGLE) degree rotation anti-clockwise\n");
    printf("    --imir AXIS                       : Add imir property (mirroring). 0=top-to-bottom, 1=left-to-right\n");
    printf("    --clli MaxCLL,MaxPALL             : Add clli property (content light level information).\n");
    printf("    --repetition-count N              : Number of times an animated image sequence will be repeated, or 'infinite' for infinite repetitions. (Default: infinite)\n");
    printf("    --                                : Signal the end of options. Everything after this is interpreted as file names.\n");
    printf("\n");
    printf("Updatable options:\n");
    printf("  The following options can optionally have a :u (or :update) suffix like `-q:u Q`, to apply only to input files appearing after the option:\n");
    printf("    -q,--qcolor Q                     : Quality for color in %d..%d where %d is lossless\n",
           AVIF_QUALITY_WORST,
           AVIF_QUALITY_BEST,
           AVIF_QUALITY_LOSSLESS);
    printf("    --qalpha Q                        : Quality for alpha in %d..%d where %d is lossless\n",
           AVIF_QUALITY_WORST,
           AVIF_QUALITY_BEST,
           AVIF_QUALITY_LOSSLESS);
#if defined(AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION)
    printf("    --qgain-map Q                     : Quality for the gain map in %d..%d where %d is lossless\n",
           AVIF_QUALITY_WORST,
           AVIF_QUALITY_BEST,
           AVIF_QUALITY_LOSSLESS);
#endif
    printf("    --tilerowslog2 R                  : log2 of number of tile rows in 0..6. (Default: 0)\n");
    printf("                                        If specified, switch to manual tiling.\n");
    printf("    --tilecolslog2 C                  : log2 of number of tile columns 0..6. (Default: 0)\n");
    printf("                                        If specified, switch to manual tiling.\n");
    printf("    --autotiling                      : Set --tilerowslog2 and --tilecolslog2 automatically\n");
    printf("                                        If specified, switch to automatic tiling.\n");
    printf("                                        avifenc starts in automatic tiling mode.\n");
    printf("    --min QP                          : Deprecated, use -q 0..100 instead\n");
    printf("    --max QP                          : Deprecated, use -q 0..100 instead\n");
    printf("    --minalpha QP                     : Deprecated, use --qalpha 0..100 instead\n");
    printf("    --maxalpha QP                     : Deprecated, use --qalpha 0..100 instead\n");
    printf("    --scaling-mode N[/D]              : EXPERIMENTAL: Set frame (layer) scaling mode as given fraction. If omitted, the denominator defaults to 1. (Default: 1/1)\n");
    printf("    --duration D                      : Frame durations (in timescales) (default: 1). This option always applies to following inputs with or without the `:u` suffix.\n");
    printf("    -a,--advanced KEY[=VALUE]         : Pass an advanced, codec-specific key/value string pair directly to the codec. avifenc will warn on any not used by the codec.\n");
    printf("\n");
    if (avifCodecName(AVIF_CODEC_CHOICE_AOM, 0)) {
        printf("aom-specific advanced options:\n");
        printf("    1. <key>=<value> applies to both the color (YUV) planes and the alpha plane (if present).\n");
        printf("    2. color:<key>=<value> or c:<key>=<value> applies only to the color (YUV) planes.\n");
        printf("    3. alpha:<key>=<value> or a:<key>=<value> applies only to the alpha plane (if present).\n");
        printf("       Since the alpha plane is encoded as a monochrome image, the options that refer to the chroma planes,\n");
        printf("       such as enable-chroma-deltaq=B, should not be used with the alpha plane. In addition, the film grain\n");
        printf("       options are unlikely to make sense for the alpha plane.\n");
        printf("\n");
        printf("    When used with libaom 3.0.0 or later, any key-value pairs supported by the aom_codec_set_option() function\n");
        printf("    can be used. When used with libaom 2.0.x or older, the following key-value pairs can be used:\n");
        printf("\n");
        printf("    aq-mode=M                         : Adaptive quantization mode. 0=off (default), 1=variance, 2=complexity, 3=cyclic refresh\n");
        printf("    cq-level=Q                        : Constant/Constrained Quality level in 0..63, end-usage must be set to cq or q\n");
        printf("    enable-chroma-deltaq=B            : Enable delta quantization in chroma planes. 0=disable (default), 1=enable\n");
        printf("    end-usage=MODE                    : Rate control mode, one of 'vbr', 'cbr', 'cq', or 'q'\n");
        printf("    sharpness=S                       : Bias towards block sharpness in rate-distortion optimization of transform coefficients in 0..7. (Default: 0)\n");
        printf("    tune=METRIC                       : Tune the encoder for distortion metric, one of 'psnr' or 'ssim'. (Default: psnr)\n");
        printf("    film-grain-test=TEST              : Film grain test vectors in 0..16. 0=none (default), 1=test1, 2=test2, ... 16=test16\n");
        printf("    film-grain-table=FILENAME         : Path to file containing film grain parameters\n");
        printf("\n");
    }
    avifPrintVersions();
}

// This is *very* arbitrary, I just want to set people's expectations a bit
static const char * qualityString(int quality)
{
    if (quality == AVIF_QUALITY_LOSSLESS) {
        return "Lossless";
    }
    if (quality >= 80) {
        return "High";
    }
    if (quality >= 50) {
        return "Medium";
    }
    if (quality == AVIF_QUALITY_WORST) {
        return "Worst";
    }
    return "Low";
}

// Parse exactly n uint32_t from arg with separator character delim.
// Output must be able to hold at least n elements.
// Length of arg shall not exceed 127 characters or result can be truncated.
static avifBool parseU32List(uint32_t output[], int n, const char * arg, const char delim)
{
    char buffer[128];
    strncpy(buffer, arg, 127);
    buffer[127] = 0;

    // strtok wants a string for delim, so build a single character string here.
    const char delims[2] = { delim, '\0' };

    int index = 0;
    char * token = buffer;
    if (n > 1) {
        token = strtok(buffer, delims);
    }
    while (token != NULL) {
        output[index] = (uint32_t)atoi(token);
        ++index;
        if (index >= n) {
            break;
        }

        token = strtok(NULL, delims);
    }

    // Exactly n, and no more separator character
    if (index == n && strchr(token, delim) == NULL) {
        return AVIF_TRUE;
    }
    return AVIF_FALSE;
}

typedef enum avifOptionSuffixType
{
    AVIF_OPTION_SUFFIX_NONE,
    AVIF_OPTION_SUFFIX_UPDATE,
    AVIF_OPTION_SUFFIX_INVALID,
} avifOptionSuffixType;

static avifOptionSuffixType parseOptionSuffix(const char * arg, avifBool warnNoSuffix)
{
    const char * suffix = strchr(arg, ':');

    if (suffix == NULL) {
        if (warnNoSuffix) {
            fprintf(stderr,
                    "WARNING: %s is applying to all inputs. Use %s:u to apply only to inputs after it, "
                    "or move it before first input to avoid ambiguity.\n",
                    arg,
                    arg);
        }
        return AVIF_OPTION_SUFFIX_NONE;
    }

    if (!strcmp(suffix, ":u") || !strcmp(suffix, ":update")) {
        return AVIF_OPTION_SUFFIX_UPDATE;
    }

    fprintf(stderr, "ERROR: Unknown option suffix in flag %s.\n", arg);
    return AVIF_OPTION_SUFFIX_INVALID;
}

static avifBool strpre(const char * str, const char * prefix)
{
    return strncmp(str, prefix, strlen(prefix)) == 0;
}

static avifBool convertCropToClap(uint32_t srcW, uint32_t srcH, uint32_t clapValues[8])
{
    avifCleanApertureBox clap;
    avifCropRect cropRect;
    cropRect.x = clapValues[0];
    cropRect.y = clapValues[1];
    cropRect.width = clapValues[2];
    cropRect.height = clapValues[3];

    avifDiagnostics diag;
    avifDiagnosticsClearError(&diag);
    avifBool convertResult = avifCleanApertureBoxFromCropRect(&clap, &cropRect, srcW, srcH, &diag);
    if (!convertResult) {
        fprintf(stderr,
                "ERROR: Impossible crop rect: imageSize:[%ux%u], cropRect:[%u,%u, %ux%u] - %s\n",
                srcW,
                srcH,
                cropRect.x,
                cropRect.y,
                cropRect.width,
                cropRect.height,
                diag.error);
        return convertResult;
    }

    clapValues[0] = clap.widthN;
    clapValues[1] = clap.widthD;
    clapValues[2] = clap.heightN;
    clapValues[3] = clap.heightD;
    clapValues[4] = clap.horizOffN;
    clapValues[5] = clap.horizOffD;
    clapValues[6] = clap.vertOffN;
    clapValues[7] = clap.vertOffD;
    return AVIF_TRUE;
}

static avifBool avifInputAddCachedImage(avifInput * input)
{
    avifImage * newImage = avifImageCreateEmpty();
    if (!newImage) {
        return AVIF_FALSE;
    }
    avifInputCacheEntry * newCachedImages = malloc((input->cacheCount + 1) * sizeof(*input->cache));
    if (!newCachedImages) {
        avifImageDestroy(newImage);
        return AVIF_FALSE;
    }
    avifInputCacheEntry * oldCachedImages = input->cache;
    input->cache = newCachedImages;
    if (input->cacheCount) {
        memcpy(input->cache, oldCachedImages, input->cacheCount * sizeof(*input->cache));
    }
    memset(&input->cache[input->cacheCount], 0, sizeof(input->cache[input->cacheCount]));
    input->cache[input->cacheCount].fileIndex = input->fileIndex;
    input->cache[input->cacheCount].image = newImage;
    ++input->cacheCount;
    free(oldCachedImages);
    return AVIF_TRUE;
}

static avifBool fileExists(const char * filename)
{
    FILE * outfile = fopen(filename, "rb");
    if (outfile) {
        fclose(outfile);
        return AVIF_TRUE;
    }
    return AVIF_FALSE;
}

static const avifInputFile * avifInputGetFile(const avifInput * input, int imageIndex)
{
    if (imageIndex < input->cacheCount) {
        return &input->files[input->cache[imageIndex].fileIndex];
    }
    if (input->fileIndex >= input->filesCount) {
        return NULL;
    }

    if (input->files[input->fileIndex].filename == AVIF_FILENAME_STDIN) {
        assert(input->fileIndex == 0);
        ungetc(fgetc(stdin), stdin); // Kick stdin to force EOF

        if (feof(stdin)) {
            return NULL;
        }
    }

    return &input->files[input->fileIndex];
}

static avifBool avifInputHasRemainingData(const avifInput * input, int imageIndex)
{
    if (imageIndex < input->cacheCount) {
        return AVIF_TRUE;
    }
    if (input->fileIndex >= input->filesCount) {
        return AVIF_FALSE;
    }
    if (input->files[input->fileIndex].filename == AVIF_FILENAME_STDIN) {
        return !feof(stdin);
    }
    return AVIF_TRUE;
}

static avifBool avifInputReadImage(avifInput * input,
                                   int imageIndex,
                                   avifBool ignoreColorProfile,
                                   avifBool ignoreExif,
                                   avifBool ignoreXMP,
                                   avifBool allowChangingCicp,
                                   avifBool ignoreGainMap,
                                   avifImage * image,
                                   const avifInputFileSettings ** settings,
                                   uint32_t * outDepth,
                                   avifBool * sourceIsRGB,
                                   avifAppSourceTiming * sourceTiming,
                                   avifChromaDownsampling chromaDownsampling,
                                   avifAppFileFormat inputFormat)
{
    if (imageIndex < input->cacheCount) {
        const avifInputCacheEntry * cached = &input->cache[imageIndex];
        const avifCropRect rect = { 0, 0, cached->image->width, cached->image->height };
        if (avifImageSetViewRect(image, cached->image, &rect) != AVIF_RESULT_OK) {
            assert(AVIF_FALSE);
        }
#if defined(AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION)
        if (cached->image->gainMap && cached->image->gainMap->image) {
            image->gainMap->image = avifImageCreateEmpty();
            const avifCropRect gainMapRect = { 0, 0, cached->image->gainMap->image->width, cached->image->gainMap->image->height };
            if (avifImageSetViewRect(image->gainMap->image, cached->image->gainMap->image, &gainMapRect) != AVIF_RESULT_OK) {
                assert(AVIF_FALSE);
            }
        }
#endif
        if (settings) {
            *settings = cached->settings;
        }
        if (outDepth) {
            *outDepth = cached->fileBitDepth;
        }
        if (sourceIsRGB) {
            *sourceIsRGB = cached->fileIsRGB;
        }
        if (sourceTiming) {
            *sourceTiming = cached->sourceTiming;
        }
        return AVIF_TRUE;
    }

    avifImage * dstImage = image;
    const avifInputFileSettings ** dstSettings = settings;
    uint32_t * dstDepth = outDepth;
    avifBool * dstSourceIsRGB = sourceIsRGB;
    avifAppSourceTiming * dstSourceTiming = sourceTiming;
    if (input->cacheEnabled) {
        if (!avifInputAddCachedImage(input)) {
            fprintf(stderr, "ERROR: Out of memory");
            return AVIF_FALSE;
        }
        assert(imageIndex + 1 == input->cacheCount);
        dstImage = input->cache[imageIndex].image;
        // Copy CICP, clap etc.
        if (avifImageCopy(dstImage, image, /*planes=*/0) != AVIF_RESULT_OK) {
            assert(AVIF_FALSE);
        }
        dstSettings = &input->cache[imageIndex].settings;
        dstDepth = &input->cache[imageIndex].fileBitDepth;
        dstSourceIsRGB = &input->cache[imageIndex].fileIsRGB;
        dstSourceTiming = &input->cache[imageIndex].sourceTiming;
    }

    if (dstSourceTiming) {
        // A source timing of all 0s is a sentinel value hinting that the value is unset / should be
        // ignored. This is memset here as many of the paths in avifInputReadImage() do not set these
        // values. See the declaration for avifAppSourceTiming for more information.
        memset(dstSourceTiming, 0, sizeof(avifAppSourceTiming));
    }

    if (input->fileIndex >= input->filesCount) {
        return AVIF_FALSE;
    }
    const avifInputFile * currentFile = &input->files[input->fileIndex];
    if (currentFile->filename == AVIF_FILENAME_STDIN) {
        if (feof(stdin)) {
            return AVIF_FALSE;
        }
        if (inputFormat == AVIF_APP_FILE_FORMAT_UNKNOWN) {
            inputFormat = AVIF_APP_FILE_FORMAT_Y4M;
        }
    }
    if (avifReadImage(currentFile->filename,
                      inputFormat,
                      input->requestedFormat,
                      input->requestedDepth,
                      chromaDownsampling,
                      ignoreColorProfile,
                      ignoreExif,
                      ignoreXMP,
                      allowChangingCicp,
                      ignoreGainMap,
                      UINT32_MAX,
                      dstImage,
                      dstDepth,
                      dstSourceTiming,
                      &input->frameIter) == AVIF_APP_FILE_FORMAT_UNKNOWN) {
        fprintf(stderr,
                "ERROR: Couldn't read %s file %s\n",
                avifFileFormatToString(inputFormat),
                currentFile->filename == AVIF_FILENAME_STDIN ? "from standard input" : currentFile->filename);
        if (currentFile->filename == AVIF_FILENAME_STDIN && inputFormat == AVIF_APP_FILE_FORMAT_Y4M) {
            fprintf(stderr, "Specify --input-format if the input is not y4m\n");
        }
        return AVIF_FALSE;
    }

    if (!input->frameIter) {
        ++input->fileIndex;
    }
    if (dstSourceIsRGB) {
        *dstSourceIsRGB = (inputFormat != AVIF_APP_FILE_FORMAT_Y4M);
    }
    if (dstSettings) {
        *dstSettings = &currentFile->settings;
    }
    assert(dstImage->yuvFormat != AVIF_PIXEL_FORMAT_NONE);

    if (input->cacheEnabled) {
        // Reuse the just created cache entry.
        assert(imageIndex < input->cacheCount);
        return avifInputReadImage(input,
                                  imageIndex,
                                  ignoreColorProfile,
                                  ignoreExif,
                                  ignoreXMP,
                                  allowChangingCicp,
                                  ignoreGainMap,
                                  image,
                                  settings,
                                  outDepth,
                                  sourceIsRGB,
                                  sourceTiming,
                                  chromaDownsampling,
                                  inputFormat);
    }
    return AVIF_TRUE;
}

// Returns NULL if a memory allocation failed. The return value should be freed with free().
static char * avifStrdup(const char * str)
{
    size_t len = strlen(str);
    char * dup = malloc(len + 1);
    if (!dup) {
        return NULL;
    }
    memcpy(dup, str, len + 1);
    return dup;
}

// key is not null-terminated. value is null-terminated.
static avifBool avifCodecSpecificOptionsAddKeyValue(avifCodecSpecificOptions * options, const char * key, size_t keyLength, const char * value)
{
    avifBool success = AVIF_FALSE;
    char ** oldKeys = options->keys;
    char ** oldValues = options->values;
    options->keys = malloc((options->count + 1) * sizeof(*options->keys));
    options->values = malloc((options->count + 1) * sizeof(*options->values));
    if (!options->keys || !options->values) {
        free(options->keys);
        free(options->values);
        options->keys = oldKeys;
        options->values = oldValues;
        return AVIF_FALSE;
    }
    if (options->count) {
        memcpy(options->keys, oldKeys, options->count * sizeof(*options->keys));
        memcpy(options->values, oldValues, options->count * sizeof(*options->values));
    }

    options->values[options->count] = avifStrdup(value);
    options->keys[options->count] = malloc(keyLength + 1);
    if (!options->values[options->count] || !options->keys[options->count]) {
        goto cleanup;
    }
    memcpy(options->keys[options->count], key, keyLength);
    options->keys[options->count][keyLength] = '\0';
    success = AVIF_TRUE;
cleanup:
    ++options->count;
    free(oldKeys);
    free(oldValues);
    return success;
}

static avifBool avifCodecSpecificOptionsAdd(avifCodecSpecificOptions * options, const char * keyValue)
{
    const char * value = strchr(keyValue, '=');
    if (value) {
        // Keep the parts on the left and on the right of the equal sign,
        // but not the equal sign itself.
        const size_t keyLength = value - keyValue;
        return avifCodecSpecificOptionsAddKeyValue(options, keyValue, keyLength, value + 1);
    }
    // Pass in a non-NULL, empty string. Codecs can use the mere existence of a key as a boolean value.
    return avifCodecSpecificOptionsAddKeyValue(options, keyValue, strlen(keyValue), "");
}

static void avifCodecSpecificOptionsFree(avifCodecSpecificOptions * options)
{
    while (options->count) {
        --options->count;
        free(options->keys[options->count]);
        free(options->values[options->count]);
    }
    free(options->keys);
    free(options->values);
    options->keys = NULL;
    options->values = NULL;
}

static void avifSettingsEntryIntOverwrite(avifSettingsEntryInt * dst, const avifSettingsEntryInt * src)
{
    if (src->set) {
        dst->set = AVIF_TRUE;
        dst->value = src->value;
    }
}

static avifBool avifInputFileSettingsOverwrite(avifInputFileSettings * dst, const avifInputFileSettings * src)
{
    avifSettingsEntryIntOverwrite(&dst->quality, &src->quality);
    avifSettingsEntryIntOverwrite(&dst->qualityAlpha, &src->qualityAlpha);
    avifSettingsEntryIntOverwrite(&dst->minQuantizer, &src->minQuantizer);
    avifSettingsEntryIntOverwrite(&dst->maxQuantizer, &src->maxQuantizer);
    avifSettingsEntryIntOverwrite(&dst->minQuantizerAlpha, &src->minQuantizerAlpha);
    avifSettingsEntryIntOverwrite(&dst->maxQuantizerAlpha, &src->maxQuantizerAlpha);
    avifSettingsEntryIntOverwrite(&dst->tileRowsLog2, &src->tileRowsLog2);
    avifSettingsEntryIntOverwrite(&dst->tileColsLog2, &src->tileColsLog2);
    avifSettingsEntryIntOverwrite(&dst->autoTiling, &src->autoTiling);
    if (src->scalingMode.set) {
        dst->scalingMode.set = AVIF_TRUE;
        dst->scalingMode.value = src->scalingMode.value;
    }
    for (int i = 0; i < src->codecSpecificOptions.count; ++i) {
        const char * key = src->codecSpecificOptions.keys[i];
        const char * value = src->codecSpecificOptions.values[i];
        if (!avifCodecSpecificOptionsAddKeyValue(&dst->codecSpecificOptions, key, strlen(key), value)) {
            fprintf(stderr, "ERROR: Failed to copy codec specific option: %s = %s\n", key, value);
            return AVIF_FALSE;
        }
    }
    return AVIF_TRUE;
}

// Returns the best cell size for a given horizontal or vertical dimension.
static avifBool avifGetBestCellSize(const char * dimensionStr, uint32_t numPixels, uint32_t numCells, avifBool isSubsampled, uint32_t * cellSize)
{
    assert(numPixels);
    assert(numCells);

    // ISO/IEC 23008-12:2017, Section 6.6.2.3.1:
    //   The reconstructed image is formed by tiling the input images into a grid with a column width
    //   (potentially excluding the right-most column) equal to tile_width and a row height (potentially
    //   excluding the bottom-most row) equal to tile_height, without gap or overlap, and then
    //   trimming on the right and the bottom to the indicated output_width and output_height.
    // The priority could be to use a cell size that is a multiple of 64, but there is not always a valid one,
    // even though it is recommended by MIAF. Just use ceil(numPixels/numCells) for simplicity and to avoid
    // as much padding in the right-most and bottom-most cells as possible.
    // Use uint64_t computation to avoid a potential uint32_t overflow.
    *cellSize = (uint32_t)(((uint64_t)numPixels + numCells - 1) / numCells);

    // ISO/IEC 23000-22:2019, Section 7.3.11.4.2:
    //   - the tile_width shall be greater than or equal to 64, and should be a multiple of 64
    //   - the tile_height shall be greater than or equal to 64, and should be a multiple of 64
    if (*cellSize < 64) {
        *cellSize = 64;
        if ((uint64_t)(numCells - 1) * *cellSize >= (uint64_t)numPixels) {
            // Some cells would be entirely off-canvas.
            fprintf(stderr, "ERROR: There are too many cells %s (%u) to have at least 64 pixels per cell.\n", dimensionStr, numCells);
            return AVIF_FALSE;
        }
    }

    // The maximum AV1 frame size is 65536 pixels inclusive.
    if (*cellSize > 65536) {
        fprintf(stderr, "ERROR: Cell size %u is bigger %s than the maximum frame size 65536.\n", *cellSize, dimensionStr);
        return AVIF_FALSE;
    }

    // ISO/IEC 23000-22:2019, Section 7.3.11.4.2:
    //   - when the images are in the 4:2:2 chroma sampling format the horizontal tile offsets and widths,
    //     and the output width, shall be even numbers;
    //   - when the images are in the 4:2:0 chroma sampling format both the horizontal and vertical tile
    //     offsets and widths, and the output width and height, shall be even numbers.
    if (isSubsampled && (*cellSize & 1)) {
        ++*cellSize;
        if ((uint64_t)(numCells - 1) * *cellSize >= (uint64_t)numPixels) {
            // Some cells would be entirely off-canvas.
            fprintf(stderr, "ERROR: Odd cell size %u is forbidden on a %s subsampled image.\n", *cellSize - 1, dimensionStr);
            return AVIF_FALSE;
        }
    }

    // Each pixel is covered by exactly one cell, and each cell contains at least one pixel.
    assert(((uint64_t)(numCells - 1) * *cellSize < (uint64_t)numPixels) && ((uint64_t)numCells * *cellSize >= (uint64_t)numPixels));
    return AVIF_TRUE;
}

static avifBool avifImageSplitGrid(const avifImage * gridSplitImage, uint32_t gridCols, uint32_t gridRows, avifImage ** gridCells)
{
    uint32_t cellWidth, cellHeight;
    avifPixelFormatInfo formatInfo;
    avifGetPixelFormatInfo(gridSplitImage->yuvFormat, &formatInfo);
    const avifBool isSubsampledX = !formatInfo.monochrome && formatInfo.chromaShiftX;
    const avifBool isSubsampledY = !formatInfo.monochrome && formatInfo.chromaShiftY;
    if (!avifGetBestCellSize("horizontally", gridSplitImage->width, gridCols, isSubsampledX, &cellWidth) ||
        !avifGetBestCellSize("vertically", gridSplitImage->height, gridRows, isSubsampledY, &cellHeight)) {
        return AVIF_FALSE;
    }

    for (uint32_t gridY = 0; gridY < gridRows; ++gridY) {
        for (uint32_t gridX = 0; gridX < gridCols; ++gridX) {
            uint32_t gridIndex = gridX + (gridY * gridCols);
            avifImage * cellImage = avifImageCreateEmpty();
            if (!cellImage) {
                fprintf(stderr, "ERROR: Cell creation failed: out of memory\n");
                return AVIF_FALSE;
            }
            gridCells[gridIndex] = cellImage;

            avifCropRect cellRect = { gridX * cellWidth, gridY * cellHeight, cellWidth, cellHeight };
            if (cellRect.x + cellRect.width > gridSplitImage->width) {
                cellRect.width = gridSplitImage->width - cellRect.x;
            }
            if (cellRect.y + cellRect.height > gridSplitImage->height) {
                cellRect.height = gridSplitImage->height - cellRect.y;
            }
            const avifResult copyResult = avifImageSetViewRect(cellImage, gridSplitImage, &cellRect);
            if (copyResult != AVIF_RESULT_OK) {
                fprintf(stderr, "ERROR: Cell creation failed: %s\n", avifResultToString(copyResult));
                return AVIF_FALSE;
            }
        }
    }
    return AVIF_TRUE;
}

#define INVALID_QUALITY (-1)
#define DEFAULT_QUALITY 60 // Maps to a quantizer (QP) of 25.
#define DEFAULT_QUALITY_GAIN_MAP DEFAULT_QUALITY
#define PROGRESSIVE_WORST_QUALITY 10 // Not doing automatic layered encoding below this quality
#define PROGRESSIVE_START_QUALITY 2  // First layer use this quality

static avifBool avifEncodeUpdateEncoderSettings(avifEncoder * encoder, const avifInputFileSettings * settings)
{
    if (!settings) {
        return AVIF_TRUE;
    }

    if (settings->quality.set) {
        encoder->quality = settings->quality.value;
    }
    if (settings->qualityAlpha.set) {
        encoder->qualityAlpha = settings->qualityAlpha.value;
    }
    if (settings->minQuantizer.set) {
        encoder->minQuantizer = settings->minQuantizer.value;
    }
    if (settings->maxQuantizer.set) {
        encoder->maxQuantizer = settings->maxQuantizer.value;
    }
    if (settings->minQuantizerAlpha.set) {
        encoder->minQuantizerAlpha = settings->minQuantizerAlpha.value;
    }
    if (settings->maxQuantizerAlpha.set) {
        encoder->maxQuantizerAlpha = settings->maxQuantizerAlpha.value;
    }
    if (settings->tileRowsLog2.set) {
        encoder->tileRowsLog2 = settings->tileRowsLog2.value;
    }
    if (settings->tileColsLog2.set) {
        encoder->tileColsLog2 = settings->tileColsLog2.value;
    }
    if (settings->autoTiling.set) {
        encoder->autoTiling = settings->autoTiling.value;
    }
    if (settings->scalingMode.set) {
        encoder->scalingMode = settings->scalingMode.value;
    }
    for (int i = 0; i < settings->codecSpecificOptions.count; ++i) {
        if (avifEncoderSetCodecSpecificOption(encoder, settings->codecSpecificOptions.keys[i], settings->codecSpecificOptions.values[i]) !=
            AVIF_RESULT_OK) {
            fprintf(stderr,
                    "ERROR: Failed to set codec specific option: %s = %s\n",
                    settings->codecSpecificOptions.keys[i],
                    settings->codecSpecificOptions.values[i]);
            return AVIF_FALSE;
        }
    }

    return AVIF_TRUE;
}

static avifBool avifEncoderVerifyImageCompatibility(const avifImage * refImage,
                                                    const avifImage * testImage,
                                                    const char * seriesType,
                                                    const char * filename)
{
    // Verify that this frame's properties matches the first frame's properties
    if ((refImage->width != testImage->width) || (refImage->height != testImage->height)) {
        fprintf(stderr,
                "ERROR: Image %s dimensions mismatch, [%ux%u] vs [%ux%u]: %s\n",
                seriesType,
                refImage->width,
                refImage->height,
                testImage->width,
                testImage->height,
                filename);
        return AVIF_FALSE;
    }
    if (refImage->depth != testImage->depth) {
        fprintf(stderr, "ERROR: Image %s depth mismatch, [%u] vs [%u]: %s\n", seriesType, refImage->depth, testImage->depth, filename);
        return AVIF_FALSE;
    }
    if ((refImage->colorPrimaries != testImage->colorPrimaries) ||
        (refImage->transferCharacteristics != testImage->transferCharacteristics) ||
        (refImage->matrixCoefficients != testImage->matrixCoefficients)) {
        fprintf(stderr,
                "ERROR: Image %s CICP mismatch, [%u/%u/%u] vs [%u/%u/%u]: %s\n",
                seriesType,
                refImage->colorPrimaries,
                refImage->matrixCoefficients,
                refImage->transferCharacteristics,
                testImage->colorPrimaries,
                testImage->transferCharacteristics,
                testImage->matrixCoefficients,
                filename);
        return AVIF_FALSE;
    }
    if (refImage->yuvRange != testImage->yuvRange) {
        fprintf(stderr,
                "ERROR: Image %s range mismatch, [%s] vs [%s]: %s\n",
                seriesType,
                (refImage->yuvRange == AVIF_RANGE_FULL) ? "Full" : "Limited",
                (testImage->yuvRange == AVIF_RANGE_FULL) ? "Full" : "Limited",
                filename);
        return AVIF_FALSE;
    }

    return AVIF_TRUE;
}

static avifBool avifEncodeRestOfImageSequence(avifEncoder * encoder,
                                              const avifSettings * settings,
                                              avifInput * input,
                                              int imageIndex,
                                              const avifImage * firstImage)
{
    avifBool success = AVIF_FALSE;
    avifImage * nextImage = NULL;
    const avifInputFileSettings * nextSettings = NULL;

    const avifInputFile * nextFile;
    while ((nextFile = avifInputGetFile(input, imageIndex)) != NULL) {
        uint64_t nextDurationInTimescales = nextFile->duration ? nextFile->duration : settings->outputTiming.duration;

        if (nextImage) {
            avifImageDestroy(nextImage);
        }
        nextImage = avifImageCreateEmpty();
        if (!nextImage) {
            fprintf(stderr, "ERROR: Out of memory\n");
            goto cleanup;
        }
        nextImage->colorPrimaries = firstImage->colorPrimaries;
        nextImage->transferCharacteristics = firstImage->transferCharacteristics;
        nextImage->matrixCoefficients = firstImage->matrixCoefficients;
        nextImage->yuvRange = firstImage->yuvRange;
        nextImage->alphaPremultiplied = firstImage->alphaPremultiplied;

        // Ignore ICC, Exif and XMP because only the metadata of the first frame is taken into
        // account by the libavif API.
        // Ignore gain map as it's not supported for sequences.
        if (!avifInputReadImage(input,
                                imageIndex,
                                /*ignoreColorProfile=*/AVIF_TRUE,
                                /*ignoreExif=*/AVIF_TRUE,
                                /*ignoreXMP=*/AVIF_TRUE,
                                /*allowChangingCicp=*/AVIF_FALSE,
                                /*ignoreGainMap=*/AVIF_TRUE,
                                nextImage,
                                &nextSettings,
                                /*outDepth=*/NULL,
                                /*sourceIsRGB=*/NULL,
                                /*sourceTiming=*/NULL,
                                settings->chromaDownsampling,
                                settings->inputFormat)) {
            goto cleanup;
        }
        if (!avifEncoderVerifyImageCompatibility(firstImage, nextImage, "sequence", avifPrettyFilename(nextFile->filename))) {
            goto cleanup;
        }
        if (!avifEncodeUpdateEncoderSettings(encoder, nextSettings)) {
            goto cleanup;
        }

        char manualTilingStr[128];
        snprintf(manualTilingStr, sizeof(manualTilingStr), "tileRowsLog2 [%d], tileColsLog2 [%d]", encoder->tileRowsLog2, encoder->tileColsLog2);

        printf(" * Encoding frame %d [%" PRIu64 "/%" PRIu64 " ts] color quality [%d (%s)], alpha quality [%d (%s)], %s: %s\n",
               imageIndex,
               nextDurationInTimescales,
               settings->outputTiming.timescale,
               encoder->quality,
               qualityString(encoder->quality),
               encoder->qualityAlpha,
               qualityString(encoder->qualityAlpha),
               encoder->autoTiling ? "automatic tiling" : manualTilingStr,
               avifPrettyFilename(nextFile->filename));

        const avifResult nextImageResult = avifEncoderAddImage(encoder, nextImage, nextDurationInTimescales, AVIF_ADD_IMAGE_FLAG_NONE);
        if (nextImageResult != AVIF_RESULT_OK) {
            fprintf(stderr, "ERROR: Failed to encode image: %s\n", avifResultToString(nextImageResult));
            goto cleanup;
        }
        ++imageIndex;
    }
    success = AVIF_TRUE;

cleanup:
    if (nextImage) {
        avifImageDestroy(nextImage);
    }
    return success;
}

static avifBool avifEncodeRestOfLayeredImage(avifEncoder * encoder,
                                             const avifSettings * settings,
                                             avifInput * input,
                                             int layerIndex,
                                             const avifImage * firstImage)
{
    avifBool success = AVIF_FALSE;
    int layers = encoder->extraLayerCount + 1;
    // --progressive only allows one input, so directly read from it.
    int targetQuality = (settings->overrideQuality != INVALID_QUALITY) ? settings->overrideQuality
                                                                       : input->files[0].settings.quality.value;

    avifImage * nextImage = NULL;
    const avifImage * encodingImage = firstImage;
    const avifInputFileSettings * nextSettings = NULL;

    if (settings->progressive && avifInputHasRemainingData(input, layerIndex)) {
        fprintf(stderr, "ERROR: Automatic layered encoding can only have one input image.\n");
        goto cleanup;
    }

    while (layerIndex < layers) {
        if (settings->progressive) {
            // reversed lerp, so that last layer reaches exact targetQuality
            encoder->quality = targetQuality - (targetQuality - PROGRESSIVE_START_QUALITY) *
                                                   (encoder->extraLayerCount - layerIndex) / encoder->extraLayerCount;
        } else {
            const avifInputFile * nextFile = avifInputGetFile(input, layerIndex);
            // main() function should set number of layers to number of input,
            // so nextFile should not be NULL.
            assert(nextFile);

            if (nextImage) {
                avifImageDestroy(nextImage);
            }
            nextImage = avifImageCreateEmpty();
            if (!nextImage) {
                fprintf(stderr, "ERROR: Out of memory\n");
                goto cleanup;
            }
            nextImage->colorPrimaries = firstImage->colorPrimaries;
            nextImage->transferCharacteristics = firstImage->transferCharacteristics;
            nextImage->matrixCoefficients = firstImage->matrixCoefficients;
            nextImage->yuvRange = firstImage->yuvRange;
            nextImage->alphaPremultiplied = firstImage->alphaPremultiplied;

            // Ignore ICC, Exif and XMP because only the metadata of the first frame is taken into
            // account by the libavif API.
            // Ignore gain map because the two features are currently incompatible.
            if (!avifInputReadImage(input,
                                    layerIndex,
                                    /*ignoreColorProfile=*/AVIF_TRUE,
                                    /*ignoreExif=*/AVIF_TRUE,
                                    /*ignoreXMP=*/AVIF_TRUE,
                                    !settings->cicpExplicitlySet,
                                    /*ignoreGainMap=*/AVIF_TRUE,
                                    nextImage,
                                    &nextSettings,
                                    /*outDepth=*/NULL,
                                    /*sourceIsRGB=*/NULL,
                                    /*sourceTiming=*/NULL,
                                    settings->chromaDownsampling,
                                    settings->inputFormat)) {
                goto cleanup;
            }
            // frameIter is NULL if y4m reached end, so single frame y4m is still supported.
            if (input->frameIter) {
                fprintf(stderr,
                        "ERROR: Layered encoding does not support input with multiple frames: %s.\n",
                        avifPrettyFilename(nextFile->filename));
                goto cleanup;
            }
            if (!avifEncoderVerifyImageCompatibility(firstImage, nextImage, "layer", avifPrettyFilename(nextFile->filename))) {
                goto cleanup;
            }
            if (!avifEncodeUpdateEncoderSettings(encoder, nextSettings)) {
                goto cleanup;
            }
            encodingImage = nextImage;
        }

        printf(" * Encoding layer %d: color quality [%d (%s)], alpha quality [%d (%s)]\n",
               layerIndex,
               encoder->quality,
               qualityString(encoder->quality),
               encoder->qualityAlpha,
               qualityString(encoder->qualityAlpha));

        const avifResult result = avifEncoderAddImage(encoder, encodingImage, settings->outputTiming.duration, AVIF_ADD_IMAGE_FLAG_NONE);
        if (result != AVIF_RESULT_OK) {
            fprintf(stderr, "ERROR: Failed to encode image: %s\n", avifResultToString(result));
            goto cleanup;
        }
        ++layerIndex;
    }

    // main() function should set number of layers to number of input,
    // so there should be no input left.
    assert(!avifInputHasRemainingData(input, layerIndex));
    success = AVIF_TRUE;
cleanup:
    if (nextImage) {
        avifImageDestroy(nextImage);
    }
    return success;
}

static avifBool avifEncodeImagesFixedQuality(const avifSettings * settings,
                                             avifInput * input,
                                             const avifInputFile * firstFile,
                                             const avifImage * firstImage,
                                             const avifImage * const * gridCells,
                                             avifRWData * encoded,
                                             avifEncodedByteSizes * byteSizes)
{
    avifBool success = AVIF_FALSE;
    avifRWDataFree(encoded);
    avifEncoder * encoder = avifEncoderCreate();
    if (!encoder) {
        fprintf(stderr, "ERROR: Out of memory\n");
        goto cleanup;
    }

    encoder->maxThreads = settings->jobs;
    encoder->codecChoice = settings->codecChoice;
    encoder->speed = settings->speed;
    encoder->timescale = settings->outputTiming.timescale;
    encoder->keyframeInterval = settings->keyframeInterval;
    encoder->repetitionCount = settings->repetitionCount;
    encoder->headerFormat = settings->headerFormat;
    encoder->extraLayerCount = settings->layers - 1;
    if (!avifEncodeUpdateEncoderSettings(encoder, &firstFile->settings)) {
        goto cleanup;
    }

    if (settings->overrideQuality != INVALID_QUALITY) {
        encoder->quality = settings->overrideQuality;
    }
    if (settings->overrideQualityAlpha != INVALID_QUALITY) {
        encoder->qualityAlpha = settings->overrideQualityAlpha;
    }
#if defined(AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION)
    if (settings->qualityGainMap != INVALID_QUALITY) {
        encoder->qualityGainMap = settings->qualityGainMap;
    }
#endif

    const char * const codecName = avifCodecName(settings->codecChoice, AVIF_CODEC_FLAG_CAN_ENCODE);
    char speedStr[16];
    if (settings->speed == AVIF_SPEED_DEFAULT) {
        strcpy(speedStr, "default");
    } else {
        snprintf(speedStr, sizeof(speedStr), "%d", settings->speed);
    }
    char gainMapStr[100] = { 0 };
#if defined(AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION)
    if (firstImage->gainMap && firstImage->gainMap->image) {
        snprintf(gainMapStr, sizeof(gainMapStr), ", gain map quality [%d (%s)]", encoder->qualityGainMap, qualityString(encoder->qualityGainMap));
    }
#endif

    char manualTilingStr[128];
    snprintf(manualTilingStr, sizeof(manualTilingStr), "tileRowsLog2 [%d], tileColsLog2 [%d]", encoder->tileRowsLog2, encoder->tileColsLog2);

    printf("Encoding with initial settings: codec '%s' speed [%s], color quality [%d (%s)], alpha quality [%d (%s)]%s, %s, %d worker thread(s), please wait...\n",
           codecName ? codecName : "none",
           speedStr,
           encoder->quality,
           qualityString(encoder->quality),
           encoder->qualityAlpha,
           qualityString(encoder->qualityAlpha),
           gainMapStr,
           encoder->autoTiling ? "automatic tiling" : manualTilingStr,
           settings->jobs);
    if (settings->progressive) {
        // If --progressive is specified and the color quality is less than
        // PROGRESSIVE_WORST_QUALITY, the main() function returns an error and
        // we should not reach here.
        assert(encoder->quality >= PROGRESSIVE_WORST_QUALITY);
        // Encode the base layer with a very low quality to ensure a small encoded size.
        encoder->quality = 2;
        // Low alpha quality resulted in weird artifact, so we don't do it.
    }

    if (settings->layers > 1) {
        printf(" * Encoding layer %d: color quality [%d (%s)], alpha quality [%d (%s)]\n",
               0,
               encoder->quality,
               qualityString(encoder->quality),
               encoder->qualityAlpha,
               qualityString(encoder->qualityAlpha));
    }

    if (settings->gridDimsPresent) {
        const avifResult addImageResult =
            avifEncoderAddImageGrid(encoder, settings->gridDims[0], settings->gridDims[1], gridCells, AVIF_ADD_IMAGE_FLAG_SINGLE);
        if (addImageResult != AVIF_RESULT_OK) {
            fprintf(stderr, "ERROR: Failed to encode image grid: %s\n", avifResultToString(addImageResult));
            goto cleanup;
        }
    } else {
        int imageIndex = 1; // firstImage with imageIndex 0 is already available.

        avifAddImageFlags addImageFlags = AVIF_ADD_IMAGE_FLAG_NONE;
        if (!avifInputHasRemainingData(input, imageIndex) && (settings->layers == 1)) {
            addImageFlags |= AVIF_ADD_IMAGE_FLAG_SINGLE;
        }

        uint64_t firstDurationInTimescales = firstFile->duration ? firstFile->duration : settings->outputTiming.duration;
        if ((firstFile->filename == AVIF_FILENAME_STDIN && settings->inputFormat == AVIF_APP_FILE_FORMAT_Y4M) ||
            (settings->layers == 1 && input->filesCount > 1)) {
            snprintf(manualTilingStr,
                     sizeof(manualTilingStr),
                     "tileRowsLog2 [%d], tileColsLog2 [%d]",
                     encoder->tileRowsLog2,
                     encoder->tileColsLog2);

            printf(" * Encoding frame %d [%" PRIu64 "/%" PRIu64 " ts] color quality [%d (%s)], alpha quality [%d (%s)], %s: %s\n",
                   0,
                   firstDurationInTimescales,
                   settings->outputTiming.timescale,
                   encoder->quality,
                   qualityString(encoder->quality),
                   encoder->qualityAlpha,
                   qualityString(encoder->qualityAlpha),
                   encoder->autoTiling ? "automatic tiling" : manualTilingStr,
                   avifPrettyFilename(firstFile->filename));
        }
        const avifResult addImageResult = avifEncoderAddImage(encoder, firstImage, firstDurationInTimescales, addImageFlags);
        if (addImageResult != AVIF_RESULT_OK) {
            fprintf(stderr, "ERROR: Failed to encode image: %s\n", avifResultToString(addImageResult));
            goto cleanup;
        }

        if (settings->layers > 1) {
            if (!avifEncodeRestOfLayeredImage(encoder, settings, input, imageIndex, firstImage)) {
                goto cleanup;
            }
        } else {
            // Not generating a single-image grid: Use all remaining input files as subsequent
            // frames.
            if (!avifEncodeRestOfImageSequence(encoder, settings, input, imageIndex, firstImage)) {
                goto cleanup;
            }
        }
    }

    const avifResult finishResult = avifEncoderFinish(encoder, encoded);
    if (finishResult != AVIF_RESULT_OK) {
        fprintf(stderr, "ERROR: Failed to finish encoding: %s\n", avifResultToString(finishResult));
        goto cleanup;
    }
    success = AVIF_TRUE;
    byteSizes->colorSizeBytes = encoder->ioStats.colorOBUSize;
    byteSizes->alphaSizeBytes = encoder->ioStats.alphaOBUSize;
#if defined(AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION)
    byteSizes->gainMapSizeBytes = avifEncoderGetGainMapSizeBytes(encoder);
#endif

cleanup:
    if (encoder) {
        if (!success) {
            avifDumpDiagnostics(&encoder->diag);
        }
        avifEncoderDestroy(encoder);
    }
    return success;
}

static avifBool avifEncodeImages(avifSettings * settings,
                                 avifInput * input,
                                 const avifInputFile * firstFile,
                                 const avifImage * firstImage,
                                 const avifImage * const * gridCells,
                                 avifRWData * encoded,
                                 avifEncodedByteSizes * byteSizes)
{
    if (settings->targetSize == -1) {
        return avifEncodeImagesFixedQuality(settings, input, firstFile, firstImage, gridCells, encoded, byteSizes);
    }

    avifBool hasGainMap = AVIF_FALSE;
    avifBool allQualitiesConstrained = settings->qualityIsConstrained && settings->qualityAlphaIsConstrained;
#if defined(AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION)
    hasGainMap = (firstImage->gainMap && firstImage->gainMap->image);
    if (hasGainMap) {
        allQualitiesConstrained = allQualitiesConstrained && settings->qualityGainMapIsConstrained;
    }
#endif

    if (allQualitiesConstrained) {
        fprintf(stderr, "ERROR: --target-size is used with constrained --qcolor and --qalpha %s\n", (hasGainMap ? "and --qgain-map" : ""));
        return AVIF_FALSE;
    }

    printf("Starting a binary search to find the %s%s generating the encoded image size closest to %d bytes, please wait...\n",
           settings->qualityAlphaIsConstrained ? "color quality"
                                               : (settings->qualityIsConstrained ? "alpha quality" : "color and alpha qualities"),
           (hasGainMap && !settings->qualityGainMapIsConstrained) ? " and gain map quality" : "",
           settings->targetSize);
    const size_t targetSize = (size_t)settings->targetSize;

    // TODO(yguyon): Use quantizer instead of quality because quantizer range is smaller (faster binary search).
    int closestQuality = INVALID_QUALITY;
    avifRWData closestEncoded = { NULL, 0 };
    size_t closestSizeDiff = 0;
    avifEncodedByteSizes closestByteSizes = { 0, 0, 0 };

    int minQuality = settings->progressive ? PROGRESSIVE_WORST_QUALITY : AVIF_QUALITY_WORST; // inclusive
    int maxQuality = AVIF_QUALITY_BEST;                                                      // inclusive
    while (minQuality <= maxQuality) {
        const int quality = (minQuality + maxQuality) / 2;
        if (!settings->qualityIsConstrained) {
            settings->overrideQuality = quality;
        }
        if (!settings->qualityAlphaIsConstrained) {
            settings->overrideQualityAlpha = quality;
        }
        if (!settings->qualityGainMapIsConstrained) {
            settings->qualityGainMap = quality;
        }

        if (!avifEncodeImagesFixedQuality(settings, input, firstFile, firstImage, gridCells, encoded, byteSizes)) {
            avifRWDataFree(&closestEncoded);
            return AVIF_FALSE;
        }
        printf("Encoded image of size %" AVIF_FMT_ZU " bytes.\n", encoded->size);

        if (encoded->size == targetSize) {
            return AVIF_TRUE;
        }

        size_t sizeDiff;
        if (encoded->size > targetSize) {
            sizeDiff = encoded->size - targetSize;
            maxQuality = quality - 1;
        } else {
            sizeDiff = targetSize - encoded->size;
            minQuality = quality + 1;
        }

        if ((closestQuality == INVALID_QUALITY) || (sizeDiff < closestSizeDiff)) {
            closestQuality = quality;
            avifRWDataFree(&closestEncoded);
            closestEncoded = *encoded;
            encoded->size = 0;
            encoded->data = NULL;
            closestSizeDiff = sizeDiff;
            closestByteSizes = *byteSizes;
        }
    }

    if (!settings->qualityIsConstrained) {
        settings->overrideQuality = closestQuality;
    }
    if (!settings->qualityAlphaIsConstrained) {
        settings->overrideQualityAlpha = closestQuality;
    }
    avifRWDataFree(encoded);
    *encoded = closestEncoded;
    *byteSizes = closestByteSizes;
    printf("Kept the encoded image of size %" AVIF_FMT_ZU " bytes generated with ", encoded->size);
    if (!settings->qualityIsConstrained) {
        printf("color quality %d", settings->overrideQuality);
    }
    if (!settings->qualityAlphaIsConstrained) {
        if (!settings->qualityIsConstrained) {
            printf(" and ");
        }
        printf("alpha quality %d", settings->overrideQualityAlpha);
    }
    printf(".\n");
    return AVIF_TRUE;
}

static void avifInputAdd(avifInput * input, const char * filePath, uint64_t duration, avifInputFileSettings * pendingSettings)
{
    input->files[input->filesCount].filename = filePath;
    input->files[input->filesCount].duration = duration;
    input->files[input->filesCount].settings = *pendingSettings;
    memset(pendingSettings, 0, sizeof(*pendingSettings));
    ++input->filesCount;
}

static int quantizerToQuality(int minQuantizer, int maxQuantizer)
{
    // When calculating the average quantizer, discard the fractional part for a
    // bias toward better quality.
    const int quantizer = (minQuantizer + maxQuantizer) / 2;
    const int quality = ((63 - quantizer) * 100 + 31) / 63;
    return quality;
}

int main(int argc, char * argv[])
{
    if (argc < 2) {
        syntaxShort();
        return 1;
    }

    const char * outputFilename = NULL;

    avifInput input;
    memset(&input, 0, sizeof(input));
    input.files = malloc(sizeof(avifInputFile) * argc);
    if (input.files == NULL) {
        fprintf(stderr, "ERROR: memory allocation failure\n");
        return 1;
    }
    input.requestedFormat = AVIF_PIXEL_FORMAT_NONE; // AVIF_PIXEL_FORMAT_NONE is used as a sentinel for "auto"

    // See here for the discussion on the semi-arbitrary defaults for speed:
    //     https://github.com/AOMediaCodec/libavif/issues/440

    int returnCode = 1;
    avifBool noOverwrite = AVIF_FALSE;
    avifSettings settings;
    memset(&settings, 0, sizeof(settings));
    settings.codecChoice = AVIF_CODEC_CHOICE_AUTO;
    settings.jobs = -1;
    settings.targetSize = -1;
    settings.qualityIsConstrained = AVIF_FALSE;
    settings.qualityAlphaIsConstrained = AVIF_FALSE;
    settings.overrideQuality = INVALID_QUALITY;
    settings.overrideQualityAlpha = INVALID_QUALITY;
    settings.qualityGainMap = DEFAULT_QUALITY_GAIN_MAP;
    settings.progressive = AVIF_FALSE;
    settings.layered = AVIF_FALSE;
    settings.layers = 0;
    settings.speed = 6;
    settings.headerFormat = AVIF_HEADER_DEFAULT;
    settings.repetitionCount = AVIF_REPETITION_COUNT_INFINITE;
    settings.keyframeInterval = 0;
    settings.ignoreExif = AVIF_FALSE;
    settings.ignoreXMP = AVIF_FALSE;
    settings.ignoreColorProfile = AVIF_FALSE;
    settings.ignoreGainMap = AVIF_FALSE;
    settings.cicpExplicitlySet = AVIF_FALSE;
    settings.inputFormat = AVIF_APP_FILE_FORMAT_UNKNOWN;

    avifInputFileSettings pendingSettings;
    memset(&pendingSettings, 0, sizeof(pendingSettings));

    avifBool cropConversionRequired = AVIF_FALSE;
    uint8_t irotAngle = 0xff; // sentinel value indicating "unused"
    uint8_t imirAxis = 0xff;  // sentinel value indicating "unused"
    avifRange requestedRange = AVIF_RANGE_FULL;
    avifBool lossless = AVIF_FALSE;
    avifImage * image = NULL;
    avifRWData raw = AVIF_DATA_EMPTY;
    avifRWData exifOverride = AVIF_DATA_EMPTY;
    avifRWData xmpOverride = AVIF_DATA_EMPTY;
    avifRWData iccOverride = AVIF_DATA_EMPTY;
    avifBool premultiplyAlpha = AVIF_FALSE;
    uint32_t gridCellCount = 0;
    avifImage ** gridCells = NULL;
    avifImage * gridSplitImage = NULL; // used for cleanup tracking

    // By default, the color profile itself is unspecified, so CP/TC are set (to 2) accordingly.
    // However, if the end-user doesn't specify any CICP, we will convert to YUV using BT601
    // coefficients anyway (as MC:2 falls back to MC:5/6), so we might as well signal it explicitly.
    // See: ISO/IEC 23000-22:2019 Amendment 2, or the comment in avifCalcYUVCoefficients()
    settings.colorPrimaries = AVIF_COLOR_PRIMARIES_UNSPECIFIED;
    settings.transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED;
    settings.matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT601;
    settings.chromaDownsampling = AVIF_CHROMA_DOWNSAMPLING_AUTOMATIC;

    int argIndex = 1;
    while (argIndex < argc) {
        const char * arg = argv[argIndex];

        if (!strcmp(arg, "--")) {
            // Stop parsing flags, everything after this is positional arguments
            ++argIndex;
            // Parse additional positional arguments if any
            while (argIndex < argc) {
                arg = argv[argIndex];
                avifInputAdd(&input, /*filePath=*/arg, settings.outputTiming.duration, &pendingSettings);
                ++argIndex;
            }
            break;
        } else if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) {
            syntaxLong();
            returnCode = 0;
            goto cleanup;
        } else if (!strcmp(arg, "-V") || !strcmp(arg, "--version")) {
            avifPrintVersions();
            returnCode = 0;
            goto cleanup;
        } else if (!strcmp(arg, "--no-overwrite")) {
            noOverwrite = AVIF_TRUE;
        } else if (!strcmp(arg, "-j") || !strcmp(arg, "--jobs")) {
            NEXTARG();
            if (!strcmp(arg, "all")) {
                settings.jobs = avifQueryCPUCount();
            } else {
                settings.jobs = atoi(arg);
                if (settings.jobs < 1) {
                    settings.jobs = 1;
                }
            }
        } else if (!strcmp(arg, "--stdin")) {
            avifInputAdd(&input, AVIF_FILENAME_STDIN, settings.outputTiming.duration, &pendingSettings);

            if (input.filesCount == 2) {
                // The only valid pattern here is
                //   avifenc [settings...] output.avif [more_settings...] --stdin
                // because multiple input files are forbidden with --stdin and
                // there must be an output file specified with or without --output.
                // Invalid patterns will be rejected later on.

                // Merge all the settings seen so far and associate them with stdin only.
                if (!avifInputFileSettingsOverwrite(/*dst=*/&input.files[0].settings, /*src=*/&input.files[1].settings)) {
                    fprintf(stderr, "ERROR: memory allocation failure\n");
                    goto cleanup;
                }
                avifCodecSpecificOptionsFree(&input.files[1].settings.codecSpecificOptions);
                input.files[1].settings = input.files[0].settings;
                memset(&input.files[0].settings, 0, sizeof(input.files[0].settings));

                // Swap the file and stdin so that the file is last and picked as output later on.
                const avifInputFile output = input.files[0];
                input.files[0] = input.files[1];
                input.files[1] = output;

                // This should now be equivalent to:
                //   avifenc [settings...] [more_settings...] --stdin output.avif

            } else if (input.filesCount > 2) {
                fprintf(stderr, "ERROR: there cannot be any other input if --stdin is specified\n");
                goto cleanup;
            }
        } else if (!strcmp(arg, "--input-format")) {
            NEXTARG();
            if (!strcmp(arg, "jpg") || !strcmp(arg, "jpeg")) {
                settings.inputFormat = AVIF_APP_FILE_FORMAT_JPEG;
            } else if (!strcmp(arg, "png")) {
                settings.inputFormat = AVIF_APP_FILE_FORMAT_PNG;
            } else if (!strcmp(arg, "y4m")) {
                settings.inputFormat = AVIF_APP_FILE_FORMAT_Y4M;
            } else if (!strcmp(arg, "auto")) {
                settings.inputFormat = AVIF_APP_FILE_FORMAT_UNKNOWN;
            } else {
                fprintf(stderr, "ERROR: invalid stdin file format (expected one of jpeg/png/y4m/auto): %s\n", arg);
                goto cleanup;
            }
        } else if (!strcmp(arg, "-o") || !strcmp(arg, "--output")) {
            NEXTARG();
            outputFilename = arg;
#if defined(AVIF_ENABLE_EXPERIMENTAL_MINI)
        } else if (!strcmp(arg, "--mini")) {
            settings.headerFormat |= AVIF_HEADER_MINI;
#endif // AVIF_ENABLE_EXPERIMENTAL_MINI
        } else if (!strcmp(arg, "-d") || !strcmp(arg, "--depth")) {
            NEXTARG();
            input.requestedDepth = atoi(arg);
            if ((input.requestedDepth != 8) && (input.requestedDepth != 10) && (input.requestedDepth != 12)) {
                fprintf(stderr, "ERROR: invalid depth: %s\n", arg);
                goto cleanup;
            }
        } else if (!strcmp(arg, "-y") || !strcmp(arg, "--yuv")) {
            NEXTARG();
            if (!strcmp(arg, "444")) {
                input.requestedFormat = AVIF_PIXEL_FORMAT_YUV444;
            } else if (!strcmp(arg, "422")) {
                input.requestedFormat = AVIF_PIXEL_FORMAT_YUV422;
            } else if (!strcmp(arg, "420")) {
                input.requestedFormat = AVIF_PIXEL_FORMAT_YUV420;
            } else if (!strcmp(arg, "400")) {
                input.requestedFormat = AVIF_PIXEL_FORMAT_YUV400;
            } else {
                fprintf(stderr, "ERROR: invalid format: %s\n", arg);
                goto cleanup;
            }
        } else if (!strcmp(arg, "-k") || !strcmp(arg, "--keyframe")) {
            NEXTARG();
            settings.keyframeInterval = atoi(arg);
        } else if (!strcmp(arg, "-q") || !strcmp(arg, "--qcolor") || strpre(arg, "-q:") || strpre(arg, "--qcolor:")) {
            // For compatibility reason unsuffixed flags always apply to all input (as if they appear before first input).
            // Print a warning if unsuffixed flag appears after input file.
            avifOptionSuffixType type = parseOptionSuffix(arg, /*warnNoSuffix=*/input.filesCount != 0);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            NEXTARG();
            int quality = atoi(arg);
            if (quality < AVIF_QUALITY_WORST) {
                quality = AVIF_QUALITY_WORST;
            }
            if (quality > AVIF_QUALITY_BEST) {
                quality = AVIF_QUALITY_BEST;
            }
            if (type == AVIF_OPTION_SUFFIX_UPDATE || input.filesCount == 0) {
                pendingSettings.quality = intSettingsEntryOf(quality);
            } else {
                input.files[0].settings.quality = intSettingsEntryOf(quality);
            }
        } else if (!strcmp(arg, "--qalpha") || strpre(arg, "--qalpha:")) {
            avifOptionSuffixType type = parseOptionSuffix(arg, input.filesCount != 0);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            NEXTARG();
            int qualityAlpha = atoi(arg);
            if (qualityAlpha < AVIF_QUALITY_WORST) {
                qualityAlpha = AVIF_QUALITY_WORST;
            }
            if (qualityAlpha > AVIF_QUALITY_BEST) {
                qualityAlpha = AVIF_QUALITY_BEST;
            }
            if (type == AVIF_OPTION_SUFFIX_UPDATE || input.filesCount == 0) {
                pendingSettings.qualityAlpha = intSettingsEntryOf(qualityAlpha);
            } else {
                input.files[0].settings.qualityAlpha = intSettingsEntryOf(qualityAlpha);
            }
        } else if (!strcmp(arg, "--min") || strpre(arg, "--min:")) {
            avifOptionSuffixType type = parseOptionSuffix(arg, input.filesCount != 0);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            NEXTARG();
            int minQuantizer = atoi(arg);
            if (minQuantizer < AVIF_QUANTIZER_BEST_QUALITY) {
                minQuantizer = AVIF_QUANTIZER_BEST_QUALITY;
            }
            if (minQuantizer > AVIF_QUANTIZER_WORST_QUALITY) {
                minQuantizer = AVIF_QUANTIZER_WORST_QUALITY;
            }
            if (type == AVIF_OPTION_SUFFIX_UPDATE || input.filesCount == 0) {
                pendingSettings.minQuantizer = intSettingsEntryOf(minQuantizer);
            } else {
                input.files[0].settings.minQuantizer = intSettingsEntryOf(minQuantizer);
            }
        } else if (!strcmp(arg, "--max") || strpre(arg, "--max:")) {
            avifOptionSuffixType type = parseOptionSuffix(arg, input.filesCount != 0);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            NEXTARG();
            int maxQuantizer = atoi(arg);
            if (maxQuantizer < AVIF_QUANTIZER_BEST_QUALITY) {
                maxQuantizer = AVIF_QUANTIZER_BEST_QUALITY;
            }
            if (maxQuantizer > AVIF_QUANTIZER_WORST_QUALITY) {
                maxQuantizer = AVIF_QUANTIZER_WORST_QUALITY;
            }
            if (type == AVIF_OPTION_SUFFIX_UPDATE || input.filesCount == 0) {
                pendingSettings.maxQuantizer = intSettingsEntryOf(maxQuantizer);
            } else {
                input.files[0].settings.maxQuantizer = intSettingsEntryOf(maxQuantizer);
            }
        } else if (!strcmp(arg, "--minalpha") || strpre(arg, "--minalpha:")) {
            avifOptionSuffixType type = parseOptionSuffix(arg, input.filesCount != 0);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            NEXTARG();
            int minQuantizerAlpha = atoi(arg);
            if (minQuantizerAlpha < AVIF_QUANTIZER_BEST_QUALITY) {
                minQuantizerAlpha = AVIF_QUANTIZER_BEST_QUALITY;
            }
            if (minQuantizerAlpha > AVIF_QUANTIZER_WORST_QUALITY) {
                minQuantizerAlpha = AVIF_QUANTIZER_WORST_QUALITY;
            }
            if (type == AVIF_OPTION_SUFFIX_UPDATE || input.filesCount == 0) {
                pendingSettings.minQuantizerAlpha = intSettingsEntryOf(minQuantizerAlpha);
            } else {
                input.files[0].settings.minQuantizerAlpha = intSettingsEntryOf(minQuantizerAlpha);
            }
        } else if (!strcmp(arg, "--maxalpha") || strpre(arg, "--maxalpha:")) {
            avifOptionSuffixType type = parseOptionSuffix(arg, input.filesCount != 0);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            NEXTARG();
            int maxQuantizerAlpha = atoi(arg);
            if (maxQuantizerAlpha < AVIF_QUANTIZER_BEST_QUALITY) {
                maxQuantizerAlpha = AVIF_QUANTIZER_BEST_QUALITY;
            }
            if (maxQuantizerAlpha > AVIF_QUANTIZER_WORST_QUALITY) {
                maxQuantizerAlpha = AVIF_QUANTIZER_WORST_QUALITY;
            }
            if (type == AVIF_OPTION_SUFFIX_UPDATE || input.filesCount == 0) {
                pendingSettings.maxQuantizerAlpha = intSettingsEntryOf(maxQuantizerAlpha);
            } else {
                input.files[0].settings.maxQuantizerAlpha = intSettingsEntryOf(maxQuantizerAlpha);
            }
        } else if (!strcmp(arg, "--target-size")) {
            NEXTARG();
            settings.targetSize = atoi(arg);
            if (settings.targetSize < 0) {
                settings.targetSize = -1;
            }
        } else if (!strcmp(arg, "--tilerowslog2") || strpre(arg, "--tilerowslog2:")) {
            avifOptionSuffixType type = parseOptionSuffix(arg, input.filesCount != 0);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            NEXTARG();
            int tileRowsLog2 = atoi(arg);
            if (tileRowsLog2 < 0) {
                tileRowsLog2 = 0;
            }
            if (tileRowsLog2 > 6) {
                tileRowsLog2 = 6;
            }
            if (type == AVIF_OPTION_SUFFIX_UPDATE || input.filesCount == 0) {
                pendingSettings.tileRowsLog2 = intSettingsEntryOf(tileRowsLog2);
            } else {
                input.files[0].settings.tileRowsLog2 = intSettingsEntryOf(tileRowsLog2);
            }
        } else if (!strcmp(arg, "--tilecolslog2") || strpre(arg, "--tilecolslog2:")) {
            avifOptionSuffixType type = parseOptionSuffix(arg, input.filesCount != 0);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            NEXTARG();
            int tileColsLog2 = atoi(arg);
            if (tileColsLog2 < 0) {
                tileColsLog2 = 0;
            }
            if (tileColsLog2 > 6) {
                tileColsLog2 = 6;
            }
            if (type == AVIF_OPTION_SUFFIX_UPDATE || input.filesCount == 0) {
                pendingSettings.tileColsLog2 = intSettingsEntryOf(tileColsLog2);
            } else {
                input.files[0].settings.tileColsLog2 = intSettingsEntryOf(tileColsLog2);
            }
        } else if (!strcmp(arg, "--autotiling") || strpre(arg, "--autotiling:")) {
            avifOptionSuffixType type = parseOptionSuffix(arg, input.filesCount != 0);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            if (type == AVIF_OPTION_SUFFIX_UPDATE || input.filesCount == 0) {
                pendingSettings.autoTiling = boolSettingsEntryOf(AVIF_TRUE);
            } else {
                input.files[0].settings.autoTiling = boolSettingsEntryOf(AVIF_TRUE);
            }
        } else if (!strcmp(arg, "--progressive")) {
            if (settings.layered) {
                fprintf(stderr, "ERROR: Can not use both --progressive and --layered\n");
                goto cleanup;
            }
            settings.progressive = AVIF_TRUE;
        } else if (!strcmp(arg, "--layered")) {
            if (settings.progressive) {
                fprintf(stderr, "ERROR: Can not use both --progressive and --layered\n");
                goto cleanup;
            }
            settings.layered = AVIF_TRUE;
        } else if (!strcmp(arg, "--scaling-mode") || strpre(arg, "--scaling-mode:")) {
            avifOptionSuffixType type = parseOptionSuffix(arg, input.filesCount != 0);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            NEXTARG();
            uint32_t frac[2] = { 0, 1 };
            if (!(parseU32List(frac, 1, arg, '/') || parseU32List(frac, 2, arg, '/')) || frac[0] > INT32_MAX || frac[1] > INT32_MAX) {
                fprintf(stderr, "ERROR: Invalid scaling mode: %s\n", arg);
                goto cleanup;
            }
            if (type == AVIF_OPTION_SUFFIX_UPDATE || input.filesCount == 0) {
                pendingSettings.scalingMode = scalingModeSettingsEntryOf(frac[0], frac[1]);
            } else {
                input.files[0].settings.scalingMode = scalingModeSettingsEntryOf(frac[0], frac[1]);
            }
        } else if (!strcmp(arg, "-g") || !strcmp(arg, "--grid")) {
            NEXTARG();
            if (!parseU32List(settings.gridDims, 2, arg, 'x')) {
                fprintf(stderr, "ERROR: Invalid grid dims: %s\n", arg);
                goto cleanup;
            }
            settings.gridDimsPresent = AVIF_TRUE;
            if ((settings.gridDims[0] == 0) || (settings.gridDims[0] > 256) || (settings.gridDims[1] == 0) ||
                (settings.gridDims[1] > 256)) {
                fprintf(stderr, "ERROR: Invalid grid dims (valid dim range [1-256]): %s\n", arg);
                goto cleanup;
            }
        } else if (!strcmp(arg, "--cicp") || !strcmp(arg, "--nclx")) {
            NEXTARG();
            uint32_t cicp[3];
            if (!parseU32List(cicp, 3, arg, '/')) {
                fprintf(stderr, "ERROR: Invalid CICP value: %s\n", arg);
                goto cleanup;
            }
            settings.colorPrimaries = (avifColorPrimaries)cicp[0];
            settings.transferCharacteristics = (avifTransferCharacteristics)cicp[1];
            settings.matrixCoefficients = (avifMatrixCoefficients)cicp[2];
            settings.cicpExplicitlySet = AVIF_TRUE;
        } else if (!strcmp(arg, "-r") || !strcmp(arg, "--range")) {
            NEXTARG();
            if (!strcmp(arg, "limited") || !strcmp(arg, "l")) {
                requestedRange = AVIF_RANGE_LIMITED;
            } else if (!strcmp(arg, "full") || !strcmp(arg, "f")) {
                requestedRange = AVIF_RANGE_FULL;
            } else {
                fprintf(stderr, "ERROR: Unknown range: %s\n", arg);
                goto cleanup;
            }
        } else if (!strcmp(arg, "-s") || !strcmp(arg, "--speed")) {
            NEXTARG();
            if (!strcmp(arg, "default") || !strcmp(arg, "d")) {
                settings.speed = AVIF_SPEED_DEFAULT;
            } else {
                settings.speed = atoi(arg);
                if (settings.speed > AVIF_SPEED_FASTEST) {
                    settings.speed = AVIF_SPEED_FASTEST;
                }
                if (settings.speed < AVIF_SPEED_SLOWEST) {
                    settings.speed = AVIF_SPEED_SLOWEST;
                }
            }
        } else if (!strcmp(arg, "--exif")) {
            NEXTARG();
            if (!avifReadEntireFile(arg, &exifOverride)) {
                fprintf(stderr, "ERROR: Unable to read Exif metadata: %s\n", arg);
                goto cleanup;
            }
            settings.ignoreExif = AVIF_TRUE;
        } else if (!strcmp(arg, "--xmp")) {
            NEXTARG();
            if (!avifReadEntireFile(arg, &xmpOverride)) {
                fprintf(stderr, "ERROR: Unable to read XMP metadata: %s\n", arg);
                goto cleanup;
            }
            settings.ignoreXMP = AVIF_TRUE;
        } else if (!strcmp(arg, "--icc")) {
            NEXTARG();
            if (!avifReadEntireFile(arg, &iccOverride)) {
                fprintf(stderr, "ERROR: Unable to read ICC profile: %s\n", arg);
                goto cleanup;
            }
            settings.ignoreColorProfile = AVIF_TRUE;
        } else if (!strcmp(arg, "--duration") || strpre(arg, "--duration:")) {
            // --duration is special, we always treat it as suffixed with :u, so don't print warning for it.
            avifOptionSuffixType type = parseOptionSuffix(arg, /*warnNoSuffix=*/AVIF_FALSE);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            NEXTARG();
            int durationInt = atoi(arg);
            if (durationInt < 1) {
                fprintf(stderr, "ERROR: Invalid duration: %d\n", durationInt);
                goto cleanup;
            }
            settings.outputTiming.duration = (uint64_t)durationInt;
        } else if (!strcmp(arg, "--timescale") || !strcmp(arg, "--fps")) {
            NEXTARG();
            int timescaleInt = atoi(arg);
            if (timescaleInt < 1) {
                fprintf(stderr, "ERROR: Invalid timescale: %d\n", timescaleInt);
                goto cleanup;
            }
            settings.outputTiming.timescale = (uint64_t)timescaleInt;
        } else if (!strcmp(arg, "-c") || !strcmp(arg, "--codec")) {
            NEXTARG();
            settings.codecChoice = avifCodecChoiceFromName(arg);
            if (settings.codecChoice == AVIF_CODEC_CHOICE_AUTO) {
                fprintf(stderr, "ERROR: Unrecognized codec: %s\n", arg);
                goto cleanup;
            } else {
                const char * codecName = avifCodecName(settings.codecChoice, AVIF_CODEC_FLAG_CAN_ENCODE);
                if (codecName == NULL) {
                    fprintf(stderr, "ERROR: Codec cannot encode: %s\n", arg);
                    goto cleanup;
                }
            }
        } else if (!strcmp(arg, "-a") || !strcmp(arg, "--advanced") || strpre(arg, "-a:") || strpre(arg, "--advanced:")) {
            avifOptionSuffixType type = parseOptionSuffix(arg, input.filesCount != 0);
            if (type == AVIF_OPTION_SUFFIX_INVALID) {
                goto cleanup;
            }
            NEXTARG();
            avifInputFileSettings * targetSettings =
                (type == AVIF_OPTION_SUFFIX_UPDATE || input.filesCount == 0) ? &pendingSettings : &input.files[0].settings;
            if (!avifCodecSpecificOptionsAdd(&targetSettings->codecSpecificOptions, arg)) {
                fprintf(stderr, "ERROR: Out of memory when setting codec specific option: %s\n", arg);
                goto cleanup;
            }
        } else if (!strcmp(arg, "--ignore-exif")) {
            settings.ignoreExif = AVIF_TRUE;
        } else if (!strcmp(arg, "--ignore-xmp")) {
            settings.ignoreXMP = AVIF_TRUE;
        } else if (!strcmp(arg, "--ignore-profile") || !strcmp(arg, "--ignore-icc")) {
            settings.ignoreColorProfile = AVIF_TRUE;
#if defined(AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION)
        } else if (!strcmp(arg, "--ignore-gain-map")) {
            settings.ignoreGainMap = AVIF_TRUE;
        } else if (!strcmp(arg, "--qgain-map")) {
            NEXTARG();
            int qualityGainMap = atoi(arg);
            if (qualityGainMap < AVIF_QUALITY_WORST) {
                qualityGainMap = AVIF_QUALITY_WORST;
            }
            if (qualityGainMap > AVIF_QUALITY_BEST) {
                qualityGainMap = AVIF_QUALITY_BEST;
            }
            settings.qualityGainMap = qualityGainMap;
            settings.qualityGainMapIsConstrained = AVIF_TRUE;
#endif
        } else if (!strcmp(arg, "--pasp")) {
            NEXTARG();
            if (!parseU32List(settings.paspValues, 2, arg, ',')) {
                fprintf(stderr, "ERROR: Invalid pasp values: %s\n", arg);
                goto cleanup;
            }
            settings.paspPresent = AVIF_TRUE;
        } else if (!strcmp(arg, "--crop")) {
            NEXTARG();
            if (!parseU32List(settings.clapValues, 4, arg, ',')) {
                fprintf(stderr, "ERROR: Invalid crop values: %s\n", arg);
                goto cleanup;
            }
            cropConversionRequired = AVIF_TRUE;
        } else if (!strcmp(arg, "--clap")) {
            NEXTARG();
            if (!parseU32List(settings.clapValues, 8, arg, ',')) {
                fprintf(stderr, "ERROR: Invalid clap values: %s\n", arg);
                goto cleanup;
            }
            settings.clapValid = AVIF_TRUE;
        } else if (!strcmp(arg, "--irot")) {
            NEXTARG();
            irotAngle = (uint8_t)atoi(arg);
            if (irotAngle > 3) {
                fprintf(stderr, "ERROR: Invalid irot angle: %s\n", arg);
                goto cleanup;
            }
        } else if (!strcmp(arg, "--imir")) {
            NEXTARG();
            imirAxis = (uint8_t)atoi(arg);
            if (imirAxis > 1) {
                fprintf(stderr, "ERROR: Invalid imir axis: %s\n", arg);
                goto cleanup;
            }
        } else if (!strcmp(arg, "--clli")) {
            NEXTARG();
            if (!parseU32List(settings.clliValues, 2, arg, ',') || settings.clliValues[0] >= (1u << 16) ||
                settings.clliValues[1] >= (1u << 16)) {
                fprintf(stderr, "ERROR: Invalid clli values: %s\n", arg);
                goto cleanup;
            }
            settings.clliPresent = AVIF_TRUE;
        } else if (!strcmp(arg, "--repetition-count")) {
            NEXTARG();
            if (!strcmp(arg, "infinite")) {
                settings.repetitionCount = AVIF_REPETITION_COUNT_INFINITE;
            } else {
                settings.repetitionCount = atoi(arg);
                if (settings.repetitionCount < 0) {
                    fprintf(stderr, "ERROR: Invalid repetition count: %s\n", arg);
                    goto cleanup;
                }
            }
        } else if (!strcmp(arg, "-l") || !strcmp(arg, "--lossless")) {
            lossless = AVIF_TRUE;
        } else if (!strcmp(arg, "-p") || !strcmp(arg, "--premultiply")) {
            premultiplyAlpha = AVIF_TRUE;
        } else if (!strcmp(arg, "--sharpyuv")) {
            settings.chromaDownsampling = AVIF_CHROMA_DOWNSAMPLING_SHARP_YUV;
        } else if (arg[0] == '-') {
            fprintf(stderr, "ERROR: unrecognized option %s\n\n", arg);
            syntaxLong();
            goto cleanup;
        } else {
            // Positional argument
            avifInputAdd(&input, /*filePath=*/arg, settings.outputTiming.duration, &pendingSettings);
        }

        ++argIndex;
    }

    // Alpha quality defaults to the same value as (color) quality until the first time it's explicitly set.
    for (int i = 0; i < input.filesCount; ++i) {
        avifInputFileSettings * fileSettings = &input.files[i].settings;
        if (fileSettings->qualityAlpha.set) {
            break;
        }
        fileSettings->qualityAlpha = fileSettings->quality;
    }

    if (settings.jobs == -1) {
        settings.jobs = avifQueryCPUCount();
    }

    // Check global lossless parameters and set to default if needed.
    if (lossless) {
        // Pixel format.
        if (input.requestedFormat != AVIF_PIXEL_FORMAT_NONE && input.requestedFormat != AVIF_PIXEL_FORMAT_YUV444 &&
            input.requestedFormat != AVIF_PIXEL_FORMAT_YUV400) {
            fprintf(stderr,
                    "When set, the pixel format can only be 444 in lossless "
                    "mode. 400 also works if the input is grayscale.\n");
            goto cleanup;
        }
        // Codec.
        const char * codecName = avifCodecName(settings.codecChoice, AVIF_CODEC_FLAG_CAN_ENCODE);
        if (codecName && !strcmp(codecName, "rav1e")) {
            fprintf(stderr, "rav1e doesn't support lossless encoding yet: https://github.com/xiph/rav1e/issues/151\n");
            goto cleanup;
        } else if (codecName && !strcmp(codecName, "svt")) {
            char versions[256];
            avifCodecVersions(versions);
            const char svtVersionPrefix[] = "svt [enc]:v";
            const char * svtVersionPrefixPos = strstr(versions, svtVersionPrefix);
            if (svtVersionPrefixPos == NULL) {
                // Make sure the syntax returned by avifCodecVersions() did not change.
                assert(strstr(versions, "svt") == NULL && strstr(versions, "SVT") == NULL);
                // Let the encode fail later because SVT was not included in the build.
            } else {
                const char * svtVersion = svtVersionPrefixPos + strlen(svtVersionPrefix);
                const int svtMajorVersion = atoi(svtVersion);
                if (svtMajorVersion < 3) {
                    fprintf(stderr, "SVT-AV1 lossless support was added in version 3.0.0, current major version is only %d\n", svtMajorVersion);
                    goto cleanup;
                }
            }
        }
        // Range.
        if (requestedRange != AVIF_RANGE_FULL) {
            fprintf(stderr, "Range has to be full in lossless mode.\n");
            goto cleanup;
        }
        // Matrix coefficients.
        if (settings.cicpExplicitlySet) {
            if (settings.matrixCoefficients != AVIF_MATRIX_COEFFICIENTS_IDENTITY &&
                settings.matrixCoefficients != AVIF_MATRIX_COEFFICIENTS_YCGCO_RE &&
                settings.matrixCoefficients != AVIF_MATRIX_COEFFICIENTS_YCGCO_RO) {
                fprintf(stderr, "Matrix coefficients have to be identity, YCgCo-Re, or YCgCo-Ro in lossless mode.\n");
                goto cleanup;
            }
        } else {
            settings.matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
        }
        if (settings.progressive) {
            fprintf(stderr, "Automatic layered encoding is unsupported in lossless mode.\n");
        }
    }

    avifInputFileSettings emptySettingsReference;
    memset(&emptySettingsReference, 0, sizeof(emptySettingsReference));

    if (!outputFilename && input.filesCount > 1 && input.files[input.filesCount - 1].filename != AVIF_FILENAME_STDIN) {
        --input.filesCount;
        outputFilename = input.files[input.filesCount].filename;
        if (memcmp(&input.files[input.filesCount].settings, &emptySettingsReference, sizeof(avifInputFileSettings)) != 0) {
            fprintf(stderr, "WARNING: Trailing options with update suffix has no effect. Place them before the input you intend to apply to.\n");
        }
    }

    if (input.filesCount < 1) {
        fprintf(stderr, "ERROR: no input specified\n");
        goto cleanup;
    }

    if (input.files[0].filename == AVIF_FILENAME_STDIN && input.filesCount > 1) {
        fprintf(stderr, "ERROR: there cannot be any other input if --stdin is specified\n");
        goto cleanup;
    }

    if (!outputFilename) {
        fprintf(stderr, "ERROR: no output specified\n");
        goto cleanup;
    }

    if (noOverwrite && fileExists(outputFilename)) {
        fprintf(stderr, "ERROR: output file %s already exists and --no-overwrite was specified\n", outputFilename);
        goto cleanup;
    }

#if defined(_WIN32)
    if (input.files[0].filename == AVIF_FILENAME_STDIN) {
        setmode(fileno(stdin), O_BINARY);
    }
#endif

    if (memcmp(&pendingSettings, &emptySettingsReference, sizeof(avifInputFileSettings)) != 0) {
        fprintf(stderr, "WARNING: Trailing options with update suffix has no effect. Place them before the input you intend to apply to.\n");
    }

    // Check layer config
    if (settings.progressive) {
        assert(!settings.layered);
        if (input.filesCount > 1) {
            fprintf(stderr, "ERROR: --progressive only supports one input.\n");
            goto cleanup;
        }
        // for automatic layered encoding, make a 2 layer AVIF.
        settings.layers = 2;
    } else if (settings.layered) {
        // For manual layered encoding, infer number of layers from input count.
        // For multi-frame input (Y4Ms) layered encoding only use the first frame,
        // so that we can assume number of inputs is number of layers.
        // We don't support changing config halfway encoding on input,
        // therefore encoding layered AVIF with single multi-frame input is not very meaningful.
        if (input.filesCount < 2 || input.filesCount > AVIF_MAX_AV1_LAYER_COUNT) {
            fprintf(stderr, "Encoding layered AVIF required 2 to %d inputs, but got %d.\n", AVIF_MAX_AV1_LAYER_COUNT, input.filesCount);
            goto cleanup;
        }
        settings.layers = input.filesCount;
    } else {
        settings.layers = 1;
    }
    if (settings.layers > 1 && settings.gridDimsPresent) {
        fprintf(stderr, "Layered grid image unimplemented in avifenc.\n");
        goto cleanup;
    }

    for (int i = 0; i < input.filesCount; ++i) {
        avifInputFile * file = &input.files[i];
        avifInputFileSettings * fileSettings = &file->settings;

        // Check tiling parameters.
        // Automatic tiling (autoTiling) and manual tiling (tileRowsLog2, tileColsLog2) are mutually exclusive, which means:
        // - At each input, only one of the two may be set.
        // - At some input, specifying one disables the other.
        if (fileSettings->autoTiling.set) {
            if (fileSettings->tileRowsLog2.set || fileSettings->tileColsLog2.set) {
                fprintf(stderr, "ERROR: --autotiling is specified but --tilerowslog2 or --tilecolslog2 is also specified for current input.\n");
                goto cleanup;
            }
            // At this point, autoTiling of this input file can only be set by command line.
            // (automatic generation of setting entries happens below)
            // Since it's a boolean flag, its value must be AVIF_TRUE.
            assert(fileSettings->autoTiling.value);
            // Therefore disable manual tiling at this input (in case it was enabled at previous input).
            fileSettings->tileRowsLog2 = intSettingsEntryOf(0);
            fileSettings->tileColsLog2 = intSettingsEntryOf(0);
        } else if (fileSettings->tileColsLog2.set || fileSettings->tileRowsLog2.set) {
            // If this file has manual tile config set, disable automatic tiling, for the same reason as above.
            fileSettings->autoTiling = boolSettingsEntryOf(AVIF_FALSE);
        }

        // Check per-input lossy/lossless parameters.
        if (lossless) {
            // Quality.
            if ((fileSettings->quality.set && fileSettings->quality.value != AVIF_QUALITY_LOSSLESS) ||
                (fileSettings->qualityAlpha.set && fileSettings->qualityAlpha.value != AVIF_QUALITY_LOSSLESS)) {
                fprintf(stderr, "ERROR: Quality cannot be set in lossless mode, except to %d.\n", AVIF_QUALITY_LOSSLESS);
                goto cleanup;
            }
            // Quantizers.
            if ((fileSettings->minQuantizer.set && fileSettings->minQuantizer.value != AVIF_QUANTIZER_LOSSLESS) ||
                (fileSettings->maxQuantizer.set && fileSettings->maxQuantizer.value != AVIF_QUANTIZER_LOSSLESS) ||
                (fileSettings->minQuantizerAlpha.set && fileSettings->minQuantizerAlpha.value != AVIF_QUANTIZER_LOSSLESS) ||
                (fileSettings->maxQuantizerAlpha.set && fileSettings->maxQuantizerAlpha.value != AVIF_QUANTIZER_LOSSLESS)) {
                fprintf(stderr, "ERROR: Quantizers cannot be set in lossless mode, except to %d.\n", AVIF_QUANTIZER_LOSSLESS);
                goto cleanup;
            }
        } else {
            if (settings.progressive) {
                assert(DEFAULT_QUALITY >= PROGRESSIVE_WORST_QUALITY);
                if (fileSettings->quality.set && fileSettings->quality.value < PROGRESSIVE_WORST_QUALITY) {
                    fprintf(stderr, "ERROR: --qcolor must be at least %d when using --progressive.\n", PROGRESSIVE_WORST_QUALITY);
                    goto cleanup;
                }
                // --progressive only adjust color quality
            }
        }

        // Set defaults for first input file.
        if (i == 0) {
            // This check only applies to the first input.
            // Following inputs can change only one and leave the other unchanged.
            if (fileSettings->minQuantizer.set != fileSettings->maxQuantizer.set) {
                fprintf(stderr,
                        "ERROR: --min and --max must be either both specified or both unspecified for input %s.\n",
                        avifPrettyFilename(file->filename));
                goto cleanup;
            }
            if (fileSettings->minQuantizerAlpha.set != fileSettings->maxQuantizerAlpha.set) {
                fprintf(stderr,
                        "ERROR: --minalpha and --maxalpha must be either both specified or both unspecified for input %s.\n",
                        avifPrettyFilename(file->filename));
                goto cleanup;
            }
            if (fileSettings->minQuantizer.set && fileSettings->maxQuantizer.set) {
                fprintf(stderr,
                        "WARNING: --min and --max are deprecated, please use -q 0..100 instead. "
                        "--min %d --max %d is equivalent to -q %d\n",
                        fileSettings->minQuantizer.value,
                        fileSettings->maxQuantizer.value,
                        quantizerToQuality(fileSettings->minQuantizer.value, fileSettings->maxQuantizer.value));
            }
            if (fileSettings->minQuantizerAlpha.set && fileSettings->maxQuantizerAlpha.set) {
                fprintf(stderr,
                        "WARNING: --minalpha and --maxalpha are deprecated, please use --qalpha 0..100 instead. "
                        "--minalpha %d --maxalpha %d is equivalent to --qalpha %d\n",
                        fileSettings->minQuantizerAlpha.value,
                        fileSettings->maxQuantizerAlpha.value,
                        quantizerToQuality(fileSettings->minQuantizerAlpha.value, fileSettings->maxQuantizerAlpha.value));
            }

            if (!fileSettings->autoTiling.set) {
                fileSettings->autoTiling = boolSettingsEntryOf(AVIF_TRUE);
            }
            if (!fileSettings->tileRowsLog2.set) {
                fileSettings->tileRowsLog2 = intSettingsEntryOf(0);
            }
            if (!fileSettings->tileColsLog2.set) {
                fileSettings->tileColsLog2 = intSettingsEntryOf(0);
            }

            // Set lossy/lossless parameters to default if needed.
            if (lossless) {
                // Add lossless settings.
                // Settings on first input will be inherited by all inputs, so this is sufficient.
                fileSettings->quality = intSettingsEntryOf(AVIF_QUALITY_LOSSLESS);
                fileSettings->qualityAlpha = intSettingsEntryOf(AVIF_QUALITY_LOSSLESS);
                fileSettings->minQuantizer = intSettingsEntryOf(AVIF_QUANTIZER_LOSSLESS);
                fileSettings->maxQuantizer = intSettingsEntryOf(AVIF_QUANTIZER_LOSSLESS);
                fileSettings->minQuantizerAlpha = intSettingsEntryOf(AVIF_QUANTIZER_LOSSLESS);
                fileSettings->maxQuantizerAlpha = intSettingsEntryOf(AVIF_QUANTIZER_LOSSLESS);
            } else {
                settings.qualityIsConstrained = fileSettings->quality.set;
                settings.qualityAlphaIsConstrained = fileSettings->qualityAlpha.set;

                if (fileSettings->minQuantizer.set) {
                    assert(fileSettings->maxQuantizer.set);
                    if (!fileSettings->quality.set) {
                        const int quality = quantizerToQuality(fileSettings->minQuantizer.value, fileSettings->maxQuantizer.value);
                        fileSettings->quality = intSettingsEntryOf(quality);
                    }
                } else {
                    assert(!fileSettings->maxQuantizer.set);
                    if (!fileSettings->quality.set) {
                        fileSettings->quality = intSettingsEntryOf(DEFAULT_QUALITY);
                    }
                    fileSettings->minQuantizer = intSettingsEntryOf(AVIF_QUANTIZER_BEST_QUALITY);
                    fileSettings->maxQuantizer = intSettingsEntryOf(AVIF_QUANTIZER_WORST_QUALITY);
                }

                if (fileSettings->minQuantizerAlpha.set) {
                    assert(fileSettings->maxQuantizerAlpha.set);
                    if (!fileSettings->qualityAlpha.set) {
                        const int qualityAlpha =
                            quantizerToQuality(fileSettings->minQuantizerAlpha.value, fileSettings->maxQuantizerAlpha.value);
                        fileSettings->qualityAlpha = intSettingsEntryOf(qualityAlpha);
                    }
                } else {
                    assert(!fileSettings->maxQuantizerAlpha.set);
                    if (!fileSettings->qualityAlpha.set) {
                        fileSettings->qualityAlpha = fileSettings->quality;
                    }
                    fileSettings->minQuantizerAlpha = intSettingsEntryOf(AVIF_QUANTIZER_BEST_QUALITY);
                    fileSettings->maxQuantizerAlpha = intSettingsEntryOf(AVIF_QUANTIZER_WORST_QUALITY);
                }
            }

            if (!fileSettings->scalingMode.set) {
                fileSettings->scalingMode = scalingModeSettingsEntryOf(1, 1);
            }
        }
    }

    image = avifImageCreateEmpty();
    if (!image) {
        fprintf(stderr, "ERROR: Out of memory\n");
        goto cleanup;
    }

    // Set these in advance so any upcoming RGB -> YUV use the proper coefficients
    image->colorPrimaries = settings.colorPrimaries;
    image->transferCharacteristics = settings.transferCharacteristics;
    image->matrixCoefficients = settings.matrixCoefficients;
    image->yuvRange = requestedRange;
    image->alphaPremultiplied = premultiplyAlpha;

    if ((image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_IDENTITY) && (input.requestedFormat != AVIF_PIXEL_FORMAT_NONE) &&
        (input.requestedFormat != AVIF_PIXEL_FORMAT_YUV444)) {
        // User explicitly asked for non YUV444 yuvFormat, while matrixCoefficients was likely
        // set to AVIF_MATRIX_COEFFICIENTS_IDENTITY as a side effect of --lossless,
        // and Identity is only valid with YUV444. Set matrixCoefficients back to the default.
        image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT601;

        if (settings.cicpExplicitlySet) {
            // Only warn if someone explicitly asked for identity.
            printf("WARNING: matrixCoefficients may not be set to identity (0) when %s. Resetting MC to defaults (%d).\n",
                   (input.requestedFormat == AVIF_PIXEL_FORMAT_YUV400) ? "encoding 4:0:0" : "subsampling",
                   image->matrixCoefficients);
        }
    }

    // --target-size requires multiple encodings of the same files. Cache the input images.
    input.cacheEnabled = (settings.targetSize != -1);

    const avifInputFile * firstFile = avifInputGetFile(&input, /*imageIndex=*/0);
    uint32_t sourceDepth = 0;
    avifBool sourceWasRGB = AVIF_FALSE;
    avifAppSourceTiming firstSourceTiming;
    const avifBool isImageSequence = (!settings.gridDimsPresent) && (settings.layers == 1) && (input.filesCount > 1);
    // Gain maps are not supported for animations or layered images.
    const avifBool ignoreGainMap = settings.ignoreGainMap || isImageSequence || settings.progressive;
    if (!avifInputReadImage(&input,
                            /*imageIndex=*/0,
                            settings.ignoreColorProfile,
                            settings.ignoreExif,
                            settings.ignoreXMP,
                            /*allowChangingCicp=*/!settings.cicpExplicitlySet,
                            ignoreGainMap,
                            image,
                            /*settings=*/NULL, // Must use the setting for first input
                            &sourceDepth,
                            &sourceWasRGB,
                            &firstSourceTiming,
                            settings.chromaDownsampling,
                            settings.inputFormat)) {
        goto cleanup;
    }

    // Check again for -y auto or for y4m input (y4m input ignores input.requestedFormat and
    // retains the format in file).
    if ((image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_IDENTITY) && (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400)) {
        image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT601;

        if (settings.cicpExplicitlySet) {
            // Only warn if someone explicitly asked for identity.
            printf("WARNING: matrixCoefficients may not be set to identity (0) when encoding 4:0:0. Resetting MC to defaults (%d).\n",
                   image->matrixCoefficients);
        }
    }
    if ((image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_IDENTITY) && (image->yuvFormat != AVIF_PIXEL_FORMAT_YUV444)) {
        fprintf(stderr, "matrixCoefficients may not be set to identity (0) when subsampling.\n");
        goto cleanup;
    }

    printf("Successfully loaded: %s\n", avifPrettyFilename(firstFile->filename));

    // Prepare image timings
    if ((settings.outputTiming.duration == 0) && (settings.outputTiming.timescale == 0) && (firstSourceTiming.duration > 0) &&
        (firstSourceTiming.timescale > 0)) {
        // Set the default duration and timescale to the first image's timing.
        settings.outputTiming = firstSourceTiming;
    } else {
        // Set output timing defaults to 30 fps
        if (settings.outputTiming.duration == 0) {
            settings.outputTiming.duration = 1;
        }
        if (settings.outputTiming.timescale == 0) {
            settings.outputTiming.timescale = 30;
        }
    }

    if ((iccOverride.size && (avifImageSetProfileICC(image, iccOverride.data, iccOverride.size) != AVIF_RESULT_OK)) ||
        (exifOverride.size && (avifImageSetMetadataExif(image, exifOverride.data, exifOverride.size) != AVIF_RESULT_OK)) ||
        (xmpOverride.size && (avifImageSetMetadataXMP(image, xmpOverride.data, xmpOverride.size) != AVIF_RESULT_OK))) {
        fprintf(stderr, "Error when setting overridden metadata: out of memory.\n");
        goto cleanup;
    }

    if (!image->icc.size && !settings.cicpExplicitlySet && (image->colorPrimaries == AVIF_COLOR_PRIMARIES_UNSPECIFIED) &&
        (image->transferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED)) {
        // The final image has no ICC profile, the user didn't specify any CICP, and the source
        // image didn't provide any CICP. Explicitly signal SRGB CP/TC here, as 2/2/x will be
        // interpreted as SRGB anyway.
        image->colorPrimaries = AVIF_COLOR_PRIMARIES_SRGB;
        image->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_SRGB;
    }

#if defined(AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION)
    if (image->gainMap && !image->gainMap->altICC.size) {
        if (image->gainMap->altColorPrimaries == AVIF_COLOR_PRIMARIES_UNSPECIFIED) {
            // Assume the alternate image has the same primaries as the base image.
            image->gainMap->altColorPrimaries = image->colorPrimaries;
        }
        if (image->gainMap->altTransferCharacteristics == AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED) {
            // Assume the alternate image is PQ HDR.
            image->gainMap->altTransferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_PQ;
        }
    }
#endif // AVIF_ENABLE_JPEG_GAIN_MAP_CONVERSION

    if (settings.paspPresent) {
        image->transformFlags |= AVIF_TRANSFORM_PASP;
        image->pasp.hSpacing = settings.paspValues[0];
        image->pasp.vSpacing = settings.paspValues[1];
    }
    if (cropConversionRequired) {
        if (!convertCropToClap(image->width, image->height, settings.clapValues)) {
            goto cleanup;
        }
        settings.clapValid = AVIF_TRUE;
    }
    if (settings.clapValid) {
        image->transformFlags |= AVIF_TRANSFORM_CLAP;
        image->clap.widthN = settings.clapValues[0];
        image->clap.widthD = settings.clapValues[1];
        image->clap.heightN = settings.clapValues[2];
        image->clap.heightD = settings.clapValues[3];
        image->clap.horizOffN = settings.clapValues[4];
        image->clap.horizOffD = settings.clapValues[5];
        image->clap.vertOffN = settings.clapValues[6];
        image->clap.vertOffD = settings.clapValues[7];

        // Validate clap
        avifCropRect cropRect;
        avifDiagnostics diag;
        avifDiagnosticsClearError(&diag);
        if (!avifCropRectFromCleanApertureBox(&cropRect, &image->clap, image->width, image->height, &diag)) {
            fprintf(stderr,
                    "ERROR: Invalid clap: width:[%d / %d], height:[%d / %d], horizOff:[%d / %d], vertOff:[%d / %d] - %s\n",
                    (int32_t)image->clap.widthN,
                    (int32_t)image->clap.widthD,
                    (int32_t)image->clap.heightN,
                    (int32_t)image->clap.heightD,
                    (int32_t)image->clap.horizOffN,
                    (int32_t)image->clap.horizOffD,
                    (int32_t)image->clap.vertOffN,
                    (int32_t)image->clap.vertOffD,
                    diag.error);
            goto cleanup;
        }
    }
    if (irotAngle != 0xff) {
        image->transformFlags |= AVIF_TRANSFORM_IROT;
        image->irot.angle = irotAngle;
    }
    if (imirAxis != 0xff) {
        image->transformFlags |= AVIF_TRANSFORM_IMIR;
        image->imir.axis = imirAxis;
    }
    if (settings.clliPresent) {
        image->clli.maxCLL = (uint16_t)settings.clliValues[0];
        image->clli.maxPALL = (uint16_t)settings.clliValues[1];
    }

    avifBool hasAlpha = (image->alphaPlane && image->alphaRowBytes);
    avifBool usingLosslessColor = (firstFile->settings.quality.value == AVIF_QUALITY_LOSSLESS);
    avifBool usingLosslessAlpha = (firstFile->settings.qualityAlpha.value == AVIF_QUALITY_LOSSLESS);
    avifBool using400 = (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400);
    avifBool using444 = (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV444);
    avifBool usingFullRange = (image->yuvRange == AVIF_RANGE_FULL);
    avifBool usingIdentityMatrix = (image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_IDENTITY);

    // Guess if the enduser is asking for lossless and enable it so that warnings can be emitted
    if (!lossless && usingLosslessColor && (!hasAlpha || usingLosslessAlpha)) {
        // The enduser is probably expecting lossless. Turn it on and emit warnings
        printf("Quality set to %d, assuming --lossless to enable warnings on potential lossless issues.\n", AVIF_QUALITY_LOSSLESS);
        lossless = AVIF_TRUE;
    }

    // Check for any reasons lossless will fail, and complain loudly
    if (lossless) {
        if (!usingLosslessColor) {
            fprintf(stderr,
                    "WARNING: [--lossless] Color quality (-q or --qcolor) not set to %d. Color output might not be lossless.\n",
                    AVIF_QUALITY_LOSSLESS);
            lossless = AVIF_FALSE;
        }

        if (hasAlpha && !usingLosslessAlpha) {
            fprintf(stderr,
                    "WARNING: [--lossless] Alpha present and alpha quality (--qalpha) not set to %d. Alpha output might not be lossless.\n",
                    AVIF_QUALITY_LOSSLESS);
            lossless = AVIF_FALSE;
        }

        if (usingIdentityMatrix && (sourceDepth != image->depth)) {
            fprintf(stderr,
                    "WARNING: [--lossless] Identity matrix is used but input depth (%d) does not match output depth (%d). Output might not be lossless.\n",
                    sourceDepth,
                    image->depth);
            lossless = AVIF_FALSE;
        }

        if (sourceWasRGB) {
            if (!using444 && !using400) {
                fprintf(stderr,
                        "WARNING: [--lossless] Input data was RGB and YUV "
                        "subsampling (-y) isn't YUV444 or YUV400. Output might "
                        "not be lossless.\n");
                lossless = AVIF_FALSE;
            }

            if (!usingFullRange) {
                fprintf(stderr, "WARNING: [--lossless] Input data was RGB and output range (-r) isn't full. Output might not be lossless.\n");
                lossless = AVIF_FALSE;
            }

            avifBool matrixCoefficientsAreLosslessCompatible = usingIdentityMatrix ||
                                                               image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO_RE ||
                                                               image->matrixCoefficients == AVIF_MATRIX_COEFFICIENTS_YCGCO_RO;
            if (!matrixCoefficientsAreLosslessCompatible && !using400) {
                fprintf(stderr, "WARNING: [--lossless] Input data was RGB and matrixCoefficients isn't set to identity (--cicp x/x/0) or YCgCo-Re/Ro (--cicp x/x/16 or x/x/17); Output might not be lossless.\n");
                lossless = AVIF_FALSE;
            }
        }
    }

    if (settings.gridDimsPresent) {
        // Grid image!

        gridCellCount = settings.gridDims[0] * settings.gridDims[1];
        printf("Preparing to encode a %ux%u grid (%u cells)...\n", settings.gridDims[0], settings.gridDims[1], gridCellCount);

        gridCells = calloc(gridCellCount, sizeof(avifImage *));
        if (gridCells == NULL) {
            fprintf(stderr, "ERROR: memory allocation failure\n");
            goto cleanup;
        }
        gridCells[0] = image; // take ownership of image

        int imageIndex = 1; // The first grid cell was loaded into image (imageIndex 0).
        const avifInputFile * nextFile;
        while ((nextFile = avifInputGetFile(&input, imageIndex)) != NULL) {
            if (imageIndex == 1) {
                printf("Loading additional cells for grid image (%u cells)...\n", gridCellCount);
            }
            if (imageIndex >= (int)gridCellCount) {
                // We have enough, warn and continue
                fprintf(stderr,
                        "WARNING: [--grid] More than %u images were supplied for this %ux%u grid. The rest will be ignored.\n",
                        gridCellCount,
                        settings.gridDims[0],
                        settings.gridDims[1]);
                break;
            }

            // Ensure no settings is set for other cells
            if (memcmp(&nextFile->settings, &emptySettingsReference, sizeof(avifInputFileSettings)) != 0) {
                fprintf(stderr, "ERROR: Grid image cannot use different settings for each cell.\n");
                goto cleanup;
            }

            avifImage * cellImage = avifImageCreateEmpty();
            if (!cellImage) {
                fprintf(stderr, "ERROR: Out of memory\n");
                goto cleanup;
            }
            cellImage->colorPrimaries = image->colorPrimaries;
            cellImage->transferCharacteristics = image->transferCharacteristics;
            cellImage->matrixCoefficients = image->matrixCoefficients;
            cellImage->yuvRange = image->yuvRange;
            cellImage->alphaPremultiplied = image->alphaPremultiplied;
            gridCells[imageIndex] = cellImage;

            // Ignore ICC, Exif and XMP because only the metadata of the first frame is taken into
            // account by the libavif API.
            if (!avifInputReadImage(&input,
                                    imageIndex,
                                    /*ignoreColorProfile=*/AVIF_TRUE,
                                    /*ignoreExif=*/AVIF_TRUE,
                                    /*ignoreXMP=*/AVIF_TRUE,
                                    /*allowChangingCicp=*/AVIF_FALSE,
                                    settings.ignoreGainMap,
                                    cellImage,
                                    /*settings=*/NULL,
                                    /*outDepth=*/NULL,
                                    /*sourceIsRGB=*/NULL,
                                    /*sourceTiming=*/NULL,
                                    settings.chromaDownsampling,
                                    settings.inputFormat)) {
                goto cleanup;
            }
            // Let avifEncoderAddImageGrid() verify the grid integrity (valid cell sizes, depths etc.).

            ++imageIndex;
        }

        if (imageIndex == 1) {
            printf("Single image input for a grid image. Attempting to split into %u cells...\n", gridCellCount);
            gridSplitImage = image;
            gridCells[0] = NULL;

            if (!avifImageSplitGrid(gridSplitImage, settings.gridDims[0], settings.gridDims[1], gridCells)) {
                goto cleanup;
            }
        } else if (imageIndex != (int)gridCellCount) {
            fprintf(stderr, "ERROR: Not enough input files for grid image! (expecting %u, or a single image to be split)\n", gridCellCount);
            goto cleanup;
        }
        // TODO(yguyon): Check if it is possible to use frames from a single input file as grid cells. Maybe forbid it.
    }

    const char * lossyHint = " (Lossy)";
    if (lossless) {
        lossyHint = " (Lossless)";
    }
    printf("AVIF to be written:%s\n", lossyHint);
    const avifImage * avif = gridCells ? gridCells[0] : image;
    avifImageDump(avif,
                  settings.gridDims[0],
                  settings.gridDims[1],
                  settings.layers > 1 ? AVIF_PROGRESSIVE_STATE_AVAILABLE : AVIF_PROGRESSIVE_STATE_UNAVAILABLE);

    avifEncodedByteSizes byteSizes = { 0, 0, 0 };
    if (!avifEncodeImages(&settings, &input, firstFile, image, (const avifImage * const *)gridCells, &raw, &byteSizes)) {
        goto cleanup;
    }

    printf("Encoded successfully.\n");
    printf(" * Color total size: %" AVIF_FMT_ZU " bytes\n", byteSizes.colorSizeBytes);
    printf(" * Alpha total size: %" AVIF_FMT_ZU " bytes\n", byteSizes.alphaSizeBytes);
    if (byteSizes.gainMapSizeBytes > 0) {
        printf(" * Gain Map AV1 total size: %" AVIF_FMT_ZU " bytes\n", byteSizes.gainMapSizeBytes);
    }
    if (isImageSequence) {
        if (settings.repetitionCount == AVIF_REPETITION_COUNT_INFINITE) {
            printf(" * Repetition Count: Infinite\n");
        } else {
            printf(" * Repetition Count: %d\n", settings.repetitionCount);
        }
    }
    if (noOverwrite && fileExists(outputFilename)) {
        // check again before write
        fprintf(stderr, "ERROR: output file %s already exists and --no-overwrite was specified\n", outputFilename);
        goto cleanup;
    }
    FILE * f = fopen(outputFilename, "wb");
    if (!f) {
        fprintf(stderr, "ERROR: Failed to open file for write: %s\n", outputFilename);
        goto cleanup;
    }
    if (fwrite(raw.data, 1, raw.size, f) != raw.size) {
        fprintf(stderr, "Failed to write %" AVIF_FMT_ZU " bytes: %s\n", raw.size, outputFilename);
        goto cleanup;
    } else {
        printf("Wrote AVIF: %s\n", outputFilename);
    }
    fclose(f);
    returnCode = 0;

cleanup:
    if (gridCells) {
        for (uint32_t i = 0; i < gridCellCount; ++i) {
            if (gridCells[i]) {
                avifImageDestroy(gridCells[i]);
            }
        }
        free(gridCells);
    } else if (image) { // image is owned/cleaned up by gridCells if it exists
        avifImageDestroy(image);
    }
    if (gridSplitImage) {
        avifImageDestroy(gridSplitImage);
    }
    avifRWDataFree(&raw);
    avifRWDataFree(&exifOverride);
    avifRWDataFree(&xmpOverride);
    avifRWDataFree(&iccOverride);
    avifCodecSpecificOptionsFree(&pendingSettings.codecSpecificOptions);
    while (input.cacheCount) {
        --input.cacheCount;
        if (input.cache[input.cacheCount].image) {
            avifImageDestroy(input.cache[input.cacheCount].image);
        }
    }
    free(input.cache);
    while (input.filesCount) {
        --input.filesCount;
        avifInputFile * file = &input.files[input.filesCount];
        avifCodecSpecificOptionsFree(&file->settings.codecSpecificOptions);
    }
    free(input.files);

    return returnCode;
}
