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

#include "include/codec/SkCodec.h"
#include "include/codec/SkEncodedImageFormat.h"
#include "include/codec/SkJpegDecoder.h"
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkDataTable.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkStream.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/encode/SkEncoder.h"
#include "include/encode/SkJpegEncoder.h"
#include "include/encode/SkPngEncoder.h"
#include "include/encode/SkWebpEncoder.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkMalloc.h"
#include "include/private/base/SkTemplates.h"
#include "modules/skcms/src/skcms_public.h"
#include "src/core/SkColorPriv.h"
#include "src/core/SkConvertPixels.h"
#include "src/core/SkImageInfoPriv.h"
#include "tests/Test.h"
#include "tools/DecodeUtils.h"

#if defined(SK_CODEC_DECODES_PNG_WITH_LIBPNG)
#include "include/codec/SkPngDecoder.h"
#endif

#if defined(SK_CODEC_DECODES_PNG_WITH_RUST)
#include "include/codec/SkPngRustDecoder.h"
#endif

#if defined(SK_CODEC_ENCODES_PNG_WITH_RUST)
#include "include/encode/SkPngRustEncoder.h"
#endif

#include <png.h>
#include <webp/decode.h>

#include <algorithm>
#include <cstddef>
#include <initializer_list>
#include <memory>
#include <string>
#include <vector>

static sk_sp<SkData> encode(SkEncodedImageFormat format, const SkPixmap& src) {
    switch (format) {
        case SkEncodedImageFormat::kJPEG:
            return SkJpegEncoder::Encode(src, SkJpegEncoder::Options());
        case SkEncodedImageFormat::kPNG:
            return SkPngEncoder::Encode(src, SkPngEncoder::Options());
        default:
            return nullptr;
    }
}

static std::unique_ptr<SkEncoder> make(SkEncodedImageFormat format, SkWStream* dst,
                                       const SkPixmap& src) {
    switch (format) {
        case SkEncodedImageFormat::kJPEG:
            return SkJpegEncoder::Make(dst, src, SkJpegEncoder::Options());
        case SkEncodedImageFormat::kPNG:
            return SkPngEncoder::Make(dst, src, SkPngEncoder::Options());
        default:
            return nullptr;
    }
}

static void test_encode(skiatest::Reporter* r, SkEncodedImageFormat format) {
    SkBitmap bitmap;
    bool success = ToolUtils::GetResourceAsBitmap("images/mandrill_128.png", &bitmap);
    if (!success) {
        return;
    }

    SkPixmap src;
    success = bitmap.peekPixels(&src);
    REPORTER_ASSERT(r, success);
    if (!success) {
        return;
    }

    sk_sp<SkData> data0 = encode(format, src);
    REPORTER_ASSERT(r, success);

    SkDynamicMemoryWStream dst1, dst2, dst3;
    auto encoder1 = make(format, &dst1, src);
    for (int i = 0; i < src.height(); i++) {
        success = encoder1->encodeRows(1);
        REPORTER_ASSERT(r, success);
    }

    auto encoder2 = make(format, &dst2, src);
    for (int i = 0; i < src.height(); i+=3) {
        success = encoder2->encodeRows(3);
        REPORTER_ASSERT(r, success);
    }

    auto encoder3 = make(format, &dst3, src);
    success = encoder3->encodeRows(200);
    REPORTER_ASSERT(r, success);

    sk_sp<SkData> data1 = dst1.detachAsData();
    sk_sp<SkData> data2 = dst2.detachAsData();
    sk_sp<SkData> data3 = dst3.detachAsData();
    REPORTER_ASSERT(r, data0->equals(data1.get()));
    REPORTER_ASSERT(r, data0->equals(data2.get()));
    REPORTER_ASSERT(r, data0->equals(data3.get()));
}

DEF_TEST(Encode, r) {
    test_encode(r, SkEncodedImageFormat::kJPEG);
    test_encode(r, SkEncodedImageFormat::kPNG);
}

static inline bool almost_equals(SkPMColor a, SkPMColor b, int tolerance) {
    if (SkTAbs((int)SkGetPackedR32(a) - (int)SkGetPackedR32(b)) > tolerance) {
        return false;
    }

    if (SkTAbs((int)SkGetPackedG32(a) - (int)SkGetPackedG32(b)) > tolerance) {
        return false;
    }

    if (SkTAbs((int)SkGetPackedB32(a) - (int)SkGetPackedB32(b)) > tolerance) {
        return false;
    }

    if (SkTAbs((int)SkGetPackedA32(a) - (int)SkGetPackedA32(b)) > tolerance) {
        return false;
    }

    return true;
}

