blob: fc4f665e688c66f3aa3016d9f43615a45c573182 [file] [log] [blame]
msarettbb9f7742016-05-17 09:31:20 -07001/*
2 * Copyright 2016 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
msarett8cc20912016-05-23 09:29:29 -07008#ifndef SkColorSpace_Base_DEFINED
9#define SkColorSpace_Base_DEFINED
10
11#include "SkColorSpace.h"
msarettab926f02016-05-25 08:53:40 -070012#include "SkData.h"
msarette077e062016-05-24 10:16:53 -070013#include "SkTemplates.h"
msarettbb9f7742016-05-17 09:31:20 -070014
15struct SkGammaCurve {
msarettc4ce6b52016-06-16 07:37:41 -070016 bool isNamed() const {
17 bool result = (SkColorSpace::kNonStandard_GammaNamed != fNamed);
18 SkASSERT(!result || (0.0f == fValue));
19 SkASSERT(!result || (0 == fTableSize));
20 SkASSERT(!result || (0.0f == fG && 0.0f == fE));
21 return result;
22 }
23
msarettbb9f7742016-05-17 09:31:20 -070024 bool isValue() const {
25 bool result = (0.0f != fValue);
msarettc4ce6b52016-06-16 07:37:41 -070026 SkASSERT(!result || SkColorSpace::kNonStandard_GammaNamed == fNamed);
msarettbb9f7742016-05-17 09:31:20 -070027 SkASSERT(!result || (0 == fTableSize));
msaretta4fa4f62016-06-06 10:42:51 -070028 SkASSERT(!result || (0.0f == fG && 0.0f == fE));
msarettbb9f7742016-05-17 09:31:20 -070029 return result;
30 }
31
32 bool isTable() const {
33 bool result = (0 != fTableSize);
msarettc4ce6b52016-06-16 07:37:41 -070034 SkASSERT(!result || SkColorSpace::kNonStandard_GammaNamed == fNamed);
msarettbb9f7742016-05-17 09:31:20 -070035 SkASSERT(!result || (0.0f == fValue));
msaretta4fa4f62016-06-06 10:42:51 -070036 SkASSERT(!result || (0.0f == fG && 0.0f == fE));
msarettbb9f7742016-05-17 09:31:20 -070037 SkASSERT(!result || fTable);
38 return result;
39 }
40
msarett61a999c2016-05-18 06:28:43 -070041 bool isParametric() const {
msaretta4fa4f62016-06-06 10:42:51 -070042 bool result = (0.0f != fG || 0.0f != fE);
msarettc4ce6b52016-06-16 07:37:41 -070043 SkASSERT(!result || SkColorSpace::kNonStandard_GammaNamed == fNamed);
msarett61a999c2016-05-18 06:28:43 -070044 SkASSERT(!result || (0.0f == fValue));
45 SkASSERT(!result || (0 == fTableSize));
46 return result;
47 }
msarettbb9f7742016-05-17 09:31:20 -070048
msarettc4ce6b52016-06-16 07:37:41 -070049 // We have four different ways to represent gamma.
50 // (1) A known, named type:
51 SkColorSpace::GammaNamed fNamed;
52
53 // (2) A single value:
msarettbb9f7742016-05-17 09:31:20 -070054 float fValue;
55
msarettc4ce6b52016-06-16 07:37:41 -070056 // (3) A lookup table:
msarettbb9f7742016-05-17 09:31:20 -070057 uint32_t fTableSize;
58 std::unique_ptr<float[]> fTable;
59
msarettc4ce6b52016-06-16 07:37:41 -070060 // (4) Parameters for a curve:
msarett61a999c2016-05-18 06:28:43 -070061 // Y = (aX + b)^g + c for X >= d
62 // Y = eX + f otherwise
63 float fG;
64 float fA;
65 float fB;
66 float fC;
67 float fD;
68 float fE;
69 float fF;
msarettbb9f7742016-05-17 09:31:20 -070070
msarettc4ce6b52016-06-16 07:37:41 -070071 SkGammaCurve()
72 : fNamed(SkColorSpace::kNonStandard_GammaNamed)
73 , fValue(0.0f)
msarettbb9f7742016-05-17 09:31:20 -070074 , fTableSize(0)
75 , fTable(nullptr)
msarett61a999c2016-05-18 06:28:43 -070076 , fG(0.0f)
77 , fA(0.0f)
78 , fB(0.0f)
79 , fC(0.0f)
80 , fD(0.0f)
81 , fE(0.0f)
82 , fF(0.0f)
msarettbb9f7742016-05-17 09:31:20 -070083 {}
84};
85
86struct SkGammas : public SkRefCnt {
87public:
msarettc4ce6b52016-06-16 07:37:41 -070088 static SkColorSpace::GammaNamed Named(SkGammaCurve curves[3]) {
89 if (SkColorSpace::kLinear_GammaNamed == curves[0].fNamed &&
90 SkColorSpace::kLinear_GammaNamed == curves[1].fNamed &&
91 SkColorSpace::kLinear_GammaNamed == curves[2].fNamed)
92 {
93 return SkColorSpace::kLinear_GammaNamed;
94 }
95
96 if (SkColorSpace::kSRGB_GammaNamed == curves[0].fNamed &&
97 SkColorSpace::kSRGB_GammaNamed == curves[1].fNamed &&
98 SkColorSpace::kSRGB_GammaNamed == curves[2].fNamed)
99 {
100 return SkColorSpace::kSRGB_GammaNamed;
101 }
102
103 if (SkColorSpace::k2Dot2Curve_GammaNamed == curves[0].fNamed &&
104 SkColorSpace::k2Dot2Curve_GammaNamed == curves[1].fNamed &&
105 SkColorSpace::k2Dot2Curve_GammaNamed == curves[2].fNamed)
106 {
107 return SkColorSpace::k2Dot2Curve_GammaNamed;
108 }
109
110 return SkColorSpace::kNonStandard_GammaNamed;
msarettbb9f7742016-05-17 09:31:20 -0700111 }
112
msarettdc27a642016-06-06 12:02:31 -0700113 const SkGammaCurve& operator[](int i) {
114 SkASSERT(0 <= i && i < 3);
115 return (&fRed)[i];
116 }
117
msarett264f88a2016-05-17 13:57:15 -0700118 const SkGammaCurve fRed;
119 const SkGammaCurve fGreen;
120 const SkGammaCurve fBlue;
msarettbb9f7742016-05-17 09:31:20 -0700121
msarett264f88a2016-05-17 13:57:15 -0700122 SkGammas(SkGammaCurve red, SkGammaCurve green, SkGammaCurve blue)
123 : fRed(std::move(red))
124 , fGreen(std::move(green))
125 , fBlue(std::move(blue))
126 {}
127
msarettbb9f7742016-05-17 09:31:20 -0700128 SkGammas() {}
129
130 friend class SkColorSpace;
131};
132
133struct SkColorLookUpTable {
134 static const uint8_t kMaxChannels = 16;
135
136 uint8_t fInputChannels;
137 uint8_t fOutputChannels;
138 uint8_t fGridPoints[kMaxChannels];
139 std::unique_ptr<float[]> fTable;
140
141 SkColorLookUpTable() {
142 memset(this, 0, sizeof(struct SkColorLookUpTable));
143 }
144};
145
msarett8cc20912016-05-23 09:29:29 -0700146class SkColorSpace_Base : public SkColorSpace {
147public:
148
msarettc4ce6b52016-06-16 07:37:41 -0700149 static sk_sp<SkColorSpace> NewRGB(float gammas[3], const SkMatrix44& toXYZD50);
150
msarette077e062016-05-24 10:16:53 -0700151 const sk_sp<SkGammas>& gammas() const { return fGammas; }
msarett8cc20912016-05-23 09:29:29 -0700152
msarettdc27a642016-06-06 12:02:31 -0700153 SkColorLookUpTable* colorLUT() const { return fColorLUT.get(); }
154
msarettab926f02016-05-25 08:53:40 -0700155 /**
156 * Writes this object as an ICC profile.
157 */
158 sk_sp<SkData> writeToICC() const;
159
msarett8cc20912016-05-23 09:29:29 -0700160private:
161
msarettc4ce6b52016-06-16 07:37:41 -0700162 static sk_sp<SkColorSpace> NewRGB(GammaNamed gammaNamed, const SkMatrix44& toXYZD50,
msarettab926f02016-05-25 08:53:40 -0700163 sk_sp<SkData> profileData);
164
msarettc4ce6b52016-06-16 07:37:41 -0700165 SkColorSpace_Base(GammaNamed gammaNamed, const SkMatrix44& toXYZ, Named named,
msarettab926f02016-05-25 08:53:40 -0700166 sk_sp<SkData> profileData);
msarett8cc20912016-05-23 09:29:29 -0700167
msarettc4ce6b52016-06-16 07:37:41 -0700168 SkColorSpace_Base(SkColorLookUpTable* colorLUT, sk_sp<SkGammas> gammas, const SkMatrix44& toXYZ,
169 sk_sp<SkData> profileData);
msarett8cc20912016-05-23 09:29:29 -0700170
171 SkAutoTDelete<SkColorLookUpTable> fColorLUT;
172 sk_sp<SkGammas> fGammas;
msarettab926f02016-05-25 08:53:40 -0700173 sk_sp<SkData> fProfileData;
msarett8cc20912016-05-23 09:29:29 -0700174
175 friend class SkColorSpace;
176 typedef SkColorSpace INHERITED;
177};
178
179static inline SkColorSpace_Base* as_CSB(SkColorSpace* colorSpace) {
180 return static_cast<SkColorSpace_Base*>(colorSpace);
181}
182
msarettab926f02016-05-25 08:53:40 -0700183static inline const SkColorSpace_Base* as_CSB(const SkColorSpace* colorSpace) {
184 return static_cast<const SkColorSpace_Base*>(colorSpace);
185}
186
msarett888dc162016-05-23 10:21:17 -0700187static inline SkColorSpace_Base* as_CSB(const sk_sp<SkColorSpace>& colorSpace) {
188 return static_cast<SkColorSpace_Base*>(colorSpace.get());
189}
190
msarettbb9f7742016-05-17 09:31:20 -0700191#endif