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

#include "include/core/SkTypes.h"
#ifdef SK_ENABLE_NDK_IMAGES
#include "include/core/SkColorSpace.h"
#include "include/encode/SkJpegEncoder.h"
#include "include/encode/SkPngEncoder.h"
#include "include/encode/SkWebpEncoder.h"
#include "include/ports/SkImageGeneratorNDK.h"

#include "tests/Test.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"

#include <vector>

static std::unique_ptr<SkImageGenerator> make_generator(const char* path, skiatest::Reporter* r) {
    auto data = GetResourceAsData(path);
    if (data) {
        auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(std::move(data));
        if (gen) {
            return gen;
        }
        ERRORF(r, "Failed to create NDK generator from %s\n", path);
    } else {
        // Silently fail so developers can skip using --resources
    }
    return nullptr;
}

DEF_TEST(NdkDecode, r) {
    static const struct {
        const char* fPath;
        SkISize     fSize;
    } recs[] = {
        {"images/CMYK.jpg", {642, 516}},
        {"images/arrow.png", {187, 312}},
        {"images/baby_tux.webp", {386, 395}},
        {"images/color_wheel.gif", {128, 128}},
        {"images/rle.bmp", {320, 240}},
        {"images/color_wheel.ico", {128, 128}},
        {"images/google_chrome.ico", {256, 256}},
        {"images/mandrill.wbmp", {512, 512}},
    };
    for (auto& rec : recs) {
        auto gen = make_generator(rec.fPath, r);
        if (!gen) continue;

        const auto& info = gen->getInfo();
        REPORTER_ASSERT(r, info.dimensions() == rec.fSize);

        SkBitmap bm;
        bm.allocPixels(info);
        REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));

        REPORTER_ASSERT(r, info.alphaType() != kUnpremul_SkAlphaType);
        auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType);
        bm.allocPixels(unpremulInfo);
        REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
    }
}

DEF_TEST(NdkDecode_nullData, r) {
    auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(nullptr);
    REPORTER_ASSERT(r, !gen);
}

static constexpr skcms_TransferFunction k2Dot6 = {2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};

static constexpr skcms_Matrix3x3 kDCIP3 = {{
        {0.486143, 0.323835, 0.154234},
        {0.226676, 0.710327, 0.0629966},
        {0.000800549, 0.0432385, 0.78275},
}};

DEF_TEST(NdkDecode_reportedColorSpace, r) {
    for (sk_sp<SkColorSpace> cs : {
        sk_sp<SkColorSpace>(nullptr),
        SkColorSpace::MakeSRGB(),
        SkColorSpace::MakeSRGBLinear(),
        SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kSRGB),
        SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020),
        SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3),
        SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB),
        SkColorSpace::MakeRGB(k2Dot6, kDCIP3),
    }) {
        SkBitmap bm;
        bm.allocPixels(SkImageInfo::Make(10, 10, kRGBA_F16_SkColorType, kOpaque_SkAlphaType, cs));
        bm.eraseColor(SK_ColorBLUE);

        for (auto format : { SkEncodedImageFormat::kPNG,
                             SkEncodedImageFormat::kJPEG,
                             SkEncodedImageFormat::kWEBP }) {
            SkDynamicMemoryWStream stream;
            if (format == SkEncodedImageFormat::kJPEG) {
                SkJpegEncoder::Options opts;
                opts.fQuality = 80;
                REPORTER_ASSERT(r, SkJpegEncoder::Encode(&stream, bm.pixmap(), opts));
            } else if (format == SkEncodedImageFormat::kPNG) {
                REPORTER_ASSERT(r, SkPngEncoder::Encode(&stream, bm.pixmap(), {}));
            } else {
                SkWebpEncoder::Options opts;
                opts.fQuality = 80;
                REPORTER_ASSERT(r, SkWebpEncoder::Encode(&stream, bm.pixmap(), opts));
            }

            auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(stream.detachAsData());
            if (!gen) {
                ERRORF(r, "Failed to encode!");
                return;
            }

            if (!cs) cs = SkColorSpace::MakeSRGB();
            REPORTER_ASSERT(r, SkColorSpace::Equals(gen->getInfo().colorSpace(), cs.get()));
        }
    }
}

