blob: b2d5818e84e31b5e4e58ffcfa8e170be23d07b4b [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));
msarett61a999c2016-05-18 06:28:43 -070019 SkASSERT(!result || (0.0f == fG));
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));
msarett61a999c2016-05-18 06:28:43 -070026 SkASSERT(!result || (0.0f == fG));
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 {
32 bool result = (0.0f != fG);
33 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
msarett264f88a2016-05-17 13:57:15 -070081 const SkGammaCurve fRed;
82 const SkGammaCurve fGreen;
83 const SkGammaCurve fBlue;
msarettbb9f7742016-05-17 09:31:20 -070084
85 SkGammas(float red, float green, float blue)
86 : fRed(red)
87 , fGreen(green)
88 , fBlue(blue)
89 {}
90
msarett264f88a2016-05-17 13:57:15 -070091 SkGammas(SkGammaCurve red, SkGammaCurve green, SkGammaCurve blue)
92 : fRed(std::move(red))
93 , fGreen(std::move(green))
94 , fBlue(std::move(blue))
95 {}
96
msarettbb9f7742016-05-17 09:31:20 -070097 SkGammas() {}
98
99 friend class SkColorSpace;
100};
101
102struct SkColorLookUpTable {
103 static const uint8_t kMaxChannels = 16;
104
105 uint8_t fInputChannels;
106 uint8_t fOutputChannels;
107 uint8_t fGridPoints[kMaxChannels];
108 std::unique_ptr<float[]> fTable;
109
110 SkColorLookUpTable() {
111 memset(this, 0, sizeof(struct SkColorLookUpTable));
112 }
113};
114
msarett8cc20912016-05-23 09:29:29 -0700115class SkColorSpace_Base : public SkColorSpace {
116public:
117
msarette077e062016-05-24 10:16:53 -0700118 const sk_sp<SkGammas>& gammas() const { return fGammas; }
msarett8cc20912016-05-23 09:29:29 -0700119
msarettab926f02016-05-25 08:53:40 -0700120 /**
121 * Writes this object as an ICC profile.
122 */
123 sk_sp<SkData> writeToICC() const;
124
msarett8cc20912016-05-23 09:29:29 -0700125private:
126
msarettab926f02016-05-25 08:53:40 -0700127 static sk_sp<SkColorSpace> NewRGB(const float gammas[3], const SkMatrix44& toXYZD50,
128 sk_sp<SkData> profileData);
129
130 SkColorSpace_Base(sk_sp<SkGammas> gammas, const SkMatrix44& toXYZ, Named,
131 sk_sp<SkData> profileData);
msarett8cc20912016-05-23 09:29:29 -0700132
133 SkColorSpace_Base(sk_sp<SkGammas> gammas, GammaNamed gammaNamed, const SkMatrix44& toXYZ,
msarettab926f02016-05-25 08:53:40 -0700134 Named, sk_sp<SkData> profileData);
msarett8cc20912016-05-23 09:29:29 -0700135
136 SkColorSpace_Base(SkColorLookUpTable* colorLUT, sk_sp<SkGammas> gammas,
msarettab926f02016-05-25 08:53:40 -0700137 const SkMatrix44& toXYZ, sk_sp<SkData> profileData);
msarett8cc20912016-05-23 09:29:29 -0700138
139 SkAutoTDelete<SkColorLookUpTable> fColorLUT;
140 sk_sp<SkGammas> fGammas;
msarettab926f02016-05-25 08:53:40 -0700141 sk_sp<SkData> fProfileData;
msarett8cc20912016-05-23 09:29:29 -0700142
143 friend class SkColorSpace;
144 typedef SkColorSpace INHERITED;
145};
146
147static inline SkColorSpace_Base* as_CSB(SkColorSpace* colorSpace) {
148 return static_cast<SkColorSpace_Base*>(colorSpace);
149}
150
msarettab926f02016-05-25 08:53:40 -0700151static inline const SkColorSpace_Base* as_CSB(const SkColorSpace* colorSpace) {
152 return static_cast<const SkColorSpace_Base*>(colorSpace);
153}
154
msarett888dc162016-05-23 10:21:17 -0700155static inline SkColorSpace_Base* as_CSB(const sk_sp<SkColorSpace>& colorSpace) {
156 return static_cast<SkColorSpace_Base*>(colorSpace.get());
157}
158
msarettbb9f7742016-05-17 09:31:20 -0700159#endif