blob: 6289b09f500ee393b15842558f5ff361fd0b8b84 [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 {}
msarettb3906762016-06-22 14:07:48 -070084
85 bool quickEquals(const SkGammaCurve& that) const {
86 return (this->fNamed == that.fNamed) && (this->fValue == that.fValue) &&
87 (this->fTableSize == that.fTableSize) && (this->fTable == that.fTable) &&
88 (this->fG == that.fG) && (this->fA == that.fA) && (this->fB == that.fB) &&
89 (this->fC == that.fC) && (this->fD == that.fD) && (this->fE == that.fE) &&
90 (this->fF == that.fF);
91 }
msarettbb9f7742016-05-17 09:31:20 -070092};
93
94struct SkGammas : public SkRefCnt {
95public:
msarettc4ce6b52016-06-16 07:37:41 -070096 static SkColorSpace::GammaNamed Named(SkGammaCurve curves[3]) {
97 if (SkColorSpace::kLinear_GammaNamed == curves[0].fNamed &&
98 SkColorSpace::kLinear_GammaNamed == curves[1].fNamed &&
99 SkColorSpace::kLinear_GammaNamed == curves[2].fNamed)
100 {
101 return SkColorSpace::kLinear_GammaNamed;
102 }
103
104 if (SkColorSpace::kSRGB_GammaNamed == curves[0].fNamed &&
105 SkColorSpace::kSRGB_GammaNamed == curves[1].fNamed &&
106 SkColorSpace::kSRGB_GammaNamed == curves[2].fNamed)
107 {
108 return SkColorSpace::kSRGB_GammaNamed;
109 }
110
111 if (SkColorSpace::k2Dot2Curve_GammaNamed == curves[0].fNamed &&
112 SkColorSpace::k2Dot2Curve_GammaNamed == curves[1].fNamed &&
113 SkColorSpace::k2Dot2Curve_GammaNamed == curves[2].fNamed)
114 {
115 return SkColorSpace::k2Dot2Curve_GammaNamed;
116 }
117
118 return SkColorSpace::kNonStandard_GammaNamed;
msarettbb9f7742016-05-17 09:31:20 -0700119 }
120
msarettb3906762016-06-22 14:07:48 -0700121 const SkGammaCurve& operator[](int i) const {
msarettdc27a642016-06-06 12:02:31 -0700122 SkASSERT(0 <= i && i < 3);
123 return (&fRed)[i];
124 }
125
msarett264f88a2016-05-17 13:57:15 -0700126 const SkGammaCurve fRed;
127 const SkGammaCurve fGreen;
128 const SkGammaCurve fBlue;
msarettbb9f7742016-05-17 09:31:20 -0700129
msarett264f88a2016-05-17 13:57:15 -0700130 SkGammas(SkGammaCurve red, SkGammaCurve green, SkGammaCurve blue)
131 : fRed(std::move(red))
132 , fGreen(std::move(green))
133 , fBlue(std::move(blue))
134 {}
135
msarettbb9f7742016-05-17 09:31:20 -0700136 SkGammas() {}
137
138 friend class SkColorSpace;
139};
140
msarett0f83e012016-06-23 15:12:52 -0700141struct SkColorLookUpTable : public SkRefCnt {
msarettbb9f7742016-05-17 09:31:20 -0700142 uint8_t fInputChannels;
143 uint8_t fOutputChannels;
msarett0f83e012016-06-23 15:12:52 -0700144 uint8_t fGridPoints[3];
msarettbb9f7742016-05-17 09:31:20 -0700145 std::unique_ptr<float[]> fTable;
146
msarett0f83e012016-06-23 15:12:52 -0700147 SkColorLookUpTable()
148 : fInputChannels(0)
149 , fOutputChannels(0)
150 , fTable(nullptr)
151 {
152 fGridPoints[0] = fGridPoints[1] = fGridPoints[2] = 0;
msarettbb9f7742016-05-17 09:31:20 -0700153 }
154};
155
msarett8cc20912016-05-23 09:29:29 -0700156class SkColorSpace_Base : public SkColorSpace {
157public:
158
msarettc4ce6b52016-06-16 07:37:41 -0700159 static sk_sp<SkColorSpace> NewRGB(float gammas[3], const SkMatrix44& toXYZD50);
160
msarettb3906762016-06-22 14:07:48 -0700161 const SkGammas* gammas() const { return fGammas.get(); }
msarett8cc20912016-05-23 09:29:29 -0700162
msarettb3906762016-06-22 14:07:48 -0700163 const SkColorLookUpTable* colorLUT() const { return fColorLUT.get(); }
msarettdc27a642016-06-06 12:02:31 -0700164
msarettab926f02016-05-25 08:53:40 -0700165 /**
166 * Writes this object as an ICC profile.
167 */
168 sk_sp<SkData> writeToICC() const;
169
msarett8cc20912016-05-23 09:29:29 -0700170private:
171
msarett111a42d2016-06-22 08:18:54 -0700172 static sk_sp<SkColorSpace> NewRGB(GammaNamed gammaNamed, const SkMatrix44& toXYZD50);
msarettab926f02016-05-25 08:53:40 -0700173
msarett111a42d2016-06-22 08:18:54 -0700174 SkColorSpace_Base(GammaNamed gammaNamed, const SkMatrix44& toXYZ, Named named);
msarett8cc20912016-05-23 09:29:29 -0700175
msarett0f83e012016-06-23 15:12:52 -0700176 SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, sk_sp<SkGammas> gammas,
177 const SkMatrix44& toXYZ, sk_sp<SkData> profileData);
msarett8cc20912016-05-23 09:29:29 -0700178
msarett0f83e012016-06-23 15:12:52 -0700179 sk_sp<SkColorLookUpTable> fColorLUT;
180 sk_sp<SkGammas> fGammas;
181 sk_sp<SkData> fProfileData;
msarett8cc20912016-05-23 09:29:29 -0700182
183 friend class SkColorSpace;
msarettb3906762016-06-22 14:07:48 -0700184 friend class ColorSpaceXformTest;
msarett8cc20912016-05-23 09:29:29 -0700185 typedef SkColorSpace INHERITED;
186};
187
188static inline SkColorSpace_Base* as_CSB(SkColorSpace* colorSpace) {
189 return static_cast<SkColorSpace_Base*>(colorSpace);
190}
191
msarettab926f02016-05-25 08:53:40 -0700192static inline const SkColorSpace_Base* as_CSB(const SkColorSpace* colorSpace) {
193 return static_cast<const SkColorSpace_Base*>(colorSpace);
194}
195
msarett888dc162016-05-23 10:21:17 -0700196static inline SkColorSpace_Base* as_CSB(const sk_sp<SkColorSpace>& colorSpace) {
197 return static_cast<SkColorSpace_Base*>(colorSpace.get());
198}
199
msarettbb9f7742016-05-17 09:31:20 -0700200#endif