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

// This is a barebones y4m reader/writer for basic libavif testing. It is NOT comprehensive!

#include "y4m.h"

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

#include "avif/avif.h"
#include "avifexif.h"
#include "avifutil.h"

#define Y4M_MAX_LINE_SIZE 2048 // Arbitrary limit. Y4M headers should be much smaller than this

struct y4mFrameIterator
{
    int width;
    int height;
    int depth;
    avifBool hasAlpha;
    avifPixelFormat format;
    avifRange range;
    avifChromaSamplePosition chromaSamplePosition;
    avifAppSourceTiming sourceTiming;

    FILE * inputFile;
    const char * displayFilename;
};

// Sets frame->format, frame->depth, frame->hasAlpha, and frame->chromaSamplePosition.
static avifBool y4mColorSpaceParse(const char * formatString, struct y4mFrameIterator * frame)
{
    frame->hasAlpha = AVIF_FALSE;
    frame->chromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;

    if (!strcmp(formatString, "C420jpeg")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV420;
        frame->depth = 8;
        // Chroma sample position is center.
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C420mpeg2")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV420;
        frame->depth = 8;
        frame->chromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_VERTICAL;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C420paldv")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV420;
        frame->depth = 8;
        frame->chromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_COLOCATED;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C444p10")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV444;
        frame->depth = 10;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C422p10")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV422;
        frame->depth = 10;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C420p10")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV420;
        frame->depth = 10;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C444p12")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV444;
        frame->depth = 12;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C422p12")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV422;
        frame->depth = 12;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C420p12")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV420;
        frame->depth = 12;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C444")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV444;
        frame->depth = 8;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C444alpha")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV444;
        frame->depth = 8;
        frame->hasAlpha = AVIF_TRUE;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C422")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV422;
        frame->depth = 8;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "C420")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV420;
        frame->depth = 8;
        // Chroma sample position is center.
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "Cmono")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV400;
        frame->depth = 8;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "Cmono10")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV400;
        frame->depth = 10;
        return AVIF_TRUE;
    }
    if (!strcmp(formatString, "Cmono12")) {
        frame->format = AVIF_PIXEL_FORMAT_YUV400;
        frame->depth = 12;
        return AVIF_TRUE;
    }
    return AVIF_FALSE;
}

// Returns an unsigned integer value parsed from [start:end[.
// Returns -1 in case of failure.
static int y4mReadUnsignedInt(const char * start, const char * end)
{
    const char * p = start;
    int64_t value = 0;
    while (p < end && *p >= '0' && *p <= '9') {
        value = value * 10 + (*(p++) - '0');
        if (value > INT_MAX) {
            return -1;
        }
    }
    return (p == start) ? -1 : (int)value;
}

// Note: this modifies framerateString
static avifBool y4mFramerateParse(char * framerateString, avifAppSourceTiming * sourceTiming)
{
    if (framerateString[0] != 'F') {
        return AVIF_FALSE;
    }
    ++framerateString; // skip past 'F'

    char * colonLocation = strchr(framerateString, ':');
    if (!colonLocation) {
        return AVIF_FALSE;
    }
    *colonLocation = 0;
    ++colonLocation;

    int numerator = atoi(framerateString);
    int denominator = atoi(colonLocation);
    if ((numerator < 1) || (denominator < 1)) {
        return AVIF_FALSE;
    }

    sourceTiming->timescale = (uint64_t)numerator;
    sourceTiming->duration = (uint64_t)denominator;
    return AVIF_TRUE;
}

static avifBool getHeaderString(uint8_t * p, uint8_t * end, char * out, size_t maxChars)
{
    uint8_t * headerEnd = p;
    while ((*headerEnd != ' ') && (*headerEnd != '\n')) {
        if (headerEnd >= end) {
            return AVIF_FALSE;
        }
        ++headerEnd;
    }
    size_t formatLen = headerEnd - p;
    if (formatLen > maxChars) {
        return AVIF_FALSE;
    }

    strncpy(out, (const char *)p, formatLen);
    out[formatLen] = 0;
    return AVIF_TRUE;
}