DEF_TEST(NdkDecode_ColorSpace, r) {
    for (const char* path: {
        "images/CMYK.jpg",
        "images/arrow.png",
        "images/baby_tux.webp",
        "images/color_wheel.gif",
        "images/rle.bmp",
        "images/color_wheel.ico",
        "images/google_chrome.ico",
        "images/mandrill.wbmp",
    }) {
        auto gen = make_generator(path, r);
        if (!gen) continue;

        for (sk_sp<SkColorSpace> cs : {
            sk_sp<SkColorSpace>(nullptr),
            SkColorSpace::MakeSRGB(),
            SkColorSpace::MakeSRGBLinear(),
            SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kSRGB),
            SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020),
            SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3),
            SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB),
            SkColorSpace::MakeRGB(k2Dot6, kDCIP3),
        }) {
            auto info = gen->getInfo().makeColorSpace(cs);

            SkBitmap bm;
            bm.allocPixels(info);
            REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
        }

        std::vector<sk_sp<SkColorSpace>> unsupportedCs;
        for (auto gamut : { SkNamedGamut::kSRGB, SkNamedGamut::kAdobeRGB, SkNamedGamut::kDisplayP3,
                            SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) {
            unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kPQ, gamut));
            unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kHLG, gamut));
            unsupportedCs.push_back(SkColorSpace::MakeRGB(k2Dot6, gamut));
        }

        for (auto gamut : { SkNamedGamut::kSRGB, SkNamedGamut::kDisplayP3,
                            SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) {
            unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, gamut));
        }

        for (auto gamut : { SkNamedGamut::kAdobeRGB, SkNamedGamut::kDisplayP3,
                            SkNamedGamut::kXYZ }) {
            unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, gamut));
        }

        for (auto gamut : { SkNamedGamut::kAdobeRGB, SkNamedGamut::kDisplayP3,
                            SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) {
            unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, gamut));
        }

        for (auto gamut : { SkNamedGamut::kAdobeRGB,
                            SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) {
            unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut));
        }

        for (auto fn : { SkNamedTransferFn::kSRGB, SkNamedTransferFn::k2Dot2,
                         SkNamedTransferFn::kLinear, SkNamedTransferFn::kRec2020 }) {
            unsupportedCs.push_back(SkColorSpace::MakeRGB(fn, kDCIP3));
        }

        for (auto unsupported : unsupportedCs) {
            auto info = gen->getInfo().makeColorSpace(unsupported);

            SkBitmap bm;
            bm.allocPixels(info);
            REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap()));
        }
    }
}

DEF_TEST(NdkDecode_reuseNoColorSpace, r) {
    static const struct {
        const char*         fPath;
        sk_sp<SkColorSpace> fCorrectedColorSpace;
        bool                fIsOpaque;
    } recs[] = {
        // AImageDecoder defaults to ADATASPACE_UNKNOWN for this image.
        {"images/wide_gamut_yellow_224_224_64.jpeg", SkColorSpace::MakeSRGB(), true},
        // This image is SRGB, so convert to a different color space.
        {"images/example_1.png", SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2,
                                                       SkNamedGamut::kAdobeRGB), false},
    };
    for (auto& rec : recs) {
        auto gen = make_generator(rec.fPath, r);
        if (!gen) continue;

        REPORTER_ASSERT(r, gen->getInfo().colorSpace()->isSRGB());
        REPORTER_ASSERT(r, gen->getInfo().isOpaque() == rec.fIsOpaque);

        auto noColorCorrection = gen->getInfo().makeColorSpace(nullptr);
        if (rec.fIsOpaque) {
            // Use something other than the default color type to verify that the modified color
            // type is used even when the color space is reset.
            noColorCorrection = noColorCorrection.makeColorType(kRGB_565_SkColorType);
        }

        SkBitmap orig;
        orig.allocPixels(noColorCorrection);
        REPORTER_ASSERT(r, gen->getPixels(orig.pixmap()));

        SkBitmap corrected;
        corrected.allocPixels(noColorCorrection.makeColorSpace(rec.fCorrectedColorSpace));
        REPORTER_ASSERT(r, gen->getPixels(corrected.pixmap()));

        REPORTER_ASSERT(r, !ToolUtils::equal_pixels(orig, corrected));

        SkBitmap reuse;
        reuse.allocPixels(noColorCorrection);
        REPORTER_ASSERT(r, gen->getPixels(reuse.pixmap()));

        REPORTER_ASSERT(r, ToolUtils::equal_pixels(orig, reuse));
    }
}

