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

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

Issue 2652503002: Use SkICC in gfx::ICCProfile and gfx::ColorSpace (Closed)
Patch Set: Rebase Created 3 years, 10 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 | « ui/gfx/color_space.h ('k') | ui/gfx/color_transform.h » ('j') | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_space.h" 5 #include "ui/gfx/color_space.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/synchronization/lock.h" 10 #include "base/synchronization/lock.h"
11 #include "third_party/skia/include/core/SkColorSpace.h" 11 #include "third_party/skia/include/core/SkColorSpace.h"
12 #include "ui/gfx/icc_profile.h" 12 #include "ui/gfx/icc_profile.h"
13 13
14 namespace gfx { 14 namespace gfx {
15 15
16 namespace {
17
18 SkColorSpaceTransferFn InvertTransferFn(SkColorSpaceTransferFn fn) {
19 SkColorSpaceTransferFn fn_inv = {0};
20 if (fn.fA > 0 && fn.fG > 0) {
21 double a_to_the_g = pow(fn.fA, fn.fG);
22 fn_inv.fA = 1.f / a_to_the_g;
23 fn_inv.fB = -fn.fE / a_to_the_g;
24 fn_inv.fG = 1.f / fn.fG;
25 }
26 fn_inv.fD = fn.fC * fn.fD + fn.fF;
27 fn_inv.fE = -fn.fB / fn.fA;
28 if (fn.fC != 0) {
29 fn_inv.fC = 1.f / fn.fC;
30 fn_inv.fF = -fn.fF / fn.fC;
31 }
32 return fn_inv;
33 }
34 };
35
16 ColorSpace::PrimaryID ColorSpace::PrimaryIDFromInt(int primary_id) { 36 ColorSpace::PrimaryID ColorSpace::PrimaryIDFromInt(int primary_id) {
17 if (primary_id < 0 || primary_id > static_cast<int>(PrimaryID::LAST)) 37 if (primary_id < 0 || primary_id > static_cast<int>(PrimaryID::LAST))
18 return PrimaryID::UNKNOWN; 38 return PrimaryID::UNKNOWN;
19 if (primary_id > static_cast<int>(PrimaryID::LAST_STANDARD_VALUE) && 39 if (primary_id > static_cast<int>(PrimaryID::LAST_STANDARD_VALUE) &&
20 primary_id < 1000) 40 primary_id < 1000)
21 return PrimaryID::UNKNOWN; 41 return PrimaryID::UNKNOWN;
22 return static_cast<PrimaryID>(primary_id); 42 return static_cast<PrimaryID>(primary_id);
23 } 43 }
24 44
25 ColorSpace::TransferID ColorSpace::TransferIDFromInt(int transfer_id) { 45 ColorSpace::TransferID ColorSpace::TransferIDFromInt(int transfer_id) {
26 if (transfer_id < 0 || transfer_id > static_cast<int>(TransferID::LAST)) 46 if (transfer_id < 0 || transfer_id > static_cast<int>(TransferID::LAST))
27 return TransferID::UNKNOWN; 47 return TransferID::UNKNOWN;
28 if (transfer_id > static_cast<int>(TransferID::LAST_STANDARD_VALUE) && 48 if (transfer_id > static_cast<int>(TransferID::LAST_STANDARD_VALUE) &&
29 transfer_id < 1000) 49 transfer_id < 1000)
30 return TransferID::UNKNOWN; 50 return TransferID::UNKNOWN;
31 return static_cast<TransferID>(transfer_id); 51 return static_cast<TransferID>(transfer_id);
32 } 52 }
33 53
34 ColorSpace::MatrixID ColorSpace::MatrixIDFromInt(int matrix_id) { 54 ColorSpace::MatrixID ColorSpace::MatrixIDFromInt(int matrix_id) {
35 if (matrix_id < 0 || matrix_id > static_cast<int>(MatrixID::LAST)) 55 if (matrix_id < 0 || matrix_id > static_cast<int>(MatrixID::LAST))
36 return MatrixID::UNKNOWN; 56 return MatrixID::UNKNOWN;
37 if (matrix_id > static_cast<int>(MatrixID::LAST_STANDARD_VALUE) && 57 if (matrix_id > static_cast<int>(MatrixID::LAST_STANDARD_VALUE) &&
38 matrix_id < 1000) 58 matrix_id < 1000)
39 return MatrixID::UNKNOWN; 59 return MatrixID::UNKNOWN;
40 return static_cast<MatrixID>(matrix_id); 60 return static_cast<MatrixID>(matrix_id);
41 } 61 }
42 62
43 ColorSpace::ColorSpace() { 63 ColorSpace::ColorSpace() {}
44 memset(custom_primary_matrix_, 0, sizeof(custom_primary_matrix_));
45 }
46 64
47 ColorSpace::ColorSpace(PrimaryID primaries, 65 ColorSpace::ColorSpace(PrimaryID primaries,
48 TransferID transfer, 66 TransferID transfer,
49 MatrixID matrix, 67 MatrixID matrix,
50 RangeID range) 68 RangeID range)
51 : primaries_(primaries), 69 : primaries_(primaries),
52 transfer_(transfer), 70 transfer_(transfer),
53 matrix_(matrix), 71 matrix_(matrix),
54 range_(range) { 72 range_(range) {}
55 memset(custom_primary_matrix_, 0, sizeof(custom_primary_matrix_));
56 // TODO: Set profile_id_
57 }
58 73
59 ColorSpace::ColorSpace(int primaries, int transfer, int matrix, RangeID range) 74 ColorSpace::ColorSpace(int primaries, int transfer, int matrix, RangeID range)
60 : primaries_(PrimaryIDFromInt(primaries)), 75 : primaries_(PrimaryIDFromInt(primaries)),
61 transfer_(TransferIDFromInt(transfer)), 76 transfer_(TransferIDFromInt(transfer)),
62 matrix_(MatrixIDFromInt(matrix)), 77 matrix_(MatrixIDFromInt(matrix)),
63 range_(range) { 78 range_(range) {}
64 memset(custom_primary_matrix_, 0, sizeof(custom_primary_matrix_));
65 // TODO: Set profile_id_
66 }
67 79
68 ColorSpace::ColorSpace(const ColorSpace& other) 80 ColorSpace::ColorSpace(const ColorSpace& other)
69 : primaries_(other.primaries_), 81 : primaries_(other.primaries_),
70 transfer_(other.transfer_), 82 transfer_(other.transfer_),
71 matrix_(other.matrix_), 83 matrix_(other.matrix_),
72 range_(other.range_), 84 range_(other.range_),
73 icc_profile_id_(other.icc_profile_id_), 85 icc_profile_id_(other.icc_profile_id_),
74 sk_color_space_(other.sk_color_space_) { 86 icc_profile_sk_color_space_(other.icc_profile_sk_color_space_) {
75 memcpy(custom_primary_matrix_, other.custom_primary_matrix_, 87 if (transfer_ == TransferID::CUSTOM) {
76 sizeof(custom_primary_matrix_)); 88 memcpy(custom_transfer_params_, other.custom_transfer_params_,
89 sizeof(custom_transfer_params_));
90 }
91 if (primaries_ == PrimaryID::CUSTOM) {
92 memcpy(custom_primary_matrix_, other.custom_primary_matrix_,
93 sizeof(custom_primary_matrix_));
94 }
77 } 95 }
78 96
79 ColorSpace::~ColorSpace() = default; 97 ColorSpace::~ColorSpace() = default;
80 98
81 // static 99 // static
82 ColorSpace ColorSpace::CreateSRGB() { 100 ColorSpace ColorSpace::CreateSRGB() {
83 ColorSpace result(PrimaryID::BT709, TransferID::IEC61966_2_1, MatrixID::RGB, 101 return ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_1, MatrixID::RGB,
84 RangeID::FULL); 102 RangeID::FULL);
85 result.sk_color_space_ = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
86 return result;
87 } 103 }
88 104
89 // static 105 // static
90 ColorSpace ColorSpace::CreateSCRGBLinear() { 106 ColorSpace ColorSpace::CreateSCRGBLinear() {
91 return ColorSpace(PrimaryID::BT709, TransferID::LINEAR_HDR, MatrixID::RGB, 107 return ColorSpace(PrimaryID::BT709, TransferID::LINEAR_HDR, MatrixID::RGB,
92 RangeID::FULL); 108 RangeID::FULL);
93 } 109 }
94 110
95 // Static 111 // Static
96 ColorSpace ColorSpace::CreateXYZD50() { 112 ColorSpace ColorSpace::CreateXYZD50() {
(...skipping 20 matching lines...) Expand all
117 } 133 }
118 134
119 bool ColorSpace::operator==(const ColorSpace& other) const { 135 bool ColorSpace::operator==(const ColorSpace& other) const {
120 if (primaries_ != other.primaries_ || transfer_ != other.transfer_ || 136 if (primaries_ != other.primaries_ || transfer_ != other.transfer_ ||
121 matrix_ != other.matrix_ || range_ != other.range_) 137 matrix_ != other.matrix_ || range_ != other.range_)
122 return false; 138 return false;
123 if (primaries_ == PrimaryID::CUSTOM && 139 if (primaries_ == PrimaryID::CUSTOM &&
124 memcmp(custom_primary_matrix_, other.custom_primary_matrix_, 140 memcmp(custom_primary_matrix_, other.custom_primary_matrix_,
125 sizeof(custom_primary_matrix_))) 141 sizeof(custom_primary_matrix_)))
126 return false; 142 return false;
143 if (transfer_ == TransferID::CUSTOM &&
144 memcmp(custom_transfer_params_, other.custom_transfer_params_,
145 sizeof(custom_transfer_params_)))
146 return false;
127 return true; 147 return true;
128 } 148 }
129 149
130 bool ColorSpace::IsHDR() const { 150 bool ColorSpace::IsHDR() const {
131 return transfer_ == TransferID::SMPTEST2084 || 151 return transfer_ == TransferID::SMPTEST2084 ||
132 transfer_ == TransferID::ARIB_STD_B67 || 152 transfer_ == TransferID::ARIB_STD_B67 ||
133 transfer_ == TransferID::LINEAR_HDR; 153 transfer_ == TransferID::LINEAR_HDR;
134 } 154 }
135 155
136 bool ColorSpace::operator!=(const ColorSpace& other) const { 156 bool ColorSpace::operator!=(const ColorSpace& other) const {
(...skipping 19 matching lines...) Expand all
156 return false; 176 return false;
157 if (primaries_ == PrimaryID::CUSTOM) { 177 if (primaries_ == PrimaryID::CUSTOM) {
158 int primary_result = 178 int primary_result =
159 memcmp(custom_primary_matrix_, other.custom_primary_matrix_, 179 memcmp(custom_primary_matrix_, other.custom_primary_matrix_,
160 sizeof(custom_primary_matrix_)); 180 sizeof(custom_primary_matrix_));
161 if (primary_result < 0) 181 if (primary_result < 0)
162 return true; 182 return true;
163 if (primary_result > 0) 183 if (primary_result > 0)
164 return false; 184 return false;
165 } 185 }
186 if (transfer_ == TransferID::CUSTOM) {
187 int transfer_result =
188 memcmp(custom_transfer_params_, other.custom_transfer_params_,
189 sizeof(custom_transfer_params_));
190 if (transfer_result < 0)
191 return true;
192 if (transfer_result > 0)
193 return false;
194 }
166 return false; 195 return false;
167 } 196 }
168 197
198 sk_sp<SkColorSpace> ColorSpace::ToSkColorSpace() const {
199 // If we got a specific SkColorSpace from the ICCProfile that this color space
200 // was created from, use that.
201 if (icc_profile_sk_color_space_)
202 return icc_profile_sk_color_space_;
203
204 // Unspecified color spaces correspond to the null SkColorSpace.
205 if (primaries_ == PrimaryID::UNSPECIFIED ||
206 transfer_ == TransferID::UNSPECIFIED) {
207 return nullptr;
208 }
209
210 // Handle only full-range RGB spaces.
211 if (matrix_ != MatrixID::RGB) {
212 DLOG(ERROR) << "Not creating non-RGB SkColorSpace";
213 return nullptr;
214 }
215 if (range_ != RangeID::FULL) {
216 DLOG(ERROR) << "Not creating non-full-range SkColorSpace";
217 return nullptr;
218 }
219
220 // Use the named SRGB and linear-SRGB instead of the generic constructors.
221 if (primaries_ == PrimaryID::BT709) {
222 if (transfer_ == TransferID::IEC61966_2_1)
223 return SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
224 if (transfer_ == TransferID::LINEAR || transfer_ == TransferID::LINEAR_HDR)
225 return SkColorSpace::MakeNamed(SkColorSpace::kSRGBLinear_Named);
226 }
227
228 SkMatrix44 to_xyz_d50;
229 GetPrimaryMatrix(&to_xyz_d50);
230
231 // Use the named sRGB and linear transfer functions.
232 if (transfer_ == TransferID::IEC61966_2_1) {
233 return SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
234 to_xyz_d50);
235 }
236 if (transfer_ == TransferID::LINEAR || transfer_ == TransferID::LINEAR_HDR) {
237 return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
238 to_xyz_d50);
239 }
240
241 // Use the parametric transfer function if no other option is available.
242 SkColorSpaceTransferFn fn;
243 if (!GetTransferFunction(&fn)) {
244 DLOG(ERROR) << "Failed to parameterize transfer function for SkColorSpace";
245 return nullptr;
246 }
247 return SkColorSpace::MakeRGB(fn, to_xyz_d50);
248 }
249
169 ColorSpace ColorSpace::FromSkColorSpace( 250 ColorSpace ColorSpace::FromSkColorSpace(
170 const sk_sp<SkColorSpace>& sk_color_space) { 251 const sk_sp<SkColorSpace>& sk_color_space) {
171 if (!sk_color_space) 252 if (!sk_color_space)
172 return gfx::ColorSpace(); 253 return gfx::ColorSpace();
173 if (SkColorSpace::Equals( 254 if (SkColorSpace::Equals(
174 sk_color_space.get(), 255 sk_color_space.get(),
175 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).get())) 256 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).get()))
176 return gfx::ColorSpace::CreateSRGB(); 257 return gfx::ColorSpace::CreateSRGB();
177 258
178 // TODO(crbug.com/634102): Add conversion to gfx::ColorSpace for 259 // TODO(crbug.com/634102): Add conversion to gfx::ColorSpace for
179 // non-ICC-profile based color spaces. 260 // non-ICC-profile based color spaces.
180 ICCProfile icc_profile = ICCProfile::FromSkColorSpace(sk_color_space); 261 ICCProfile icc_profile = ICCProfile::FromSkColorSpace(sk_color_space);
181 return icc_profile.GetColorSpace(); 262 return icc_profile.GetColorSpace();
182 } 263 }
183 264
265 void ColorSpace::GetPrimaryMatrix(SkMatrix44* to_XYZD50) const {
266 SkColorSpacePrimaries primaries = {0};
267 switch (primaries_) {
268 case ColorSpace::PrimaryID::CUSTOM:
269 to_XYZD50->set3x3RowMajorf(custom_primary_matrix_);
270 return;
271
272 case ColorSpace::PrimaryID::RESERVED0:
273 case ColorSpace::PrimaryID::RESERVED:
274 case ColorSpace::PrimaryID::UNSPECIFIED:
275 case ColorSpace::PrimaryID::UNKNOWN:
276 case ColorSpace::PrimaryID::BT709:
277 // BT709 is our default case. Put it after the switch just
278 // in case we somehow get an id which is not listed in the switch.
279 // (We don't want to use "default", because we want the compiler
280 // to tell us if we forgot some enum values.)
281 primaries.fRX = 0.640f;
282 primaries.fRY = 0.330f;
283 primaries.fGX = 0.300f;
284 primaries.fGY = 0.600f;
285 primaries.fBX = 0.150f;
286 primaries.fBY = 0.060f;
287 primaries.fWX = 0.3127f;
288 primaries.fWY = 0.3290f;
289 break;
290
291 case ColorSpace::PrimaryID::BT470M:
292 primaries.fRX = 0.67f;
293 primaries.fRY = 0.33f;
294 primaries.fGX = 0.21f;
295 primaries.fGY = 0.71f;
296 primaries.fBX = 0.14f;
297 primaries.fBY = 0.08f;
298 primaries.fWX = 0.31f;
299 primaries.fWY = 0.316f;
300 break;
301
302 case ColorSpace::PrimaryID::BT470BG:
303 primaries.fRX = 0.64f;
304 primaries.fRY = 0.33f;
305 primaries.fGX = 0.29f;
306 primaries.fGY = 0.60f;
307 primaries.fBX = 0.15f;
308 primaries.fBY = 0.06f;
309 primaries.fWX = 0.3127f;
310 primaries.fWY = 0.3290f;
311 break;
312
313 case ColorSpace::PrimaryID::SMPTE170M:
314 case ColorSpace::PrimaryID::SMPTE240M:
315 primaries.fRX = 0.630f;
316 primaries.fRY = 0.340f;
317 primaries.fGX = 0.310f;
318 primaries.fGY = 0.595f;
319 primaries.fBX = 0.155f;
320 primaries.fBY = 0.070f;
321 primaries.fWX = 0.3127f;
322 primaries.fWY = 0.3290f;
323 break;
324
325 case ColorSpace::PrimaryID::FILM:
326 primaries.fRX = 0.681f;
327 primaries.fRY = 0.319f;
328 primaries.fGX = 0.243f;
329 primaries.fGY = 0.692f;
330 primaries.fBX = 0.145f;
331 primaries.fBY = 0.049f;
332 primaries.fWX = 0.310f;
333 primaries.fWY = 0.136f;
334 break;
335
336 case ColorSpace::PrimaryID::BT2020:
337 primaries.fRX = 0.708f;
338 primaries.fRY = 0.292f;
339 primaries.fGX = 0.170f;
340 primaries.fGY = 0.797f;
341 primaries.fBX = 0.131f;
342 primaries.fBY = 0.046f;
343 primaries.fWX = 0.3127f;
344 primaries.fWY = 0.3290f;
345 break;
346
347 case ColorSpace::PrimaryID::SMPTEST428_1:
348 primaries.fRX = 1.0f;
349 primaries.fRY = 0.0f;
350 primaries.fGX = 0.0f;
351 primaries.fGY = 1.0f;
352 primaries.fBX = 0.0f;
353 primaries.fBY = 0.0f;
354 primaries.fWX = 1.0f / 3.0f;
355 primaries.fWY = 1.0f / 3.0f;
356 break;
357
358 case ColorSpace::PrimaryID::SMPTEST431_2:
359 primaries.fRX = 0.680f;
360 primaries.fRY = 0.320f;
361 primaries.fGX = 0.265f;
362 primaries.fGY = 0.690f;
363 primaries.fBX = 0.150f;
364 primaries.fBY = 0.060f;
365 primaries.fWX = 0.314f;
366 primaries.fWY = 0.351f;
367 break;
368
369 case ColorSpace::PrimaryID::SMPTEST432_1:
370 primaries.fRX = 0.680f;
371 primaries.fRY = 0.320f;
372 primaries.fGX = 0.265f;
373 primaries.fGY = 0.690f;
374 primaries.fBX = 0.150f;
375 primaries.fBY = 0.060f;
376 primaries.fWX = 0.3127f;
377 primaries.fWY = 0.3290f;
378 break;
379
380 case ColorSpace::PrimaryID::XYZ_D50:
381 primaries.fRX = 1.0f;
382 primaries.fRY = 0.0f;
383 primaries.fGX = 0.0f;
384 primaries.fGY = 1.0f;
385 primaries.fBX = 0.0f;
386 primaries.fBY = 0.0f;
387 primaries.fWX = 0.34567f;
388 primaries.fWY = 0.35850f;
389 break;
390 }
391 primaries.toXYZD50(to_XYZD50);
392 }
393
394 bool ColorSpace::GetTransferFunction(SkColorSpaceTransferFn* fn) const {
395 // Default to F(x) = pow(x, 1)
396 fn->fA = 1;
397 fn->fB = 0;
398 fn->fC = 1;
399 fn->fD = 0;
400 fn->fE = 0;
401 fn->fF = 0;
402 fn->fG = 1;
403
404 switch (transfer_) {
405 case ColorSpace::TransferID::CUSTOM:
406 fn->fA = custom_transfer_params_[0];
407 fn->fB = custom_transfer_params_[1];
408 fn->fC = custom_transfer_params_[2];
409 fn->fD = custom_transfer_params_[3];
410 fn->fE = custom_transfer_params_[4];
411 fn->fF = custom_transfer_params_[5];
412 fn->fG = custom_transfer_params_[6];
413 return true;
414 case ColorSpace::TransferID::LINEAR:
415 case ColorSpace::TransferID::LINEAR_HDR:
416 return true;
417 case ColorSpace::TransferID::GAMMA22:
418 fn->fG = 2.2f;
419 return true;
420 case ColorSpace::TransferID::GAMMA24:
421 fn->fG = 2.4f;
422 return true;
423 case ColorSpace::TransferID::GAMMA28:
424 fn->fG = 2.8f;
425 return true;
426 case ColorSpace::TransferID::RESERVED0:
427 case ColorSpace::TransferID::RESERVED:
428 case ColorSpace::TransferID::UNSPECIFIED:
429 case ColorSpace::TransferID::UNKNOWN:
430 // All unknown values default to BT709
431 case ColorSpace::TransferID::BT709:
432 case ColorSpace::TransferID::SMPTE170M:
433 case ColorSpace::TransferID::BT2020_10:
434 case ColorSpace::TransferID::BT2020_12:
435 fn->fA = 0.909672431050f;
436 fn->fB = 0.090327568950f;
437 fn->fC = 0.222222222222f;
438 fn->fD = 0.081242862158f;
439 fn->fG = 2.222222222222f;
440 return true;
441 case ColorSpace::TransferID::SMPTE240M:
442 fn->fA = 0.899626676224f;
443 fn->fB = 0.100373323776f;
444 fn->fC = 0.250000000000f;
445 fn->fD = 0.091286342118f;
446 fn->fG = 2.222222222222f;
447 return true;
448 case ColorSpace::TransferID::IEC61966_2_1:
449 fn->fA = 0.947867345704f;
450 fn->fB = 0.052132654296f;
451 fn->fC = 0.077399380805f;
452 fn->fD = 0.040449937172f;
453 fn->fG = 2.400000000000f;
454 return true;
455 case ColorSpace::TransferID::SMPTEST428_1:
456 fn->fA = 0.225615407568f;
457 fn->fE = -1.091041666667f;
458 fn->fG = 2.600000000000f;
459 return true;
460 case ColorSpace::TransferID::IEC61966_2_4:
461 // This could potentially be represented the same as IEC61966_2_1, but
462 // it handles negative values differently.
463 break;
464 case ColorSpace::TransferID::ARIB_STD_B67:
465 case ColorSpace::TransferID::BT1361_ECG:
466 case ColorSpace::TransferID::LOG:
467 case ColorSpace::TransferID::LOG_SQRT:
468 case ColorSpace::TransferID::SMPTEST2084:
469 case ColorSpace::TransferID::SMPTEST2084_NON_HDR:
470 break;
471 }
472
473 return false;
474 }
475
476 bool ColorSpace::GetInverseTransferFunction(SkColorSpaceTransferFn* fn) const {
477 if (!GetTransferFunction(fn))
478 return false;
479 *fn = InvertTransferFn(*fn);
480 return true;
481 }
482
184 } // namespace gfx 483 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/color_space.h ('k') | ui/gfx/color_transform.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698