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

Side by Side Diff: src/core/SkColorSpace.cpp

Issue 1985903002: Prepare SkColorSpace to be a public API (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 7 months 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
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkAtomics.h" 8 #include "SkAtomics.h"
9 #include "SkColorSpace.h" 9 #include "SkColorSpace.h"
10 #include "SkColorSpacePriv.h"
10 #include "SkOnce.h" 11 #include "SkOnce.h"
11 12
12 static bool color_space_almost_equal(float a, float b) { 13 static bool color_space_almost_equal(float a, float b) {
13 return SkTAbs(a - b) < 0.01f; 14 return SkTAbs(a - b) < 0.01f;
14 } 15 }
15 16
16 void SkFloat3::dump() const {
17 SkDebugf("[%7.4f %7.4f %7.4f]\n", fVec[0], fVec[1], fVec[2]);
18 }
19
20 //////////////////////////////////////////////////////////////////////////////// ////////////////// 17 //////////////////////////////////////////////////////////////////////////////// //////////////////
21 18
22 static int32_t gUniqueColorSpaceID; 19 static int32_t gUniqueColorSpaceID;
23 20
24 SkColorSpace::SkColorSpace(SkGammas gammas, const SkMatrix44& toXYZD50, Named na med) 21 SkColorSpace::SkColorSpace(sk_sp<SkGammas> gammas, const SkMatrix44& toXYZD50, N amed named)
25 : fGammas(std::move(gammas)) 22 : fGammas(gammas)
26 , fToXYZD50(toXYZD50) 23 , fToXYZD50(toXYZD50)
27 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) 24 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
28 , fNamed(named) 25 , fNamed(named)
29 {} 26 {}
30 27
31 SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, SkGammas gammas, 28 SkColorSpace::SkColorSpace(SkColorLookUpTable* colorLUT, sk_sp<SkGammas> gammas,
32 const SkMatrix44& toXYZD50) 29 const SkMatrix44& toXYZD50)
33 : fColorLUT(std::move(colorLUT)) 30 : fColorLUT(colorLUT)
34 , fGammas(std::move(gammas)) 31 , fGammas(gammas)
35 , fToXYZD50(toXYZD50) 32 , fToXYZD50(toXYZD50)
36 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) 33 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
37 , fNamed(kUnknown_Named) 34 , fNamed(kUnknown_Named)
38 {} 35 {}
39 36
40 const float gSRGB_toXYZD50[] { 37 const float gSRGB_toXYZD50[] {
41 0.4358f, 0.2224f, 0.0139f, // * R 38 0.4358f, 0.2224f, 0.0139f, // * R
42 0.3853f, 0.7170f, 0.0971f, // * G 39 0.3853f, 0.7170f, 0.0971f, // * G
43 0.1430f, 0.0606f, 0.7139f, // * B 40 0.1430f, 0.0606f, 0.7139f, // * B
44 }; 41 };
(...skipping 22 matching lines...) Expand all
67 color_space_almost_equal(toXYZD50.getFloat(2, 2), standard[8]) && 64 color_space_almost_equal(toXYZD50.getFloat(2, 2), standard[8]) &&
68 color_space_almost_equal(toXYZD50.getFloat(0, 3), 0.0f) && 65 color_space_almost_equal(toXYZD50.getFloat(0, 3), 0.0f) &&
69 color_space_almost_equal(toXYZD50.getFloat(1, 3), 0.0f) && 66 color_space_almost_equal(toXYZD50.getFloat(1, 3), 0.0f) &&
70 color_space_almost_equal(toXYZD50.getFloat(2, 3), 0.0f) && 67 color_space_almost_equal(toXYZD50.getFloat(2, 3), 0.0f) &&
71 color_space_almost_equal(toXYZD50.getFloat(3, 0), 0.0f) && 68 color_space_almost_equal(toXYZD50.getFloat(3, 0), 0.0f) &&
72 color_space_almost_equal(toXYZD50.getFloat(3, 1), 0.0f) && 69 color_space_almost_equal(toXYZD50.getFloat(3, 1), 0.0f) &&
73 color_space_almost_equal(toXYZD50.getFloat(3, 2), 0.0f) && 70 color_space_almost_equal(toXYZD50.getFloat(3, 2), 0.0f) &&
74 color_space_almost_equal(toXYZD50.getFloat(3, 3), 1.0f); 71 color_space_almost_equal(toXYZD50.getFloat(3, 3), 1.0f);
75 } 72 }
76 73
77 sk_sp<SkColorSpace> SkColorSpace::NewRGB(SkGammas gammas, const SkMatrix44& toXY ZD50) { 74 static SkOnce gStandardGammasOnce;
75 static SkGammas* gStandardGammas;
76
77 sk_sp<SkColorSpace> SkColorSpace::NewRGB(float gammaVals[3], const SkMatrix44& t oXYZD50) {
78 sk_sp<SkGammas> gammas = nullptr;
79
78 // Check if we really have sRGB or Adobe RGB 80 // Check if we really have sRGB or Adobe RGB
79 if (color_space_almost_equal(2.2f, gammas.fRed.fValue) && 81 if (color_space_almost_equal(2.2f, gammaVals[0]) &&
80 color_space_almost_equal(2.2f, gammas.fGreen.fValue) && 82 color_space_almost_equal(2.2f, gammaVals[1]) &&
81 color_space_almost_equal(2.2f, gammas.fBlue.fValue)) 83 color_space_almost_equal(2.2f, gammaVals[2]))
82 { 84 {
85 gStandardGammasOnce([] {
86 gStandardGammas = new SkGammas(2.2f, 2.2f, 2.2f);
87 });
88 gammas = sk_ref_sp(gStandardGammas);
89
83 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { 90 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) {
84 return SkColorSpace::NewNamed(kSRGB_Named); 91 return SkColorSpace::NewNamed(kSRGB_Named);
85 } else if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) { 92 } else if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) {
86 return SkColorSpace::NewNamed(kAdobeRGB_Named); 93 return SkColorSpace::NewNamed(kAdobeRGB_Named);
87 } 94 }
88 } 95 }
89 96
90 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUn known_Named)); 97 if (!gammas) {
98 gammas = sk_ref_sp(new SkGammas(gammaVals[0], gammaVals[1], gammaVals[2] ));
99 }
100 return sk_sp<SkColorSpace>(new SkColorSpace(gammas, toXYZD50, kUnknown_Named ));
91 } 101 }
92 102
93 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { 103 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
94 static SkOnce sRGBOnce; 104 static SkOnce sRGBOnce;
95 static SkColorSpace* sRGB; 105 static SkColorSpace* sRGB;
96 static SkOnce adobeRGBOnce; 106 static SkOnce adobeRGBOnce;
97 static SkColorSpace* adobeRGB; 107 static SkColorSpace* adobeRGB;
98 108
99 switch (named) { 109 switch (named) {
100 case kSRGB_Named: { 110 case kSRGB_Named: {
111 gStandardGammasOnce([] {
112 gStandardGammas = new SkGammas(2.2f, 2.2f, 2.2f);
113 });
114
101 sRGBOnce([] { 115 sRGBOnce([] {
102 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); 116 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor);
103 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50); 117 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50);
104 sRGB = new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), srgbToxyzD50 , kSRGB_Named); 118 sRGB = new SkColorSpace(sk_ref_sp(gStandardGammas), srgbToxyzD50 , kSRGB_Named);
105 }); 119 });
106 return sk_ref_sp(sRGB); 120 return sk_ref_sp(sRGB);
107 } 121 }
108 case kAdobeRGB_Named: { 122 case kAdobeRGB_Named: {
123 gStandardGammasOnce([] {
124 gStandardGammas = new SkGammas(2.2f, 2.2f, 2.2f);
125 });
126
109 adobeRGBOnce([] { 127 adobeRGBOnce([] {
110 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct or); 128 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct or);
111 adobergbToxyzD50.set3x3ColMajorf(gAdobeRGB_toXYZD50); 129 adobergbToxyzD50.set3x3ColMajorf(gAdobeRGB_toXYZD50);
112 adobeRGB = new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), adobergb ToxyzD50, 130 adobeRGB = new SkColorSpace(sk_ref_sp(gStandardGammas), adobergb ToxyzD50,
113 kAdobeRGB_Named); 131 kAdobeRGB_Named);
114 }); 132 });
115 return sk_ref_sp(adobeRGB); 133 return sk_ref_sp(adobeRGB);
116 } 134 }
117 default: 135 default:
118 break; 136 break;
119 } 137 }
120 return nullptr; 138 return nullptr;
121 } 139 }
122 140
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 array[10] = SkFixedToFloat(read_big_endian_int(src + 32)); 547 array[10] = SkFixedToFloat(read_big_endian_int(src + 32));
530 array[11] = 0; 548 array[11] = 0;
531 array[12] = SkFixedToFloat(read_big_endian_int(src + 36)); // translate R 549 array[12] = SkFixedToFloat(read_big_endian_int(src + 36)); // translate R
532 array[13] = SkFixedToFloat(read_big_endian_int(src + 40)); // translate G 550 array[13] = SkFixedToFloat(read_big_endian_int(src + 40)); // translate G
533 array[14] = SkFixedToFloat(read_big_endian_int(src + 44)); 551 array[14] = SkFixedToFloat(read_big_endian_int(src + 44));
534 array[15] = 1; 552 array[15] = 1;
535 toXYZ->setColMajorf(array); 553 toXYZ->setColMajorf(array);
536 return true; 554 return true;
537 } 555 }
538 556
539 bool SkColorSpace::LoadA2B0(SkColorLookUpTable* colorLUT, SkGammas* gammas, SkMa trix44* toXYZ, 557 bool SkColorSpace::LoadA2B0(SkColorLookUpTable* colorLUT, sk_sp<SkGammas> gammas , SkMatrix44* toXYZ,
540 const uint8_t* src, size_t len) { 558 const uint8_t* src, size_t len) {
541 if (len < 32) { 559 if (len < 32) {
542 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len); 560 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len);
543 return false; 561 return false;
544 } 562 }
545 563
546 uint32_t type = read_big_endian_uint(src); 564 uint32_t type = read_big_endian_uint(src);
547 if (kTAG_AtoBType != type) { 565 if (kTAG_AtoBType != type) {
548 // FIXME (msarett): Need to support lut8Type and lut16Type. 566 // FIXME (msarett): Need to support lut8Type and lut16Type.
549 SkColorSpacePrintf("Unsupported A to B tag type.\n"); 567 SkColorSpacePrintf("Unsupported A to B tag type.\n");
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 float toXYZ[9]; 673 float toXYZ[9];
656 if (!load_xyz(&toXYZ[0], r->addr((const uint8_t*) base), r->fLen gth) || 674 if (!load_xyz(&toXYZ[0], r->addr((const uint8_t*) base), r->fLen gth) ||
657 !load_xyz(&toXYZ[3], g->addr((const uint8_t*) base), g->fLen gth) || 675 !load_xyz(&toXYZ[3], g->addr((const uint8_t*) base), g->fLen gth) ||
658 !load_xyz(&toXYZ[6], b->addr((const uint8_t*) base), b->fLen gth)) 676 !load_xyz(&toXYZ[6], b->addr((const uint8_t*) base), b->fLen gth))
659 { 677 {
660 return_null("Need valid rgb tags for XYZ space"); 678 return_null("Need valid rgb tags for XYZ space");
661 } 679 }
662 680
663 // It is not uncommon to see missing or empty gamma tags. This indicates 681 // It is not uncommon to see missing or empty gamma tags. This indicates
664 // that we should use unit gamma. 682 // that we should use unit gamma.
665 SkGammas gammas; 683 sk_sp<SkGammas> gammas(new SkGammas());
666 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC); 684 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC);
667 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC); 685 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC);
668 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC); 686 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC);
669 if (!r || !SkColorSpace::LoadGammas(&gammas.fRed, 1, 687 if (!r || !SkColorSpace::LoadGammas(&gammas->fRed, 1,
670 r->addr((const uint8_t*) bas e), r->fLength)) { 688 r->addr((const uint8_t*) bas e), r->fLength)) {
671 SkColorSpacePrintf("Failed to read R gamma tag.\n"); 689 SkColorSpacePrintf("Failed to read R gamma tag.\n");
672 } 690 }
673 if (!g || !SkColorSpace::LoadGammas(&gammas.fGreen, 1, 691 if (!g || !SkColorSpace::LoadGammas(&gammas->fGreen, 1,
674 g->addr((const uint8_t*) bas e), g->fLength)) { 692 g->addr((const uint8_t*) bas e), g->fLength)) {
675 SkColorSpacePrintf("Failed to read G gamma tag.\n"); 693 SkColorSpacePrintf("Failed to read G gamma tag.\n");
676 } 694 }
677 if (!b || !SkColorSpace::LoadGammas(&gammas.fBlue, 1, 695 if (!b || !SkColorSpace::LoadGammas(&gammas->fBlue, 1,
678 b->addr((const uint8_t*) bas e), b->fLength)) { 696 b->addr((const uint8_t*) bas e), b->fLength)) {
679 SkColorSpacePrintf("Failed to read B gamma tag.\n"); 697 SkColorSpacePrintf("Failed to read B gamma tag.\n");
680 } 698 }
681 699
682 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor); 700 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
683 mat.set3x3ColMajorf(toXYZ); 701 mat.set3x3ColMajorf(toXYZ);
684 return SkColorSpace::NewRGB(std::move(gammas), mat); 702 if (gammas->isValues()) {
703 // When we have values, take advantage of the NewFromRGB ini tializer.
704 // This allows us to check for canonical sRGB and Adobe RGB.
705 float gammaVals[3];
706 gammaVals[0] = gammas->fRed.fValue;
707 gammaVals[1] = gammas->fGreen.fValue;
708 gammaVals[2] = gammas->fBlue.fValue;
709 return SkColorSpace::NewRGB(gammaVals, mat);
710 } else {
711 return sk_sp<SkColorSpace>(new SkColorSpace(gammas, mat, kUn known_Named));
712 }
685 } 713 }
686 714
687 // Recognize color profile specified by A2B0 tag. 715 // Recognize color profile specified by A2B0 tag.
688 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); 716 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0);
689 if (a2b0) { 717 if (a2b0) {
690 SkColorLookUpTable colorLUT; 718 SkAutoTDelete<SkColorLookUpTable> colorLUT(new SkColorLookUpTabl e());
691 SkGammas gammas; 719 sk_sp<SkGammas> gammas(new SkGammas());
692 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); 720 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
693 if (!SkColorSpace::LoadA2B0(&colorLUT, &gammas, &toXYZ, 721 if (!SkColorSpace::LoadA2B0(colorLUT, gammas, &toXYZ,
694 a2b0->addr((const uint8_t*) base), a 2b0->fLength)) { 722 a2b0->addr((const uint8_t*) base), a 2b0->fLength)) {
695 return_null("Failed to parse A2B0 tag"); 723 return_null("Failed to parse A2B0 tag");
696 } 724 }
697 725
698 // If there is no colorLUT, use NewRGB. This allows us to check if the 726 if (colorLUT->fTable) {
699 // profile is sRGB. 727 return sk_sp<SkColorSpace>(new SkColorSpace(colorLUT.release (), gammas, toXYZ));
700 if (!colorLUT.fTable) { 728 } else if (gammas->isValues()) {
701 return SkColorSpace::NewRGB(std::move(gammas), toXYZ); 729 // When we have values, take advantage of the NewFromRGB ini tializer.
730 // This allows us to check for canonical sRGB and Adobe RGB.
731 float gammaVals[3];
732 gammaVals[0] = gammas->fRed.fValue;
733 gammaVals[1] = gammas->fGreen.fValue;
734 gammaVals[2] = gammas->fBlue.fValue;
735 return SkColorSpace::NewRGB(gammaVals, toXYZ);
736 } else {
737 return sk_sp<SkColorSpace>(new SkColorSpace(gammas, toXYZ, k Unknown_Named));
702 } 738 }
703
704 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), std::move(gammas),
705 toXYZ));
706 } 739 }
707 740
708 } 741 }
709 default: 742 default:
710 break; 743 break;
711 } 744 }
712 745
713 return_null("ICC profile contains unsupported colorspace"); 746 return_null("ICC profile contains unsupported colorspace");
714 } 747 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698