// The NDK supports scaling up to arbitrary dimensions. Skia forces clients to do this in a
// separate step, so the client is in charge of how to do the upscale.
DEF_TEST(NdkDecode_noUpscale, r) {
    for (const char* path: {
        "images/CMYK.jpg",
        "images/arrow.png",
        "images/baby_tux.webp",
        "images/color_wheel.gif",
        "images/rle.bmp",
        "images/color_wheel.ico",
        "images/google_chrome.ico",
        "images/mandrill.wbmp",
    }) {
        auto gen = make_generator(path, r);
        if (!gen) continue;

        const auto actualDimensions = gen->getInfo().dimensions();
        const int width = actualDimensions.width();
        const int height = actualDimensions.height();
        for (SkISize dims : {
            SkISize{width*2, height*2},
            SkISize{width + 1, height + 1},
        }) {
            auto info = gen->getInfo().makeDimensions(dims);
            SkBitmap bm;
            bm.allocPixels(info);
            REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap()));
        }
    }
}

// libwebp supports downscaling to an arbitrary scale factor, and this is supported by the NDK.
DEF_TEST(NdkDecode_webpArbitraryDownscale, r) {
    for (const char* path: {
        "images/baby_tux.webp",
        "images/yellow_rose.webp",
        "images/webp-color-profile-lossless.webp",
    }) {
        auto gen = make_generator(path, r);
        if (!gen) continue;

        const auto actualDimensions = gen->getInfo().dimensions();
        const int width = actualDimensions.width();
        const int height = actualDimensions.height();
        for (SkISize dims : {
            SkISize{width/2, height/2},
            SkISize{width/4, height/4},
            SkISize{width/7, height/7},
            SkISize{width - 1, height - 1},
            SkISize{1, 1},
            SkISize{5, 20}
        }) {
            auto info = gen->getInfo().makeDimensions(dims);
            SkBitmap bm;
            bm.allocPixels(info);
            REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));

            REPORTER_ASSERT(r, info.alphaType() != kUnpremul_SkAlphaType);
            auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType);
            bm.allocPixels(unpremulInfo);
            REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
        }
    }
}

// libjpeg-turbo supports downscaling to some scale factors.
DEF_TEST(NdkDecode_jpegDownscale, r) {
    static const struct {
        const char* fPath;
        SkISize     fSupportedSizes[4];
    } recs[] = {
        {"images/CMYK.jpg", {{642,516},{321,258},{161,129},{81,65}}},
        {"images/dog.jpg", {{180,180},{90,90},{45,45},{23,23}}},
        {"images/grayscale.jpg", {{128,128},{64,64},{32,32},{16,16}}},
        {"images/brickwork-texture.jpg", {{512,512},{256,256},{128,128},{64,64}}},
        {"images/mandrill_h2v1.jpg", {{512,512},{256,256},{128,128},{64,64}}},
        {"images/ducky.jpg", {{489,537},{245,269},{123,135},{62,68}}},
    };
    for (auto& rec : recs) {
        auto gen = make_generator(rec.fPath, r);
        if (!gen) continue;

        for (SkISize dims : rec.fSupportedSizes) {
            auto info = gen->getInfo().makeDimensions(dims);
            SkBitmap bm;
            bm.allocPixels(info);
            if (!gen->getPixels(bm.pixmap())) {
                ERRORF(r, "failed to decode %s to {%i,%i}\n", rec.fPath, dims.width(),
                          dims.height());
            }

            REPORTER_ASSERT(r, info.alphaType() != kUnpremul_SkAlphaType);
            auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType);
            bm.allocPixels(unpremulInfo);
            REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
        }
    }
}

