| OLD | NEW |
| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 } | 185 } |
| 186 | 186 |
| 187 default: | 187 default: |
| 188 // Handled by SkColorSpaceTransferFn. | 188 // Handled by SkColorSpaceTransferFn. |
| 189 break; | 189 break; |
| 190 } | 190 } |
| 191 NOTREACHED(); | 191 NOTREACHED(); |
| 192 return 0; | 192 return 0; |
| 193 } | 193 } |
| 194 | 194 |
| 195 GFX_EXPORT Transform GetTransferMatrix(ColorSpace::MatrixID id) { | 195 Transform GetTransferMatrix(const gfx::ColorSpace& color_space) { |
| 196 // Default values for BT709; | 196 SkMatrix44 transfer_matrix; |
| 197 float Kr = 0.2126f; | 197 color_space.GetTransferMatrix(&transfer_matrix); |
| 198 float Kb = 0.0722f; | 198 return Transform(transfer_matrix); |
| 199 switch (id) { | |
| 200 case ColorSpace::MatrixID::RGB: | |
| 201 return Transform(); | |
| 202 | |
| 203 case ColorSpace::MatrixID::BT709: | |
| 204 case ColorSpace::MatrixID::UNSPECIFIED: | |
| 205 case ColorSpace::MatrixID::RESERVED: | |
| 206 case ColorSpace::MatrixID::UNKNOWN: | |
| 207 // Default values are already set. | |
| 208 break; | |
| 209 | |
| 210 case ColorSpace::MatrixID::FCC: | |
| 211 Kr = 0.30f; | |
| 212 Kb = 0.11f; | |
| 213 break; | |
| 214 | |
| 215 case ColorSpace::MatrixID::BT470BG: | |
| 216 case ColorSpace::MatrixID::SMPTE170M: | |
| 217 Kr = 0.299f; | |
| 218 Kb = 0.144f; | |
| 219 break; | |
| 220 | |
| 221 case ColorSpace::MatrixID::SMPTE240M: | |
| 222 Kr = 0.212f; | |
| 223 Kb = 0.087f; | |
| 224 break; | |
| 225 | |
| 226 case ColorSpace::MatrixID::YCOCG: | |
| 227 return Transform(0.25f, 0.5f, 0.25f, 0.5f, // 1 | |
| 228 -0.25f, 0.5f, -0.25f, 0.5f, // 2 | |
| 229 0.5f, 0.0f, -0.5f, 0.0f, // 3 | |
| 230 0.0f, 0.0f, 0.0f, 1.0f); // 4 | |
| 231 | |
| 232 case ColorSpace::MatrixID::BT2020_NCL: | |
| 233 Kr = 0.2627f; | |
| 234 Kb = 0.0593f; | |
| 235 break; | |
| 236 | |
| 237 // BT2020_CL is a special case. | |
| 238 // Basically we return a matrix that transforms RGB values | |
| 239 // to RYB values. (We replace the green component with the | |
| 240 // the luminance.) Later steps will compute the Cb & Cr values. | |
| 241 case ColorSpace::MatrixID::BT2020_CL: | |
| 242 Kr = 0.2627f; | |
| 243 Kb = 0.0593f; | |
| 244 return Transform(1.0f, 0.0f, 0.0f, 0.0f, // R | |
| 245 Kr, 1.0f - Kr - Kb, Kb, 0.0f, // Y | |
| 246 0.0f, 0.0f, 1.0f, 0.0f, // B | |
| 247 0.0f, 0.0f, 0.0f, 1.0f); | |
| 248 | |
| 249 case ColorSpace::MatrixID::YDZDX: | |
| 250 return Transform(0.0f, 1.0f, 0.0f, 0.0f, // 1 | |
| 251 0.0f, -0.5f, 0.986566f / 2.0f, 0.5f, // 2 | |
| 252 0.5f, -0.991902f / 2.0f, 0.0f, 0.5f, // 3 | |
| 253 0.0f, 0.0f, 0.0f, 1.0f); // 4 | |
| 254 } | |
| 255 float u_m = 0.5f / (1.0f - Kb); | |
| 256 float v_m = 0.5f / (1.0f - Kr); | |
| 257 return Transform( | |
| 258 Kr, 1.0f - Kr - Kb, Kb, 0.0f, // 1 | |
| 259 u_m * -Kr, u_m * -(1.0f - Kr - Kb), u_m * (1.0f - Kb), 0.5f, // 2 | |
| 260 v_m * (1.0f - Kr), v_m * -(1.0f - Kr - Kb), v_m * -Kb, 0.5f, // 3 | |
| 261 0.0f, 0.0f, 0.0f, 1.0f); // 4 | |
| 262 } | 199 } |
| 263 | 200 |
| 264 Transform GetRangeAdjustMatrix(ColorSpace::RangeID range, | 201 Transform GetRangeAdjustMatrix(const gfx::ColorSpace& color_space) { |
| 265 ColorSpace::MatrixID matrix) { | 202 SkMatrix44 range_adjust_matrix; |
| 266 switch (range) { | 203 color_space.GetRangeAdjustMatrix(&range_adjust_matrix); |
| 267 case ColorSpace::RangeID::FULL: | 204 return Transform(range_adjust_matrix); |
| 268 case ColorSpace::RangeID::UNSPECIFIED: | |
| 269 return Transform(); | |
| 270 | |
| 271 case ColorSpace::RangeID::DERIVED: | |
| 272 case ColorSpace::RangeID::LIMITED: | |
| 273 break; | |
| 274 } | |
| 275 switch (matrix) { | |
| 276 case ColorSpace::MatrixID::RGB: | |
| 277 case ColorSpace::MatrixID::YCOCG: | |
| 278 // TODO(hubbe): Use Transform:Scale3d / Transform::Translate3d here. | |
| 279 return Transform(255.0f / 219.0f, 0.0f, 0.0f, -16.0f / 219.0f, // 1 | |
| 280 0.0f, 255.0f / 219.0f, 0.0f, -16.0f / 219.0f, // 2 | |
| 281 0.0f, 0.0f, 255.0f / 219.0f, -16.0f / 219.0f, // 3 | |
| 282 0.0f, 0.0f, 0.0f, 1.0f); // 4 | |
| 283 | |
| 284 case ColorSpace::MatrixID::BT709: | |
| 285 case ColorSpace::MatrixID::UNSPECIFIED: | |
| 286 case ColorSpace::MatrixID::RESERVED: | |
| 287 case ColorSpace::MatrixID::FCC: | |
| 288 case ColorSpace::MatrixID::BT470BG: | |
| 289 case ColorSpace::MatrixID::SMPTE170M: | |
| 290 case ColorSpace::MatrixID::SMPTE240M: | |
| 291 case ColorSpace::MatrixID::BT2020_NCL: | |
| 292 case ColorSpace::MatrixID::BT2020_CL: | |
| 293 case ColorSpace::MatrixID::YDZDX: | |
| 294 case ColorSpace::MatrixID::UNKNOWN: | |
| 295 // TODO(hubbe): Use Transform:Scale3d / Transform::Translate3d here. | |
| 296 return Transform(255.0f / 219.0f, 0.0f, 0.0f, -16.0f / 219.0f, // 1 | |
| 297 0.0f, 255.0f / 224.0f, 0.0f, -15.5f / 224.0f, // 2 | |
| 298 0.0f, 0.0f, 255.0f / 224.0f, -15.5f / 224.0f, // 3 | |
| 299 0.0f, 0.0f, 0.0f, 1.0f); // 4 | |
| 300 } | |
| 301 NOTREACHED(); | |
| 302 return Transform(); | |
| 303 } | 205 } |
| 304 | 206 |
| 305 class ColorTransformMatrix; | 207 class ColorTransformMatrix; |
| 306 class ColorTransformToLinear; | 208 class ColorTransformToLinear; |
| 307 class ColorTransformFromLinear; | 209 class ColorTransformFromLinear; |
| 308 class ColorTransformToBT2020CL; | 210 class ColorTransformToBT2020CL; |
| 309 class ColorTransformFromBT2020CL; | 211 class ColorTransformFromBT2020CL; |
| 310 class ColorTransformNull; | 212 class ColorTransformNull; |
| 311 | 213 |
| 312 class ColorTransformInternal : public ColorTransform { | 214 class ColorTransformInternal : public ColorTransform { |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 break; | 600 break; |
| 699 | 601 |
| 700 default: // Do nothing | 602 default: // Do nothing |
| 701 break; | 603 break; |
| 702 } | 604 } |
| 703 | 605 |
| 704 // TODO(hubbe): shrink gamuts here (never stretch gamuts) | 606 // TODO(hubbe): shrink gamuts here (never stretch gamuts) |
| 705 } | 607 } |
| 706 | 608 |
| 707 builder->Append(base::MakeUnique<ColorTransformMatrix>( | 609 builder->Append(base::MakeUnique<ColorTransformMatrix>( |
| 708 GetRangeAdjustMatrix(from.range_, from.matrix_))); | 610 GetRangeAdjustMatrix(from))); |
| 709 | 611 |
| 710 builder->Append(base::MakeUnique<ColorTransformMatrix>( | 612 builder->Append(base::MakeUnique<ColorTransformMatrix>( |
| 711 Invert(GetTransferMatrix(from.matrix_)))); | 613 Invert(GetTransferMatrix(from)))); |
| 712 | 614 |
| 713 SkColorSpaceTransferFn to_linear_fn; | 615 SkColorSpaceTransferFn to_linear_fn; |
| 714 bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); | 616 bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); |
| 715 builder->Append(base::MakeUnique<ColorTransformToLinear>( | 617 builder->Append(base::MakeUnique<ColorTransformToLinear>( |
| 716 from.transfer_, to_linear_fn, to_linear_fn_valid)); | 618 from.transfer_, to_linear_fn, to_linear_fn_valid)); |
| 717 | 619 |
| 718 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { | 620 if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { |
| 719 // BT2020 CL is a special case. | 621 // BT2020 CL is a special case. |
| 720 builder->Append(base::MakeUnique<ColorTransformFromBT2020CL>()); | 622 builder->Append(base::MakeUnique<ColorTransformFromBT2020CL>()); |
| 721 } | 623 } |
| 722 builder->Append( | 624 builder->Append( |
| 723 base::MakeUnique<ColorTransformMatrix>(GetPrimaryTransform(from))); | 625 base::MakeUnique<ColorTransformMatrix>(GetPrimaryTransform(from))); |
| 724 | 626 |
| 725 builder->Append(base::MakeUnique<ColorTransformMatrix>( | 627 builder->Append(base::MakeUnique<ColorTransformMatrix>( |
| 726 Invert(GetPrimaryTransform(to)))); | 628 Invert(GetPrimaryTransform(to)))); |
| 727 if (to.matrix_ == ColorSpace::MatrixID::BT2020_CL) { | 629 if (to.matrix_ == ColorSpace::MatrixID::BT2020_CL) { |
| 728 // BT2020 CL is a special case. | 630 // BT2020 CL is a special case. |
| 729 builder->Append(base::MakeUnique<ColorTransformToBT2020CL>()); | 631 builder->Append(base::MakeUnique<ColorTransformToBT2020CL>()); |
| 730 } | 632 } |
| 731 | 633 |
| 732 SkColorSpaceTransferFn from_linear_fn; | 634 SkColorSpaceTransferFn from_linear_fn; |
| 733 bool from_linear_fn_valid = to.GetInverseTransferFunction(&from_linear_fn); | 635 bool from_linear_fn_valid = to.GetInverseTransferFunction(&from_linear_fn); |
| 734 builder->Append(base::MakeUnique<ColorTransformFromLinear>( | 636 builder->Append(base::MakeUnique<ColorTransformFromLinear>( |
| 735 to.transfer_, from_linear_fn, from_linear_fn_valid)); | 637 to.transfer_, from_linear_fn, from_linear_fn_valid)); |
| 736 | 638 |
| 737 builder->Append( | 639 builder->Append( |
| 738 base::MakeUnique<ColorTransformMatrix>(GetTransferMatrix(to.matrix_))); | 640 base::MakeUnique<ColorTransformMatrix>(GetTransferMatrix(to))); |
| 739 | 641 |
| 740 builder->Append(base::MakeUnique<ColorTransformMatrix>( | 642 builder->Append(base::MakeUnique<ColorTransformMatrix>( |
| 741 Invert(GetRangeAdjustMatrix(to.range_, to.matrix_)))); | 643 Invert(GetRangeAdjustMatrix(to)))); |
| 742 } | 644 } |
| 743 }; | 645 }; |
| 744 | 646 |
| 745 class QCMSColorTransform : public ColorTransformInternal { | 647 class QCMSColorTransform : public ColorTransformInternal { |
| 746 public: | 648 public: |
| 747 // Takes ownership of the profiles | 649 // Takes ownership of the profiles |
| 748 QCMSColorTransform(qcms_profile* from, qcms_profile* to) | 650 QCMSColorTransform(qcms_profile* from, qcms_profile* to) |
| 749 : from_(from), to_(to) {} | 651 : from_(from), to_(to) {} |
| 750 ~QCMSColorTransform() override { | 652 ~QCMSColorTransform() override { |
| 751 qcms_profile_release(from_); | 653 qcms_profile_release(from_); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 bool from_linear_fn_valid = space.GetInverseTransferFunction(&from_linear_fn); | 757 bool from_linear_fn_valid = space.GetInverseTransferFunction(&from_linear_fn); |
| 856 | 758 |
| 857 ColorTransformFromLinear from_linear_transform(transfer, from_linear_fn, | 759 ColorTransformFromLinear from_linear_transform(transfer, from_linear_fn, |
| 858 from_linear_fn_valid); | 760 from_linear_fn_valid); |
| 859 TriStim color(v, v, v); | 761 TriStim color(v, v, v); |
| 860 from_linear_transform.transform(&color, 1); | 762 from_linear_transform.transform(&color, 1); |
| 861 return color.x(); | 763 return color.x(); |
| 862 } | 764 } |
| 863 | 765 |
| 864 } // namespace gfx | 766 } // namespace gfx |
| OLD | NEW |