static inline bool almost_equals(const SkBitmap& a, const SkBitmap& b, int tolerance) {
    if (a.info() != b.info()) {
        return false;
    }

    SkASSERT(kN32_SkColorType == a.colorType());
    for (int y = 0; y < a.height(); y++) {
        for (int x = 0; x < a.width(); x++) {
            if (!almost_equals(*a.getAddr32(x, y), *b.getAddr32(x, y), tolerance)) {
                return false;
            }
        }
    }

    return true;
}

void test_png_encoding_roundtrip_from_specific_source_format(skiatest::Reporter* r,
                                                             SkColorType colorType,
                                                             SkAlphaType alphaType,
                                                             int tolerance) {
    ///////////////////////////////////////////////////
    // Decode the test image into `originalBitmapRgba8`
    // (RGBA8, as the name implies).
    SkBitmap originalBitmapRgba8;
    {
        const char* resource = (kOpaque_SkAlphaType == alphaType) ? "images/color_wheel.jpg"
                                                                  : "images/color_wheel.png";
        sk_sp<SkData> data = GetResourceAsData(resource);
        if (!data) {
            return;
        }
        std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(data);
        REPORTER_ASSERT(r, !!codec);
        if (!codec) {
            return;
        }
        SkImageInfo dstInfo = codec->getInfo().makeColorType(kRGBA_8888_SkColorType);
        originalBitmapRgba8.allocPixels(dstInfo);
        SkCodec::Result result = codec->getPixels(
                dstInfo, originalBitmapRgba8.getPixels(), originalBitmapRgba8.rowBytes());
        REPORTER_ASSERT(r,
                        result == SkCodec::kSuccess,
                        "result=%s, color=%d, alpha=%d",
                        SkCodec::ResultToString(result),
                        static_cast<int>(colorType),
                        static_cast<int>(alphaType));
        if (result != SkCodec::kSuccess) {
            return;
        }
    }

    //////////////////////////////////////////////////////////////////
    // Transform `originalBitmapRgba8` into `originalBitmap` (into the
    // `colorType` / `alphaType` that this test cares about).
    SkBitmap originalBitmap;
    {
        SkImageInfo dstInfo =
                originalBitmapRgba8.info().makeColorType(colorType).makeAlphaType(alphaType);
        originalBitmap.allocPixels(dstInfo);

        bool success = SkConvertPixels(dstInfo, originalBitmap.getPixels(), dstInfo.minRowBytes(),
                                       originalBitmapRgba8.info(), originalBitmapRgba8.getPixels(),
                                       originalBitmapRgba8.info().minRowBytes());

        REPORTER_ASSERT(r, success);
        if (!success) {
            return;
        }
    }

    /////////////////////////////////////////////
    // Encode `originalBitmap` into `encodedPng`.
    sk_sp<SkData> encodedPng;
    {
        SkPixmap src;
        bool success = originalBitmap.peekPixels(&src);
        REPORTER_ASSERT(r, success);
        if (!success) {
            return;
        }
        SkDynamicMemoryWStream buf;
#if defined(SK_CODEC_ENCODES_PNG_WITH_RUST)
        success = SkPngRustEncoder::Encode(&buf, src, SkPngRustEncoder::Options());
#else
        success = SkPngEncoder::Encode(&buf, src, SkPngEncoder::Options());
#endif
        REPORTER_ASSERT(r, success);
        if (!success) {
            return;
        }
        encodedPng = buf.detachAsData();
    }

    /////////////////////////////////////////////////////
    // Decode `encodedPng` into `roundtripBitmap` (RGBA8).
    SkBitmap roundtripBitmap;
    {
        std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(encodedPng);
        REPORTER_ASSERT(r, !!codec);
        if (!codec) {
            return;
        }
        SkImageInfo dstInfo = codec->getInfo().makeColorType(kRGBA_8888_SkColorType);
        roundtripBitmap.allocPixels(dstInfo);
        SkCodec::Result result =
                codec->getPixels(dstInfo, roundtripBitmap.getPixels(), roundtripBitmap.rowBytes());
        REPORTER_ASSERT(r,
                        result == SkCodec::kSuccess,
                        "result=%s, color=%d, alpha=%d",
                        SkCodec::ResultToString(result),
                        static_cast<int>(colorType),
                        static_cast<int>(alphaType));
        if (result != SkCodec::kSuccess) {
            return;
        }
    }

    //////////////////////////////////////////////////////////////////////////
    // Ensure that `originalBitmap` into `roundtripBitmap` are (almost) equal.
    // (We can't use the `almost_equals` overload which operates on `SkBitmap`s,
    // because our bitmaps may expectedly have differente alpha types.)
    if (originalBitmapRgba8.dimensions() != roundtripBitmap.dimensions()) {
        REPORTER_ASSERT(r, false);
        return;
    }
    for (int y = 0; y < originalBitmap.height(); y++) {
        for (int x = 0; x < originalBitmap.width(); x++) {
            SkColor originalColor = originalBitmap.getColor(x, y);
            SkColor roundtripColor = roundtripBitmap.getColor(x, y);
            SkPMColor originalPremulColor = SkPreMultiplyColor(originalColor);
            SkPMColor roundtripPremulColor = SkPreMultiplyColor(roundtripColor);
            bool almost_same = almost_equals(originalPremulColor, roundtripPremulColor, tolerance);
            REPORTER_ASSERT(r,
                            almost_same,
                            "x=%d, y=%d, original=0x%08x, roundtrip=0x%08x, color=%d, alpha=%d",
                            x,
                            y,
                            originalPremulColor,
                            roundtripPremulColor,
                            static_cast<int>(colorType),
                            static_cast<int>(alphaType));
            if (!almost_same) {
                return;
            }
        }
    }
}

