/*
 * Copyright 2020 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

// This program converts an image from stdin (e.g. a JPEG, PNG, etc.) to stdout
// (in the NIA/NIE format, a trivial image file format).
//
// The NIA/NIE file format specification is at:
// https://github.com/google/wuffs/blob/master/doc/spec/nie-spec.md
//
// Pass "-1" or "-first-frame-only" as a command line flag to output NIE (a
// still image) instead of NIA (an animated image). The output format (NIA or
// NIE) depends only on this flag's absence or presence, not on the stdin
// image's format.
//
// There are multiple codec implementations of any given image format. For
// example, as of May 2020, Chromium, Skia and Wuffs each have their own BMP
// decoder implementation. There is no standard "libbmp" that they all share.
// Comparing this program's output (or hashed output) to similar programs in
// other repositories can identify image inputs for which these decoders (or
// different versions of the same decoder) produce different output (pixels).
//
// An equivalent program (using the Chromium image codecs) is at:
// https://crrev.com/c/2210331
//
// An equivalent program (using the Wuffs image codecs) is at:
// https://github.com/google/wuffs/blob/master/example/convert-to-nia/convert-to-nia.c

#include <stdio.h>
#include <string.h>

#include "include/codec/SkCodec.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkData.h"
#include "src/core/SkAutoMalloc.h"

static inline void set_u32le(uint8_t* ptr, uint32_t val) {
    ptr[0] = val >> 0;
    ptr[1] = val >> 8;
    ptr[2] = val >> 16;
    ptr[3] = val >> 24;
}

static inline void set_u64le(uint8_t* ptr, uint64_t val) {
    ptr[0] = val >> 0;
    ptr[1] = val >> 8;
    ptr[2] = val >> 16;
    ptr[3] = val >> 24;
    ptr[4] = val >> 32;
    ptr[5] = val >> 40;
    ptr[6] = val >> 48;
    ptr[7] = val >> 56;
}

static void write_nix_header(uint32_t magicU32le, uint32_t width, uint32_t height) {
    uint8_t data[16];
    set_u32le(data + 0, magicU32le);
    set_u32le(data + 4, 0x346E62FF);  // 4 bytes per pixel non-premul BGRA.
    set_u32le(data + 8, width);
    set_u32le(data + 12, height);
    fwrite(data, 1, 16, stdout);
}

static bool write_nia_duration(uint64_t totalDurationMillis) {
    // Flicks are NIA's unit of time. One flick (frame-tick) is 1 / 705_600_000
    // of a second. See https://github.com/OculusVR/Flicks
    static constexpr uint64_t flicksPerMilli = 705600;
    if (totalDurationMillis > (INT64_MAX / flicksPerMilli)) {
        // Converting from millis to flicks would overflow.
        return false;
    }

    uint8_t data[8];
    set_u64le(data + 0, totalDurationMillis * flicksPerMilli);
    fwrite(data, 1, 8, stdout);
    return true;
}

static void write_nie_pixels(uint32_t width, uint32_t height, const SkBitmap& bm) {
    static constexpr size_t kBufferSize = 4096;
    uint8_t                 buf[kBufferSize];
    size_t                  n = 0;
    for (uint32_t y = 0; y < height; y++) {
        for (uint32_t x = 0; x < width; x++) {
            SkColor c = bm.getColor(x, y);
            buf[n++] = SkColorGetB(c);
            buf[n++] = SkColorGetG(c);
            buf[n++] = SkColorGetR(c);
            buf[n++] = SkColorGetA(c);
            if (n == kBufferSize) {
                fwrite(buf, 1, n, stdout);
                n = 0;
            }
        }
    }
    if (n > 0) {
        fwrite(buf, 1, n, stdout);
    }
}

static void write_nia_padding(uint32_t width, uint32_t height) {
    // 4 bytes of padding when the width and height are both odd.
    if (width & height & 1) {
        uint8_t data[4];
        set_u32le(data + 0, 0);
        fwrite(data, 1, 4, stdout);
    }
}

static void write_nia_footer(int repetitionCount, bool stillImage) {
    uint8_t data[8];
    if (stillImage || (repetitionCount == SkCodec::kRepetitionCountInfinite)) {
        set_u32le(data + 0, 0);
    } else {
        // NIA's loop count and Skia's repetition count differ by one. See
        // https://github.com/google/wuffs/blob/master/doc/spec/nie-spec.md#nii-footer
        set_u32le(data + 0, 1 + repetitionCount);
    }
    set_u32le(data + 4, 0x80000000);
    fwrite(data, 1, 8, stdout);
}

int main(int argc, char** argv) {
    bool firstFrameOnly = false;
    for (int a = 1; a < argc; a++) {
        if ((strcmp(argv[a], "-1") == 0) || (strcmp(argv[a], "-first-frame-only") == 0)) {
            firstFrameOnly = true;
            break;
        }
    }

    std::unique_ptr<SkCodec> codec(SkCodec::MakeFromData(SkData::MakeFromFILE(stdin)));
    if (!codec) {
        SkDebugf("Decode failed.\n");
        return 1;
    }
    codec->getInfo().makeColorSpace(nullptr);
    SkBitmap bm;
    bm.allocPixels(codec->getInfo());
    size_t bmByteSize = bm.computeByteSize();

    // Cache a frame that future frames may depend on.
    int          cachedFrame = SkCodec::kNoFrame;
    SkAutoMalloc cachedFramePixels;

    uint64_t  totalDurationMillis = 0;
    const int frameCount = codec->getFrameCount();
    if (frameCount == 0) {
        SkDebugf("No frames.\n");
        return 1;
    }
    // The SkCodec::getFrameInfo comment says that this vector will be empty
    // for still (not animated) images, even though frameCount should be 1.
    std::vector<SkCodec::FrameInfo> frameInfos = codec->getFrameInfo();
    bool                            stillImage = frameInfos.empty();

    for (int i = 0; i < frameCount; i++) {
        SkCodec::Options opts;
        opts.fFrameIndex = i;

        if (!stillImage) {
            int durationMillis = frameInfos[i].fDuration;
            if (durationMillis < 0) {
                SkDebugf("Negative animation duration.\n");
                return 1;
            }
            totalDurationMillis += static_cast<uint64_t>(durationMillis);
            if (totalDurationMillis > INT64_MAX) {
                SkDebugf("Unsupported animation duration.\n");
                return 1;
            }

            if ((cachedFrame != SkCodec::kNoFrame) &&
                (cachedFrame == frameInfos[i].fRequiredFrame) && cachedFramePixels.get()) {
                opts.fPriorFrame = cachedFrame;
                memcpy(bm.getPixels(), cachedFramePixels.get(), bmByteSize);
            }
        }

        if (!firstFrameOnly) {
            if (i == 0) {
                write_nix_header(0x41AFC36E,  // "nïA" magic string as a u32le.
                                 bm.width(), bm.height());
            }

            if (!write_nia_duration(totalDurationMillis)) {
                SkDebugf("Unsupported animation duration.\n");
                return 1;
            }
        }

        const SkCodec::Result result =
            codec->getPixels(codec->getInfo(), bm.getPixels(), bm.rowBytes(), &opts);
        if ((result != SkCodec::kSuccess) && (result != SkCodec::kIncompleteInput)) {
            SkDebugf("Decode frame pixels #%d failed.\n", i);
            return 1;
        }

        // If the next frame depends on this one, store it in cachedFrame. It
        // is possible that we may discard a frame that future frames depend
        // on, but the codec will simply redecode the discarded frame.
        if ((static_cast<size_t>(i + 1) < frameInfos.size()) &&
            (frameInfos[i + 1].fRequiredFrame == i)) {
            cachedFrame = i;
            memcpy(cachedFramePixels.reset(bmByteSize), bm.getPixels(), bmByteSize);
        }

        int width = bm.width();
        int height = bm.height();
        write_nix_header(0x45AFC36E,  // "nïE" magic string as a u32le.
                         width, height);
        write_nie_pixels(width, height, bm);
        if (result == SkCodec::kIncompleteInput) {
            SkDebugf("Incomplete input.\n");
            return 1;
        }
        if (firstFrameOnly) {
            return 0;
        }
        write_nia_padding(width, height);
    }
    write_nia_footer(codec->getRepetitionCount(), stillImage);
    return 0;
}
