Chromium Code Reviews| 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 |