DEF_TEST(Encode_png_roundtrip_for_different_source_formats, r) {
    test_png_encoding_roundtrip_from_specific_source_format(
            r, kN32_SkColorType, kOpaque_SkAlphaType, 0);
    test_png_encoding_roundtrip_from_specific_source_format(
            r, kN32_SkColorType, kUnpremul_SkAlphaType, 0);
    test_png_encoding_roundtrip_from_specific_source_format(
            r, kN32_SkColorType, kPremul_SkAlphaType, 0);
    test_png_encoding_roundtrip_from_specific_source_format(
            r, kRGB_565_SkColorType, kOpaque_SkAlphaType, 1);

    // PNG encoder used to narrow down `kRGBA_F16_SkColorType` from RGBA to RGB
    // (BE16) by skipping the alpha channel via `png_set_filler`.  But this
    // wasn't done quite right for `kRGBA_F32_SkColorType`, which motivated this
    // test.  See the code review comments of http://review.skia.org/922676 for
    // more details.
    test_png_encoding_roundtrip_from_specific_source_format(
            r, kRGBA_F16_SkColorType, kOpaque_SkAlphaType, 0);
    test_png_encoding_roundtrip_from_specific_source_format(
            r, kRGBA_F16_SkColorType, kPremul_SkAlphaType, 1);
    test_png_encoding_roundtrip_from_specific_source_format(
            r, kRGBA_F32_SkColorType, kOpaque_SkAlphaType, 0);
}

DEF_TEST(Encode_JPG, r) {
    auto image = ToolUtils::GetResourceAsImage("images/mandrill_128.png");
    if (!image) {
        return;
    }

    for (auto ct : { kRGBA_8888_SkColorType,
                     kBGRA_8888_SkColorType,
                     kRGB_565_SkColorType,
                     kARGB_4444_SkColorType,
                     kGray_8_SkColorType,
                     kRGBA_F16_SkColorType }) {
        for (auto at : { kPremul_SkAlphaType, kUnpremul_SkAlphaType, kOpaque_SkAlphaType }) {
            auto info = SkImageInfo::Make(image->width(), image->height(), ct, at);
            auto surface = SkSurfaces::Raster(info);
            auto canvas = surface->getCanvas();
            canvas->drawImage(image, 0, 0);

            SkBitmap bm;
            bm.allocPixels(info);
            if (!surface->makeImageSnapshot()->readPixels(nullptr, bm.pixmap(), 0, 0)) {
                ERRORF(r, "failed to readPixels! ct: %i\tat: %i\n", ct, at);
                continue;
            }
            for (auto alphaOption : { SkJpegEncoder::AlphaOption::kIgnore,
                                      SkJpegEncoder::AlphaOption::kBlendOnBlack }) {
                SkJpegEncoder::Options opts;
                opts.fAlphaOption = alphaOption;
                if (!SkJpegEncoder::Encode(bm.pixmap(), opts)) {
                    REPORTER_ASSERT(r, ct == kARGB_4444_SkColorType
                                    && alphaOption == SkJpegEncoder::AlphaOption::kBlendOnBlack);
                }
            }
        }
    }
}

