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

#include <cmath>
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkShader.h"
#include "include/private/SkGainmapInfo.h"
#include "include/private/SkGainmapShader.h"
#include "tests/Test.h"

static bool approx_equal(const SkColor4f& a, const SkColor4f& b) {
    constexpr float kEpsilon = 1e-3f;
    return std::abs(a.fR - b.fR) < kEpsilon && std::abs(a.fG - b.fG) < kEpsilon &&
           std::abs(a.fB - b.fB) < kEpsilon && std::abs(a.fA - b.fA) < kEpsilon;
}

// Create a 1x1 image with a specified color.
static sk_sp<SkImage> make_1x1_image(
        sk_sp<SkColorSpace> imageColorSpace,
        SkAlphaType imageAlphaType,
        SkColor4f imageColor,
        sk_sp<SkColorSpace> imageColorColorSpace = SkColorSpace::MakeSRGBLinear()) {
    SkImageInfo bmInfo =
            SkImageInfo::Make(1, 1, kRGBA_F32_SkColorType, imageAlphaType, imageColorSpace);
    SkBitmap bm;
    bm.allocPixels(bmInfo);

    SkImageInfo writePixelsInfo = SkImageInfo::Make(
            1, 1, kRGBA_F32_SkColorType, kUnpremul_SkAlphaType, imageColorColorSpace);
    SkPixmap writePixelsPixmap(writePixelsInfo, &imageColor, writePixelsInfo.minRowBytes());
    bm.writePixels(writePixelsPixmap, 0, 0);
    return SkImages::RasterFromBitmap(bm);
}

// Return gainmap info that will scale 1 up to the specified hdrRatioMax.
static SkGainmapInfo simple_gainmap_info(float hdrRatioMax) {
    SkGainmapInfo gainmapInfo;
    gainmapInfo.fDisplayRatioSdr = 1.f;
    gainmapInfo.fDisplayRatioHdr = hdrRatioMax;
    gainmapInfo.fEpsilonSdr = {0.f, 0.f, 0.f, 1.f};
    gainmapInfo.fEpsilonHdr = {0.f, 0.f, 0.f, 1.f};
    gainmapInfo.fGainmapRatioMin = {1.f, 1.f, 1.f, 1.f};
    gainmapInfo.fGainmapRatioMax = {hdrRatioMax, hdrRatioMax, hdrRatioMax, 1.f};
    return gainmapInfo;
}

// Draw using a gainmap to a canvas with the specified HDR to SDR ratio and the specified color
// space. Return the result as unpremultiplied sRGB linear.
static SkColor4f draw_1x1_gainmap(sk_sp<SkImage> baseImage,
                                  sk_sp<SkImage> gainmapImage,
                                  const SkGainmapInfo& gainmapInfo,
                                  float dstRatio,
                                  sk_sp<SkColorSpace> dstColorSpace = SkColorSpace::MakeSRGB()) {
    constexpr auto kRect = SkRect::MakeWH(1.f, 1.f);
    SkImageInfo canvasInfo =
            SkImageInfo::Make(1, 1, kRGBA_F32_SkColorType, kPremul_SkAlphaType, dstColorSpace);
    SkBitmap canvasBitmap;
    canvasBitmap.allocPixels(canvasInfo);
    canvasBitmap.eraseColor(SK_ColorTRANSPARENT);

    sk_sp<SkShader> shader = SkGainmapShader::Make(baseImage,
                                                   kRect,
                                                   SkSamplingOptions(),
                                                   gainmapImage,
                                                   kRect,
                                                   SkSamplingOptions(),
                                                   gainmapInfo,
                                                   kRect,
                                                   dstRatio,
                                                   dstColorSpace);
    SkPaint paint;
    paint.setShader(shader);
    SkCanvas canvas(canvasBitmap);
    canvas.drawRect(kRect, paint);

    SkColor4f result = {0.f, 0.f, 0.f, 0.f};
    SkImageInfo readPixelsInfo = SkImageInfo::Make(
            1, 1, kRGBA_F32_SkColorType, kUnpremul_SkAlphaType, SkColorSpace::MakeSRGBLinear());
    canvas.readPixels(readPixelsInfo, &result, sizeof(result), 0, 0);
    return result;
}

