OLD | NEW |
---|---|
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 #include "ui/gfx/transform.h" | |
13 | 14 |
14 namespace gfx { | 15 namespace gfx { |
15 | 16 |
16 namespace { | 17 namespace { |
17 | 18 |
18 SkColorSpaceTransferFn InvertTransferFn(SkColorSpaceTransferFn fn) { | 19 SkColorSpaceTransferFn InvertTransferFn(SkColorSpaceTransferFn fn) { |
19 SkColorSpaceTransferFn fn_inv = {0}; | 20 SkColorSpaceTransferFn fn_inv = {0}; |
20 if (fn.fA > 0 && fn.fG > 0) { | 21 if (fn.fA > 0 && fn.fG > 0) { |
21 double a_to_the_g = pow(fn.fA, fn.fG); | 22 double a_to_the_g = pow(fn.fA, fn.fG); |
22 fn_inv.fA = 1.f / a_to_the_g; | 23 fn_inv.fA = 1.f / a_to_the_g; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 } | 110 } |
110 | 111 |
111 // Static | 112 // Static |
112 ColorSpace ColorSpace::CreateXYZD50() { | 113 ColorSpace ColorSpace::CreateXYZD50() { |
113 return ColorSpace(PrimaryID::XYZ_D50, TransferID::LINEAR, MatrixID::RGB, | 114 return ColorSpace(PrimaryID::XYZ_D50, TransferID::LINEAR, MatrixID::RGB, |
114 RangeID::FULL); | 115 RangeID::FULL); |
115 } | 116 } |
116 | 117 |
117 // static | 118 // static |
118 ColorSpace ColorSpace::CreateJpeg() { | 119 ColorSpace ColorSpace::CreateJpeg() { |
119 return ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_1, MatrixID::BT709, | 120 return ColorSpace(PrimaryID::SMPTE170M, TransferID::IEC61966_2_1, |
hubbe
2017/02/02 04:51:37
I thought JPEG used srgb primaries by default?
ccameron
2017/02/02 17:33:52
It's not clear to me what exact spec "YUVVideoDraw
hubbe
2017/02/02 18:35:25
Yeah, YUVVideoDrawQuad::JPEG was normally just use
| |
120 RangeID::FULL); | 121 MatrixID::SMPTE170M, RangeID::FULL); |
121 } | 122 } |
122 | 123 |
123 // static | 124 // static |
124 ColorSpace ColorSpace::CreateREC601() { | 125 ColorSpace ColorSpace::CreateREC601() { |
125 return ColorSpace(PrimaryID::SMPTE170M, TransferID::SMPTE170M, | 126 return ColorSpace(PrimaryID::SMPTE170M, TransferID::SMPTE170M, |
126 MatrixID::SMPTE170M, RangeID::LIMITED); | 127 MatrixID::SMPTE170M, RangeID::LIMITED); |
127 } | 128 } |
128 | 129 |
129 // static | 130 // static |
130 ColorSpace ColorSpace::CreateREC709() { | 131 ColorSpace ColorSpace::CreateREC709() { |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
473 return false; | 474 return false; |
474 } | 475 } |
475 | 476 |
476 bool ColorSpace::GetInverseTransferFunction(SkColorSpaceTransferFn* fn) const { | 477 bool ColorSpace::GetInverseTransferFunction(SkColorSpaceTransferFn* fn) const { |
477 if (!GetTransferFunction(fn)) | 478 if (!GetTransferFunction(fn)) |
478 return false; | 479 return false; |
479 *fn = InvertTransferFn(*fn); | 480 *fn = InvertTransferFn(*fn); |
480 return true; | 481 return true; |
481 } | 482 } |
482 | 483 |
484 void ColorSpace::GetTransferMatrix(SkMatrix44* matrix) const { | |
485 float Kr = 0; | |
486 float Kb = 0; | |
487 switch (matrix_) { | |
488 case ColorSpace::MatrixID::RGB: | |
489 matrix->setIdentity(); | |
490 return; | |
491 | |
492 case ColorSpace::MatrixID::BT709: | |
493 case ColorSpace::MatrixID::UNSPECIFIED: | |
494 case ColorSpace::MatrixID::RESERVED: | |
495 case ColorSpace::MatrixID::UNKNOWN: | |
496 Kr = 0.2126f; | |
497 Kb = 0.0722f; | |
498 break; | |
499 | |
500 case ColorSpace::MatrixID::FCC: | |
501 Kr = 0.30f; | |
502 Kb = 0.11f; | |
503 break; | |
504 | |
505 case ColorSpace::MatrixID::BT470BG: | |
506 case ColorSpace::MatrixID::SMPTE170M: | |
507 Kr = 0.299f; | |
508 Kb = 0.114f; | |
509 break; | |
510 | |
511 case ColorSpace::MatrixID::SMPTE240M: | |
512 Kr = 0.212f; | |
513 Kb = 0.087f; | |
514 break; | |
515 | |
516 case ColorSpace::MatrixID::YCOCG: { | |
517 float data[16] = { | |
518 0.25f, 0.5f, 0.25f, 0.5f, // Y | |
519 -0.25f, 0.5f, -0.25f, 0.5f, // Cg | |
520 0.5f, 0.0f, -0.5f, 0.0f, // Co | |
521 0.0f, 0.0f, 0.0f, 1.0f | |
522 }; | |
523 matrix->setRowMajorf(data); | |
524 return; | |
525 } | |
526 | |
527 // BT2020_CL is a special case. | |
528 // Basically we return a matrix that transforms RGB values | |
529 // to RYB values. (We replace the green component with the | |
530 // the luminance.) Later steps will compute the Cb & Cr values. | |
531 case ColorSpace::MatrixID::BT2020_CL: { | |
532 Kr = 0.2627f; | |
533 Kb = 0.0593f; | |
534 float data[16] = { | |
535 1.0f, 0.0f, 0.0f, 0.0f, // R | |
536 Kr, 1.0f - Kr - Kb, Kb, 0.0f, // Y | |
537 0.0f, 0.0f, 1.0f, 0.0f, // B | |
538 0.0f, 0.0f, 0.0f, 1.0f | |
539 }; | |
540 matrix->setRowMajorf(data); | |
541 return; | |
542 } | |
543 | |
544 case ColorSpace::MatrixID::BT2020_NCL: | |
545 Kr = 0.2627f; | |
546 Kb = 0.0593f; | |
547 break; | |
548 | |
549 case ColorSpace::MatrixID::YDZDX: { | |
550 float data[16] = { | |
551 0.0f, 1.0f, 0.0f, 0.0f, // Y | |
552 0.0f, -0.5f, 0.986566f / 2.0f, 0.5f, // DX or DZ | |
553 0.5f, -0.991902f / 2.0f, 0.0f, 0.5f, // DZ or DX | |
554 0.0f, 0.0f, 0.0f, 1.0f, | |
555 }; | |
556 matrix->setRowMajorf(data); | |
557 return; | |
558 } | |
559 } | |
560 float Kg = 1.0f - Kr - Kb; | |
561 float u_m = 0.5f / (1.0f - Kb); | |
562 float v_m = 0.5f / (1.0f - Kr); | |
563 float data[16] = { | |
564 Kr, Kg, Kb, 0.0f, // Y | |
565 u_m * -Kr, u_m * -Kg, u_m * (1.0f - Kb), 0.5f, // U | |
566 v_m * (1.0f - Kr), v_m * -Kg, v_m * -Kb, 0.5f, // V | |
567 0.0f, 0.0f, 0.0f, 1.0f, | |
568 }; | |
569 matrix->setRowMajorf(data); | |
570 } | |
571 | |
572 void ColorSpace::GetRangeAdjustMatrix(SkMatrix44* matrix) const { | |
573 switch (range_) { | |
574 case RangeID::FULL: | |
575 case RangeID::UNSPECIFIED: | |
576 matrix->setIdentity(); | |
577 return; | |
578 | |
579 case RangeID::DERIVED: | |
580 case RangeID::LIMITED: | |
581 break; | |
582 } | |
583 switch (matrix_) { | |
584 case MatrixID::RGB: | |
585 case MatrixID::YCOCG: | |
586 matrix->setScale(255.0f/219.0f, 255.0f/219.0f, 255.0f/219.0f); | |
587 matrix->postTranslate(-16.0f/219.0f, -16.0f/219.0f, -16.0f/219.0f); | |
588 break; | |
589 | |
590 case MatrixID::BT709: | |
591 case MatrixID::UNSPECIFIED: | |
592 case MatrixID::RESERVED: | |
593 case MatrixID::FCC: | |
594 case MatrixID::BT470BG: | |
595 case MatrixID::SMPTE170M: | |
596 case MatrixID::SMPTE240M: | |
597 case MatrixID::BT2020_NCL: | |
598 case MatrixID::BT2020_CL: | |
599 case MatrixID::YDZDX: | |
600 case MatrixID::UNKNOWN: | |
601 matrix->setScale(255.0f/219.0f, 255.0f/224.0f, 255.0f/224.0f); | |
602 matrix->postTranslate(-16.0f/219.0f, -15.5f/224.0f, -15.5f/224.0f); | |
603 break; | |
604 } | |
605 } | |
606 | |
483 } // namespace gfx | 607 } // namespace gfx |
OLD | NEW |