DEF_TEST(Encode_JpegDownsample, r) {
    SkBitmap bitmap;
    bool success = ToolUtils::GetResourceAsBitmap("images/mandrill_128.png", &bitmap);
    if (!success) {
        return;
    }

    SkPixmap src;
    success = bitmap.peekPixels(&src);
    REPORTER_ASSERT(r, success);
    if (!success) {
        return;
    }

    SkJpegEncoder::Options options;
    sk_sp<SkData> data0 = SkJpegEncoder::Encode(src, options);
    REPORTER_ASSERT(r, data0);

    options.fDownsample = SkJpegEncoder::Downsample::k422;
    sk_sp<SkData> data1 = SkJpegEncoder::Encode(src, options);
    REPORTER_ASSERT(r, data1);

    options.fDownsample = SkJpegEncoder::Downsample::k444;
    sk_sp<SkData> data2 = SkJpegEncoder::Encode(src, options);
    REPORTER_ASSERT(r, data2);

    REPORTER_ASSERT(r, data0->size() < data1->size());
    REPORTER_ASSERT(r, data1->size() < data2->size());

    SkBitmap bm0, bm1, bm2;
    SkImages::DeferredFromEncodedData(data0)->asLegacyBitmap(&bm0);
    SkImages::DeferredFromEncodedData(data1)->asLegacyBitmap(&bm1);
    SkImages::DeferredFromEncodedData(data2)->asLegacyBitmap(&bm2);
    REPORTER_ASSERT(r, almost_equals(bm0, bm1, 60));
    REPORTER_ASSERT(r, almost_equals(bm1, bm2, 60));
}

static inline void pushComment(
        std::vector<std::string>& comments, const char* keyword, const char* text) {
    comments.push_back(keyword);
    comments.push_back(text);
}

static void testPngComments(const SkPixmap& src, SkPngEncoder::Options& options,
        skiatest::Reporter* r) {
    std::vector<std::string> commentStrings;
    pushComment(commentStrings, "key", "text");
    pushComment(commentStrings, "test", "something");
    pushComment(commentStrings, "have some", "spaces in both");

    std::string longKey(PNG_KEYWORD_MAX_LENGTH, 'x');
#ifdef SK_DEBUG
    commentStrings.push_back(longKey);
#else
    // We call SkDEBUGFAILF it the key is too long so we'll only test this in release mode.
    commentStrings.push_back(longKey + "x");
#endif
    commentStrings.push_back("");

    std::vector<const char*> commentPointers;
    std::vector<size_t> commentSizes;
    for(auto& str : commentStrings) {
        commentPointers.push_back(str.c_str());
        commentSizes.push_back(str.length() + 1);
    }

    options.fComments = SkDataTable::MakeCopyArrays((void const *const *)commentPointers.data(),
            commentSizes.data(), commentStrings.size());


    sk_sp<SkData> dst = SkPngEncoder::Encode(src, options);
    REPORTER_ASSERT(r, dst);
    SkSpan<const char> output{ (const char*)dst->data(), dst->size() };

    // Each chunk is of the form length (4 bytes), chunk type (tEXt), data,
    // checksum (4 bytes).  Make sure we find all of them in the encoded
    // results.
    const char kExpected1[] =
        "\x00\x00\x00\x08tEXtkey\x00text\x9e\xe7\x66\x51";
    const char kExpected2[] =
        "\x00\x00\x00\x0etEXttest\x00something\x29\xba\xef\xac";
    const char kExpected3[] =
        "\x00\x00\x00\x18tEXthave some\x00spaces in both\x8d\x69\x34\x2d";
    std::string longKeyRecord = "tEXt" + longKey; // A snippet of our long key comment
    std::string tooLongRecord = "tExt" + longKey + "x"; // A snippet whose key is too long

    auto search1 = std::search(output.begin(), output.end(),
            kExpected1, kExpected1 + sizeof(kExpected1));
    auto search2 = std::search(output.begin(), output.end(),
            kExpected2, kExpected2 + sizeof(kExpected2));
    auto search3 = std::search(output.begin(), output.end(),
            kExpected3, kExpected3 + sizeof(kExpected3));
    auto search4 = std::search(output.begin(), output.end(),
            longKeyRecord.begin(), longKeyRecord.end());
    auto search5 = std::search(output.begin(), output.end(),
            tooLongRecord.begin(), tooLongRecord.end());

    REPORTER_ASSERT(r, search1 != output.end());
    REPORTER_ASSERT(r, search2 != output.end());
    REPORTER_ASSERT(r, search3 != output.end());
    REPORTER_ASSERT(r, search4 != output.end());
    REPORTER_ASSERT(r, search5 == output.end());
    // Comments test ends
}