// Verify that the gainmap shader correctly applies the base, gainmap, and destination rectangles.
DEF_TEST(GainmapShader_rects, r) {
    SkColor4f sdrColors[5][2] = {
            {{-1.f, -1.f, -1.f, 1.0f}, {-1.f, -1.f, -1.f, 1.0f}},
            {{1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 0.5f, 1.0f}},
            {{1.0f, 0.5f, 1.0f, 1.0f}, {1.0f, 0.5f, 0.5f, 1.0f}},
            {{0.5f, 1.0f, 1.0f, 1.0f}, {0.5f, 1.0f, 0.5f, 1.0f}},
            {{0.5f, 0.5f, 1.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}},
    };
    SkPixmap sdrPixmap(SkImageInfo::Make(2, 5, kRGBA_F32_SkColorType, kOpaque_SkAlphaType),
                       sdrColors,
                       2 * sizeof(SkColor4f));
    auto sdrImage = SkImages::RasterFromPixmap(sdrPixmap, nullptr, nullptr);
    const auto sdrImageRect = SkRect::MakeXYWH(0.f, 1.f, 2.f, 4.f);

    // The top pixel indicates to gain only red, and the bottom pixel indicates to gain everything
    // except red.
    SkColor4f gainmapColors[2][2] = {
            {{-1.f, -1.f, -1.f, 1.f}, {1.0f, 0.0f, 0.0f, 1.f}},
            {{-1.f, -1.f, -1.f, 1.f}, {0.0f, 1.0f, 1.0f, 1.f}},
    };
    SkPixmap gainmapPixmap(SkImageInfo::Make(2, 2, kRGBA_F32_SkColorType, kOpaque_SkAlphaType),
                           gainmapColors,
                           2 * sizeof(SkColor4f));
    auto gainmapImage = SkImages::RasterFromPixmap(gainmapPixmap, nullptr, nullptr);
    const auto gainmapImageRect = SkRect::MakeXYWH(1.f, 0.f, 1.f, 2.f);
    SkGainmapInfo gainmapInfo = simple_gainmap_info(2.f);
    gainmapInfo.fEpsilonHdr[0] = 0.1f;

    SkImageInfo canvasInfo = SkImageInfo::Make(
            4, 6, kRGBA_F32_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
    SkBitmap canvasBitmap;
    canvasBitmap.allocPixels(canvasInfo);
    canvasBitmap.eraseColor(SK_ColorTRANSPARENT);
    const auto canvasRect = SkRect::MakeXYWH(1.f, 1.f, 2.f, 4.f);

    sk_sp<SkShader> shader = SkGainmapShader::Make(sdrImage,
                                                   sdrImageRect,
                                                   SkSamplingOptions(),
                                                   gainmapImage,
                                                   gainmapImageRect,
                                                   SkSamplingOptions(),
                                                   gainmapInfo,
                                                   canvasRect,
                                                   gainmapInfo.fDisplayRatioHdr,
                                                   canvasInfo.refColorSpace());
    SkPaint paint;
    paint.setShader(shader);
    SkCanvas canvas(canvasBitmap);
    canvas.drawRect(canvasRect, paint);

    // Compute and compare the expected colors.
    // This is linearToSRGB(srgbToLinear(1.0)*2.0) = linearToSRGB(2.0).
    constexpr float k10G = 1.353256028586302f;
    // This is linearToSRGB(srgbToLinear(0.5)*2.0)
    constexpr float k05G = 0.6858361015012847f;
    // The 'R' component also has a fEpsilonHdr set.
    // This is linearToSRGB(srgbToLinear(1.0)*2.0-0.1) = linearToSRGB(1.9).
    constexpr float kR10G = 1.3234778541409058f;
    // This is linearToSRGB(srgbToLinear(0.5)-0.1)
    // The gain map is 0.f (no gain), but there are still affectd by the offset.
    constexpr float kR05G = 0.371934685412575f;
    SkColor4f expectedColors[4][2] = {
            {{kR10G, 1.0f, 1.0f, 1.0f}, {kR10G, 1.0f, 0.5f, 1.0f}},
            {{kR10G, 0.5f, 1.0f, 1.0f}, {kR10G, 0.5f, 0.5f, 1.0f}},
            {{kR05G, k10G, k10G, 1.0f}, {kR05G, k10G, k05G, 1.0f}},
            {{kR05G, k05G, k10G, 1.0f}, {kR05G, k05G, k05G, 1.0f}},
    };
    for (int y = 0; y < 4; ++y) {
        for (int x = 0; x < 2; ++x) {
            const auto color = canvasBitmap.getColor4f(x + 1, y + 1);
            const auto& expected = expectedColors[y][x];
            REPORTER_ASSERT(r,
                            approx_equal(color, expected),
                            "color (%.3f %.3f %.3f %.3f) does not match expected color (%.3f %.3f "
                            "%.3f %.3f) at "
                            "pixel (%d, %d)",
                            color.fR,
                            color.fG,
                            color.fB,
                            color.fA,
                            expected.fR,
                            expected.fG,
                            expected.fB,
                            expected.fA,
                            x,
                            y);
        }
    }
}

DEF_TEST(GainmapShader_baseImageIsHdr, r) {
    SkColor4f hdrColors[4][2] = {
            {{1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 0.5f, 1.0f}},
            {{1.0f, 0.5f, 1.0f, 1.0f}, {1.0f, 0.5f, 0.5f, 1.0f}},
            {{0.5f, 1.0f, 1.0f, 1.0f}, {0.5f, 1.0f, 0.5f, 1.0f}},
            {{0.5f, 0.5f, 1.0f, 1.0f}, {0.5f, 0.5f, 0.5f, 1.0f}},
    };
    SkPixmap hdrPixmap(SkImageInfo::Make(2, 4, kRGBA_F32_SkColorType, kOpaque_SkAlphaType),
                       hdrColors,
                       2 * sizeof(SkColor4f));
    auto hdrImage = SkImages::RasterFromPixmap(hdrPixmap, nullptr, nullptr);
    const auto hdrImageRect = SkRect::MakeXYWH(0.f, 0.f, 2.f, 4.f);

    // The top pixel indicates to gain only red, and the bottom pixel indicates to gain everything
    // except red.
    SkColor4f gainmapColors[2][1] = {
            {{1.0f, 0.0f, 0.0f, 1.f}},
            {{0.0f, 1.0f, 1.0f, 1.f}},
    };
    SkPixmap gainmapPixmap(SkImageInfo::Make(1, 2, kRGBA_F32_SkColorType, kOpaque_SkAlphaType),
                           gainmapColors,
                           1 * sizeof(SkColor4f));
    auto gainmapImage = SkImages::RasterFromPixmap(gainmapPixmap, nullptr, nullptr);
    const auto gainmapImageRect = SkRect::MakeXYWH(0.f, 0.f, 1.f, 2.f);
    SkGainmapInfo gainmapInfo = simple_gainmap_info(2.f);
    gainmapInfo.fBaseImageType = SkGainmapInfo::BaseImageType::kHDR;
    gainmapInfo.fEpsilonSdr[0] = 0.1f;

    SkImageInfo canvasInfo = SkImageInfo::Make(
            2, 4, kRGBA_F32_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
    SkBitmap canvasBitmap;
    canvasBitmap.allocPixels(canvasInfo);
    canvasBitmap.eraseColor(SK_ColorTRANSPARENT);
    const auto canvasRect = SkRect::MakeXYWH(0.f, 0.f, 2.f, 4.f);

    sk_sp<SkShader> shader = SkGainmapShader::Make(hdrImage,
                                                   hdrImageRect,
                                                   SkSamplingOptions(),
                                                   gainmapImage,
                                                   gainmapImageRect,
                                                   SkSamplingOptions(),
                                                   gainmapInfo,
                                                   canvasRect,
                                                   gainmapInfo.fDisplayRatioSdr,
                                                   canvasInfo.refColorSpace());
    SkPaint paint;
    paint.setShader(shader);
    SkCanvas canvas(canvasBitmap);
    canvas.drawRect(canvasRect, paint);

    // Compute and compare the expected colors.
    // This is linearToSRGB(srgbToLinear(1.0)*0.5) = linearToSRGB(0.5).
    constexpr float k10G = 0.7353569830524495f;
    // This is linearToSRGB(srgbToLinear(0.5)*0.5)
    constexpr float k05G = 0.3607802138332792f;
    // The 'R' component also has a fEpsilonSdr set.
    // This is linearToSRGB(srgbToLinear(1.0)*0.5-0.1) = linearToSRGB(0.4).
    constexpr float kR10G = 0.6651850846308363f;
    // This is linearToSRGB(srgbToLinear(0.5)-0.1)
    // The gain map is 0.f (no gain), but there are still affectd by the offset.
    constexpr float kR05G = 0.371934685412575f;
    SkColor4f expectedColors[4][2] = {
            {{kR10G, 1.0f, 1.0f, 1.0f}, {kR10G, 1.0f, 0.5f, 1.0f}},
            {{kR10G, 0.5f, 1.0f, 1.0f}, {kR10G, 0.5f, 0.5f, 1.0f}},
            {{kR05G, k10G, k10G, 1.0f}, {kR05G, k10G, k05G, 1.0f}},
            {{kR05G, k05G, k10G, 1.0f}, {kR05G, k05G, k05G, 1.0f}},
    };
    for (int y = 0; y < 4; ++y) {
        for (int x = 0; x < 2; ++x) {
            const auto color = canvasBitmap.getColor4f(x, y);
            const auto& expected = expectedColors[y][x];
            REPORTER_ASSERT(r,
                            approx_equal(color, expected),
                            "color (%.3f %.3f %.3f %.3f) does not match expected color (%.3f %.3f "
                            "%.3f %.3f) at "
                            "pixel (%d, %d)",
                            color.fR,
                            color.fG,
                            color.fB,
                            color.fA,
                            expected.fR,
                            expected.fG,
                            expected.fB,
                            expected.fA,
                            x,
                            y);
        }
    }
}

// Verify that the gainmap shader isn't affected by the color spaces of the base, gainmap, or
// destination. But the fGainmapMathColorSpace is taken into account.
DEF_TEST(GainmapShader_colorSpace, r) {
    auto sdrColorSpace =
            SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kSRGB)->makeColorSpin();
    auto gainmapColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kPQ, SkNamedGamut::kRec2020);
    auto dstColorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kHLG, SkNamedGamut::kDisplayP3);

    constexpr SkColor4f kSdrColor = {0.25f, 0.5f, 1.f, 1.f};
    constexpr SkColor4f kGainmapColor = {
            0.0f,  // The sRGB G channel will have a exp2(0.0)=1.000 gain.
            0.5f,  // The sRGB B channel will have a exp2(0.5)=1.414 gain.
            1.0f,  // The sRGB R channel will have a exp2(1.0)=2.000 gain.
            1.f};
    constexpr SkColor4f kExpectedColor = {0.5f, 0.5f, 1.414f, 1.f};

    auto sdrImage = make_1x1_image(sdrColorSpace, kOpaque_SkAlphaType, kSdrColor);
    auto gainmapImage = make_1x1_image(
            gainmapColorSpace, kOpaque_SkAlphaType, kGainmapColor, gainmapColorSpace);
    SkGainmapInfo gainmapInfo = simple_gainmap_info(2.f);

    auto color = draw_1x1_gainmap(
            sdrImage, gainmapImage, gainmapInfo, gainmapInfo.fDisplayRatioHdr, dstColorSpace);
    REPORTER_ASSERT(r, approx_equal(color, kExpectedColor));

    // Setting fGainmapMathColorSpace to the base image's color space does not change the result.
    gainmapInfo.fGainmapMathColorSpace = sdrColorSpace;
    color = draw_1x1_gainmap(
            sdrImage, gainmapImage, gainmapInfo, gainmapInfo.fDisplayRatioHdr, dstColorSpace);
    REPORTER_ASSERT(r, approx_equal(color, kExpectedColor));

    // Setting fGainmapMathColorSpace ot a different color space does change the result.
    gainmapInfo.fGainmapMathColorSpace =
            SkColorSpace::MakeRGB(SkNamedTransferFn::kPQ, SkNamedGamut::kRec2020);
    color = draw_1x1_gainmap(
            sdrImage, gainmapImage, gainmapInfo, gainmapInfo.fDisplayRatioHdr, dstColorSpace);
    REPORTER_ASSERT(r, !approx_equal(color, kExpectedColor));
}