DEF_TEST(NdkDecode_reuseJpeg, r) {
    auto gen = make_generator("images/CMYK.jpg", r);
    if (!gen) return;

    SkImageInfo info = gen->getInfo();
    SkBitmap orig;
    orig.allocPixels(info);
    REPORTER_ASSERT(r, gen->getPixels(orig.pixmap()));

    info = info.makeWH(321, 258);
    SkBitmap downscaled;
    downscaled.allocPixels(info);
    REPORTER_ASSERT(r, gen->getPixels(downscaled.pixmap()));

    SkBitmap reuse;
    reuse.allocPixels(gen->getInfo());
    REPORTER_ASSERT(r, gen->getPixels(reuse.pixmap()));

    REPORTER_ASSERT(r, ToolUtils::equal_pixels(orig, reuse));
}

// The NDK supports scaling down to arbitrary dimensions. Skia forces clients to do this in a
// separate step, so the client is in charge of how to do the downscale.
DEF_TEST(NdkDecode_noDownscale, r) {
    for (const char* path: {
        "images/arrow.png",
        "images/color_wheel.gif",
        "images/rle.bmp",
        "images/color_wheel.ico",
        "images/google_chrome.ico",
        "images/mandrill.wbmp",
    }) {
        auto gen = make_generator(path, r);
        if (!gen) continue;

        const auto actualDimensions = gen->getInfo().dimensions();
        const int width = actualDimensions.width();
        const int height = actualDimensions.height();
        for (SkISize dims : {
            SkISize{width/2, height/2},
            SkISize{width/3, height/3},
            SkISize{width/4, height/4},
            SkISize{width/8, height/8},
            SkISize{width - 1, height - 1},
        }) {
            auto info = gen->getInfo().makeDimensions(dims);
            SkBitmap bm;
            bm.allocPixels(info);
            REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap()));
        }
    }
}

DEF_TEST(NdkDecode_Gray8, r) {
    static const struct {
        const char* fPath;
        bool        fGrayscale;
    } recs[] = {
        {"images/CMYK.jpg", false},
        {"images/arrow.png", false},
        {"images/baby_tux.webp", false},
        {"images/color_wheel.gif", false},
        {"images/rle.bmp", false},
        {"images/color_wheel.ico", false},
        {"images/google_chrome.ico", false},
        {"images/mandrill.wbmp", true},
        {"images/grayscale.jpg", true},
        {"images/grayscale.png", true},
    };
    for (auto& rec : recs) {
        auto gen = make_generator(rec.fPath, r);
        if (!gen) continue;

        SkImageInfo info = gen->getInfo();
        if (rec.fGrayscale) {
            REPORTER_ASSERT(r, info.colorType() == kGray_8_SkColorType);
            REPORTER_ASSERT(r, info.alphaType() == kOpaque_SkAlphaType);
        } else {
            info = info.makeColorType(kGray_8_SkColorType);
        }
        SkBitmap bm;
        bm.allocPixels(info);
        bool success = gen->getPixels(bm.pixmap());
        if (success != rec.fGrayscale) {
            ERRORF(r, "Expected decoding %s to Gray8 to %s. Actual: %s\n", rec.fPath,
                      (rec.fGrayscale ? "succeed" : "fail"), (success ? "succeed" : "fail"));
        }
    }
}