DEF_TEST(Encode_PngOptions, r) {
    SkBitmap bitmap;
    bool success = ToolUtils::GetResourceAsBitmap("images/mandrill_128.png", &bitmap);
    if (!success) {
        return;
    }

    SkPixmap src;
    success = bitmap.peekPixels(&src);
    REPORTER_ASSERT(r, success);
    if (!success) {
        return;
    }

    SkDynamicMemoryWStream dst0, dst1, dst2;
    SkPngEncoder::Options options;
    success = SkPngEncoder::Encode(&dst0, src, options);
    REPORTER_ASSERT(r, success);

    options.fFilterFlags = SkPngEncoder::FilterFlag::kUp;
    success = SkPngEncoder::Encode(&dst1, src, options);
    REPORTER_ASSERT(r, success);

    options.fZLibLevel = 3;
    success = SkPngEncoder::Encode(&dst2, src, options);
    REPORTER_ASSERT(r, success);

    testPngComments(src, options, r);

    sk_sp<SkData> data0 = dst0.detachAsData();
    sk_sp<SkData> data1 = dst1.detachAsData();
    sk_sp<SkData> data2 = dst2.detachAsData();
    REPORTER_ASSERT(r, data0->size() < data1->size());
    REPORTER_ASSERT(r, data1->size() < data2->size());

    SkBitmap bm0, bm1, bm2;
    SkImages::DeferredFromEncodedData(data0)->asLegacyBitmap(&bm0);
    SkImages::DeferredFromEncodedData(data1)->asLegacyBitmap(&bm1);
    SkImages::DeferredFromEncodedData(data2)->asLegacyBitmap(&bm2);
    REPORTER_ASSERT(r, almost_equals(bm0, bm1, 0));
    REPORTER_ASSERT(r, almost_equals(bm0, bm2, 0));
}

#ifndef SK_BUILD_FOR_GOOGLE3
DEF_TEST(Encode_WebpQuality, r) {
    SkBitmap bm;
    bm.allocN32Pixels(100, 100);
    bm.eraseColor(SK_ColorBLUE);

    SkWebpEncoder::Options opts;
    opts.fCompression = SkWebpEncoder::Compression::kLossless;
    sk_sp<SkData> dataLossLess = SkWebpEncoder::Encode(bm.pixmap(), opts);
    SkASSERT_RELEASE(dataLossLess);

    opts.fCompression = SkWebpEncoder::Compression::kLossy;
    opts.fQuality = 99;
    sk_sp<SkData> dataLossy = SkWebpEncoder::Encode(bm.pixmap(), opts);
    SkASSERT_RELEASE(dataLossy);

    enum Format {
        kMixed    = 0,
        kLossy    = 1,
        kLossless = 2,
    };

    auto test = [&r](const sk_sp<SkData>& data, Format expected) {
        auto printFormat = [](int f) {
            switch (f) {
                case kMixed:    return "mixed";
                case kLossy:    return "lossy";
                case kLossless: return "lossless";
                default:        return "unknown";
            }
        };

        if (!data) {
            ERRORF(r, "Failed to encode. Expected %s", printFormat(expected));
            return;
        }

        WebPBitstreamFeatures features;
        auto status = WebPGetFeatures(data->bytes(), data->size(), &features);
        if (status != VP8_STATUS_OK) {
            ERRORF(r, "Encode had an error %i. Expected %s", status, printFormat(expected));
            return;
        }

        if (expected != features.format) {
            ERRORF(r, "Expected %s encode, but got format %s", printFormat(expected),
                                                               printFormat(features.format));
        }
    };

    test(dataLossy,    kLossy);
    test(dataLossLess, kLossless);
}
#endif