static int y4mReadLine(FILE * inputFile, avifRWData * raw, const char * displayFilename)
{
    static const int maxBytes = Y4M_MAX_LINE_SIZE;
    int bytesRead = 0;
    uint8_t * front = raw->data;

    for (;;) {
        if (fread(front, 1, 1, inputFile) != 1) {
            fprintf(stderr, "Failed to read line: %s\n", displayFilename);
            break;
        }

        ++bytesRead;
        if (bytesRead >= maxBytes) {
            break;
        }

        if (*front == '\n') {
            return bytesRead;
        }
        ++front;
    }
    return -1;
}

// Limits each sample value to fit into avif->depth bits.
// Returns AVIF_TRUE if any sample was clamped this way.
static avifBool y4mClampSamples(avifImage * avif)
{
    if (!avifImageUsesU16(avif)) {
        assert(avif->depth == 8);
        return AVIF_FALSE;
    }
    assert(avif->depth < 16); // Otherwise it could be skipped too.

    // AV1 encoders and decoders do not care whether the samples are full range or limited range
    // for the internal computation: it is only passed as an informative tag, so ignore avif->yuvRange.
    const uint16_t maxSampleValue = (uint16_t)((1u << avif->depth) - 1u);

    avifBool samplesWereClamped = AVIF_FALSE;
    for (int plane = AVIF_CHAN_Y; plane <= AVIF_CHAN_A; ++plane) {
        uint32_t planeHeight = avifImagePlaneHeight(avif, plane); // 0 for UV if 4:0:0.
        uint32_t planeWidth = avifImagePlaneWidth(avif, plane);
        uint8_t * row = avifImagePlane(avif, plane);
        uint32_t rowBytes = avifImagePlaneRowBytes(avif, plane);
        for (uint32_t y = 0; y < planeHeight; ++y) {
            uint16_t * row16 = (uint16_t *)row;
            for (uint32_t x = 0; x < planeWidth; ++x) {
                if (row16[x] > maxSampleValue) {
                    row16[x] = maxSampleValue;
                    samplesWereClamped = AVIF_TRUE;
                }
            }
            row += rowBytes;
        }
    }
    return samplesWereClamped;
}

#define ADVANCE(BYTES)    \
    do {                  \
        p += BYTES;       \
        if (p >= end)     \
            goto cleanup; \
    } while (0)

avifBool y4mRead(const char * inputFilename,
                 uint32_t imageSizeLimit,
                 avifImage * avif,
                 avifAppSourceTiming * sourceTiming,
                 struct y4mFrameIterator ** iter)
{
    avifBool result = AVIF_FALSE;

    struct y4mFrameIterator frame;
    frame.width = -1;
    frame.height = -1;
    // Default to the color space "C420" to match the defaults of aomenc and ffmpeg.
    frame.depth = 8;
    frame.hasAlpha = AVIF_FALSE;
    frame.format = AVIF_PIXEL_FORMAT_YUV420;
    frame.range = AVIF_RANGE_LIMITED;
    frame.chromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN;
    memset(&frame.sourceTiming, 0, sizeof(avifAppSourceTiming));
    frame.inputFile = NULL;
    frame.displayFilename = inputFilename;

    avifRWData raw = AVIF_DATA_EMPTY;
    if (avifRWDataRealloc(&raw, Y4M_MAX_LINE_SIZE) != AVIF_RESULT_OK) {
        fprintf(stderr, "Out of memory\n");
        goto cleanup;
    }

