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

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

Issue 2203663002: ColorTransform, transforms colors from one color space to another (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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_transform.h ('k') | ui/gfx/color_transform_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/gfx/color_transform.h"
6
7 #include <vector>
8
9 #include "base/logging.h"
10 #include "ui/gfx/color_space.h"
11 #include "ui/gfx/transform.h"
12
13 namespace gfx {
14
15 Transform Invert(const Transform& t) {
16 Transform ret = t;
17 if (!t.GetInverse(&ret)) {
18 LOG(ERROR) << "Inverse should alsways be possible.";
19 }
20 return ret;
21 }
22
23 ColorTransform::TriStim Map(const Transform& t, ColorTransform::TriStim color) {
24 t.TransformPoint(&color);
25 return color;
26 }
27
28 // XY color coordinate
29 typedef std::pair<float, float> XY;
ccameron 2016/08/02 02:47:38 use gfx::PointF instead of std::pair<float,float>
hubbe 2016/08/02 08:10:57 Gone.
30
31 std::vector<XY> GetPrimaries(ColorSpace::PrimaryID id) {
ccameron 2016/08/02 02:47:38 Don't return a std::vector here -- pass the return
hubbe 2016/08/02 08:10:57 Calling the arguments red/green/blue is somewhat m
ccameron 2016/08/02 17:12:57 Yeah, I was wondering about that ... in particular
32 std::vector<XY> ret(4);
33 switch (id) {
34 default:
35 // If we don't know, assume BT709
36
37 case ColorSpace::PrimaryID::BT709:
38 // Red
39 ret[0].first = 0.640;
40 ret[0].second = 0.330;
41 // Green
42 ret[1].first = 0.300;
43 ret[1].second = 0.600;
44 // Blue
45 ret[2].first = 0.150;
46 ret[2].second = 0.060;
47 // Whitepoint (D65)
48 ret[3].first = 0.3127;
49 ret[3].second = 0.3290;
50 break;
51
52 case ColorSpace::PrimaryID::BT470M:
53 // Red
54 ret[0].first = 0.67;
55 ret[0].second = 0.33;
56 // Green
57 ret[1].first = 0.21;
58 ret[1].second = 0.71;
59 // Blue
60 ret[2].first = 0.14;
61 ret[2].second = 0.08;
62 // Whitepoint
63 ret[3].first = 0.31;
64 ret[3].second = 0.316;
65 break;
66
67 case ColorSpace::PrimaryID::BT470BG:
68 // Red
69 ret[0].first = 0.64;
70 ret[0].second = 0.33;
71 // Green
72 ret[1].first = 0.29;
73 ret[1].second = 0.60;
74 // Blue
75 ret[2].first = 0.15;
76 ret[2].second = 0.06;
77 // Whitepoint (D65)
78 ret[3].first = 0.3127;
79 ret[3].second = 0.3290;
80 break;
81
82 case ColorSpace::PrimaryID::SMPTE170M:
83 case ColorSpace::PrimaryID::SMPTE240M:
84 // Red
85 ret[0].first = 0.630;
86 ret[0].second = 0.340;
87 // Green
88 ret[1].first = 0.310;
89 ret[1].second = 0.595;
90 // Blue
91 ret[2].first = 0.155;
92 ret[2].second = 0.070;
93 // Whitepoint (D65)
94 ret[3].first = 0.3127;
95 ret[3].second = 0.3290;
96 break;
97
98 case ColorSpace::PrimaryID::FILM:
99 // Red
100 ret[0].first = 0.681;
101 ret[0].second = 0.319;
102 // Green
103 ret[1].first = 0.243;
104 ret[1].second = 0.692;
105 // Blue
106 ret[2].first = 0.145;
107 ret[2].second = 0.049;
108 // Whitepoint (C)
109 ret[3].first = 0.310;
110 ret[3].second = 0.136;
111 break;
112
113 case ColorSpace::PrimaryID::BT2020:
114 // Red
115 ret[0].first = 0.708;
116 ret[0].second = 0.292;
117 // Green
118 ret[1].first = 0.170;
119 ret[1].second = 0.797;
120 // Blue
121 ret[2].first = 0.131;
122 ret[2].second = 0.046;
123 // Whitepoint (D65)
124 ret[3].first = 0.3127;
125 ret[3].second = 0.3290;
126 break;
127
128 case ColorSpace::PrimaryID::SMPTEST428_1:
129 // X
130 ret[0].first = 1.0;
131 ret[0].second = 0.0;
132 // Y
133 ret[1].first = 0.0;
134 ret[1].second = 1.0;
135 // Z
136 ret[2].first = 0.0;
137 ret[2].second = 0.0;
138 // Whitepoint (E)
139 ret[3].first = 1.0f / 3.0f;
140 ret[3].second = 1.0f / 3.0f;
141 break;
142
143 case ColorSpace::PrimaryID::SMPTEST431_2:
144 // Red
145 ret[0].first = 0.680;
146 ret[0].second = 0.320;
147 // Green
148 ret[1].first = 0.265;
149 ret[1].second = 0.690;
150 // Blue
151 ret[2].first = 0.150;
152 ret[2].second = 0.060;
153 // Whitepoint
154 ret[3].first = 0.314;
155 ret[3].second = 0.351;
156 break;
157
158 case ColorSpace::PrimaryID::SMPTEST432_1:
159 // Red
160 ret[0].first = 0.680;
161 ret[0].second = 0.320;
162 // Green
163 ret[1].first = 0.265;
164 ret[1].second = 0.690;
165 // Blue
166 ret[2].first = 0.150;
167 ret[2].second = 0.060;
168 // Whitepoint (D65)
169 ret[3].first = 0.3127;
170 ret[3].second = 0.3290;
171 break;
172
173 case ColorSpace::PrimaryID::XYZ_D50:
174 // X
175 ret[0].first = 1.0;
176 ret[0].second = 0.0;
177 // Y
178 ret[1].first = 0.0;
179 ret[1].second = 1.0;
180 // Z
181 ret[2].first = 0.0;
182 ret[2].second = 0.0;
183 // D50
184 ret[3].first = 0.34567;
185 ret[3].second = 0.35850;
186 break;
187 }
188 return ret;
189 }
190
191 ColorTransform::TriStim xy2xyz(const XY& xy) {
ccameron 2016/08/02 02:47:39 naming nit: rename to XYToTriStim Function names
hubbe 2016/08/02 08:10:57 That doesn't specify what color space the tristim
192 return ColorTransform::TriStim(xy.first, xy.second,
193 1.0f - xy.first - xy.second);
194 }
195
196 GFX_EXPORT Transform GetPrimaryMatrix(ColorSpace::PrimaryID id) {
ccameron 2016/08/02 02:47:38 This can be made simpler by using the existing mat
hubbe 2016/08/02 08:10:57 I like Scale3d, but I think the order in your func
ccameron 2016/08/02 17:12:57 Makes sense.
197 std::vector<XY> primaries = GetPrimaries(id);
198 ColorTransform::TriStim Rxyz = xy2xyz(primaries[0]);
199 ColorTransform::TriStim Gxyz = xy2xyz(primaries[1]);
200 ColorTransform::TriStim Bxyz = xy2xyz(primaries[2]);
201 ColorTransform::TriStim Wxyz = xy2xyz(primaries[3]);
ccameron 2016/08/02 17:12:57 Y was wondering why we didn't call them just "prim
202 ColorTransform::TriStim WXYZ(Wxyz.x() / Wxyz.y(), 1.0f, Wxyz.z() / Wxyz.y());
203
204 Transform tmp(Rxyz.x(), Gxyz.x(), Bxyz.x(), 0.0f, Rxyz.y(), Gxyz.y(),
205 Bxyz.y(), 0.0f, Rxyz.z(), Gxyz.z(), Bxyz.z(), 0.0f, 0.0f, 0.0f,
206 0.0f, 1.0f);
207
208 ColorTransform::TriStim conv = Map(Invert(tmp), WXYZ);
209 Transform ret(
210 conv.x() * tmp.matrix().get(0, 0), conv.y() * tmp.matrix().get(0, 1),
211 conv.z() * tmp.matrix().get(0, 2), 0.0f,
212 conv.x() * tmp.matrix().get(1, 0), conv.y() * tmp.matrix().get(1, 1),
213 conv.z() * tmp.matrix().get(1, 2), 0.0f,
214 conv.x() * tmp.matrix().get(2, 0), conv.y() * tmp.matrix().get(2, 1),
215 conv.z() * tmp.matrix().get(2, 2), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
216
217 // Chromatic adaptation.
218 Transform bradford(0.8951000f, 0.2664000f, -0.1614000f, 0.0f, -0.7502000f,
219 1.7135000f, 0.0367000f, 0.0f, 0.0389000f, -0.0685000f,
220 1.0296000f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
221
222 Transform bradford_inv = Invert(bradford);
223
224 ColorTransform::TriStim D50(0.9642, 1.0000, 0.8249);
225 ColorTransform::TriStim source_response = Map(bradford, WXYZ);
226 ColorTransform::TriStim dest_response = Map(bradford, D50);
227
228 Transform adapter(dest_response.x() / source_response.x(), 0.0f, 0.0f, 0.0f,
229 0.0f, dest_response.y() / source_response.y(), 0.0f, 0.0f,
230 0.0f, 0.0f, dest_response.z() / source_response.z(), 0.0f,
231 0.0f, 0.0f, 0.0f, 1.0f);
232
233 return bradford * adapter * bradford_inv * ret;
234 }
235
236 GFX_EXPORT float fromLinear(ColorSpace::TransferID id, float v) {
ccameron 2016/08/02 02:47:39 Nit: capitalization: FromLinear.
hubbe 2016/08/02 08:10:57 Done.
237 switch (id) {
238 default:
239 case ColorSpace::TransferID::BT709:
240 case ColorSpace::TransferID::SMPTE170M:
241 case ColorSpace::TransferID::BT2020_10:
242 case ColorSpace::TransferID::BT2020_12: {
243 v = fmax(0.0f, v);
244 float a = 1.099296826809442f;
245 float b = 0.018053968510807;
246 if (v <= b) {
247 return 4.5f * v;
248 } else {
249 return a * pow(v, 0.45f) - (a - 1.0f);
250 }
251 }
252
253 case ColorSpace::TransferID::GAMMA22:
254 v = fmax(0.0f, v);
255 return pow(v, 1.0f / 2.2f);
256
257 case ColorSpace::TransferID::GAMMA28:
258 v = fmax(0.0f, v);
259 return pow(v, 1.0f / 2.8f);
260
261 case ColorSpace::TransferID::SMPTE240M: {
262 v = fmax(0.0f, v);
263 float a = 1.11157219592173128753f;
264 float b = 0.02282158552944503135f;
265 if (v <= b) {
266 return 4.0f * v;
267 } else {
268 return a * pow(v, 0.45f) - (a - 1.0f);
269 }
270 }
271
272 case ColorSpace::TransferID::LINEAR:
273 return v;
274
275 case ColorSpace::TransferID::LOG:
276 if (v < 0.01)
277 return 0.0;
278 return 1.0 + log(v) / log(10.0f) / 2.0f;
279
280 case ColorSpace::TransferID::LOG_SQRT:
281 if (v < sqrt(10.0f) / 1000.0)
282 return 0.0;
283 return 1.0 + log(v) / log(10.0f) / 2.5f;
284
285 case ColorSpace::TransferID::IEC61966_2_4: {
286 float a = 1.099296826809442f;
287 float b = 0.018053968510807f;
288 if (v < -b) {
289 return -a * pow(-v, 0.45) + (a - 1.0f);
290 } else if (v <= b) {
291 return 4.5 * v;
292 } else {
293 return a * pow(v, 0.45) - (a - 1.0f);
294 }
295 }
296
297 case ColorSpace::TransferID::BT1361_ECG: {
298 float a = 1.099;
299 float b = 0.018;
300 float l = 0.0045;
301 if (v < -l) {
302 return -(a * pow(-4.0f * v, 0.45) + (a - 1.0f)) / 4.0f;
303 } else if (v <= b) {
304 return 4.5 * v;
305 } else {
306 return a * pow(v, 0.45) - (a - 1.0f);
307 }
308 }
309
310 case ColorSpace::TransferID::IEC61966_2_1: { // SRGB
311 v = fmax(0.0f, v);
312 float a = 1.055f;
313 float b = 0.0031308f;
314 if (v < b) {
315 return 12.92f * v;
316 } else {
317 return a * pow(v, 1.0f / 2.4f) - (a - 1.0f);
318 }
319 }
320 case ColorSpace::TransferID::SMPTEST2084: {
321 v = fmax(0.0f, v);
322 float m1 = (2610.0 / 4096.0) / 4.0;
323 float m2 = (2523.0 / 4096.0) * 128.0;
324 float c1 = 3424.0 / 4096.0;
325 float c2 = (2413.0 / 4096.0) * 32.0;
326 float c3 = (2392.0 / 4096.0) * 32.0;
327 return pow((c1 + c2 * pow(v, m1)) / (1.0f + c3 * pow(v, m1)), m2);
328 }
329
330 case ColorSpace::TransferID::SMPTEST428_1:
331 v = fmax(0.0f, v);
332 return pow(48.0f * v + 52.37f, 1.0f / 2.6f);
333
334 // Chrome-specific values below
335 case ColorSpace::TransferID::GAMMA24:
336 v = fmax(0.0f, v);
337 return pow(v, 1.0f / 2.4f);
338 }
339 }
340
341 GFX_EXPORT float toLinear(ColorSpace::TransferID id, float v) {
ccameron 2016/08/02 02:47:38 nit: ToLinear
hubbe 2016/08/02 08:10:57 Done.
342 switch (id) {
343 default:
344 case ColorSpace::TransferID::BT709:
345 case ColorSpace::TransferID::SMPTE170M:
346 case ColorSpace::TransferID::BT2020_10:
347 case ColorSpace::TransferID::BT2020_12: {
348 v = fmax(0.0f, v);
349 float a = 1.099296826809442f;
350 float b = 0.018053968510807;
351 if (v < fromLinear(ColorSpace::TransferID::BT709, b)) {
352 return v / 4.5f;
353 } else {
354 return pow((v + a - 1.0f) / a, 1.0f / 0.45f);
355 }
356 }
357
358 case ColorSpace::TransferID::GAMMA22:
359 v = fmax(0.0f, v);
360 return pow(v, 2.2f);
361
362 case ColorSpace::TransferID::GAMMA28:
363 v = fmax(0.0f, v);
364 return pow(v, 2.8f);
365
366 case ColorSpace::TransferID::SMPTE240M: {
367 v = fmax(0.0f, v);
368 float a = 1.11157219592173128753f;
369 float b = 0.02282158552944503135f;
370 if (v <= fromLinear(ColorSpace::TransferID::SMPTE240M, b)) {
371 return v / 4.0f;
372 } else {
373 return pow((v + a - 1.0f) / a, 1.0f / 0.45f);
374 }
375 }
376
377 case ColorSpace::TransferID::LINEAR:
378 return v;
379
380 case ColorSpace::TransferID::LOG:
381 if (v < 0.0)
382 return 0.0;
383 return pow(10.0, (v - 1.0f) * 2.0f);
384
385 case ColorSpace::TransferID::LOG_SQRT:
386 if (v < 0.0)
387 return 0.0;
388 return pow(10.0, (v - 1.0f) * 2.5f);
389
390 case ColorSpace::TransferID::IEC61966_2_4: {
391 float a = 1.099296826809442f;
392 float b = 0.018053968510807f;
393 if (v < fromLinear(ColorSpace::TransferID::IEC61966_2_4, -a)) {
394 return -pow((a - 1.0f - v) / a, 1.0f / 0.45f);
395 } else if (v <= fromLinear(ColorSpace::TransferID::IEC61966_2_4, b)) {
396 return v / 4.5f;
397 } else {
398 return pow((v + a - 1.0f) / a, 1.0f / 0.45f);
399 }
400 }
401
402 case ColorSpace::TransferID::BT1361_ECG: {
403 float a = 1.099;
404 float b = 0.018;
405 float l = 0.0045;
406 if (v < fromLinear(ColorSpace::TransferID::BT1361_ECG, -l)) {
407 return -pow((1.0f - a - v * 4.0) / a, 1.0f / 0.45f) / 4.0f;
408 } else if (v <= fromLinear(ColorSpace::TransferID::BT1361_ECG, b)) {
409 return v / 4.5f;
410 } else {
411 return pow((v + a - 1.0f) / a, 1.0f / 0.45f);
412 }
413 }
414
415 case ColorSpace::TransferID::IEC61966_2_1: { // SRGB
416 v = fmax(0.0f, v);
417 float a = 1.055f;
418 float b = 0.0031308f;
419 if (v < fromLinear(ColorSpace::TransferID::IEC61966_2_1, b)) {
420 return v / 12.92f;
421 } else {
422 return pow((v + a - 1.0f) / a, 2.4f);
423 }
424 }
425
426 case ColorSpace::TransferID::SMPTEST2084: {
427 v = fmax(0.0f, v);
428 float m1 = (2610.0f / 4096.0f) / 4.0f;
429 float m2 = (2523.0f / 4096.0f) * 128.0f;
430 float c1 = 3424.0f / 4096.0f;
431 float c2 = (2413.0f / 4096.0f) * 32.0f;
432 float c3 = (2392.0f / 4096.0f) * 32.0f;
433 return pow(fmax(pow(v, 1.0 / m2) - c1, 0) / (c2 - c3 * pow(v, 1.0 / m2)),
434 1.0f / m1);
435 }
436
437 case ColorSpace::TransferID::SMPTEST428_1:
438 return (pow(v, 2.6f) - 52.37f) / 48.0f;
439
440 // Chrome-specific values below
441 case ColorSpace::TransferID::GAMMA24:
442 v = fmax(0.0f, v);
443 return pow(v, 2.4f);
444 }
445 }
446
447 GFX_EXPORT Transform GetTransferMatrix(ColorSpace::MatrixID id) {
448 float Kr, Kb;
449 switch (id) {
450 case ColorSpace::MatrixID::RGB:
451 return Transform();
452
453 case ColorSpace::MatrixID::BT709:
454 case ColorSpace::MatrixID::UNSPECIFIED:
455 case ColorSpace::MatrixID::RESERVED:
456 Kr = 0.2126f;
457 Kb = 0.0722f;
458 break;
459
460 case ColorSpace::MatrixID::FCC:
461 Kr = 0.30f;
462 Kb = 0.11f;
463 break;
464
465 case ColorSpace::MatrixID::BT470BG:
466 case ColorSpace::MatrixID::SMPTE170M:
467 Kr = 0.299f;
468 Kb = 0.144f;
469 break;
470
471 case ColorSpace::MatrixID::SMPTE240M:
472 Kr = 0.212f;
473 Kb = 0.087f;
474 break;
475
476 case ColorSpace::MatrixID::YCOCG:
477 return Transform(0.25f, 0.5f, 0.25f, 0.5, // 1
478 -0.25f, 0.5f, -0.25f, 0.5, // 2
479 0.5f, 0.0f, -0.5f, 0.0, // 3
480 0.0f, 0.0f, 0.0f, 1.0f); // 4
481
482 // TODO(hubbe): Check if the CL equation is right.
483 case ColorSpace::MatrixID::BT2020_NCL:
484 case ColorSpace::MatrixID::BT2020_CL:
485 Kr = 0.2627f;
486 Kb = 0.0593f;
487 break;
488
489 case ColorSpace::MatrixID::YDZDX:
490 return Transform(0.0f, 1.0f, 0.0, 0.0f, // 1
491 0.0f, -0.5f, 0.986566f / 2.0f, 0.5f, // 2
492 0.5f, -0.991902f / 2.0f, 0.0f, 0.5f, // 3
493 0.0f, 0.0f, 0.0f, 1.0f); // 4
494 }
495 float u_m = 0.5f / (1.0f - Kb);
496 float v_m = 0.5f / (1.0f - Kr);
497 return Transform(
498 Kr, 1.0f - Kr - Kb, Kb, 0.0f, // 1
499 u_m * -Kr, u_m * -(1.0f - Kr - Kb), u_m * (1.0f - Kb), 0.5f, // 2
500 v_m * (1.0f - Kr), v_m * -(1.0f - Kr - Kb), v_m * -Kb, 0.5f, // 3
501 0.0f, 0.0f, 0.0f, 1.0f); // 4
502 }
503
504 Transform GetRangeAdjustMatrix(ColorSpace::RangeID range,
505 ColorSpace::MatrixID matrix) {
506 switch (range) {
507 case ColorSpace::RangeID::FULL:
508 return Transform();
509
510 case ColorSpace::RangeID::LIMITED:
511 break;
512 }
513 switch (matrix) {
514 case ColorSpace::MatrixID::RGB:
515 case ColorSpace::MatrixID::YCOCG:
516 return Transform(255.0f / 219.0f, 0.0f, 0.0f, -16.0f / 219.0f, // 1
517 0.0f, 255.0f / 219.0f, 0.0f, -16.0f / 219.0f, // 2
518 0.0f, 0.0f, 255.0f / 219.0f, -16.0f / 219.0f, // 3
519 0.0f, 0.0f, 0.0f, 1.0f); // 4
520
521 case ColorSpace::MatrixID::BT709:
522 case ColorSpace::MatrixID::UNSPECIFIED:
523 case ColorSpace::MatrixID::RESERVED:
524 case ColorSpace::MatrixID::FCC:
525 case ColorSpace::MatrixID::BT470BG:
526 case ColorSpace::MatrixID::SMPTE170M:
527 case ColorSpace::MatrixID::SMPTE240M:
528 case ColorSpace::MatrixID::BT2020_NCL:
529 case ColorSpace::MatrixID::BT2020_CL:
530 case ColorSpace::MatrixID::YDZDX:
531 return Transform(255.0f / 219.0f, 0.0f, 0.0f, -16.0f / 219.0f, // 1
532 0.0f, 255.0f / 224.0f, 0.0f, -15.5f / 224.0f, // 2
533 0.0f, 0.0f, 255.0f / 224.0f, -15.5f / 224.0f, // 3
534 0.0f, 0.0f, 0.0f, 1.0f); // 4
535 }
536 }
537
538 class ColorSpaceToColorSpaceTransform : public ColorTransform {
539 public:
540 ColorSpaceToColorSpaceTransform(const ColorSpace& from,
541 const ColorSpace& to,
542 Intent intent)
543 : from_(from), to_(to) {
544 if (intent == Intent::PERCEPTUAL) {
545 switch (from_.transfer_) {
546 case ColorSpace::TransferID::UNSPECIFIED:
547 case ColorSpace::TransferID::BT709:
548 case ColorSpace::TransferID::SMPTE170M:
549 // See SMPTE 1886
550 from_.transfer_ = ColorSpace::TransferID::GAMMA24;
551 break;
552
553 default: // Do nothing
554 break;
555 }
556
557 // TODO(hubbe): shrink gamuts here (never stretch gamuts)
558 }
559
560 Transform* from_transfer_matrix =
561 from_.matrix_ == ColorSpace::MatrixID::BT2020_CL ? &b_ : &a_;
562 Transform* to_transfer_matrix =
563 to_.matrix_ == ColorSpace::MatrixID::BT2020_CL ? &b_ : &c_;
564
565 c_ *= Invert(GetRangeAdjustMatrix(to_.range_, to_.matrix_));
566 *to_transfer_matrix *= GetTransferMatrix(to_.matrix_);
567 b_ *= Invert(GetPrimaryMatrix(to_.primaries_));
568 b_ *= GetPrimaryMatrix(from_.primaries_);
569 *from_transfer_matrix *= Invert(GetTransferMatrix(from_.matrix_));
570 a_ *= GetRangeAdjustMatrix(from_.range_, from_.matrix_);
571 }
572
573 void transform(TriStim* colors, size_t num) override {
574 for (size_t i = 0; i < num; i++) {
575 TriStim c = colors[i];
576 a_.TransformPoint(&c);
577 c.set_x(toLinear(from_.transfer_, c.x()));
578 c.set_y(toLinear(from_.transfer_, c.y()));
579 c.set_z(toLinear(from_.transfer_, c.z()));
580 b_.TransformPoint(&c);
581 c.set_x(fromLinear(to_.transfer_, c.x()));
582 c.set_y(fromLinear(to_.transfer_, c.y()));
583 c.set_z(fromLinear(to_.transfer_, c.z()));
584 c_.TransformPoint(&c);
585 colors[i] = c;
586 }
587 }
588
589 private:
590 ColorSpace from_;
591 ColorSpace to_;
592
593 // a_ -> tolinear -> b_ -> fromlinear -> c_;
594 Transform a_;
595 Transform b_;
596 Transform c_;
597 };
598
599 std::unique_ptr<ColorTransform> ColorTransform::NewColorTransform(
600 const ColorSpace& from,
601 const ColorSpace& to,
602 Intent intent) {
603 // TODO(Hubbe): Check if from and/or to can be mapped to ICC profiles and
604 // provide better transforms in those cases.
605 return std::unique_ptr<ColorTransform>(
606 new ColorSpaceToColorSpaceTransform(from, to, intent));
607 }
608
609 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/color_transform.h ('k') | ui/gfx/color_transform_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698