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

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

Issue 2559273002: color: general transformation -> affine transformation
Patch Set: Created 4 years 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
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 <vector> 7 #include <vector>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "ui/gfx/color_space.h" 10 #include "ui/gfx/color_space.h"
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 c.custom_primary_matrix_[4], c.custom_primary_matrix_[5], 645 c.custom_primary_matrix_[4], c.custom_primary_matrix_[5],
646 c.custom_primary_matrix_[6], c.custom_primary_matrix_[7], 646 c.custom_primary_matrix_[6], c.custom_primary_matrix_[7],
647 c.custom_primary_matrix_[8], c.custom_primary_matrix_[9], 647 c.custom_primary_matrix_[8], c.custom_primary_matrix_[9],
648 c.custom_primary_matrix_[10], 648 c.custom_primary_matrix_[10],
649 c.custom_primary_matrix_[11], 0.0f, 0.0f, 0.0f, 1.0f); 649 c.custom_primary_matrix_[11], 0.0f, 0.0f, 0.0f, 1.0f);
650 } else { 650 } else {
651 return GetPrimaryMatrix(c.primaries_); 651 return GetPrimaryMatrix(c.primaries_);
652 } 652 }
653 } 653 }
654 654
655 void transform(TriStim* colors, size_t num) override { 655 void transform(TriStim* colors, size_t num) const override {
656 for (size_t i = 0; i < num; i++) { 656 for (size_t i = 0; i < num; i++) {
657 TriStim c = colors[i]; 657 TriStim c = colors[i];
658 a_.TransformPoint(&c); 658 a_.TransformPoint(&c);
659 c = ToLinear(from_.transfer_, c); 659 c = ToLinear(from_.transfer_, c);
660 b_.TransformPoint(&c); 660 b_.TransformPoint(&c);
661 c.set_x(FromLinear(to_.transfer_, c.x())); 661 c.set_x(FromLinear(to_.transfer_, c.x()));
662 c.set_y(FromLinear(to_.transfer_, c.y())); 662 c.set_y(FromLinear(to_.transfer_, c.y()));
663 c.set_z(FromLinear(to_.transfer_, c.z())); 663 c.set_z(FromLinear(to_.transfer_, c.z()));
664 c_.TransformPoint(&c); 664 c_.TransformPoint(&c);
665 colors[i] = c; 665 colors[i] = c;
(...skipping 12 matching lines...) Expand all
678 678
679 class QCMSColorTransform : public ColorTransform { 679 class QCMSColorTransform : public ColorTransform {
680 public: 680 public:
681 // Takes ownership of the profiles 681 // Takes ownership of the profiles
682 QCMSColorTransform(qcms_profile* from, qcms_profile* to) 682 QCMSColorTransform(qcms_profile* from, qcms_profile* to)
683 : from_(from), to_(to) {} 683 : from_(from), to_(to) {}
684 ~QCMSColorTransform() override { 684 ~QCMSColorTransform() override {
685 qcms_profile_release(from_); 685 qcms_profile_release(from_);
686 qcms_profile_release(to_); 686 qcms_profile_release(to_);
687 } 687 }
688 void transform(TriStim* colors, size_t num) override { 688 void transform(TriStim* colors, size_t num) const override {
689 CHECK(sizeof(TriStim) == sizeof(float[3])); 689 CHECK(sizeof(TriStim) == sizeof(float[3]));
690 // QCMS doesn't like numbers outside 0..1 690 // QCMS doesn't like numbers outside 0..1
691 for (size_t i = 0; i < num; i++) { 691 for (size_t i = 0; i < num; i++) {
692 colors[i].set_x(fmin(1.0f, fmax(0.0f, colors[i].x()))); 692 colors[i].set_x(fmin(1.0f, fmax(0.0f, colors[i].x())));
693 colors[i].set_y(fmin(1.0f, fmax(0.0f, colors[i].y()))); 693 colors[i].set_y(fmin(1.0f, fmax(0.0f, colors[i].y())));
694 colors[i].set_z(fmin(1.0f, fmax(0.0f, colors[i].z()))); 694 colors[i].set_z(fmin(1.0f, fmax(0.0f, colors[i].z())));
695 } 695 }
696 qcms_chain_transform(from_, to_, reinterpret_cast<float*>(colors), 696 qcms_chain_transform(from_, to_, reinterpret_cast<float*>(colors),
697 reinterpret_cast<float*>(colors), num * 3); 697 reinterpret_cast<float*>(colors), num * 3);
698 } 698 }
699 699
700 private: 700 private:
701 qcms_profile *from_, *to_; 701 qcms_profile *from_, *to_;
702 }; 702 };
703 703
704 class ChainColorTransform : public ColorTransform { 704 class ChainColorTransform : public ColorTransform {
705 public: 705 public:
706 ChainColorTransform(std::unique_ptr<ColorTransform> a, 706 ChainColorTransform(std::unique_ptr<ColorTransform> a,
707 std::unique_ptr<ColorTransform> b) 707 std::unique_ptr<ColorTransform> b)
708 : a_(std::move(a)), b_(std::move(b)) {} 708 : a_(std::move(a)), b_(std::move(b)) {}
709 709
710 private: 710 private:
711 void transform(TriStim* colors, size_t num) override { 711 void transform(TriStim* colors, size_t num) const override {
712 a_->transform(colors, num); 712 a_->transform(colors, num);
713 b_->transform(colors, num); 713 b_->transform(colors, num);
714 } 714 }
715 std::unique_ptr<ColorTransform> a_; 715 std::unique_ptr<ColorTransform> a_;
716 std::unique_ptr<ColorTransform> b_; 716 std::unique_ptr<ColorTransform> b_;
717 }; 717 };
718 718
719 qcms_profile* GetQCMSProfileIfAvailable(const ColorSpace& color_space) { 719 qcms_profile* GetQCMSProfileIfAvailable(const ColorSpace& color_space) {
720 ICCProfile icc_profile = ICCProfile::FromColorSpace(color_space); 720 ICCProfile icc_profile = ICCProfile::FromColorSpace(color_space);
721 if (icc_profile.GetData().empty()) 721 if (icc_profile.GetData().empty())
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 from, ColorSpace::CreateXYZD50(), intent)), 769 from, ColorSpace::CreateXYZD50(), intent)),
770 std::unique_ptr<ColorTransform>( 770 std::unique_ptr<ColorTransform>(
771 new QCMSColorTransform(GetXYZD50Profile(), to_profile)))); 771 new QCMSColorTransform(GetXYZD50Profile(), to_profile))));
772 } else { 772 } else {
773 return std::unique_ptr<ColorTransform>( 773 return std::unique_ptr<ColorTransform>(
774 new ColorSpaceToColorSpaceTransform(from, to, intent)); 774 new ColorSpaceToColorSpaceTransform(from, to, intent));
775 } 775 }
776 } 776 }
777 } 777 }
778 778
779 namespace {
780
781 float TriStimChannel(const ColorTransform::TriStim& t, int c) {
782 switch (c) {
783 case 0:
784 return t.x();
785 case 1:
786 return t.y();
787 case 2:
788 return t.z();
789 case 3:
790 return 1.0f;
791 default:
792 NOTREACHED();
793 break;
794 }
795 return 0.0f;
796 };
797
798 } // namespace
799
800 bool ColorTransform::GetAffineApproximation(Transform* transform) const {
801 const int num_points = 4;
802 std::vector<TriStim> input(num_points * num_points * num_points);
803 int i = 0;
804 float offset = 0.1;
805 float mult = 0.8 / num_points;
806 for (int x = 0; x < num_points; x++) {
807 for (int y = 0; y < num_points; y++) {
808 for (int z = 0; z < num_points; z++) {
809 input[i++] = ColorTransform::TriStim(
810 offset + x * mult, offset + y * mult, offset + z * mult);
811 }
812 }
813 }
814
815 std::vector<TriStim> output(input);
816 this->transform(output.data(), output.size());
817 SkMatrix44 XtX;
818 for (int x = 0; x < 4; x++) {
819 for (int y = 0; y < 4; y++) {
820 double tmp = 0.0;
821 for (int z = 0; z < num_points * num_points * num_points; z++) {
822 tmp += TriStimChannel(input[z], x) * TriStimChannel(input[z], y);
823 }
824 XtX.setDouble(x, y, tmp);
825 }
826 }
827
828 SkMatrix44 XtXinv;
829 if (!XtX.invert(&XtXinv))
830 return false;
831
832 SkVector4 results[4];
833
834 for (int x = 0; x < 4; x++) {
835 double Xty[4];
836 for (int y = 0; y < 4; y++) {
837 double tmp = 0.0;
838 for (int z = 0; z < num_points * num_points * num_points; z++) {
839 tmp += TriStimChannel(output[z], x) * TriStimChannel(input[z], y);
840 }
841 Xty[y] = tmp;
842 }
843 results[x] = XtXinv * SkVector4(Xty[0], Xty[1], Xty[2], Xty[3]);
844 }
845
846 *transform =
847 Transform(results[0].fData[0], results[0].fData[1], results[0].fData[2],
848 results[0].fData[3], results[1].fData[0], results[1].fData[1],
849 results[1].fData[2], results[1].fData[3], results[2].fData[0],
850 results[2].fData[1], results[2].fData[2], results[2].fData[3],
851 results[3].fData[0], results[3].fData[1], results[3].fData[2],
852 results[3].fData[3]);
853 return true;
854 }
855
779 } // namespace gfx 856 } // 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