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 <cmath> | 8 #include <cmath> |
9 #include <list> | 9 #include <list> |
10 #include <memory> | 10 #include <memory> |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 step->Transform(colors, num); | 270 step->Transform(colors, num); |
271 } | 271 } |
272 size_t NumberOfStepsForTesting() const override { return steps_.size(); } | 272 size_t NumberOfStepsForTesting() const override { return steps_.size(); } |
273 | 273 |
274 private: | 274 private: |
275 void AppendColorSpaceToColorSpaceTransform(ColorSpace from, | 275 void AppendColorSpaceToColorSpaceTransform(ColorSpace from, |
276 const ColorSpace& to, | 276 const ColorSpace& to, |
277 ColorTransform::Intent intent); | 277 ColorTransform::Intent intent); |
278 void Simplify(); | 278 void Simplify(); |
279 | 279 |
280 // Retrieve the ICC profile from which |color_space| was created, only if that | |
281 // is a more precise representation of the color space than the primaries and | |
282 // transfer function in |color_space|. | |
283 ScopedQcmsProfile GetQCMSProfileIfNecessary(const ColorSpace& color_space); | |
284 | |
280 std::list<std::unique_ptr<ColorTransformStep>> steps_; | 285 std::list<std::unique_ptr<ColorTransformStep>> steps_; |
281 }; | 286 }; |
282 | 287 |
283 class ColorTransformNull : public ColorTransformStep { | 288 class ColorTransformNull : public ColorTransformStep { |
284 public: | 289 public: |
285 ColorTransformNull* GetNull() override { return this; } | 290 ColorTransformNull* GetNull() override { return this; } |
286 bool IsNull() override { return true; } | 291 bool IsNull() override { return true; } |
287 void Transform(ColorTransform::TriStim* color, size_t num) override {} | 292 void Transform(ColorTransform::TriStim* color, size_t num) override {} |
288 }; | 293 }; |
289 | 294 |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
533 } | 538 } |
534 | 539 |
535 private: | 540 private: |
536 bool null_ = false; | 541 bool null_ = false; |
537 }; | 542 }; |
538 | 543 |
539 void ColorTransformInternal::AppendColorSpaceToColorSpaceTransform( | 544 void ColorTransformInternal::AppendColorSpaceToColorSpaceTransform( |
540 ColorSpace from, | 545 ColorSpace from, |
541 const ColorSpace& to, | 546 const ColorSpace& to, |
542 ColorTransform::Intent intent) { | 547 ColorTransform::Intent intent) { |
548 // If the source was not specified, assume that it was sRGB. | |
549 if (!from.IsValid()) | |
hubbe
2017/02/16 01:28:29
It would be really cool if we could just do DCHECK
ccameron
2017/02/16 01:58:47
Maybe one day :D
I rebased this patch on top of t
| |
550 from = gfx::ColorSpace::CreateSRGB(); | |
551 | |
543 if (intent == ColorTransform::Intent::INTENT_PERCEPTUAL) { | 552 if (intent == ColorTransform::Intent::INTENT_PERCEPTUAL) { |
544 switch (from.transfer_) { | 553 switch (from.transfer_) { |
545 case ColorSpace::TransferID::UNSPECIFIED: | 554 case ColorSpace::TransferID::UNSPECIFIED: |
546 case ColorSpace::TransferID::BT709: | 555 case ColorSpace::TransferID::BT709: |
547 case ColorSpace::TransferID::SMPTE170M: | 556 case ColorSpace::TransferID::SMPTE170M: |
548 // SMPTE 1886 suggests that we should be using gamma 2.4 for BT709 | 557 // SMPTE 1886 suggests that we should be using gamma 2.4 for BT709 |
549 // content. However, most displays actually use a gamma of 2.2, and | 558 // content. However, most displays actually use a gamma of 2.2, and |
550 // user studies shows that users don't really care. Using the same | 559 // user studies shows that users don't really care. Using the same |
551 // gamma as the display will let us optimize a lot more, so lets stick | 560 // gamma as the display will let us optimize a lot more, so lets stick |
552 // with using the SRGB transfer function. | 561 // with using the SRGB transfer function. |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
647 qcms_chain_transform(from_.get(), to_.get(), | 656 qcms_chain_transform(from_.get(), to_.get(), |
648 reinterpret_cast<float*>(colors), | 657 reinterpret_cast<float*>(colors), |
649 reinterpret_cast<float*>(colors), num * 3); | 658 reinterpret_cast<float*>(colors), num * 3); |
650 } | 659 } |
651 | 660 |
652 private: | 661 private: |
653 ScopedQcmsProfile from_; | 662 ScopedQcmsProfile from_; |
654 ScopedQcmsProfile to_; | 663 ScopedQcmsProfile to_; |
655 }; | 664 }; |
656 | 665 |
657 ScopedQcmsProfile GetQCMSProfileIfAvailable(const ColorSpace& color_space) { | 666 ScopedQcmsProfile ColorTransformInternal::GetQCMSProfileIfNecessary( |
658 ICCProfile icc_profile = ICCProfile::FromColorSpace(color_space); | 667 const ColorSpace& color_space) { |
659 if (icc_profile.GetData().empty()) | 668 ICCProfile icc_profile; |
669 if (!ICCProfile::FromId(color_space.icc_profile_id_, true, &icc_profile)) | |
660 return nullptr; | 670 return nullptr; |
661 return ScopedQcmsProfile(qcms_profile_from_memory( | 671 return ScopedQcmsProfile(qcms_profile_from_memory( |
662 icc_profile.GetData().data(), icc_profile.GetData().size())); | 672 icc_profile.GetData().data(), icc_profile.GetData().size())); |
663 } | 673 } |
664 | 674 |
665 ScopedQcmsProfile GetXYZD50Profile() { | 675 ScopedQcmsProfile GetXYZD50Profile() { |
666 // QCMS is trixy, it has a datatype called qcms_CIE_xyY, but what it expects | 676 // QCMS is trixy, it has a datatype called qcms_CIE_xyY, but what it expects |
667 // is in fact not xyY color coordinates, it just wants the x/y values of the | 677 // is in fact not xyY color coordinates, it just wants the x/y values of the |
668 // primaries with Y equal to 1.0. | 678 // primaries with Y equal to 1.0. |
669 qcms_CIE_xyYTRIPLE xyz; | 679 qcms_CIE_xyYTRIPLE xyz; |
670 qcms_CIE_xyY w; | 680 qcms_CIE_xyY w; |
671 xyz.red.x = 1.0f; | 681 xyz.red.x = 1.0f; |
672 xyz.red.y = 0.0f; | 682 xyz.red.y = 0.0f; |
673 xyz.red.Y = 1.0f; | 683 xyz.red.Y = 1.0f; |
674 xyz.green.x = 0.0f; | 684 xyz.green.x = 0.0f; |
675 xyz.green.y = 1.0f; | 685 xyz.green.y = 1.0f; |
676 xyz.green.Y = 1.0f; | 686 xyz.green.Y = 1.0f; |
677 xyz.blue.x = 0.0f; | 687 xyz.blue.x = 0.0f; |
678 xyz.blue.y = 0.0f; | 688 xyz.blue.y = 0.0f; |
679 xyz.blue.Y = 1.0f; | 689 xyz.blue.Y = 1.0f; |
680 w.x = 0.34567f; | 690 w.x = 0.34567f; |
681 w.y = 0.35850f; | 691 w.y = 0.35850f; |
682 w.Y = 1.0f; | 692 w.Y = 1.0f; |
683 return ScopedQcmsProfile(qcms_profile_create_rgb_with_gamma(w, xyz, 1.0f)); | 693 return ScopedQcmsProfile(qcms_profile_create_rgb_with_gamma(w, xyz, 1.0f)); |
684 } | 694 } |
685 | 695 |
686 ColorTransformInternal::ColorTransformInternal(const ColorSpace& from, | 696 ColorTransformInternal::ColorTransformInternal(const ColorSpace& from, |
687 const ColorSpace& to, | 697 const ColorSpace& to, |
688 Intent intent) { | 698 Intent intent) { |
689 ScopedQcmsProfile from_profile = GetQCMSProfileIfAvailable(from); | 699 ScopedQcmsProfile from_profile = GetQCMSProfileIfNecessary(from); |
690 ScopedQcmsProfile to_profile = GetQCMSProfileIfAvailable(to); | 700 ScopedQcmsProfile to_profile = GetQCMSProfileIfNecessary(to); |
691 bool has_from_profile = !!from_profile; | 701 bool has_from_profile = !!from_profile; |
692 bool has_to_profile = !!to_profile; | 702 bool has_to_profile = !!to_profile; |
693 | 703 |
694 if (from_profile) { | 704 if (from_profile) { |
695 steps_.push_back(base::MakeUnique<QCMSColorTransform>( | 705 steps_.push_back(base::MakeUnique<QCMSColorTransform>( |
696 std::move(from_profile), GetXYZD50Profile())); | 706 std::move(from_profile), GetXYZD50Profile())); |
697 } | 707 } |
698 | 708 |
699 AppendColorSpaceToColorSpaceTransform( | 709 AppendColorSpaceToColorSpaceTransform( |
700 has_from_profile ? ColorSpace::CreateXYZD50() : from, | 710 has_from_profile ? ColorSpace::CreateXYZD50() : from, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
748 const ColorSpace& to, | 758 const ColorSpace& to, |
749 Intent intent) { | 759 Intent intent) { |
750 return std::unique_ptr<ColorTransform>( | 760 return std::unique_ptr<ColorTransform>( |
751 new ColorTransformInternal(from, to, intent)); | 761 new ColorTransformInternal(from, to, intent)); |
752 } | 762 } |
753 | 763 |
754 ColorTransform::ColorTransform() {} | 764 ColorTransform::ColorTransform() {} |
755 ColorTransform::~ColorTransform() {} | 765 ColorTransform::~ColorTransform() {} |
756 | 766 |
757 } // namespace gfx | 767 } // namespace gfx |
OLD | NEW |