// Copyright 2022 Google LLC. All rights reserved.
// SPDX-License-Identifier: BSD-2-Clause

#include "avif/avif.h"
#include "avifincrtest_helpers.h"

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

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

// Reads the file at path into bytes or returns false.
static avifBool readFile(const char * path, avifRWData * bytes)
{
    FILE * file;
    avifRWDataFree(bytes);
    file = fopen(path, "rb");
    if (!file) {
        return AVIF_FALSE;
    }
    if (fseek(file, 0, SEEK_END)) {
        fclose(file);
        return AVIF_FALSE;
    }
    avifRWDataRealloc(bytes, ftell(file));
    rewind(file);
    if (fread(bytes->data, bytes->size, 1, file) != 1) {
        avifRWDataFree(bytes);
        fclose(file);
        return AVIF_FALSE;
    }
    fclose(file);
    return AVIF_TRUE;
}

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

// Encodes then decodes a window of width*height pixels at the middle of the image.
// Check that non-incremental and incremental decodings produce the same pixels.
static avifBool encodeDecodeNonIncrementallyAndIncrementally(const avifImage * image,
                                                             uint32_t width,
                                                             uint32_t height,
                                                             avifBool createAlphaIfNone,
                                                             avifBool flatCells,
                                                             avifBool useNthImageApi)
{
    avifBool success = AVIF_FALSE;
    avifRWData encodedAvif = { 0 };
    uint32_t cellWidth, cellHeight;
    if (!encodeRectAsIncremental(image, width, height, createAlphaIfNone, flatCells, &encodedAvif, &cellWidth, &cellHeight)) {
        goto cleanup;
    }
    if (!decodeNonIncrementallyAndIncrementally(&encodedAvif, cellHeight, useNthImageApi)) {
        goto cleanup;
    }
    success = AVIF_TRUE;
cleanup:
    avifRWDataFree(&encodedAvif);
    return success;
}

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

int main(int argc, char * argv[])
{
    int exitCode = EXIT_FAILURE;
    avifRWData encodedAvif = { NULL, 0 };

    if (argc != 2) {
        printf("ERROR: bad arguments\n");
        printf("Usage: avifincrtest <AVIF>\n");
        goto cleanup;
    }
    const char * const avifFilePath = argv[1];

    if (!readFile(avifFilePath, &encodedAvif)) {
        printf("ERROR: cannot read AVIF: %s\n", avifFilePath);
        goto cleanup;
    }

    // First test: decode the input image incrementally and compare it with a non-incrementally decoded reference.
    avifImage * reference = avifImageCreateEmpty();
    if (!reference || !decodeNonIncrementally(&encodedAvif, reference)) {
        goto cleanup;
    }
    // Cell height is hardcoded because there is no API to extract it from an encoded payload.
    if (!decodeIncrementally(&encodedAvif, reference, /*cellHeight=*/154, /*useNthImageApi=*/AVIF_FALSE)) {
        goto cleanup;
    }

    // Second test: encode a bunch of different dimension combinations and decode them incrementally and non-incrementally.
    // Chroma subsampling requires even dimensions. See ISO 23000-22 section 7.3.11.4.2.
    const uint32_t widths[] = { 1, 64, 66, reference->width };
    const uint32_t heights[] = { 1, 64, 66, reference->height };
    for (uint32_t w = 0; w < sizeof(widths) / sizeof(widths[0]); ++w) {
        for (uint32_t h = 0; h < sizeof(heights) / sizeof(heights[0]); ++h) {
            // avifEncoderAddImageInternal() only accepts grids of one unique cell, or grids where width and height are both at least 64.
            if ((widths[w] >= 64) != (heights[h] >= 64)) {
                continue;
            }

            for (avifBool createAlpha = AVIF_FALSE; createAlpha <= AVIF_TRUE; ++createAlpha) {
                for (avifBool flatCells = AVIF_FALSE; flatCells <= AVIF_TRUE; ++flatCells) {
                    for (avifBool useNthImageApi = AVIF_FALSE; useNthImageApi <= AVIF_TRUE; ++useNthImageApi) {
                        if (!encodeDecodeNonIncrementallyAndIncrementally(reference, widths[w], heights[h], createAlpha, flatCells, useNthImageApi)) {
                            goto cleanup;
                        }
                    }
                }
            }
        }
    }

    exitCode = EXIT_SUCCESS;
cleanup:
    avifRWDataFree(&encodedAvif);
    return exitCode;
}