    if (iter && *iter) {
        // Continue reading FRAMEs from this y4m stream
        frame = **iter;
    } else {
        // Open a fresh y4m and read its header

        if (inputFilename) {
            frame.inputFile = fopen(inputFilename, "rb");
            if (!frame.inputFile) {
                fprintf(stderr, "Cannot open file for read: %s\n", inputFilename);
                goto cleanup;
            }
        } else {
            frame.inputFile = stdin;
            frame.displayFilename = "(stdin)";
        }

        int headerBytes = y4mReadLine(frame.inputFile, &raw, frame.displayFilename);
        if (headerBytes < 0) {
            fprintf(stderr, "Y4M header too large: %s\n", frame.displayFilename);
            goto cleanup;
        }
        if (headerBytes < 10) {
            fprintf(stderr, "Y4M header too small: %s\n", frame.displayFilename);
            goto cleanup;
        }

        uint8_t * end = raw.data + headerBytes;
        uint8_t * p = raw.data;

        if (memcmp(p, "YUV4MPEG2 ", 10) != 0) {
            fprintf(stderr, "Not a y4m file: %s\n", frame.displayFilename);
            goto cleanup;
        }
        ADVANCE(10); // skip past header

        char tmpBuffer[32];

        while (p != end) {
            switch (*p) {
                case 'W': // width
                    frame.width = y4mReadUnsignedInt((const char *)p + 1, (const char *)end);
                    break;
                case 'H': // height
                    frame.height = y4mReadUnsignedInt((const char *)p + 1, (const char *)end);
                    break;
                case 'C': // color space
                    if (!getHeaderString(p, end, tmpBuffer, 31)) {
                        fprintf(stderr, "Bad y4m header: %s\n", frame.displayFilename);
                        goto cleanup;
                    }
                    if (!y4mColorSpaceParse(tmpBuffer, &frame)) {
                        fprintf(stderr, "Unsupported y4m pixel format: %s\n", frame.displayFilename);
                        goto cleanup;
                    }
                    break;
                case 'F': // framerate
                    if (!getHeaderString(p, end, tmpBuffer, 31)) {
                        fprintf(stderr, "Bad y4m header: %s\n", frame.displayFilename);
                        goto cleanup;
                    }
                    if (!y4mFramerateParse(tmpBuffer, &frame.sourceTiming)) {
                        fprintf(stderr, "Unsupported framerate: %s\n", frame.displayFilename);
                        goto cleanup;
                    }
                    break;
                case 'X':
                    if (!getHeaderString(p, end, tmpBuffer, 31)) {
                        fprintf(stderr, "Bad y4m header: %s\n", frame.displayFilename);
                        goto cleanup;
                    }
                    if (!strcmp(tmpBuffer, "XCOLORRANGE=FULL")) {
                        frame.range = AVIF_RANGE_FULL;
                    }
                    break;
                default:
                    break;
            }

            // Advance past header section
            while ((*p != '\n') && (*p != ' ')) {
                ADVANCE(1);
            }
            if (*p == '\n') {
                // Done with y4m header
                break;
            }

            ADVANCE(1);
        }

        if (*p != '\n') {
            fprintf(stderr, "Truncated y4m header (no newline): %s\n", frame.displayFilename);
            goto cleanup;
        }
    }

    int frameHeaderBytes = y4mReadLine(frame.inputFile, &raw, frame.displayFilename);
    if (frameHeaderBytes < 0) {
        fprintf(stderr, "Y4M frame header too large: %s\n", frame.displayFilename);
        goto cleanup;
    }
    if (frameHeaderBytes < 6) {
        fprintf(stderr, "Y4M frame header too small: %s\n", frame.displayFilename);
        goto cleanup;
    }
    if (memcmp(raw.data, "FRAME", 5) != 0) {
        fprintf(stderr, "Truncated y4m (no frame): %s\n", frame.displayFilename);
        goto cleanup;
    }

    if ((frame.width < 1) || (frame.height < 1) || ((frame.depth != 8) && (frame.depth != 10) && (frame.depth != 12))) {
        fprintf(stderr, "Failed to parse y4m header (not enough information): %s\n", frame.displayFilename);
        goto cleanup;
    }
    if ((uint32_t)frame.width > imageSizeLimit / (uint32_t)frame.height) {
        fprintf(stderr, "Too big y4m dimensions (%d x %d > %u px): %s\n", frame.width, frame.height, imageSizeLimit, frame.displayFilename);
        goto cleanup;
    }

    if (sourceTiming) {
        *sourceTiming = frame.sourceTiming;
    }

    avifImageFreePlanes(avif, AVIF_PLANES_ALL);
    avif->width = frame.width;
    avif->height = frame.height;
    avif->depth = frame.depth;
    avif->yuvFormat = frame.format;
    avif->yuvRange = frame.range;
    avif->yuvChromaSamplePosition = frame.chromaSamplePosition;
    avifResult allocationResult = avifImageAllocatePlanes(avif, frame.hasAlpha ? AVIF_PLANES_ALL : AVIF_PLANES_YUV);
    if (allocationResult != AVIF_RESULT_OK) {
        fprintf(stderr, "Failed to allocate the planes: %s\n", avifResultToString(allocationResult));
        goto cleanup;
    }

