/*
 * 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 "SkColorPriv.h"
#include "SkColorSpace.h"
#include "SkColorSpaceXform.h"
#include "SkColorSpaceXformPriv.h"
#include "SkColorSpaceXform_Base.h"
#include "SkColorSpace_A2B.h"
#include "SkColorSpace_XYZ.h"
#include "SkData.h"
#include "SkGammas.h"
#include "SkImageInfo.h"
#include "SkMalloc.h"
#include "SkMatrix.h"
#include "SkMatrix44.h"
#include "SkRefCnt.h"
#include "SkTemplates.h"
#include "SkTypes.h"
#include "Test.h"

#include <memory>
#include <utility>
#include <vector>

static constexpr int kChannels = 3;

class ColorSpaceXformTest {
public:
    static std::unique_ptr<SkColorSpaceXform> CreateIdentityXform(const sk_sp<SkGammas>& gammas) {
        // Logically we can pass any matrix here.  For simplicty, pass I(), i.e. D50 XYZ gamut.
        sk_sp<SkColorSpace> space(new SkColorSpace_XYZ(
                kNonStandard_SkGammaNamed, gammas, SkMatrix::I(), nullptr));

        // Use special testing entry point, so we don't skip the xform, even though src == dst.
        return SlowIdentityXform(static_cast<SkColorSpace_XYZ*>(space.get()));
    }

    static std::unique_ptr<SkColorSpaceXform> CreateIdentityXform_A2B(
            SkGammaNamed gammaNamed, const sk_sp<SkGammas>& gammas) {
        std::vector<SkColorSpace_A2B::Element> srcElements;
        // sRGB
        const float values[16] = {
            0.4358f, 0.3853f, 0.1430f, 0.0f,
            0.2224f, 0.7170f, 0.0606f, 0.0f,
            0.0139f, 0.0971f, 0.7139f, 0.0f,
            0.0000f, 0.0000f, 0.0000f, 1.0f
        };
        SkMatrix44 arbitraryMatrix{SkMatrix44::kUninitialized_Constructor};
        arbitraryMatrix.setRowMajorf(values);
        if (kNonStandard_SkGammaNamed == gammaNamed) {
            SkASSERT(gammas);
            srcElements.push_back(SkColorSpace_A2B::Element(gammas));
        } else {
            srcElements.push_back(SkColorSpace_A2B::Element(gammaNamed, kChannels));
        }
        srcElements.push_back(SkColorSpace_A2B::Element(arbitraryMatrix));
        auto srcSpace =
                ColorSpaceXformTest::CreateA2BSpace(SkColorSpace_A2B::PCS::kXYZ,
                                                    std::move(srcElements));
        sk_sp<SkColorSpace> dstSpace(new SkColorSpace_XYZ(gammaNamed, gammas, arbitraryMatrix,
                                                          nullptr));

        return SkColorSpaceXform::New(static_cast<SkColorSpace_A2B*>(srcSpace.get()),
                                      static_cast<SkColorSpace_XYZ*>(dstSpace.get()));
    }

    static sk_sp<SkColorSpace> CreateA2BSpace(SkColorSpace_A2B::PCS pcs,
                                              std::vector<SkColorSpace_A2B::Element> elements) {
        return sk_sp<SkColorSpace>(new SkColorSpace_A2B(SkColorSpace::kRGB_Type,
                                                        std::move(elements),
                                                        pcs, nullptr));
    }
};

static bool almost_equal(int x, int y, int tol=1) {
    return SkTAbs(x-y) <= tol;
}

static void test_identity_xform(skiatest::Reporter* r, const sk_sp<SkGammas>& gammas,
                                bool repeat) {
    // Arbitrary set of 10 pixels
    constexpr int width = 10;
    constexpr uint32_t srcPixels[width] = {
            0xFFABCDEF, 0xFF146829, 0xFF382759, 0xFF184968, 0xFFDE8271,
            0xFF32AB52, 0xFF0383BC, 0xFF000102, 0xFFFFFFFF, 0xFFDDEEFF, };
    uint32_t dstPixels[width];

    // Create and perform an identity xform.
    std::unique_ptr<SkColorSpaceXform> xform = ColorSpaceXformTest::CreateIdentityXform(gammas);
    bool result = xform->apply(select_xform_format(kN32_SkColorType), dstPixels,
                               SkColorSpaceXform::kBGRA_8888_ColorFormat, srcPixels, width,
                               kOpaque_SkAlphaType);
    REPORTER_ASSERT(r, result);

    // Since the src->dst matrix is the identity, and the gamma curves match,
    // the pixels should be unchanged.
    for (int i = 0; i < width; i++) {
        REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >>  0) & 0xFF),
                                        SkGetPackedB32(dstPixels[i])));
        REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >>  8) & 0xFF),
                                        SkGetPackedG32(dstPixels[i])));
        REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 16) & 0xFF),
                                        SkGetPackedR32(dstPixels[i])));
        REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 24) & 0xFF),
                                        SkGetPackedA32(dstPixels[i])));
    }

    if (repeat) {
        // We should cache part of the transform after the run.  So it is interesting
        // to make sure it still runs correctly the second time.
        test_identity_xform(r, gammas, false);
    }
}

static void test_identity_xform_A2B(skiatest::Reporter* r, SkGammaNamed gammaNamed,
                                    const sk_sp<SkGammas>& gammas, int tol=1) {
#if defined(SK_USE_SKCMS)
    (void)r;
    (void)gammaNamed;
    (void)gammas;
    (void)tol;
#else
    // Arbitrary set of 10 pixels
    constexpr int width = 10;
    constexpr uint32_t srcPixels[width] = {
            0xFFABCDEF, 0xFF146829, 0xFF382759, 0xFF184968, 0xFFDE8271,
            0xFF32AB52, 0xFF0383BC, 0xFF000102, 0xFFFFFFFF, 0xFFDDEEFF, };
    uint32_t dstPixels[width];

    // Create and perform an identity xform.
    auto xform = ColorSpaceXformTest::CreateIdentityXform_A2B(gammaNamed, gammas);
    bool result = xform->apply(select_xform_format(kN32_SkColorType), dstPixels,
                               SkColorSpaceXform::kBGRA_8888_ColorFormat, srcPixels, width,
                               kOpaque_SkAlphaType);
    REPORTER_ASSERT(r, result);

    // Since the src->dst matrix is the identity, and the gamma curves match,
    // the pixels should be ~unchanged.
    for (int i = 0; i < width; i++) {
        REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >>  0) & 0xFF),
                                        SkGetPackedB32(dstPixels[i]), tol));
        REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >>  8) & 0xFF),
                                        SkGetPackedG32(dstPixels[i]), tol));
        REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 16) & 0xFF),
                                        SkGetPackedR32(dstPixels[i]), tol));
        REPORTER_ASSERT(r, almost_equal(((srcPixels[i] >> 24) & 0xFF),
                                        SkGetPackedA32(dstPixels[i]), tol));
    }
#endif
}

DEF_TEST(ColorSpaceXform_TableGamma, r) {
    // Lookup-table based gamma curves
    constexpr size_t tableSize = 10;
    void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(float) * tableSize);
    sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas(kChannels));
    for (int i = 0; i < kChannels; ++i) {
        gammas->fType[i] = SkGammas::Type::kTable_Type;
        gammas->fData[i].fTable.fSize = tableSize;
        gammas->fData[i].fTable.fOffset = 0;
    }

    float* table = SkTAddOffset<float>(memory, sizeof(SkGammas));
    table[0] = 0.00f;
    table[1] = 0.05f;
    table[2] = 0.10f;
    table[3] = 0.15f;
    table[4] = 0.25f;
    table[5] = 0.35f;
    table[6] = 0.45f;
    table[7] = 0.60f;
    table[8] = 0.75f;
    table[9] = 1.00f;
    // This table's pretty small compared to real ones in the wild (think 256),
    // so we give test_identity_xform_A2B a wide tolerance.
    // This lets us implement table transfer functions with a single lookup.
    const int tolerance = 13;

    test_identity_xform(r, gammas, true);
    test_identity_xform_A2B(r, kNonStandard_SkGammaNamed, gammas, tolerance);
}

DEF_TEST(ColorSpaceXform_ParametricGamma, r) {
    // Parametric gamma curves
    void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(SkColorSpaceTransferFn));
    sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas(kChannels));
    for (int i = 0; i < kChannels; ++i) {
        gammas->fType[i] = SkGammas::Type::kParam_Type;
        gammas->fData[i].fParamOffset = 0;
    }

    SkColorSpaceTransferFn* params = SkTAddOffset<SkColorSpaceTransferFn>
            (memory, sizeof(SkGammas));

    // Interval.
    params->fD = 0.04045f;

    // First equation:
    params->fC = 1.0f / 12.92f;
    params->fF = 0.0f;

    // Second equation:
    // Note that the function is continuous (it's actually sRGB).
    params->fA = 1.0f / 1.055f;
    params->fB = 0.055f / 1.055f;
    params->fE = 0.0f;
    params->fG = 2.4f;
    test_identity_xform(r, gammas, true);
    test_identity_xform_A2B(r, kNonStandard_SkGammaNamed, gammas);
}

DEF_TEST(ColorSpaceXform_ExponentialGamma, r) {
    // Exponential gamma curves
    sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new SkGammas(kChannels));
    for (int i = 0; i < kChannels; ++i) {
        gammas->fType[i] = SkGammas::Type::kValue_Type;
        gammas->fData[i].fValue = 1.4f;
    }
    test_identity_xform(r, gammas, true);
    test_identity_xform_A2B(r, kNonStandard_SkGammaNamed, gammas);
}

DEF_TEST(ColorSpaceXform_NamedGamma, r) {
    sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new SkGammas(kChannels));
    gammas->fType[0] = gammas->fType[1] = gammas->fType[2] = SkGammas::Type::kNamed_Type;
    gammas->fData[0].fNamed = kSRGB_SkGammaNamed;
    gammas->fData[1].fNamed = k2Dot2Curve_SkGammaNamed;
    gammas->fData[2].fNamed = kLinear_SkGammaNamed;
    test_identity_xform(r, gammas, true);
    test_identity_xform_A2B(r, kNonStandard_SkGammaNamed, gammas);
    test_identity_xform_A2B(r, kSRGB_SkGammaNamed, nullptr);
    test_identity_xform_A2B(r, k2Dot2Curve_SkGammaNamed, nullptr);
    test_identity_xform_A2B(r, kLinear_SkGammaNamed, nullptr);
}

DEF_TEST(ColorSpaceXform_NonMatchingGamma, r) {
    constexpr size_t tableSize = 10;
    void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(float) * tableSize +
                                   sizeof(SkColorSpaceTransferFn));
    sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas(kChannels));

    float* table = SkTAddOffset<float>(memory, sizeof(SkGammas));
    table[0] = 0.00f;
    table[1] = 0.15f;
    table[2] = 0.20f;
    table[3] = 0.25f;
    table[4] = 0.35f;
    table[5] = 0.45f;
    table[6] = 0.55f;
    table[7] = 0.70f;
    table[8] = 0.85f;
    table[9] = 1.00f;

    SkColorSpaceTransferFn* params = SkTAddOffset<SkColorSpaceTransferFn>(memory,
            sizeof(SkGammas) + sizeof(float) * tableSize);
    params->fA = 1.0f / 1.055f;
    params->fB = 0.055f / 1.055f;
    params->fC = 1.0f / 12.92f;
    params->fD = 0.04045f;
    params->fE = 0.0f;
    params->fF = 0.0f;
    params->fG = 2.4f;

    gammas->fType[0] = SkGammas::Type::kValue_Type;
    gammas->fData[0].fValue = 1.2f;

    // See ColorSpaceXform_TableGamma... we've decided to allow some tolerance
    // for SkJumper's implementation of tables.
    const int tolerance = 12;
    gammas->fType[1] = SkGammas::Type::kTable_Type;
    gammas->fData[1].fTable.fSize = tableSize;
    gammas->fData[1].fTable.fOffset = 0;

    gammas->fType[2] = SkGammas::Type::kParam_Type;
    gammas->fData[2].fParamOffset = sizeof(float) * tableSize;

    test_identity_xform(r, gammas, true);
    test_identity_xform_A2B(r, kNonStandard_SkGammaNamed, gammas, tolerance);
}

#if !defined(SK_USE_SKCMS)
DEF_TEST(ColorSpaceXform_A2BCLUT, r) {
    constexpr int inputChannels = 3;
    constexpr int gp            = 4; // # grid points

    constexpr int numEntries    = gp*gp*gp*3;
    const uint8_t gridPoints[3] = {gp, gp, gp};
    void* memory = sk_malloc_throw(sizeof(SkColorLookUpTable) + sizeof(float) * numEntries);
    sk_sp<SkColorLookUpTable> colorLUT(new (memory) SkColorLookUpTable(inputChannels, gridPoints));
    // make a CLUT that rotates R, G, and B ie R->G, G->B, B->R
    float* table = SkTAddOffset<float>(memory, sizeof(SkColorLookUpTable));
    for (int r = 0; r < gp; ++r) {
        for (int g = 0; g < gp; ++g) {
            for (int b = 0; b < gp; ++b) {
                table[3*(gp*gp*r + gp*g + b) + 0] = g * (1.f / (gp - 1.f));
                table[3*(gp*gp*r + gp*g + b) + 1] = b * (1.f / (gp - 1.f));
                table[3*(gp*gp*r + gp*g + b) + 2] = r * (1.f / (gp - 1.f));
            }
        }
    }

    // build an even distribution of pixels every (7 / 255) steps
    // to test the xform on
    constexpr int pixelgp   = 7;
    constexpr int numPixels = pixelgp*pixelgp*pixelgp;
    SkAutoTMalloc<uint32_t> srcPixels(numPixels);
    int srcIndex = 0;
    for (int r = 0; r < pixelgp; ++r) {
        for (int g = 0; g < pixelgp; ++g) {
            for (int b = 0; b < pixelgp; ++b) {
                const int red   = (int) (r * (255.f / (pixelgp - 1.f)));
                const int green = (int) (g * (255.f / (pixelgp - 1.f)));
                const int blue  = (int) (b * (255.f / (pixelgp - 1.f)));
                srcPixels[srcIndex] = SkColorSetRGB(red, green, blue);
                ++srcIndex;
            }
        }
    }
    SkAutoTMalloc<uint32_t> dstPixels(numPixels);

    // src space is identity besides CLUT
    std::vector<SkColorSpace_A2B::Element> srcElements;
    srcElements.push_back(SkColorSpace_A2B::Element(std::move(colorLUT)));
    auto srcSpace = ColorSpaceXformTest::CreateA2BSpace(SkColorSpace_A2B::PCS::kXYZ,
                                                        std::move(srcElements));
    // dst space is entirely identity
    auto dstSpace = SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, SkMatrix44::I());
    auto xform = SkColorSpaceXform::New(srcSpace.get(), dstSpace.get());
    bool result = xform->apply(SkColorSpaceXform::kRGBA_8888_ColorFormat, dstPixels.get(),
                               SkColorSpaceXform::kRGBA_8888_ColorFormat, srcPixels.get(),
                               numPixels, kOpaque_SkAlphaType);
    REPORTER_ASSERT(r, result);

    for (int i = 0; i < numPixels; ++i) {
        REPORTER_ASSERT(r, almost_equal(SkColorGetR(srcPixels[i]),
                                        SkColorGetG(dstPixels[i])));
        REPORTER_ASSERT(r, almost_equal(SkColorGetG(srcPixels[i]),
                                        SkColorGetB(dstPixels[i])));
        REPORTER_ASSERT(r, almost_equal(SkColorGetB(srcPixels[i]),
                                        SkColorGetR(dstPixels[i])));
    }
}
#endif

DEF_TEST(SkColorSpaceXform_LoadTail, r) {
    std::unique_ptr<uint64_t[]> srcPixel(new uint64_t[1]);
    srcPixel[0] = 0;
    uint32_t dstPixel;
    sk_sp<SkColorSpace> p3 = SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
                                                   SkColorSpace::kDCIP3_D65_Gamut);
    sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
    std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(p3.get(), srgb.get());

    // ASAN will catch us if we read past the tail.
    bool success = xform->apply(SkColorSpaceXform::kRGBA_8888_ColorFormat, &dstPixel,
                                SkColorSpaceXform::kRGBA_U16_BE_ColorFormat, srcPixel.get(), 1,
                                kUnpremul_SkAlphaType);
    REPORTER_ASSERT(r, success);
}

