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

#include "avif/avif.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t * Data, size_t Size)
{
    static avifRGBFormat rgbFormats[] = { AVIF_RGB_FORMAT_RGB, AVIF_RGB_FORMAT_RGBA };
    static size_t rgbFormatsCount = sizeof(rgbFormats) / sizeof(rgbFormats[0]);

    static avifChromaUpsampling upsamplings[] = { AVIF_CHROMA_UPSAMPLING_BILINEAR, AVIF_CHROMA_UPSAMPLING_NEAREST };
    static size_t upsamplingsCount = sizeof(upsamplings) / sizeof(upsamplings[0]);

    static uint32_t rgbDepths[] = { 8, 10 };
    static size_t rgbDepthsCount = sizeof(rgbDepths) / sizeof(rgbDepths[0]);

    static uint32_t yuvDepths[] = { 8, 10 };
    static size_t yuvDepthsCount = sizeof(yuvDepths) / sizeof(yuvDepths[0]);

    avifDecoder * decoder = avifDecoderCreate();
    // ClusterFuzz passes -rss_limit_mb=2560 to avif_decode_fuzzer. Empirically setting
    // decoder->imageSizeLimit to this value allows avif_decode_fuzzer to consume no more than
    // 2560 MB of memory.
    static_assert(11 * 1024 * 10 * 1024 <= AVIF_DEFAULT_IMAGE_SIZE_LIMIT, "");
    decoder->imageSizeLimit = 11 * 1024 * 10 * 1024;
    avifResult result = avifDecoderSetIOMemory(decoder, Data, Size);
    if (result == AVIF_RESULT_OK) {
        result = avifDecoderParse(decoder);
    }
    if (result == AVIF_RESULT_OK) {
        for (int loop = 0; loop < 2; ++loop) {
            while (avifDecoderNextImage(decoder) == AVIF_RESULT_OK) {
                if ((loop != 0) || (decoder->imageIndex != 0)) {
                    // Skip the YUV<->RGB conversion tests, which are time-consuming for large
                    // images. It suffices to run these tests only for loop == 0 and only for the
                    // first image of an image sequence.
                    continue;
                }
                avifRGBImage rgb;
                avifRGBImageSetDefaults(&rgb, decoder->image);

                for (size_t rgbFormatsIndex = 0; rgbFormatsIndex < rgbFormatsCount; ++rgbFormatsIndex) {
                    for (size_t upsamplingsIndex = 0; upsamplingsIndex < upsamplingsCount; ++upsamplingsIndex) {
                        for (size_t rgbDepthsIndex = 0; rgbDepthsIndex < rgbDepthsCount; ++rgbDepthsIndex) {
                            // Convert to RGB
                            rgb.format = rgbFormats[rgbFormatsIndex];
                            rgb.depth = rgbDepths[rgbDepthsIndex];
                            rgb.chromaUpsampling = upsamplings[upsamplingsIndex];
                            avifRGBImageAllocatePixels(&rgb);
                            avifResult rgbResult = avifImageYUVToRGB(decoder->image, &rgb);
                            // Since avifImageRGBToYUV() ignores rgb.chromaUpsampling, we only need
                            // to test avifImageRGBToYUV() with a single upsamplingsIndex.
                            if ((rgbResult == AVIF_RESULT_OK) && (upsamplingsIndex == 0)) {
                                for (size_t yuvDepthsIndex = 0; yuvDepthsIndex < yuvDepthsCount; ++yuvDepthsIndex) {
                                    // ... and back to YUV
                                    avifImage * tempImage = avifImageCreate(decoder->image->width,
                                                                            decoder->image->height,
                                                                            yuvDepths[yuvDepthsIndex],
                                                                            decoder->image->yuvFormat);
                                    avifResult yuvResult = avifImageRGBToYUV(tempImage, &rgb);
                                    if (yuvResult != AVIF_RESULT_OK) {
                                    }
                                    avifImageDestroy(tempImage);
                                }
                            }

                            avifRGBImageFreePixels(&rgb);
                        }
                    }
                }
            }

            if (loop != 1) {
                result = avifDecoderReset(decoder);
                if (result == AVIF_RESULT_OK) {
                } else {
                    break;
                }
            }
        }
    }

    avifDecoderDestroy(decoder);
    return 0; // Non-zero return values are reserved for future use.
}