DEF_TEST(Encode_WebpOptions, r) {
    SkBitmap bitmap;
    bool success = ToolUtils::GetResourceAsBitmap("images/google_chrome.ico", &bitmap);
    if (!success) {
        return;
    }

    SkPixmap src;
    success = bitmap.peekPixels(&src);
    REPORTER_ASSERT(r, success);
    if (!success) {
        return;
    }

    SkWebpEncoder::Options options;
    options.fCompression = SkWebpEncoder::Compression::kLossless;
    options.fQuality = 0.0f;
    sk_sp<SkData> data0 = SkWebpEncoder::Encode(src, options);
    REPORTER_ASSERT(r, data0);

    options.fQuality = 100.0f;
    sk_sp<SkData> data1 = SkWebpEncoder::Encode(src, options);
    REPORTER_ASSERT(r, data1);

    options.fCompression = SkWebpEncoder::Compression::kLossy;
    options.fQuality = 100.0f;
    sk_sp<SkData> data2 = SkWebpEncoder::Encode(src, options);
    REPORTER_ASSERT(r, data2);

    options.fCompression = SkWebpEncoder::Compression::kLossy;
    options.fQuality = 50.0f;
    sk_sp<SkData> data3 = SkWebpEncoder::Encode(src, options);
    REPORTER_ASSERT(r, data3);

    REPORTER_ASSERT(r, data0->size() > data1->size());
    REPORTER_ASSERT(r, data1->size() > data2->size());
    REPORTER_ASSERT(r, data2->size() > data3->size());

    SkBitmap bm0, bm1, bm2, bm3;
    SkImages::DeferredFromEncodedData(data0)->asLegacyBitmap(&bm0);
    SkImages::DeferredFromEncodedData(data1)->asLegacyBitmap(&bm1);
    SkImages::DeferredFromEncodedData(data2)->asLegacyBitmap(&bm2);
    SkImages::DeferredFromEncodedData(data3)->asLegacyBitmap(&bm3);
    REPORTER_ASSERT(r, almost_equals(bm0, bm1, 0));
    REPORTER_ASSERT(r, almost_equals(bm0, bm2, 90));
    REPORTER_ASSERT(r, almost_equals(bm2, bm3, 50));
}

DEF_TEST(Encode_WebpAnimated, r) {
    const int frameCount = 3;
    const int width = 16;
    const int height = 16;
    auto info = SkImageInfo::MakeN32Premul(width, height);
    std::vector<SkBitmap> bitmaps(frameCount);
    std::vector<SkEncoder::Frame> frames(frameCount);
    std::vector<int> durations = {50, 100, 150};
    std::vector<SkColor> colors = {SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN};

    for (int i = 0; i < frameCount; i++) {
        bitmaps[i].allocPixels(info);
        bitmaps[i].eraseColor(colors[i]);
        REPORTER_ASSERT(r, bitmaps[i].peekPixels(&frames[i].pixmap));
        frames[i].duration = durations[i];
    }

    SkDynamicMemoryWStream stream;
    SkWebpEncoder::Options options;
    options.fCompression = SkWebpEncoder::Compression::kLossless;
    options.fQuality = 100;

    REPORTER_ASSERT(r, SkWebpEncoder::EncodeAnimated(&stream, frames, options));

    auto codec = SkCodec::MakeFromData(stream.detachAsData());
    REPORTER_ASSERT(r, !!codec);

    std::vector<SkCodec::FrameInfo> frameInfos = codec->getFrameInfo();
    REPORTER_ASSERT(r, frameInfos.size() == frameCount);

    for (size_t i = 0; i < frameInfos.size(); ++i) {
        SkBitmap bitmap;
        bitmap.allocPixels(info);
        bitmap.eraseColor(0);

        SkCodec::Options codecOptions;
        codecOptions.fFrameIndex = (int)i;

        auto result = codec->getPixels(info, bitmap.getPixels(), bitmap.rowBytes(), &codecOptions);
        if (result != SkCodec::kSuccess) {
            ERRORF(r, "error in frame %zu: %s", i, SkCodec::ResultToString(result));
        }

        REPORTER_ASSERT(r, almost_equals(bitmap, bitmaps[i], 0));
        REPORTER_ASSERT(r, frameInfos[i].fDuration == durations[i]);
    }
}

