Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: ui/gfx/color_transform.cc

Issue 2643773006: Color: Use SkColorSpacePrimaries (Closed)
Patch Set: Merge more functions Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/color_transform.h" 5 #include "ui/gfx/color_transform.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 11 matching lines...) Expand all
22 namespace gfx { 22 namespace gfx {
23 23
24 Transform Invert(const Transform& t) { 24 Transform Invert(const Transform& t) {
25 Transform ret = t; 25 Transform ret = t;
26 if (!t.GetInverse(&ret)) { 26 if (!t.GetInverse(&ret)) {
27 LOG(ERROR) << "Inverse should alsways be possible."; 27 LOG(ERROR) << "Inverse should alsways be possible.";
28 } 28 }
29 return ret; 29 return ret;
30 } 30 }
31 31
32 ColorTransform::TriStim Map(const Transform& t, ColorTransform::TriStim color) { 32 void GetPrimaries(ColorSpace::PrimaryID id,
hubbe 2017/01/20 20:15:27 Remove?
ccameron 2017/01/20 23:26:16 Done.
33 t.TransformPoint(&color); 33 SkColorSpacePrimaries* primaries) {
34 return color;
35 } 34 }
36 35
37 ColorTransform::TriStim Xy2xyz(float x, float y) { 36 GFX_EXPORT Transform GetPrimaryMatrix(ColorSpace::PrimaryID id) {
38 return ColorTransform::TriStim(x, y, 1.0f - x - y); 37 SkColorSpacePrimaries primaries = {0};
39 }
40
41 void GetPrimaries(ColorSpace::PrimaryID id,
42 ColorTransform::TriStim primaries[4]) {
43 switch (id) { 38 switch (id) {
44 case ColorSpace::PrimaryID::CUSTOM: 39 case ColorSpace::PrimaryID::CUSTOM:
45 NOTREACHED(); 40 NOTREACHED();
46 41
47 case ColorSpace::PrimaryID::RESERVED0: 42 case ColorSpace::PrimaryID::RESERVED0:
48 case ColorSpace::PrimaryID::RESERVED: 43 case ColorSpace::PrimaryID::RESERVED:
49 case ColorSpace::PrimaryID::UNSPECIFIED: 44 case ColorSpace::PrimaryID::UNSPECIFIED:
50 case ColorSpace::PrimaryID::UNKNOWN: 45 case ColorSpace::PrimaryID::UNKNOWN:
51 case ColorSpace::PrimaryID::BT709: 46 case ColorSpace::PrimaryID::BT709:
52 // BT709 is our default case. Put it after the switch just 47 // BT709 is our default case. Put it after the switch just
53 // in case we somehow get an id which is not listed in the switch. 48 // in case we somehow get an id which is not listed in the switch.
54 // (We don't want to use "default", because we want the compiler 49 // (We don't want to use "default", because we want the compiler
55 // to tell us if we forgot some enum values.) 50 // to tell us if we forgot some enum values.)
51 primaries.fRX = 0.640f;
52 primaries.fRY = 0.330f;
53 primaries.fGX = 0.300f;
54 primaries.fGY = 0.600f;
55 primaries.fBX = 0.150f;
56 primaries.fBY = 0.060f;
57 primaries.fWX = 0.3127f;
58 primaries.fWY = 0.3290f;
56 break; 59 break;
57 60
58 case ColorSpace::PrimaryID::BT470M: 61 case ColorSpace::PrimaryID::BT470M:
59 // Red 62 primaries.fRX = 0.67f;
60 primaries[0] = Xy2xyz(0.67f, 0.33f); 63 primaries.fRY = 0.33f;
61 // Green 64 primaries.fGX = 0.21f;
62 primaries[1] = Xy2xyz(0.21f, 0.71f); 65 primaries.fGY = 0.71f;
63 // Blue 66 primaries.fBX = 0.14f;
64 primaries[2] = Xy2xyz(0.14f, 0.08f); 67 primaries.fBY = 0.08f;
65 // Whitepoint 68 primaries.fWX = 0.31f;
66 primaries[3] = Xy2xyz(0.31f, 0.316f); 69 primaries.fWY = 0.316f;
67 return; 70 break;
68 71
69 case ColorSpace::PrimaryID::BT470BG: 72 case ColorSpace::PrimaryID::BT470BG:
70 // Red 73 primaries.fRX = 0.64f;
71 primaries[0] = Xy2xyz(0.64f, 0.33f); 74 primaries.fRY = 0.33f;
72 // Green 75 primaries.fGX = 0.29f;
73 primaries[1] = Xy2xyz(0.29f, 0.60f); 76 primaries.fGY = 0.60f;
74 // Blue 77 primaries.fBX = 0.15f;
75 primaries[2] = Xy2xyz(0.15f, 0.06f); 78 primaries.fBY = 0.06f;
76 // Whitepoint (D65f) 79 primaries.fWX = 0.3127f;
77 primaries[3] = Xy2xyz(0.3127f, 0.3290f); 80 primaries.fWY = 0.3290f;
78 return; 81 break;
79 82
80 case ColorSpace::PrimaryID::SMPTE170M: 83 case ColorSpace::PrimaryID::SMPTE170M:
81 case ColorSpace::PrimaryID::SMPTE240M: 84 case ColorSpace::PrimaryID::SMPTE240M:
82 // Red 85 primaries.fRX = 0.630f;
83 primaries[0] = Xy2xyz(0.630f, 0.340f); 86 primaries.fRY = 0.340f;
84 // Green 87 primaries.fGX = 0.310f;
85 primaries[1] = Xy2xyz(0.310f, 0.595f); 88 primaries.fGY = 0.595f;
86 // Blue 89 primaries.fBX = 0.155f;
87 primaries[2] = Xy2xyz(0.155f, 0.070f); 90 primaries.fBY = 0.070f;
88 // Whitepoint (D65f) 91 primaries.fWX = 0.3127f;
89 primaries[3] = Xy2xyz(0.3127f, 0.3290f); 92 primaries.fWY = 0.3290f;
90 return; 93 break;
91 94
92 case ColorSpace::PrimaryID::FILM: 95 case ColorSpace::PrimaryID::FILM:
93 // Red 96 primaries.fRX = 0.681f;
94 primaries[0] = Xy2xyz(0.681f, 0.319f); 97 primaries.fRY = 0.319f;
95 // Green 98 primaries.fGX = 0.243f;
96 primaries[1] = Xy2xyz(0.243f, 0.692f); 99 primaries.fGY = 0.692f;
97 // Blue 100 primaries.fBX = 0.145f;
98 primaries[2] = Xy2xyz(0.145f, 0.049f); 101 primaries.fBY = 0.049f;
99 // Whitepoint (Cf) 102 primaries.fWX = 0.310f;
100 primaries[3] = Xy2xyz(0.310f, 0.136f); 103 primaries.fWY = 0.136f;
101 return; 104 break;
102 105
103 case ColorSpace::PrimaryID::BT2020: 106 case ColorSpace::PrimaryID::BT2020:
104 // Red 107 primaries.fRX = 0.708f;
105 primaries[0] = Xy2xyz(0.708f, 0.292f); 108 primaries.fRY = 0.292f;
106 // Green 109 primaries.fGX = 0.170f;
107 primaries[1] = Xy2xyz(0.170f, 0.797f); 110 primaries.fGY = 0.797f;
108 // Blue 111 primaries.fBX = 0.131f;
109 primaries[2] = Xy2xyz(0.131f, 0.046f); 112 primaries.fBY = 0.046f;
110 // Whitepoint (D65f) 113 primaries.fWX = 0.3127f;
111 primaries[3] = Xy2xyz(0.3127f, 0.3290f); 114 primaries.fWY = 0.3290f;
112 return; 115 break;
113 116
114 case ColorSpace::PrimaryID::SMPTEST428_1: 117 case ColorSpace::PrimaryID::SMPTEST428_1:
115 // X 118 primaries.fRX = 1.0f;
116 primaries[0] = Xy2xyz(1.0f, 0.0f); 119 primaries.fRY = 0.0f;
117 // Y 120 primaries.fGX = 0.0f;
118 primaries[1] = Xy2xyz(0.0f, 1.0f); 121 primaries.fGY = 1.0f;
119 // Z 122 primaries.fBX = 0.0f;
120 primaries[2] = Xy2xyz(0.0f, 0.0f); 123 primaries.fBY = 0.0f;
121 // Whitepoint (Ef) 124 primaries.fWX = 1.0f / 3.0f;
122 primaries[3] = Xy2xyz(1.0f / 3.0f, 1.0f / 3.0f); 125 primaries.fWY = 1.0f / 3.0f;
123 return; 126 break;
124 127
125 case ColorSpace::PrimaryID::SMPTEST431_2: 128 case ColorSpace::PrimaryID::SMPTEST431_2:
126 // Red 129 primaries.fRX = 0.680f;
127 primaries[0] = Xy2xyz(0.680f, 0.320f); 130 primaries.fRY = 0.320f;
128 // Green 131 primaries.fGX = 0.265f;
129 primaries[1] = Xy2xyz(0.265f, 0.690f); 132 primaries.fGY = 0.690f;
130 // Blue 133 primaries.fBX = 0.150f;
131 primaries[2] = Xy2xyz(0.150f, 0.060f); 134 primaries.fBY = 0.060f;
132 // Whitepoint 135 primaries.fWX = 0.314f;
133 primaries[3] = Xy2xyz(0.314f, 0.351f); 136 primaries.fWY = 0.351f;
134 return; 137 break;
135 138
136 case ColorSpace::PrimaryID::SMPTEST432_1: 139 case ColorSpace::PrimaryID::SMPTEST432_1:
137 // Red 140 primaries.fRX = 0.680f;
138 primaries[0] = Xy2xyz(0.680f, 0.320f); 141 primaries.fRY = 0.320f;
139 // Green 142 primaries.fGX = 0.265f;
140 primaries[1] = Xy2xyz(0.265f, 0.690f); 143 primaries.fGY = 0.690f;
141 // Blue 144 primaries.fBX = 0.150f;
142 primaries[2] = Xy2xyz(0.150f, 0.060f); 145 primaries.fBY = 0.060f;
143 // Whitepoint (D65f) 146 primaries.fWX = 0.3127f;
144 primaries[3] = Xy2xyz(0.3127f, 0.3290f); 147 primaries.fWY = 0.3290f;
145 return; 148 break;
146 149
147 case ColorSpace::PrimaryID::XYZ_D50: 150 case ColorSpace::PrimaryID::XYZ_D50:
148 // X 151 primaries.fRX = 1.0f;
149 primaries[0] = Xy2xyz(1.0f, 0.0f); 152 primaries.fRY = 0.0f;
150 // Y 153 primaries.fGX = 0.0f;
151 primaries[1] = Xy2xyz(0.0f, 1.0f); 154 primaries.fGY = 1.0f;
152 // Z 155 primaries.fBX = 0.0f;
153 primaries[2] = Xy2xyz(0.0f, 0.0f); 156 primaries.fBY = 0.0f;
154 // D50 157 primaries.fWX = 0.34567f;
155 primaries[3] = Xy2xyz(0.34567f, 0.35850f); 158 primaries.fWY = 0.35850f;
156 return; 159 break;
157 } 160 }
158 161
159 // Red 162 SkMatrix44 matrix;
160 primaries[0] = Xy2xyz(0.640f, 0.330f); 163 primaries.toXYZD50(&matrix);
hubbe 2017/01/20 20:15:27 I assume that this doe the same chromatic adaptati
ccameron 2017/01/20 23:26:16 Yes, see the implementation at: https://cs.chromiu
hubbe 2017/01/20 23:28:15 looks good (but a test would have been even better
161 // Green 164 return Transform(matrix);
162 primaries[1] = Xy2xyz(0.300f, 0.600f);
163 // Blue
164 primaries[2] = Xy2xyz(0.150f, 0.060f);
165 // Whitepoint (D65f)
166 primaries[3] = Xy2xyz(0.3127f, 0.3290f);
167 }
168
169 GFX_EXPORT Transform GetPrimaryMatrix(ColorSpace::PrimaryID id) {
170 ColorTransform::TriStim primaries[4];
171 GetPrimaries(id, primaries);
172 ColorTransform::TriStim WXYZ(primaries[3].x() / primaries[3].y(), 1.0f,
173 primaries[3].z() / primaries[3].y());
174
175 Transform ret(
176 primaries[0].x(), primaries[1].x(), primaries[2].x(), 0.0f, // 1
177 primaries[0].y(), primaries[1].y(), primaries[2].y(), 0.0f, // 2
178 primaries[0].z(), primaries[1].z(), primaries[2].z(), 0.0f, // 3
179 0.0f, 0.0f, 0.0f, 1.0f); // 4
180
181 ColorTransform::TriStim conv = Map(Invert(ret), WXYZ);
182 ret.Scale3d(conv.x(), conv.y(), conv.z());
183
184 // Chromatic adaptation.
185 Transform bradford(0.8951000f, 0.2664000f, -0.1614000f, 0.0f, // 1
186 -0.7502000f, 1.7135000f, 0.0367000f, 0.0f, // 2
187 0.0389000f, -0.0685000f, 1.0296000f, 0.0f, // 3
188 0.0f, 0.0f, 0.0f, 1.0f); // 4
189
190 ColorTransform::TriStim D50(0.9642f, 1.0f, 0.8249f);
191 ColorTransform::TriStim source_response = Map(bradford, WXYZ);
192 ColorTransform::TriStim dest_response = Map(bradford, D50);
193
194 Transform adapter;
195 adapter.Scale3d(dest_response.x() / source_response.x(),
196 dest_response.y() / source_response.y(),
197 dest_response.z() / source_response.z());
198
199 return Invert(bradford) * adapter * bradford * ret;
200 } 165 }
201 166
202 GFX_EXPORT float FromLinear(ColorSpace::TransferID id, float v) { 167 GFX_EXPORT float FromLinear(ColorSpace::TransferID id, float v) {
203 switch (id) { 168 switch (id) {
204 case ColorSpace::TransferID::SMPTEST2084_NON_HDR: 169 case ColorSpace::TransferID::SMPTEST2084_NON_HDR:
205 // Should already be handled. 170 // Should already be handled.
206 NOTREACHED(); 171 NOTREACHED();
207 case ColorSpace::TransferID::CUSTOM: 172 case ColorSpace::TransferID::CUSTOM:
208 // TODO(hubbe): Actually implement custom transfer functions. 173 // TODO(hubbe): Actually implement custom transfer functions.
209 case ColorSpace::TransferID::RESERVED0: 174 case ColorSpace::TransferID::RESERVED0:
(...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 to_profile ? ColorSpace::CreateXYZD50() : to, intent, &builder); 1022 to_profile ? ColorSpace::CreateXYZD50() : to, intent, &builder);
1058 if (to_profile) { 1023 if (to_profile) {
1059 builder.Append(std::unique_ptr<ColorTransformInternal>( 1024 builder.Append(std::unique_ptr<ColorTransformInternal>(
1060 new QCMSColorTransform(GetXYZD50Profile(), to_profile))); 1025 new QCMSColorTransform(GetXYZD50Profile(), to_profile)));
1061 } 1026 }
1062 1027
1063 return builder.GetTransform(); 1028 return builder.GetTransform();
1064 } 1029 }
1065 1030
1066 } // namespace gfx 1031 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698