/*
 * 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_DECODING
#include "include/ports/SkImageGeneratorNDK.h"
#include "tests/Test.h"
#include "tools/Resources.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 }) {
            auto data = SkEncodeBitmap(bm, format, 80);
            auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(std::move(data));
            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()));

        bool same = true;
        for (int y = 0; y < gen->getInfo().height(); y++) {
            auto* origLine      =      orig.getAddr(0, y);
            auto* correctedLine = corrected.getAddr(0, y);
            if (memcmp(origLine, correctedLine, orig.rowBytes()) != 0) {
                same = false;
                break;
            }
        }
        REPORTER_ASSERT(r, !same);

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

        for (int y = 0; y < gen->getInfo().height(); y++) {
            auto* origLine  =  orig.getAddr(0, y);
            auto* reuseLine = reuse.getAddr(0, y);
            if (memcmp(origLine, reuseLine, orig.rowBytes()) != 0) {
                ERRORF(r, "Bitmaps do not match!\n");
                break;
            }
        }
    }
}

// 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()));

    for (int y = 0; y < gen->getInfo().height(); y++) {
        auto* origLine  =  orig.getAddr32(0, y);
        auto* reuseLine = reuse.getAddr32(0, y);
        if (memcmp(origLine, reuseLine, orig.rowBytes()) != 0) {
            ERRORF(r, "Bitmaps do not match!\n");
            break;
        }
    }
}

// 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_DECODING
