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

#include "SkBitmap.h"
#include "SkCodec.h"
#include "SkData.h"
#include "SkImageInfo.h"
#include "SkRWBuffer.h"
#include "SkString.h"

#include "Resources.h"
#include "Test.h"

static sk_sp<SkData> make_from_resource(const char* name) {
    SkString fullPath = GetResourcePath(name);
    return SkData::MakeFromFileName(fullPath.c_str());
}

static SkImageInfo standardize_info(SkCodec* codec) {
    SkImageInfo defaultInfo = codec->getInfo();
    // Note: This drops the SkColorSpace, allowing the equality check between two
    // different codecs created from the same file to have the same SkImageInfo.
    return SkImageInfo::MakeN32Premul(defaultInfo.width(), defaultInfo.height());
}

static bool create_truth(sk_sp<SkData> data, SkBitmap* dst) {
    std::unique_ptr<SkCodec> codec(SkCodec::NewFromData(std::move(data)));
    if (!codec) {
        return false;
    }

    const SkImageInfo info = standardize_info(codec.get());
    dst->allocPixels(info);
    return SkCodec::kSuccess == codec->getPixels(info, dst->getPixels(), dst->rowBytes());
}

static void compare_bitmaps(skiatest::Reporter* r, const SkBitmap& bm1, const SkBitmap& bm2) {
    const SkImageInfo& info = bm1.info();
    if (info != bm2.info()) {
        ERRORF(r, "Bitmaps have different image infos!");
        return;
    }
    const size_t rowBytes = info.minRowBytes();
    for (int i = 0; i < info.height(); i++) {
        REPORTER_ASSERT(r, !memcmp(bm1.getAddr(0, 0), bm2.getAddr(0, 0), rowBytes));
    }
}

/*
 *  Represents a stream without all of its data.
 */
class HaltingStream : public SkStream {
public:
    HaltingStream(sk_sp<SkData> data, size_t initialLimit)
        : fTotalSize(data->size())
        , fLimit(initialLimit)
        , fStream(std::move(data))
    {}

    void addNewData(size_t extra) {
        fLimit = SkTMin(fTotalSize, fLimit + extra);
    }

    size_t read(void* buffer, size_t size) override {
        if (fStream.getPosition() + size > fLimit) {
            size = fLimit - fStream.getPosition();
        }

        return fStream.read(buffer, size);
    }

    bool isAtEnd() const override {
        return fStream.isAtEnd();
    }

    bool hasPosition() const override { return true; }
    size_t getPosition() const override { return fStream.getPosition(); }
    bool rewind() override { return fStream.rewind(); }
    bool move(long offset) override { return fStream.move(offset); }

    bool isAllDataReceived() const { return fLimit == fTotalSize; }

private:
    const size_t    fTotalSize;
    size_t          fLimit;
    SkMemoryStream  fStream;
};

static void test_partial(skiatest::Reporter* r, const char* name) {
    sk_sp<SkData> file = make_from_resource(name);
    if (!file) {
        SkDebugf("missing resource %s\n", name);
        return;
    }

    SkBitmap truth;
    if (!create_truth(file, &truth)) {
        ERRORF(r, "Failed to decode %s\n", name);
        return;
    }

    // Now decode part of the file
    HaltingStream* stream = new HaltingStream(file, file->size() / 2);

    // Note that we cheat and hold on to a pointer to stream, though it is owned by
    // partialCodec.
    std::unique_ptr<SkCodec> partialCodec(SkCodec::NewFromStream(stream));
    if (!partialCodec) {
        // Technically, this could be a small file where half the file is not
        // enough.
        ERRORF(r, "Failed to create codec for %s", name);
        return;
    }

    const SkImageInfo info = standardize_info(partialCodec.get());
    SkASSERT(info == truth.info());
    SkBitmap incremental;
    incremental.allocPixels(info);

    while (true) {
        const SkCodec::Result startResult = partialCodec->startIncrementalDecode(info,
                incremental.getPixels(), incremental.rowBytes());
        if (startResult == SkCodec::kSuccess) {
            break;
        }

        if (stream->isAllDataReceived()) {
            ERRORF(r, "Failed to start incremental decode\n");
            return;
        }

        // Append some data. The size is arbitrary, but deliberately different from
        // the buffer size used by SkPngCodec.
        stream->addNewData(1000);
    }

    while (true) {
        const SkCodec::Result result = partialCodec->incrementalDecode();

        if (result == SkCodec::kSuccess) {
            break;
        }

        REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput);

        if (stream->isAllDataReceived()) {
            ERRORF(r, "Failed to completely decode %s", name);
            return;
        }

        // Append some data. The size is arbitrary, but deliberately different from
        // the buffer size used by SkPngCodec.
        stream->addNewData(1000);
    }

    // compare to original
    compare_bitmaps(r, truth, incremental);
}

DEF_TEST(Codec_partial, r) {
    test_partial(r, "plane.png");
    test_partial(r, "plane_interlaced.png");
    test_partial(r, "yellow_rose.png");
    test_partial(r, "index8.png");
    test_partial(r, "color_wheel.png");
    test_partial(r, "mandrill_256.png");
    test_partial(r, "mandrill_32.png");
    test_partial(r, "arrow.png");
    test_partial(r, "randPixels.png");
    test_partial(r, "baby_tux.png");

    test_partial(r, "box.gif");
    test_partial(r, "randPixels.gif");
    test_partial(r, "color_wheel.gif");
}