DEF_TEST(Encode_WebpAnimated_FrameUnmatched, r) {
    // Create two frames with unmatched sizes and verify the encode should fail.
    SkEncoder::Frame frame1;
    SkBitmap bm1;
    bm1.allocPixels(SkImageInfo::MakeN32Premul(8, 8));
    bm1.eraseColor(SK_ColorYELLOW);
    REPORTER_ASSERT(r, bm1.peekPixels(&frame1.pixmap));
    frame1.duration = 200;

    SkEncoder::Frame frame2;
    SkBitmap bm2;
    bm2.allocPixels(SkImageInfo::MakeN32Premul(16, 16));
    bm2.eraseColor(SK_ColorYELLOW);
    REPORTER_ASSERT(r, bm2.peekPixels(&frame2.pixmap));
    frame2.duration = 200;

    SkDynamicMemoryWStream stream;
    SkWebpEncoder::Options options;
    options.fCompression = SkWebpEncoder::Compression::kLossy;
    options.fQuality = 100;
    std::vector<SkEncoder::Frame> frames = {frame1, frame2};
    bool output = SkWebpEncoder::EncodeAnimated(&stream, frames, options);
    REPORTER_ASSERT(r, !output);
}

DEF_TEST(Encode_Alpha, r) {
    // These formats have no sensible way to encode alpha images.
    for (auto format : { SkEncodedImageFormat::kJPEG,
                         SkEncodedImageFormat::kPNG,
                         SkEncodedImageFormat::kWEBP }) {
        for (int ctAsInt = kUnknown_SkColorType + 1; ctAsInt <= kLastEnum_SkColorType; ctAsInt++) {
            auto ct = static_cast<SkColorType>(ctAsInt);
            // Non-alpha-only colortypes are tested elsewhere.
            if (!SkColorTypeIsAlphaOnly(ct)) continue;
            SkBitmap bm;
            bm.allocPixels(SkImageInfo::Make(10, 10, ct, kPremul_SkAlphaType));
            sk_bzero(bm.getPixels(), bm.computeByteSize());
            sk_sp<SkData> encoded;
            if (format == SkEncodedImageFormat::kJPEG) {
                encoded = SkJpegEncoder::Encode(bm.pixmap(), {});
            } else if (format == SkEncodedImageFormat::kPNG) {
                encoded = SkPngEncoder::Encode(bm.pixmap(), {});
            } else {
                encoded = SkWebpEncoder::Encode(bm.pixmap(), {});
            }

            if ((format == SkEncodedImageFormat::kJPEG || format == SkEncodedImageFormat::kPNG) &&
                ct == kAlpha_8_SkColorType) {
                // We support encoding alpha8 to png and jpeg with our own private meaning.
                REPORTER_ASSERT(r, encoded);
                REPORTER_ASSERT(r, encoded->size() > 0);
            } else {
                REPORTER_ASSERT(r, !encoded);
            }
        }
    }
}