DEF_TEST(NdkDecode_Opaque_and_565, r) {
    for (const char* path: {
        "images/CMYK.jpg",
        "images/dog.jpg",
        "images/ducky.jpg",
        "images/arrow.png",
        "images/example_1.png",
        "images/explosion_sprites.png",
        "images/lut_identity.png",
        "images/grayscale.png",
        "images/baby_tux.webp",
        "images/yellow_rose.webp",
        "images/webp-color-profile-lossless.webp",
        "images/colorTables.gif",
        "images/color_wheel.gif",
        "images/flightAnim.gif",
        "images/randPixels.gif",
        "images/rle.bmp",
        "images/color_wheel.ico",
        "images/google_chrome.ico",
        "images/mandrill.wbmp",
    }) {
        auto gen = make_generator(path, r);
        if (!gen) continue;

        auto info = gen->getInfo().makeAlphaType(kOpaque_SkAlphaType);
        SkBitmap bm;
        bm.allocPixels(info);
        bool success = gen->getPixels(bm.pixmap());
        REPORTER_ASSERT(r, success == gen->getInfo().isOpaque());

        info = info.makeColorType(kRGB_565_SkColorType);
        bm.allocPixels(info);
        success = gen->getPixels(bm.pixmap());
        REPORTER_ASSERT(r, success == gen->getInfo().isOpaque());
    }
}

DEF_TEST(NdkDecode_AlwaysSupportedColorTypes, r) {
    for (const char* path: {
        "images/CMYK.jpg",
        "images/dog.jpg",
        "images/ducky.jpg",
        "images/arrow.png",
        "images/example_1.png",
        "images/explosion_sprites.png",
        "images/lut_identity.png",
        "images/grayscale.png",
        "images/baby_tux.webp",
        "images/yellow_rose.webp",
        "images/webp-color-profile-lossless.webp",
        "images/colorTables.gif",
        "images/color_wheel.gif",
        "images/flightAnim.gif",
        "images/randPixels.gif",
        "images/rle.bmp",
        "images/color_wheel.ico",
        "images/google_chrome.ico",
        "images/mandrill.wbmp",
    }) {
        auto gen = make_generator(path, r);
        if (!gen) continue;

        auto info = gen->getInfo().makeColorType(kRGBA_F16_SkColorType);
        SkBitmap bm;
        bm.allocPixels(info);
        REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));

        // This also tests that we can reuse the same generator for a different
        // color type.
        info = info.makeColorType(kRGBA_8888_SkColorType);
        bm.allocPixels(info);
        REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
    }
}

DEF_TEST(NdkDecode_UnsupportedColorTypes, r) {
    for (const char* path: {
        "images/CMYK.jpg",
        "images/dog.jpg",
        "images/ducky.jpg",
        "images/arrow.png",
        "images/example_1.png",
        "images/explosion_sprites.png",
        "images/lut_identity.png",
        "images/grayscale.png",
        "images/baby_tux.webp",
        "images/yellow_rose.webp",
        "images/webp-color-profile-lossless.webp",
        "images/colorTables.gif",
        "images/color_wheel.gif",
        "images/flightAnim.gif",
        "images/randPixels.gif",
        "images/rle.bmp",
        "images/color_wheel.ico",
        "images/google_chrome.ico",
        "images/mandrill.wbmp",
    }) {
        auto gen = make_generator(path, r);
        if (!gen) continue;

        for (SkColorType ct : {
            kUnknown_SkColorType,
            kAlpha_8_SkColorType,
            kARGB_4444_SkColorType,
            kRGB_888x_SkColorType,
            kBGRA_8888_SkColorType,
            kRGBA_1010102_SkColorType,
            kBGRA_1010102_SkColorType,
            kRGB_101010x_SkColorType,
            kBGR_101010x_SkColorType,
            kRGBA_F16Norm_SkColorType,
            kRGBA_F32_SkColorType,
            kR8G8_unorm_SkColorType,
            kA16_float_SkColorType,
            kR16G16_float_SkColorType,
            kA16_unorm_SkColorType,
            kR16G16_unorm_SkColorType,
            kR16G16B16A16_unorm_SkColorType,
        }) {
            auto info = gen->getInfo().makeColorType(ct);
            SkBitmap bm;
            bm.allocPixels(info);
            if (gen->getPixels(bm.pixmap())) {
                ERRORF(r, "Expected decoding %s to %i to fail!", path, ct);
            }
        }
    }
}
#endif // SK_ENABLE_NDK_IMAGES