    for (int plane = AVIF_CHAN_Y; plane <= AVIF_CHAN_A; ++plane) {
        uint32_t planeHeight = avifImagePlaneHeight(avif, plane); // 0 for A if no alpha and 0 for UV if 4:0:0.
        uint32_t planeWidthBytes = avifImagePlaneWidth(avif, plane) << (avif->depth > 8);
        uint8_t * row = avifImagePlane(avif, plane);
        uint32_t rowBytes = avifImagePlaneRowBytes(avif, plane);
        for (uint32_t y = 0; y < planeHeight; ++y) {
            uint32_t bytesRead = (uint32_t)fread(row, 1, planeWidthBytes, frame.inputFile);
            if (bytesRead != planeWidthBytes) {
                fprintf(stderr,
                        "Failed to read y4m row (not enough data, wanted %" PRIu32 ", got %" PRIu32 "): %s\n",
                        planeWidthBytes,
                        bytesRead,
                        frame.displayFilename);
                goto cleanup;
            }
            row += rowBytes;
        }
    }

    // libavif API does not guarantee the absence of undefined behavior if samples exceed the specified avif->depth.
    // Avoid that by making sure input values are within the correct range.
    if (y4mClampSamples(avif)) {
        fprintf(stderr, "WARNING: some samples were clamped to fit into %u bits per sample\n", avif->depth);
    }

    result = AVIF_TRUE;
cleanup:
    if (iter) {
        if (*iter) {
            free(*iter);
            *iter = NULL;
        }

        if (result && frame.inputFile) {
            ungetc(fgetc(frame.inputFile), frame.inputFile); // Kick frame.inputFile to force EOF

            if (!feof(frame.inputFile)) {
                // Remember y4m state for next time
                *iter = malloc(sizeof(struct y4mFrameIterator));
                if (*iter == NULL) {
                    fprintf(stderr, "Inter-frame state memory allocation failure\n");
                    result = AVIF_FALSE;
                } else {
                    **iter = frame;
                }
            }
        }
    }

    if (inputFilename && frame.inputFile && (!iter || !(*iter))) {
        fclose(frame.inputFile);
    }
    avifRWDataFree(&raw);
    return result;
}

