/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <ui/ColorSpace.h>

using namespace std::placeholders;

namespace android {

static constexpr float linearResponse(float v) {
    return v;
}

static constexpr float rcpResponse(float x, const ColorSpace::TransferParameters& p) {
    return x >= p.d * p.c ? (std::pow(x, 1.0f / p.g) - p.b) / p.a : x / p.c;
}

static constexpr float response(float x, const ColorSpace::TransferParameters& p) {
    return x >= p.d ? std::pow(p.a * x + p.b, p.g) : p.c * x;
}

static constexpr float rcpFullResponse(float x, const ColorSpace::TransferParameters& p) {
    return x >= p.d * p.c ? (std::pow(x - p.e, 1.0f / p.g) - p.b) / p.a : (x - p.f) / p.c;
}

static constexpr float fullResponse(float x, const ColorSpace::TransferParameters& p) {
    return x >= p.d ? std::pow(p.a * x + p.b, p.g) + p.e : p.c * x + p.f;
}

static float absRcpResponse(float x, float g,float a, float b, float c, float d) {
    float xx = std::abs(x);
    return std::copysign(xx >= d * c ? (std::pow(xx, 1.0f / g) - b) / a : xx / c, x);
}

static float absResponse(float x, float g, float a, float b, float c, float d) {
   float xx = std::abs(x);
   return std::copysign(xx >= d ? std::pow(a * xx + b, g) : c * xx, x);
}

static float safePow(float x, float e) {
    return powf(x < 0.0f ? 0.0f : x, e);
}

static ColorSpace::transfer_function toOETF(const ColorSpace::TransferParameters& parameters) {
    if (parameters.e == 0.0f && parameters.f == 0.0f) {
        return std::bind(rcpResponse, _1, parameters);
    }
    return std::bind(rcpFullResponse, _1, parameters);
}

static ColorSpace::transfer_function toEOTF( const ColorSpace::TransferParameters& parameters) {
    if (parameters.e == 0.0f && parameters.f == 0.0f) {
        return std::bind(response, _1, parameters);
    }
    return std::bind(fullResponse, _1, parameters);
}

static ColorSpace::transfer_function toOETF(float gamma) {
    if (gamma == 1.0f) {
        return linearResponse;
    }
    return std::bind(safePow, _1, 1.0f / gamma);
}

static ColorSpace::transfer_function toEOTF(float gamma) {
    if (gamma == 1.0f) {
        return linearResponse;
    }
    return std::bind(safePow, _1, gamma);
}

static constexpr std::array<float2, 3> computePrimaries(const mat3& rgbToXYZ) {
    float3 r(rgbToXYZ * float3{1, 0, 0});
    float3 g(rgbToXYZ * float3{0, 1, 0});
    float3 b(rgbToXYZ * float3{0, 0, 1});

    return {{r.xy / dot(r, float3{1}),
             g.xy / dot(g, float3{1}),
             b.xy / dot(b, float3{1})}};
}

static constexpr float2 computeWhitePoint(const mat3& rgbToXYZ) {
    float3 w(rgbToXYZ * float3{1});
    return w.xy / dot(w, float3{1});
}

ColorSpace::ColorSpace(
        const std::string& name,
        const mat3& rgbToXYZ,
        transfer_function OETF,
        transfer_function EOTF,
        clamping_function clamper) noexcept
        : mName(name)
        , mRGBtoXYZ(rgbToXYZ)
        , mXYZtoRGB(inverse(rgbToXYZ))
        , mOETF(std::move(OETF))
        , mEOTF(std::move(EOTF))
        , mClamper(std::move(clamper))
        , mPrimaries(computePrimaries(rgbToXYZ))
        , mWhitePoint(computeWhitePoint(rgbToXYZ)) {
}

ColorSpace::ColorSpace(
        const std::string& name,
        const mat3& rgbToXYZ,
        const TransferParameters parameters,
        clamping_function clamper) noexcept
        : mName(name)
        , mRGBtoXYZ(rgbToXYZ)
        , mXYZtoRGB(inverse(rgbToXYZ))
        , mParameters(parameters)
        , mOETF(toOETF(mParameters))
        , mEOTF(toEOTF(mParameters))
        , mClamper(std::move(clamper))
        , mPrimaries(computePrimaries(rgbToXYZ))
        , mWhitePoint(computeWhitePoint(rgbToXYZ)) {
}

ColorSpace::ColorSpace(
        const std::string& name,
        const mat3& rgbToXYZ,
        float gamma,
        clamping_function clamper) noexcept
        : mName(name)
        , mRGBtoXYZ(rgbToXYZ)
        , mXYZtoRGB(inverse(rgbToXYZ))
        , mParameters({gamma, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f})
        , mOETF(toOETF(gamma))
        , mEOTF(toEOTF(gamma))
        , mClamper(std::move(clamper))
        , mPrimaries(computePrimaries(rgbToXYZ))
        , mWhitePoint(computeWhitePoint(rgbToXYZ)) {
}

ColorSpace::ColorSpace(
        const std::string& name,
        const std::array<float2, 3>& primaries,
        const float2& whitePoint,
        transfer_function OETF,
        transfer_function EOTF,
        clamping_function clamper) noexcept
        : mName(name)
        , mRGBtoXYZ(computeXYZMatrix(primaries, whitePoint))
        , mXYZtoRGB(inverse(mRGBtoXYZ))
        , mOETF(std::move(OETF))
        , mEOTF(std::move(EOTF))
        , mClamper(std::move(clamper))
        , mPrimaries(primaries)
        , mWhitePoint(whitePoint) {
}

ColorSpace::ColorSpace(
        const std::string& name,
        const std::array<float2, 3>& primaries,
        const float2& whitePoint,
        const TransferParameters parameters,
        clamping_function clamper) noexcept
        : mName(name)
        , mRGBtoXYZ(computeXYZMatrix(primaries, whitePoint))
        , mXYZtoRGB(inverse(mRGBtoXYZ))
        , mParameters(parameters)
        , mOETF(toOETF(mParameters))
        , mEOTF(toEOTF(mParameters))
        , mClamper(std::move(clamper))
        , mPrimaries(primaries)
        , mWhitePoint(whitePoint) {
}

ColorSpace::ColorSpace(
        const std::string& name,
        const std::array<float2, 3>& primaries,
        const float2& whitePoint,
        float gamma,
        clamping_function clamper) noexcept
        : mName(name)
        , mRGBtoXYZ(computeXYZMatrix(primaries, whitePoint))
        , mXYZtoRGB(inverse(mRGBtoXYZ))
        , mParameters({gamma, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f})
        , mOETF(toOETF(gamma))
        , mEOTF(toEOTF(gamma))
        , mClamper(std::move(clamper))
        , mPrimaries(primaries)
        , mWhitePoint(whitePoint) {
}

constexpr mat3 ColorSpace::computeXYZMatrix(
        const std::array<float2, 3>& primaries, const float2& whitePoint) {
    const float2& R = primaries[0];
    const float2& G = primaries[1];
    const float2& B = primaries[2];
    const float2& W = whitePoint;        

    float oneRxRy = (1 - R.x) / R.y;
    float oneGxGy = (1 - G.x) / G.y;
    float oneBxBy = (1 - B.x) / B.y;
    float oneWxWy = (1 - W.x) / W.y;

    float RxRy = R.x / R.y;
    float GxGy = G.x / G.y;
    float BxBy = B.x / B.y;
    float WxWy = W.x / W.y;

    float BY =
            ((oneWxWy - oneRxRy) * (GxGy - RxRy) - (WxWy - RxRy) * (oneGxGy - oneRxRy)) /
            ((oneBxBy - oneRxRy) * (GxGy - RxRy) - (BxBy - RxRy) * (oneGxGy - oneRxRy));
    float GY = (WxWy - RxRy - BY * (BxBy - RxRy)) / (GxGy - RxRy);
    float RY = 1 - GY - BY;

    float RYRy = RY / R.y;
    float GYGy = GY / G.y;
    float BYBy = BY / B.y;

    return {
        float3{RYRy * R.x, RY, RYRy * (1 - R.x - R.y)},
        float3{GYGy * G.x, GY, GYGy * (1 - G.x - G.y)},
        float3{BYBy * B.x, BY, BYBy * (1 - B.x - B.y)}
    };
}

const ColorSpace ColorSpace::sRGB() {
    return {
        "sRGB IEC61966-2.1",
        {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
        {0.3127f, 0.3290f},
        {2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.04045f, 0.0f, 0.0f}
    };
}

const ColorSpace ColorSpace::linearSRGB() {
    return {
        "sRGB IEC61966-2.1 (Linear)",
        {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
        {0.3127f, 0.3290f}
    };
}

const ColorSpace ColorSpace::extendedSRGB() {
    return {
        "scRGB-nl IEC 61966-2-2:2003",
        {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
        {0.3127f, 0.3290f},
        std::bind(absRcpResponse, _1, 2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.04045f),
        std::bind(absResponse,    _1, 2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.04045f),
        std::bind(clamp<float>, _1, -0.799f, 2.399f)
    };
}

const ColorSpace ColorSpace::linearExtendedSRGB() {
    return {
        "scRGB IEC 61966-2-2:2003",
        {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
        {0.3127f, 0.3290f},
        1.0f,
        std::bind(clamp<float>, _1, -0.5f, 7.499f)
    };
}

const ColorSpace ColorSpace::NTSC() {
    return {
        "NTSC (1953)",
        {{float2{0.67f, 0.33f}, {0.21f, 0.71f}, {0.14f, 0.08f}}},
        {0.310f, 0.316f},
        {1 / 0.45f, 1 / 1.099f, 0.099f / 1.099f, 1 / 4.5f, 0.081f, 0.0f, 0.0f}
    };
}

const ColorSpace ColorSpace::BT709() {
    return {
        "Rec. ITU-R BT.709-5",
        {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
        {0.3127f, 0.3290f},
        {1 / 0.45f, 1 / 1.099f, 0.099f / 1.099f, 1 / 4.5f, 0.081f, 0.0f, 0.0f}
    };
}

const ColorSpace ColorSpace::BT2020() {
    return {
        "Rec. ITU-R BT.2020-1",
        {{float2{0.708f, 0.292f}, {0.170f, 0.797f}, {0.131f, 0.046f}}},
        {0.3127f, 0.3290f},
        {1 / 0.45f, 1 / 1.099f, 0.099f / 1.099f, 1 / 4.5f, 0.081f, 0.0f, 0.0f}
    };
}

const ColorSpace ColorSpace::AdobeRGB() {
    return {
        "Adobe RGB (1998)",
        {{float2{0.64f, 0.33f}, {0.21f, 0.71f}, {0.15f, 0.06f}}},
        {0.3127f, 0.3290f},
        2.2f
    };
}

const ColorSpace ColorSpace::ProPhotoRGB() {
    return {
        "ROMM RGB ISO 22028-2:2013",
        {{float2{0.7347f, 0.2653f}, {0.1596f, 0.8404f}, {0.0366f, 0.0001f}}},
        {0.34567f, 0.35850f},
        {1.8f, 1.0f, 0.0f, 1 / 16.0f, 0.031248f, 0.0f, 0.0f}
    };
}

const ColorSpace ColorSpace::DisplayP3() {
    return {
        "Display P3",
        {{float2{0.680f, 0.320f}, {0.265f, 0.690f}, {0.150f, 0.060f}}},
        {0.3127f, 0.3290f},
        {2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.039f, 0.0f, 0.0f}
    };
}

const ColorSpace ColorSpace::DCIP3() {
    return {
        "SMPTE RP 431-2-2007 DCI (P3)",
        {{float2{0.680f, 0.320f}, {0.265f, 0.690f}, {0.150f, 0.060f}}},
        {0.314f, 0.351f},
        2.6f
    };
}

const ColorSpace ColorSpace::ACES() {
    return {
        "SMPTE ST 2065-1:2012 ACES",
        {{float2{0.73470f, 0.26530f}, {0.0f, 1.0f}, {0.00010f, -0.0770f}}},
        {0.32168f, 0.33767f},
        1.0f,
        std::bind(clamp<float>, _1, -65504.0f, 65504.0f)
    };
}

const ColorSpace ColorSpace::ACEScg() {
    return {
        "Academy S-2014-004 ACEScg",
        {{float2{0.713f, 0.293f}, {0.165f, 0.830f}, {0.128f, 0.044f}}},
        {0.32168f, 0.33767f},
        1.0f,
        std::bind(clamp<float>, _1, -65504.0f, 65504.0f)
    };
}

std::unique_ptr<float3[]> ColorSpace::createLUT(uint32_t size, const ColorSpace& src,
                                                const ColorSpace& dst) {
    size = clamp(size, 2u, 256u);
    float m = 1.0f / float(size - 1);

    std::unique_ptr<float3[]> lut(new float3[size * size * size]);
    float3* data = lut.get();

    ColorSpaceConnector connector(src, dst);

    for (uint32_t z = 0; z < size; z++) {
        for (int32_t y = int32_t(size - 1); y >= 0; y--) {
            for (uint32_t x = 0; x < size; x++) {
                *data++ = connector.transform({
                    static_cast<float>(x) * m,
                    static_cast<float>(y) * m,
                    static_cast<float>(z) * m,
                });
            }
        }
    }

    return lut;
}

static const float2 ILLUMINANT_D50_XY = {0.34567f, 0.35850f};
static const float3 ILLUMINANT_D50_XYZ = {0.964212f, 1.0f, 0.825188f};
static const mat3 BRADFORD = mat3{
    float3{ 0.8951f, -0.7502f,  0.0389f},
    float3{ 0.2664f,  1.7135f, -0.0685f},
    float3{-0.1614f,  0.0367f,  1.0296f}
};

static mat3 adaptation(const mat3& matrix, const float3& srcWhitePoint, const float3& dstWhitePoint) {
    float3 srcLMS = matrix * srcWhitePoint;
    float3 dstLMS = matrix * dstWhitePoint;
    return inverse(matrix) * mat3{dstLMS / srcLMS} * matrix;
}

ColorSpaceConnector::ColorSpaceConnector(
        const ColorSpace& src,
        const ColorSpace& dst) noexcept
        : mSource(src)
        , mDestination(dst) {

    if (all(lessThan(abs(src.getWhitePoint() - dst.getWhitePoint()), float2{1e-3f}))) {
        mTransform = dst.getXYZtoRGB() * src.getRGBtoXYZ();
    } else {
        mat3 rgbToXYZ(src.getRGBtoXYZ());
        mat3 xyzToRGB(dst.getXYZtoRGB());

        float3 srcXYZ = ColorSpace::XYZ(float3{src.getWhitePoint(), 1});
        float3 dstXYZ = ColorSpace::XYZ(float3{dst.getWhitePoint(), 1});

        if (any(greaterThan(abs(src.getWhitePoint() - ILLUMINANT_D50_XY), float2{1e-3f}))) {
            rgbToXYZ = adaptation(BRADFORD, srcXYZ, ILLUMINANT_D50_XYZ) * src.getRGBtoXYZ();
        }

        if (any(greaterThan(abs(dst.getWhitePoint() - ILLUMINANT_D50_XY), float2{1e-3f}))) {
            xyzToRGB = inverse(adaptation(BRADFORD, dstXYZ, ILLUMINANT_D50_XYZ) * dst.getRGBtoXYZ());
        }

        mTransform = xyzToRGB * rgbToXYZ;
    }
}

}; // namespace android
