/*
 * 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/SkColor.h"
#include "include/core/SkImageEncoder.h"
#include "include/core/SkImageGenerator.h"
#include "include/private/SkMalloc.h"
#include "src/images/SkImageEncoderPriv.h"
#include "tests/Test.h"
#include "tools/Resources.h"
#include "tools/ToolUtils.h"

#include <stdint.h>
#include <vector>

static const char* kPng          = "png";
static const char* kJpeg         = "jpeg";
static const char* kWebpLossless = "webp_lossless";
static const char* kWebpLossy    = "webp_lossy";

namespace {
static const struct {
    SkEncodedImageFormat format;
    int                  quality;
    const char*          name;
} gRecs[] = {
    { SkEncodedImageFormat::kPNG,  100, kPng},
    { SkEncodedImageFormat::kJPEG, 100, kJpeg},
    { SkEncodedImageFormat::kWEBP, 100, kWebpLossless},
    { SkEncodedImageFormat::kWEBP,  80, kWebpLossy},
};
}

static sk_sp<SkData> encode_ndk(const SkPixmap& pmap, SkEncodedImageFormat format, int quality) {
    SkDynamicMemoryWStream stream;
    return SkEncodeImageWithNDK(&stream, pmap, format, quality) ? stream.detachAsData() : nullptr;
}

DEF_TEST(NdkEncode, r) {
    for (auto ct : { kRGBA_8888_SkColorType,
                     kRGB_565_SkColorType,
                     kRGBA_F16_SkColorType }) {
        SkBitmap bm;
        bm.allocPixels(SkImageInfo::Make(10, 10, ct, kOpaque_SkAlphaType));
        bm.eraseColor(SK_ColorBLUE);
        for (const auto& rec : gRecs) {
            auto encoded = encode_ndk(bm.pixmap(), rec.format, rec.quality);
            if (!encoded) {
                ERRORF(r, "Failed to encode %s to %s\n", ToolUtils::colortype_name(ct), rec.name);
                continue;
            }
            auto gen = SkImageGenerator::MakeFromEncoded(std::move(encoded));
            if (!gen) {
                ERRORF(r, "Failed to decode from %s as %s\n", ToolUtils::colortype_name(ct),
                       rec.name);
                continue;
            }

            if (rec.name == kPng && bm.colorType() == kRGB_565_SkColorType) {
                REPORTER_ASSERT(r, gen->getInfo().colorType() == kRGB_565_SkColorType);
            } else {
                REPORTER_ASSERT(r, gen->getInfo().colorType() == kN32_SkColorType);
            }

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

            for (int x = 0; x < bm.width();  x++)
            for (int y = 0; y < bm.height(); y++) {
                SkColor orig   = bm .getColor(x, y);
                SkColor actual = bm2.getColor(x, y);

                REPORTER_ASSERT(r, SkColorGetA(orig) == SkColorGetA(actual));
                REPORTER_ASSERT(r, SkColorGetA(orig) == 0xFF);

                if (rec.name == kPng || rec.name == kWebpLossless) {
                    REPORTER_ASSERT(r, orig == actual);
                } else {
                    int diffR = std::abs((int) SkColorGetR(orig) - (int) SkColorGetR(actual));
                    int diffG = std::abs((int) SkColorGetG(orig) - (int) SkColorGetG(actual));
                    int diffB = std::abs((int) SkColorGetB(orig) - (int) SkColorGetB(actual));
                    REPORTER_ASSERT(r, diffR <= 2 && diffG <= 1 && diffB <= 1);
                }
            }
        }
    }
}

DEF_TEST(NdkEncode_unsupportedFormats, r) {
    for (auto ct : { kRGBA_8888_SkColorType,
                     kRGB_565_SkColorType,
                     kRGBA_F16_SkColorType }) {
        SkBitmap bm;
        bm.allocPixels(SkImageInfo::Make(10, 10, ct, kOpaque_SkAlphaType));
        bm.eraseColor(SK_ColorBLUE);
        for (auto format : { SkEncodedImageFormat::kBMP,
                             SkEncodedImageFormat::kGIF,
                             SkEncodedImageFormat::kICO,
                             SkEncodedImageFormat::kWBMP,
                             SkEncodedImageFormat::kPKM,
                             SkEncodedImageFormat::kKTX,
                             SkEncodedImageFormat::kASTC,
                             SkEncodedImageFormat::kDNG,
                             SkEncodedImageFormat::kHEIF }) {
            REPORTER_ASSERT(r, !encode_ndk(bm.pixmap(), format, 100));
        }
    }
}

DEF_TEST(NdkEncode_badQuality, r) {
    for (auto ct : { kRGBA_8888_SkColorType,
                     kRGB_565_SkColorType,
                     kRGBA_F16_SkColorType }) {
        SkBitmap bm;
        bm.allocPixels(SkImageInfo::Make(10, 10, ct, kOpaque_SkAlphaType));
        bm.eraseColor(SK_ColorBLUE);
        for (auto format : { SkEncodedImageFormat::kJPEG,
                             SkEncodedImageFormat::kPNG,
                             SkEncodedImageFormat::kWEBP }) {
            for (int quality : {-1, -100, 101, 200}) {
                REPORTER_ASSERT(r, !encode_ndk(bm.pixmap(), format, quality));
            }
        }
    }
}

DEF_TEST(NdkEncode_nullPixels, r) {
    for (auto info : { SkImageInfo::MakeUnknown(),
                       SkImageInfo::MakeN32Premul(10, 10),
                       SkImageInfo::MakeN32Premul(0, 0)}) {
        SkPixmap pm(info, nullptr, info.minRowBytes());
        for (const auto& rec : gRecs) {
            REPORTER_ASSERT(r, !encode_ndk(pm, rec.format, rec.quality));
        }
    }
}

DEF_TEST(NdkEncode_badInfo, r) {
    // Allocate an arbitrary amount of memory. These infos don't have a natural
    // amount to allocate, and the encoder shouldn't touch the memory anyway.
    // But this allows us to verify that the bad info fails, even when the pixel
    // pointer is not null.
    void* pixels = sk_malloc_throw(1024);
    std::vector<SkPixmap> pixmaps{ SkPixmap(SkImageInfo::MakeN32Premul(-10, 10), pixels, 1000),
                                   SkPixmap(SkImageInfo::MakeN32Premul(10, -10), pixels, 200),
                                   SkPixmap(SkImageInfo::MakeN32Premul(10,  10), pixels, 20),
                                   SkPixmap(SkImageInfo::MakeN32Premul(10,  10), pixels, 41),
                                   SkPixmap(SkImageInfo::MakeN32Premul(10,  10), pixels, 0),
                                   SkPixmap(SkImageInfo::MakeN32Premul( 0,   0), pixels, 40)};
    if (sizeof(size_t) > sizeof(uint32_t)) {
        pixmaps.emplace_back(SkImageInfo::MakeN32Premul(10, 10),  pixels,
                             static_cast<size_t>(UINT32_MAX) + 1);
    }
    for (const auto& pm : pixmaps) {
        for (const auto& rec : gRecs) {
            REPORTER_ASSERT(r, !encode_ndk(pm, rec.format, rec.quality));
        }
    }
    free(pixels);
}

DEF_TEST(NdkEncode_unsupportedColorTypes, r) {
    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,
        kGray_8_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 = SkImageInfo::Make(7, 13, ct, kOpaque_SkAlphaType, SkColorSpace::MakeSRGB());
        SkBitmap bm;
        bm.allocPixels(info);
        bm.eraseColor(SK_ColorGREEN);
        for (const auto& rec : gRecs) {
            REPORTER_ASSERT(r, !encode_ndk(bm.pixmap(), rec.format, rec.quality));
        }
        if (!SkColorTypeIsAlwaysOpaque(ct)) {
            for (auto at : { kPremul_SkAlphaType, kUnpremul_SkAlphaType}) {
                info = info.makeAlphaType(at);
                bm.allocPixels(info);
                bm.eraseARGB(0x7F, 0xFF, 0xFF, 0xFF);
            }
            for (const auto& rec : gRecs) {
                REPORTER_ASSERT(r, !encode_ndk(bm.pixmap(), rec.format, rec.quality));
            }
        }
    }
}

DEF_TEST(NdkEncode_unsupportedAlphaTypes, r) {
    for (auto ct : { kRGBA_8888_SkColorType,
                     kRGB_565_SkColorType,
                     kRGBA_F16_SkColorType }) {
        for (auto at : { kUnknown_SkAlphaType, (SkAlphaType) -1}) {
            auto info = SkImageInfo::Make(10, 10, ct, at);
            size_t rowBytes = info.minRowBytes();
            void* pixels = sk_malloc_throw(info.computeByteSize(rowBytes));
            SkPixmap pm(info, pixels, rowBytes);
            for (const auto& rec : gRecs) {
                REPORTER_ASSERT(r, !encode_ndk(pm, rec.format, rec.quality));
            }
            free(pixels);
        }
    }
}

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},
}};


static bool nearly_equal(float a, float b) {
    return fabs(a - b) < .002f;
}

static bool nearly_equal(const skcms_TransferFunction& x, const skcms_TransferFunction& y) {
    return nearly_equal(x.g, y.g)
        && nearly_equal(x.a, y.a)
        && nearly_equal(x.b, y.b)
        && nearly_equal(x.c, y.c)
        && nearly_equal(x.d, y.d)
        && nearly_equal(x.e, y.e)
        && nearly_equal(x.f, y.f);
}

static bool nearly_equal(const skcms_Matrix3x3& a, const skcms_Matrix3x3& b) {
    for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++) {
        if (!nearly_equal(a.vals[i][j], b.vals[i][j])) return false;
    }
    return true;
}

static bool nearly_equal(SkColorSpace* a, SkColorSpace* b) {
    skcms_TransferFunction fnA,     fnB;
    skcms_Matrix3x3        gamutA,  gamutB;
    return a && b && a->isNumericalTransferFn(&fnA) && a->toXYZD50(&gamutA)
                  && b->isNumericalTransferFn(&fnB) && b->toXYZD50(&gamutB)
             && nearly_equal(fnA, fnB) && nearly_equal(gamutA, gamutB);
}

DEF_TEST(NdkEncode_ColorSpace, r) {
    const struct {
        sk_sp<SkColorSpace> cs;
        const char*         name;
    } colorSpaces[] = {
        { sk_sp<SkColorSpace>(nullptr),                                                 "null"    },
        { SkColorSpace::MakeSRGB(),                                                     "srgb"    },
        { SkColorSpace::MakeSRGBLinear(),                                            "srgb-linear"},
        { SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kSRGB),      "bt709"   },
        { SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020),   "rec2020" },
        { SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,    SkNamedGamut::kDisplayP3), "p3"      },
        { SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2,   SkNamedGamut::kAdobeRGB),  "adobeRGB"},
        { SkColorSpace::MakeRGB(k2Dot6,                      kDCIP3),                   "dci-p3"  },
    };
    for (const auto& colorSpace : colorSpaces) {
        for (auto ct : { kRGBA_8888_SkColorType, kRGB_565_SkColorType, kRGBA_F16_SkColorType }) {
            SkBitmap bm;
            bm.allocPixels(SkImageInfo::Make(10, 10, ct, kOpaque_SkAlphaType, colorSpace.cs));
            bm.eraseColor(SK_ColorRED);

            for (const auto& rec : gRecs) {
                auto encoded = encode_ndk(bm.pixmap(), rec.format, rec.quality);
                REPORTER_ASSERT(r, encoded);
                auto gen = SkImageGenerator::MakeFromEncoded(std::move(encoded));
                REPORTER_ASSERT(r, gen);

                auto  expected = colorSpace.cs ? colorSpace.cs : SkColorSpace::MakeSRGB();
                auto* actual   = gen->getInfo().colorSpace();
                if (!nearly_equal(actual, expected.get())) {
                    const char* name = "unknown";
                    for (auto named : colorSpaces) {
                        if (nearly_equal(actual, named.cs.get())) {
                            name = named.name;
                            break;
                        }
                    }

                    ERRORF(r, "Mismatch: expected: %s\tactual:%s", colorSpace.name, name);
                }
            }
        }
    }
}

DEF_TEST(NdkEncode_unsupportedColorSpace, r) {
    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) {
        for (auto ct : { kRGBA_8888_SkColorType, kRGB_565_SkColorType, kRGBA_F16_SkColorType }) {
            SkBitmap bm;
            bm.allocPixels(SkImageInfo::Make(10, 10, ct, kOpaque_SkAlphaType, unsupported));
            bm.eraseColor(SK_ColorBLUE);

            for (const auto& rec : gRecs) {
                REPORTER_ASSERT(r, !encode_ndk(bm.pixmap(), rec.format, rec.quality));
            }
        }
    }
}

#endif // SK_ENABLE_NDK_IMAGES
