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

#ifndef SkGainmapInfo_DEFINED
#define SkGainmapInfo_DEFINED

#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkRefCnt.h"
class SkData;

/**
 *  Gainmap rendering parameters. Suppose our display has HDR to SDR ratio of H and we wish to
 *  display an image with gainmap on this display. Let B be the pixel value from the base image
 *  in a color space that has the primaries of the base image and a linear transfer function. Let
 *  G be the pixel value from the gainmap. Let D be the output pixel in the same color space as B.
 *  The value of D is computed as follows:
 *
 *  First, let W be a weight parameter determing how much the gainmap will be applied.
 *    W = clamp((log(H)                - log(fDisplayRatioSdr)) /
 *              (log(fDisplayRatioHdr) - log(fDisplayRatioSdr), 0, 1)
 *
 *  Next, let L be the gainmap value in log space. We compute this from the value G that was
 *  sampled from the texture as follows:
 *    L = mix(log(fGainmapRatioMin), log(fGainmapRatioMax), pow(G, fGainmapGamma))
 *
 *  Finally, apply the gainmap to compute D, the displayed pixel. If the base image is SDR then
 *  compute:
 *    D = (B + fEpsilonSdr) * exp(L * W) - fEpsilonHdr
 *  If the base image is HDR then compute:
 *    D = (B + fEpsilonHdr) * exp(L * (W - 1)) - fEpsilonSdr
 *
 *  In the above math, log() is a natural logarithm and exp() is natural exponentiation. Note,
 *  however, that the base used for the log() and exp() functions does not affect the results of
 *  the computation (it cancels out, as long as the same base is used throughout).
 *
 *  This product includes Gain Map technology under license by Adobe.
 */
struct SkGainmapInfo {
    /**
     *  Parameters for converting the gainmap from its image encoding to log space. These are
     *  specified per color channel. The alpha value is unused.
     */
    SkColor4f fGainmapRatioMin = {1.f, 1.f, 1.f, 1.0};
    SkColor4f fGainmapRatioMax = {2.f, 2.f, 2.f, 1.0};
    SkColor4f fGainmapGamma = {1.f, 1.f, 1.f, 1.f};

    /**
     *  Parameters sometimes used in gainmap computation to avoid numerical instability.
     */
    SkColor4f fEpsilonSdr = {0.f, 0.f, 0.f, 1.0};
    SkColor4f fEpsilonHdr = {0.f, 0.f, 0.f, 1.0};

    /**
     *  If the output display's HDR to SDR ratio is less or equal than fDisplayRatioSdr then the SDR
     *  rendition is displayed. If the output display's HDR to SDR ratio is greater or equal than
     *  fDisplayRatioHdr then the HDR rendition is displayed. If the output display's HDR to SDR
     *  ratio is between these values then an interpolation between the two is displayed using the
     *  math above.
     */
    float fDisplayRatioSdr = 1.f;
    float fDisplayRatioHdr = 2.f;

    /**
     *  Whether the base image is the SDR image or the HDR image.
     */
    enum class BaseImageType {
        kSDR,
        kHDR,
    };
    BaseImageType fBaseImageType = BaseImageType::kSDR;

    /**
     *  The type of the gainmap image. If the type is kApple, then the gainmap image was originally
     *  encoded according to the specification at [0], and can be converted to the kDefault type by
     *  applying the transformation described at [1].
     *  [0] https://developer.apple.com/documentation/appkit/images_and_pdf/
     *      applying_apple_hdr_effect_to_your_photos
     *  [1] https://docs.google.com/document/d/1iUpYAThVV_FuDdeiO3t0vnlfoA1ryq0WfGS9FuydwKc
     */
    enum class Type {
        kDefault,
        kApple,
    };
    Type fType = Type::kDefault;

    /**
     * If specified, color space to apply the gainmap in, otherwise the base image's color space
     * is used. Only the color primaries are used, the transfer function is irrelevant.
     */
    sk_sp<SkColorSpace> fGainmapMathColorSpace = nullptr;

    /**
     * Return true if this can be encoded as an UltraHDR v1 image.
     */
    bool isUltraHDRv1Compatible() const;

    /**
     * If |data| contains an ISO 21496-1 version that is supported, return true. Otherwise return
     * false.
     */
    static bool ParseVersion(const SkData* data);

    /**
     * If |data| constains ISO 21496-1 metadata then parse that metadata then use it to populate
     * |info| and return true, otherwise return false. If |data| indicates that that the base image
     * color space primaries should be used for gainmap application then set
     * |fGainmapMathColorSpace| to nullptr, otherwise set |fGainmapMathColorSpace| to sRGB (the
     * default, to be overwritten by the image decoder).
     */
    static bool Parse(const SkData* data, SkGainmapInfo& info);

    /**
     * Serialize an ISO 21496-1 version 0 blob containing only the version structure.
     */
    static sk_sp<SkData> SerializeVersion();

    /**
     * Serialize an ISO 21496-1 version 0 blob containing this' gainmap parameters.
     */
    sk_sp<SkData> serialize() const;

    inline bool operator==(const SkGainmapInfo& other) const {
        return fGainmapRatioMin == other.fGainmapRatioMin &&
               fGainmapRatioMax == other.fGainmapRatioMax && fGainmapGamma == other.fGainmapGamma &&
               fEpsilonSdr == other.fEpsilonSdr && fEpsilonHdr == other.fEpsilonHdr &&
               fDisplayRatioSdr == other.fDisplayRatioSdr &&
               fDisplayRatioHdr == other.fDisplayRatioHdr &&
               fBaseImageType == other.fBaseImageType && fType == other.fType &&
               SkColorSpace::Equals(fGainmapMathColorSpace.get(),
                                    other.fGainmapMathColorSpace.get());
    }
    inline bool operator!=(const SkGainmapInfo& other) const { return !(*this == other); }
};

#endif