DEF_TEST(Codec_partialAnim, r) {
    auto path = "test640x479.gif";
    sk_sp<SkData> file = make_from_resource(path);
    if (!file) {
        return;
    }

    // This stream will be owned by fullCodec, but we hang on to the pointer
    // to determine frame offsets.
    SkStream* stream = new SkMemoryStream(file);
    std::unique_ptr<SkCodec> fullCodec(SkCodec::NewFromStream(stream));
    const auto info = standardize_info(fullCodec.get());

    // frameByteCounts stores the number of bytes to decode a particular frame.
    // - [0] is the number of bytes for the header
    // - frames[i] requires frameByteCounts[i+1] bytes to decode
    std::vector<size_t> frameByteCounts;
    std::vector<SkBitmap> frames;
    size_t lastOffset = 0;
    for (size_t i = 0; true; i++) {
        frameByteCounts.push_back(stream->getPosition() - lastOffset);
        lastOffset = stream->getPosition();

        SkBitmap frame;
        frame.allocPixels(info);

        SkCodec::Options opts;
        opts.fFrameIndex = i;
        const SkCodec::Result result = fullCodec->getPixels(info, frame.getPixels(),
                frame.rowBytes(), &opts, nullptr, nullptr);

        if (result == SkCodec::kIncompleteInput) {
            frameByteCounts.push_back(stream->getPosition() - lastOffset);

            // We need to distinguish between a partial frame and no more frames.
            // getFrameInfo lets us do this, since it tells the number of frames
            // not considering whether they are complete.
            // FIXME: Should we use a different Result?
            if (fullCodec->getFrameInfo().size() > i) {
                // This is a partial frame.
                frames.push_back(frame);
            }
            break;
        }

        if (result != SkCodec::kSuccess) {
            ERRORF(r, "Failed to decode frame %i from %s", i, path);
            return;
        }

        frames.push_back(frame);
    }

    // Now decode frames partially, then completely, and compare to the original.
    HaltingStream* haltingStream = new HaltingStream(file, frameByteCounts[0]);
    std::unique_ptr<SkCodec> partialCodec(SkCodec::NewFromStream(haltingStream));
    if (!partialCodec) {
        ERRORF(r, "Failed to create a partial codec from %s with %i bytes out of %i",
               path, frameByteCounts[0], file->size());
        return;
    }

    SkASSERT(frameByteCounts.size() > frames.size());
    for (size_t i = 0; i < frames.size(); i++) {
        const size_t fullFrameBytes = frameByteCounts[i + 1];
        const size_t firstHalf = fullFrameBytes / 2;
        const size_t secondHalf = fullFrameBytes - firstHalf;

        haltingStream->addNewData(firstHalf);

        SkBitmap frame;
        frame.allocPixels(info);

        SkCodec::Options opts;
        opts.fFrameIndex = i;
        SkCodec::Result result = partialCodec->startIncrementalDecode(info,
                frame.getPixels(), frame.rowBytes(), &opts);
        if (result != SkCodec::kSuccess) {
            ERRORF(r, "Failed to start incremental decode for %s on frame %i",
                   path, i);
            return;
        }

        result = partialCodec->incrementalDecode();
        REPORTER_ASSERT(r, SkCodec::kIncompleteInput == result);

        haltingStream->addNewData(secondHalf);
        result = partialCodec->incrementalDecode();
        REPORTER_ASSERT(r, SkCodec::kSuccess == result);

        // allocPixels locked the pixels for frame, but frames[i] was copied
        // from another bitmap, and did not retain the locked status.
        SkAutoLockPixels alp(frames[i]);
        compare_bitmaps(r, frames[i], frame);
    }
}

// Test that calling getPixels when an incremental decode has been
// started (but not finished) makes the next call to incrementalDecode
// require a call to startIncrementalDecode.
static void test_interleaved(skiatest::Reporter* r, const char* name) {
    sk_sp<SkData> file = make_from_resource(name);
    if (!file) {
        return;
    }
    const size_t halfSize = file->size() / 2;
    std::unique_ptr<SkCodec> partialCodec(SkCodec::NewFromStream(
            new HaltingStream(std::move(file), halfSize)));
    if (!partialCodec) {
        ERRORF(r, "Failed to create codec for %s", name);
        return;
    }

    const SkImageInfo info = standardize_info(partialCodec.get());
    SkBitmap incremental;
    incremental.allocPixels(info);

    const SkCodec::Result startResult = partialCodec->startIncrementalDecode(info,
            incremental.getPixels(), incremental.rowBytes());
    if (startResult != SkCodec::kSuccess) {
        ERRORF(r, "Failed to start incremental decode\n");
        return;
    }

    SkCodec::Result result = partialCodec->incrementalDecode();
    REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput);

    SkBitmap full;
    full.allocPixels(info);
    result = partialCodec->getPixels(info, full.getPixels(), full.rowBytes());
    REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput);

    // Now incremental decode will fail
    result = partialCodec->incrementalDecode();
    REPORTER_ASSERT(r, result == SkCodec::kInvalidParameters);
}

DEF_TEST(Codec_rewind, r) {
    test_interleaved(r, "plane.png");
    test_interleaved(r, "plane_interlaced.png");
    test_interleaved(r, "box.gif");
}