avifBool y4mWrite(const char * outputFilename, const avifImage * avif)
{
    avifBool hasAlpha = (avif->alphaPlane != NULL) && (avif->alphaRowBytes > 0);
    avifBool writeAlpha = AVIF_FALSE;
    char * y4mHeaderFormat = NULL;

    if (hasAlpha && ((avif->depth != 8) || (avif->yuvFormat != AVIF_PIXEL_FORMAT_YUV444))) {
        fprintf(stderr, "WARNING: writing alpha is currently only supported in 8bpc YUV444, ignoring alpha channel: %s\n", outputFilename);
    }

    if (avif->transformFlags & AVIF_TRANSFORM_CLAP) {
        avifCropRect cropRect;
        avifDiagnostics diag;
        if (avifCropRectFromCleanApertureBox(&cropRect, &avif->clap, avif->width, avif->height, &diag) &&
            (cropRect.x != 0 || cropRect.y != 0 || cropRect.width != avif->width || cropRect.height != avif->height)) {
            // TODO: https://github.com/AOMediaCodec/libavif/issues/2427 - Implement.
            fprintf(stderr,
                    "Warning: Clean Aperture values were ignored, the output image was NOT cropped to rectangle {%u,%u,%u,%u}\n",
                    cropRect.x,
                    cropRect.y,
                    cropRect.width,
                    cropRect.height);
        }
    }
    if (avifImageGetExifOrientationFromIrotImir(avif) != 1) {
        // TODO: https://github.com/AOMediaCodec/libavif/issues/2427 - Rotate the samples.
        fprintf(stderr,
                "Warning: Orientation %u was ignored, the output image was NOT rotated or mirrored\n",
                avifImageGetExifOrientationFromIrotImir(avif));
    }

    switch (avif->depth) {
        case 8:
            switch (avif->yuvFormat) {
                case AVIF_PIXEL_FORMAT_YUV444:
                    if (hasAlpha) {
                        y4mHeaderFormat = "C444alpha XYSCSS=444";
                        writeAlpha = AVIF_TRUE;
                    } else {
                        y4mHeaderFormat = "C444 XYSCSS=444";
                    }
                    break;
                case AVIF_PIXEL_FORMAT_YUV422:
                    y4mHeaderFormat = "C422 XYSCSS=422";
                    break;
                case AVIF_PIXEL_FORMAT_YUV420:
                    y4mHeaderFormat = "C420jpeg XYSCSS=420JPEG";
                    break;
                case AVIF_PIXEL_FORMAT_YUV400:
                    y4mHeaderFormat = "Cmono XYSCSS=400";
                    break;
                case AVIF_PIXEL_FORMAT_NONE:
                case AVIF_PIXEL_FORMAT_COUNT:
                    // will error later; these cases are here for warning's sake
                    break;
            }
            break;
        case 10:
            switch (avif->yuvFormat) {
                case AVIF_PIXEL_FORMAT_YUV444:
                    y4mHeaderFormat = "C444p10 XYSCSS=444P10";
                    break;
                case AVIF_PIXEL_FORMAT_YUV422:
                    y4mHeaderFormat = "C422p10 XYSCSS=422P10";
                    break;
                case AVIF_PIXEL_FORMAT_YUV420:
                    y4mHeaderFormat = "C420p10 XYSCSS=420P10";
                    break;
                case AVIF_PIXEL_FORMAT_YUV400:
                    y4mHeaderFormat = "Cmono10 XYSCSS=400";
                    break;
                case AVIF_PIXEL_FORMAT_NONE:
                case AVIF_PIXEL_FORMAT_COUNT:
                    // will error later; these cases are here for warning's sake
                    break;
            }
            break;
        case 12:
            switch (avif->yuvFormat) {
                case AVIF_PIXEL_FORMAT_YUV444:
                    y4mHeaderFormat = "C444p12 XYSCSS=444P12";
                    break;
                case AVIF_PIXEL_FORMAT_YUV422:
                    y4mHeaderFormat = "C422p12 XYSCSS=422P12";
                    break;
                case AVIF_PIXEL_FORMAT_YUV420:
                    y4mHeaderFormat = "C420p12 XYSCSS=420P12";
                    break;
                case AVIF_PIXEL_FORMAT_YUV400:
                    y4mHeaderFormat = "Cmono12 XYSCSS=400";
                    break;
                case AVIF_PIXEL_FORMAT_NONE:
                case AVIF_PIXEL_FORMAT_COUNT:
                    // will error later; these cases are here for warning's sake
                    break;
            }
            break;
        default:
            fprintf(stderr, "ERROR: y4mWrite unsupported depth: %d\n", avif->depth);
            return AVIF_FALSE;
    }

    if (y4mHeaderFormat == NULL) {
        fprintf(stderr, "ERROR: unsupported format\n");
        return AVIF_FALSE;
    }

    const char * rangeString = "XCOLORRANGE=FULL";
    if (avif->yuvRange == AVIF_RANGE_LIMITED) {
        rangeString = "XCOLORRANGE=LIMITED";
    }

    FILE * f = fopen(outputFilename, "wb");
    if (!f) {
        fprintf(stderr, "Cannot open file for write: %s\n", outputFilename);
        return AVIF_FALSE;
    }

    avifBool success = AVIF_TRUE;
    if (fprintf(f, "YUV4MPEG2 W%d H%d F25:1 Ip A0:0 %s %s\nFRAME\n", avif->width, avif->height, y4mHeaderFormat, rangeString) < 0) {
        fprintf(stderr, "Cannot write to file: %s\n", outputFilename);
        success = AVIF_FALSE;
        goto cleanup;
    }

    const int lastPlane = writeAlpha ? AVIF_CHAN_A : AVIF_CHAN_V;
    for (int plane = AVIF_CHAN_Y; plane <= lastPlane; ++plane) {
        uint32_t planeHeight = avifImagePlaneHeight(avif, plane); // 0 for UV if 4:0:0.
        uint32_t planeWidthBytes = avifImagePlaneWidth(avif, plane) << (avif->depth > 8);
        const uint8_t * row = avifImagePlane(avif, plane);
        uint32_t rowBytes = avifImagePlaneRowBytes(avif, plane);
        for (uint32_t y = 0; y < planeHeight; ++y) {
            if (fwrite(row, 1, planeWidthBytes, f) != planeWidthBytes) {
                fprintf(stderr, "Failed to write %" PRIu32 " bytes: %s\n", planeWidthBytes, outputFilename);
                success = AVIF_FALSE;
                goto cleanup;
            }
            row += rowBytes;
        }
    }

cleanup:
    fclose(f);
    if (success) {
        printf("Wrote Y4M: %s\n", outputFilename);
    }
    return success;
}