DEF_TEST(Encode_jpeg_blend_to_black, r) {
    SkBitmap originalBitmap;
    const char* resource = "images/rainbow-gradient.png";
    int jpeg_tolerance = 60;

    for (SkColorType colorType : {kRGBA_8888_SkColorType,
                                  kBGRA_8888_SkColorType,
                                  kRGBA_F16_SkColorType}) {
        for (SkAlphaType alphaType : {kUnpremul_SkAlphaType,
                                      kPremul_SkAlphaType}) {
            for (bool blendOnBlack : {true, false}) {
                skiatest::ReporterContext rc(r,
                                             SkStringPrintf(
                                                  "colorType=0x%x alphaType=0x%x blendOnBlack=%d",
                                                  unsigned(colorType),
                                                  unsigned(alphaType),
                                                  blendOnBlack));
                /////////////////////////////////////////////////////////////////
                // Decode the test image into `originalBitmap` into correct alpha
                // and color type.
                auto stream = GetResourceAsStream(resource, false);
                REPORTER_ASSERT(r, stream);
                if (!stream) {
                    return;
                }
                std::unique_ptr<SkCodec> codec;
                SkCodec::Result result = SkCodec::kSuccess;
#if defined(SK_CODEC_DECODES_PNG_WITH_LIBPNG)
                codec = SkPngDecoder::Decode(std::move(stream), &result);
#elif defined(SK_CODEC_DECODES_PNG_WITH_RUST)
                codec = SkPngRustDecoder::Decode(std::move(stream), &result);
#endif
                REPORTER_ASSERT(r, codec);
                if (!codec) {
                  return;
                }
                REPORTER_ASSERT(r,
                  result == SkCodec::kSuccess,
                  "result=%s", SkCodec::ResultToString(result));
                if (result != SkCodec::kSuccess) {
                    continue;
                }
                SkImageInfo dstInfo = codec->getInfo().makeAlphaType(alphaType)
                                                      .makeColorType(colorType);
                originalBitmap.allocPixels(dstInfo);
                result = codec->getPixels(
                    dstInfo, originalBitmap.getPixels(), originalBitmap.rowBytes());
                REPORTER_ASSERT(r,
                            result == SkCodec::kSuccess,
                            "result=%s", SkCodec::ResultToString(result));
                if (result != SkCodec::kSuccess) {
                    continue;
                }

                //////////////////////////////////////////////////////////////////////
                // Blend 'originalBitmap' onto a black background if needed, otherwise
                // disregard alpha and store in 'referenceBM'. This is the bitmap we
                // will be comparing to.
                SkBitmap referenceBM;
                bool success;
                if (blendOnBlack) {
                    SkImageInfo& referenceImageInfo = dstInfo;
                    referenceBM.allocPixels(referenceImageInfo);
                    referenceBM.eraseColor(SK_ColorBLACK);
                    SkCanvas blackCanvas(referenceBM);
                    blackCanvas.drawImage(originalBitmap.asImage(), 0, 0);
                } else {
                    SkImageInfo opaqueInfo = dstInfo.makeAlphaType(kOpaque_SkAlphaType)
                                                    .makeColorType(kRGB_888x_SkColorType);
                    referenceBM.allocPixels(opaqueInfo);
                    success = SkConvertPixels(opaqueInfo,
                                              referenceBM.getAddr(0,0),
                                              opaqueInfo.minRowBytes(),
                                              dstInfo,
                                              originalBitmap.getAddr(0, 0),
                                              dstInfo.minRowBytes());
                    REPORTER_ASSERT(r, success);
                    if (!success) { continue; }
                }

                ///////////////////////////////////////////////////////////////////////////
                // Encode 'originalBitmap' into JPEG. Then decode it into 'roundtripBitmap'.
                SkPixmap src;
                success = originalBitmap.peekPixels(&src);
                REPORTER_ASSERT(r, success);
                if (!success) { continue; }

                SkJpegEncoder::Options options;
                options.fAlphaOption = blendOnBlack ? SkJpegEncoder::AlphaOption::kBlendOnBlack
                                                    : SkJpegEncoder::AlphaOption::kIgnore;
                sk_sp<SkData> roundtripData = SkJpegEncoder::Encode(src, options);
                REPORTER_ASSERT(r, roundtripData);
                if (!roundtripData) { continue; }
                sk_sp<SkImage> image = SkImages::DeferredFromEncodedData(roundtripData);

                SkBitmap roundtripBitmap;
                std::unique_ptr<SkCodec> roundtripCodec = SkJpegDecoder::Decode(roundtripData, &result);
                SkImageInfo roundtripInfo = roundtripCodec->getInfo();
                roundtripBitmap.allocPixels(roundtripInfo);
                roundtripCodec->getPixels(
                    roundtripInfo, roundtripBitmap.getPixels(), roundtripBitmap.rowBytes());

                //////////////////////////////////////////////////////////////////////
                // Ensure that `referenceBM` and `roundtripBitmap` are (almost) equal.
                // We give a certain tolerance due to lossyness.
                if (referenceBM.dimensions() != roundtripBitmap.dimensions()) {
                    REPORTER_ASSERT(r, false);
                    continue;
                }
                bool shouldContinue = false;
                for (int y = 0; y < referenceBM.height(); y++) {
                    if (shouldContinue) { break; }
                    for (int x = 0; x < referenceBM.width(); x++) {
                        SkColor originalColor = referenceBM.getColor(x, y);
                        SkColor roundtripColor = roundtripBitmap.getColor(x, y);
                        SkPMColor originalPremulColor = SkPreMultiplyColor(originalColor);
                        SkPMColor roundtripPremulColor = SkPreMultiplyColor(roundtripColor);
                        bool almost_same = almost_equals(originalPremulColor,
                                                         roundtripPremulColor,
                                                         jpeg_tolerance);
                        REPORTER_ASSERT(r,
                                        almost_same,
                                        "x=%d, y=%d, original=0x%08x, roundtrip=0x%08x, color=%d, alpha=%d",
                                        x,
                                        y,
                                        originalPremulColor,
                                        roundtripPremulColor,
                                        static_cast<int>(colorType),
                                        static_cast<int>(alphaType));
                        if (!almost_same) {
                            shouldContinue = true;
                            break;
                        }
                    }
                }
            }
        }
    }
}
