blob: ffab17a1fd17276f223a88982f95018abacd79dd [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 {
16 bool isValue() const {
17 bool result = (0.0f != fValue);
18 SkASSERT(!result || (0 == fTableSize));
msaretta4fa4f62016-06-06 10:42:51 -070019 SkASSERT(!result || (0.0f == fG && 0.0f == fE));
msarettbb9f7742016-05-17 09:31:20 -070020 return result;
21 }
22
23 bool isTable() const {
24 bool result = (0 != fTableSize);
25 SkASSERT(!result || (0.0f == fValue));
msaretta4fa4f62016-06-06 10:42:51 -070026 SkASSERT(!result || (0.0f == fG && 0.0f == fE));
msarettbb9f7742016-05-17 09:31:20 -070027 SkASSERT(!result || fTable);
28 return result;
29 }
30
msarett61a999c2016-05-18 06:28:43 -070031 bool isParametric() const {
msaretta4fa4f62016-06-06 10:42:51 -070032 bool result = (0.0f != fG || 0.0f != fE);
msarett61a999c2016-05-18 06:28:43 -070033 SkASSERT(!result || (0.0f == fValue));
34 SkASSERT(!result || (0 == fTableSize));
35 return result;
36 }
msarettbb9f7742016-05-17 09:31:20 -070037
38 // We have three different ways to represent gamma.
39 // (1) A single value:
40 float fValue;
41
42 // (2) A lookup table:
43 uint32_t fTableSize;
44 std::unique_ptr<float[]> fTable;
45
46 // (3) Parameters for a curve:
msarett61a999c2016-05-18 06:28:43 -070047 // Y = (aX + b)^g + c for X >= d
48 // Y = eX + f otherwise
49 float fG;
50 float fA;
51 float fB;
52 float fC;
53 float fD;
54 float fE;
55 float fF;
msarettbb9f7742016-05-17 09:31:20 -070056
57 SkGammaCurve() {
58 memset(this, 0, sizeof(struct SkGammaCurve));
59 }
60
61 SkGammaCurve(float value)
62 : fValue(value)
63 , fTableSize(0)
64 , fTable(nullptr)
msarett61a999c2016-05-18 06:28:43 -070065 , fG(0.0f)
66 , fA(0.0f)
67 , fB(0.0f)
68 , fC(0.0f)
69 , fD(0.0f)
70 , fE(0.0f)
71 , fF(0.0f)
msarettbb9f7742016-05-17 09:31:20 -070072 {}
73};
74
75struct SkGammas : public SkRefCnt {
76public:
77 bool isValues() const {
78 return fRed.isValue() && fGreen.isValue() && fBlue.isValue();
79 }
80
msarettdc27a642016-06-06 12:02:31 -070081 const SkGammaCurve& operator[](int i) {
82 SkASSERT(0 <= i && i < 3);
83 return (&fRed)[i];
84 }
85
msarett264f88a2016-05-17 13:57:15 -070086 const SkGammaCurve fRed;
87 const SkGammaCurve fGreen;
88 const SkGammaCurve fBlue;
msarettbb9f7742016-05-17 09:31:20 -070089
90 SkGammas(float red, float green, float blue)
91 : fRed(red)
92 , fGreen(green)
93 , fBlue(blue)
94 {}
95
msarett264f88a2016-05-17 13:57:15 -070096 SkGammas(SkGammaCurve red, SkGammaCurve green, SkGammaCurve blue)
97 : fRed(std::move(red))
98 , fGreen(std::move(green))
99 , fBlue(std::move(blue))
100 {}
101
msarettbb9f7742016-05-17 09:31:20 -0700102 SkGammas() {}
103
104 friend class SkColorSpace;
105};
106
107struct SkColorLookUpTable {
108 static const uint8_t kMaxChannels = 16;
109
110 uint8_t fInputChannels;
111 uint8_t fOutputChannels;
112 uint8_t fGridPoints[kMaxChannels];
113 std::unique_ptr<float[]> fTable;
114
115 SkColorLookUpTable() {
116 memset(this, 0, sizeof(struct SkColorLookUpTable));
117 }
118};
119
msarett8cc20912016-05-23 09:29:29 -0700120class SkColorSpace_Base : public SkColorSpace {
121public:
122
msarette077e062016-05-24 10:16:53 -0700123 const sk_sp<SkGammas>& gammas() const { return fGammas; }
msarett8cc20912016-05-23 09:29:29 -0700124
msarettdc27a642016-06-06 12:02:31 -0700125 SkColorLookUpTable* colorLUT() const { return fColorLUT.get(); }
126
msarettab926f02016-05-25 08:53:40 -0700127 /**
128 * Writes this object as an ICC profile.
129 */
130 sk_sp<SkData> writeToICC() const;
131
msarett8cc20912016-05-23 09:29:29 -0700132private:
133
msarettab926f02016-05-25 08:53:40 -0700134 static sk_sp<SkColorSpace> NewRGB(const float gammas[3], const SkMatrix44& toXYZD50,
135 sk_sp<SkData> profileData);
136
137 SkColorSpace_Base(sk_sp<SkGammas> gammas, const SkMatrix44& toXYZ, Named,
138 sk_sp<SkData> profileData);
msarett8cc20912016-05-23 09:29:29 -0700139
140 SkColorSpace_Base(sk_sp<SkGammas> gammas, GammaNamed gammaNamed, const SkMatrix44& toXYZ,
msarettab926f02016-05-25 08:53:40 -0700141 Named, sk_sp<SkData> profileData);
msarett8cc20912016-05-23 09:29:29 -0700142
143 SkColorSpace_Base(SkColorLookUpTable* colorLUT, sk_sp<SkGammas> gammas,
msarettab926f02016-05-25 08:53:40 -0700144 const SkMatrix44& toXYZ, sk_sp<SkData> profileData);
msarett8cc20912016-05-23 09:29:29 -0700145
146 SkAutoTDelete<SkColorLookUpTable> fColorLUT;
147 sk_sp<SkGammas> fGammas;
msarettab926f02016-05-25 08:53:40 -0700148 sk_sp<SkData> fProfileData;
msarett8cc20912016-05-23 09:29:29 -0700149
150 friend class SkColorSpace;
151 typedef SkColorSpace INHERITED;
152};
153
154static inline SkColorSpace_Base* as_CSB(SkColorSpace* colorSpace) {
155 return static_cast<SkColorSpace_Base*>(colorSpace);
156}
157
msarettab926f02016-05-25 08:53:40 -0700158static inline const SkColorSpace_Base* as_CSB(const SkColorSpace* colorSpace) {
159 return static_cast<const SkColorSpace_Base*>(colorSpace);
160}
161
msarett888dc162016-05-23 10:21:17 -0700162static inline SkColorSpace_Base* as_CSB(const sk_sp<SkColorSpace>& colorSpace) {
163 return static_cast<SkColorSpace_Base*>(colorSpace.get());
164}
165
msarettbb9f7742016-05-17 09:31:20 -0700166#endif