// Verify that a fully applied Apple gainmap maps the specification.
DEF_TEST(GainmapShader_apple, r) {
    constexpr SkColor4f kSdrColor = {0.25f, 0.5f, 1.f, 1.f};
    const SkColor4f kGainmapColor = {0.0f,       // The R channel will have a linear value of 0.0.
                                     0.702250f,  // The G channel will have a linear value of 0.5.
                                     1.0f,       // The B channel will have a linear value 0f 1.0.
                                     1.f};

    // Set the HDR headroom to 5.0.
    const float kH = 5.f;

    const SkColor4f kExpectedColor = {0.25f * (1 + (kH - 1) * 0.0f),  // 0.25,
                                      0.50f * (1 + (kH - 1) * 0.5f),  // 0.5,
                                      1.00f * (1 + (kH - 1) * 1.0f),  // 5.0,
                                      1.f};

    auto sdrImage = make_1x1_image(SkColorSpace::MakeSRGB(), kOpaque_SkAlphaType, kSdrColor);
    auto gainmapImage = make_1x1_image(nullptr, kOpaque_SkAlphaType, kGainmapColor);
    SkGainmapInfo gainmapInfo = simple_gainmap_info(kH);
    gainmapInfo.fType = SkGainmapInfo::Type::kApple;

    auto color = draw_1x1_gainmap(
            sdrImage, gainmapImage, gainmapInfo, kH, SkColorSpace::MakeSRGBLinear());

    // Note that (0.250, 1.548, 5.000) is *not* an acceptable answer here (even though it's sort-of
    // close). That number is the result of not using the the Apple-compatible math.
    REPORTER_ASSERT(r, approx_equal(color, kExpectedColor));
}
