• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkGainmapInfo_DEFINED
9 #define SkGainmapInfo_DEFINED
10 
11 #include "include/core/SkColor.h"
12 
13 /**
14  *  Gainmap rendering parameters. Suppose our display has HDR to SDR ratio of H and we wish to
15  *  display an image with gainmap on this display. Let B be the pixel value from the base image
16  *  in a color space that has the primaries of the base image and a linear transfer function. Let
17  *  G be the pixel value from the gainmap. Let D be the output pixel in the same color space as B.
18  *  The value of D is computed as follows:
19  *
20  *  First, let W be a weight parameter determing how much the gainmap will be applied.
21  *    W = clamp((log(H)                - log(fDisplayRatioSdr)) /
22  *              (log(fDisplayRatioHdr) - log(fDisplayRatioSdr), 0, 1)
23  *
24  *  Next, let L be the gainmap value in log space. We compute this from the value G that was
25  *  sampled from the texture as follows:
26  *    L = mix(log(fGainmapRatioMin), log(fGainmapRatioMax), pow(G, fGainmapGamma))
27  *
28  *  Finally, apply the gainmap to compute D, the displayed pixel. If the base image is SDR then
29  *  compute:
30  *    D = (B + fEpsilonSdr) * exp(L * W) - fEpsilonHdr
31  *  If the base image is HDR then compute:
32  *    D = (B + fEpsilonHdr) * exp(L * (W - 1)) - fEpsilonSdr
33  *
34  *  In the above math, log() is a natural logarithm and exp() is natural exponentiation. Note,
35  *  however, that the base used for the log() and exp() functions does not affect the results of
36  *  the computation (it cancels out, as long as the same base is used throughout).
37  */
38 struct SkGainmapInfo {
39     /**
40      *  Parameters for converting the gainmap from its image encoding to log space. These are
41      *  specified per color channel. The alpha value is unused.
42      */
43     SkColor4f fGainmapRatioMin = {1.f, 1.f, 1.f, 1.0};
44     SkColor4f fGainmapRatioMax = {2.f, 2.f, 2.f, 1.0};
45     SkColor4f fGainmapGamma = {1.f, 1.f, 1.f, 1.f};
46 
47     /**
48      *  Parameters sometimes used in gainmap computation to avoid numerical instability.
49      */
50     SkColor4f fEpsilonSdr = {0.f, 0.f, 0.f, 1.0};
51     SkColor4f fEpsilonHdr = {0.f, 0.f, 0.f, 1.0};
52 
53     /**
54      *  If the output display's HDR to SDR ratio is less or equal than fDisplayRatioSdr then the SDR
55      *  rendition is displayed. If the output display's HDR to SDR ratio is greater or equal than
56      *  fDisplayRatioHdr then the HDR rendition is displayed. If the output display's HDR to SDR
57      *  ratio is between these values then an interpolation between the two is displayed using the
58      *  math above.
59      */
60     float fDisplayRatioSdr = 1.f;
61     float fDisplayRatioHdr = 2.f;
62 
63     /**
64      *  Whether the base image is the SDR image or the HDR image.
65      */
66     enum class BaseImageType {
67         kSDR,
68         kHDR,
69     };
70     BaseImageType fBaseImageType = BaseImageType::kSDR;
71 
72     inline bool operator==(const SkGainmapInfo& other) {
73         return fGainmapRatioMin == other.fGainmapRatioMin &&
74                fGainmapRatioMax == other.fGainmapRatioMax && fGainmapGamma == other.fGainmapGamma &&
75                fEpsilonSdr == other.fEpsilonSdr && fEpsilonHdr == other.fEpsilonHdr &&
76                fDisplayRatioSdr == other.fDisplayRatioSdr &&
77                fDisplayRatioHdr == other.fDisplayRatioHdr && fBaseImageType == other.fBaseImageType;
78     }
79     inline bool operator!=(const SkGainmapInfo& other) { return !(*this == other); }
80 
81     // TODO(ccameron): Remove these parameters once we are certain they are not used in Android.
82     enum class Type {
83         kUnknown,
84         kMultiPicture,
85         kJpegR_Linear,
86         kJpegR_HLG,
87         kJpegR_PQ,
88         kHDRGM,
89     };
90     SkColor4f fLogRatioMin = {0.f, 0.f, 0.f, 1.0};
91     SkColor4f fLogRatioMax = {1.f, 1.f, 1.f, 1.0};
92     float fHdrRatioMin = 1.f;
93     float fHdrRatioMax = 50.f;
94     Type fType = Type::kUnknown;
95 };
96 
97 #endif
98