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

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

Issue 1945693002: Create a single, unique pointer to sRGB color space (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase + Test 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
« no previous file with comments | « src/core/SkColorSpace.h ('k') | tests/ColorSpaceTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "SkOncePtr.h"
11
12 static bool color_space_almost_equal(float a, float b) {
13 return SkTAbs(a - b) < 0.01f;
14 }
10 15
11 void SkFloat3::dump() const { 16 void SkFloat3::dump() const {
12 SkDebugf("[%7.4f %7.4f %7.4f]\n", fVec[0], fVec[1], fVec[2]); 17 SkDebugf("[%7.4f %7.4f %7.4f]\n", fVec[0], fVec[1], fVec[2]);
13 } 18 }
14 19
15 //////////////////////////////////////////////////////////////////////////////// ////////////////// 20 //////////////////////////////////////////////////////////////////////////////// //////////////////
16 21
17 static int32_t gUniqueColorSpaceID; 22 static int32_t gUniqueColorSpaceID;
18 23
19 SkColorSpace::SkColorSpace(SkGammas gammas, const SkMatrix44& toXYZD50, Named na med) 24 SkColorSpace::SkColorSpace(SkGammas gammas, const SkMatrix44& toXYZD50, Named na med)
20 : fGammas(std::move(gammas)) 25 : fGammas(std::move(gammas))
21 , fToXYZD50(toXYZD50) 26 , fToXYZD50(toXYZD50)
22 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) 27 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
23 , fNamed(named) 28 , fNamed(named)
24 {} 29 {}
25 30
26 SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, SkGammas gammas, 31 SkColorSpace::SkColorSpace(SkColorLookUpTable colorLUT, SkGammas gammas,
27 const SkMatrix44& toXYZD50) 32 const SkMatrix44& toXYZD50)
28 : fColorLUT(std::move(colorLUT)) 33 : fColorLUT(std::move(colorLUT))
29 , fGammas(std::move(gammas)) 34 , fGammas(std::move(gammas))
30 , fToXYZD50(toXYZD50) 35 , fToXYZD50(toXYZD50)
31 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) 36 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID))
32 , fNamed(kUnknown_Named) 37 , fNamed(kUnknown_Named)
33 {} 38 {}
34 39
35 sk_sp<SkColorSpace> SkColorSpace::NewRGB(const SkMatrix44& toXYZD50, SkGammas ga mmas) {
36 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUn known_Named));
37 }
38
39 const float gSRGB_toXYZD50[] { 40 const float gSRGB_toXYZD50[] {
40 0.4358f, 0.2224f, 0.0139f, // * R 41 0.4358f, 0.2224f, 0.0139f, // * R
41 0.3853f, 0.7170f, 0.0971f, // * G 42 0.3853f, 0.7170f, 0.0971f, // * G
42 0.1430f, 0.0606f, 0.7139f, // * B 43 0.1430f, 0.0606f, 0.7139f, // * B
43 }; 44 };
44 45
46 SK_DECLARE_STATIC_ONCE_PTR(SkColorSpace, sRGB);
47
48 sk_sp<SkColorSpace> SkColorSpace::NewRGB(SkGammas gammas, const SkMatrix44& toXY ZD50) {
49 // Check if we really have sRGB
50 if (color_space_almost_equal(2.2f, gammas.fRed.fValue) &&
51 color_space_almost_equal(2.2f, gammas.fGreen.fValue) &&
52 color_space_almost_equal(2.2f, gammas.fBlue.fValue) &&
53 color_space_almost_equal(toXYZD50.getFloat(0, 0), gSRGB_toXYZD50[0]) &&
54 color_space_almost_equal(toXYZD50.getFloat(0, 1), gSRGB_toXYZD50[1]) &&
55 color_space_almost_equal(toXYZD50.getFloat(0, 2), gSRGB_toXYZD50[2]) &&
56 color_space_almost_equal(toXYZD50.getFloat(1, 0), gSRGB_toXYZD50[3]) &&
57 color_space_almost_equal(toXYZD50.getFloat(1, 1), gSRGB_toXYZD50[4]) &&
58 color_space_almost_equal(toXYZD50.getFloat(1, 2), gSRGB_toXYZD50[5]) &&
59 color_space_almost_equal(toXYZD50.getFloat(2, 0), gSRGB_toXYZD50[6]) &&
60 color_space_almost_equal(toXYZD50.getFloat(2, 1), gSRGB_toXYZD50[7]) &&
61 color_space_almost_equal(toXYZD50.getFloat(2, 2), gSRGB_toXYZD50[8]) &&
62 color_space_almost_equal(toXYZD50.getFloat(0, 3), 0.0f) &&
63 color_space_almost_equal(toXYZD50.getFloat(1, 3), 0.0f) &&
64 color_space_almost_equal(toXYZD50.getFloat(2, 3), 0.0f) &&
65 color_space_almost_equal(toXYZD50.getFloat(3, 0), 0.0f) &&
66 color_space_almost_equal(toXYZD50.getFloat(3, 1), 0.0f) &&
67 color_space_almost_equal(toXYZD50.getFloat(3, 2), 0.0f) &&
68 color_space_almost_equal(toXYZD50.getFloat(3, 3), 1.0f))
69 {
70 return SkColorSpace::NewNamed(kSRGB_Named);
71 }
72
73 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUn known_Named));
74 }
75
45 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { 76 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
46 switch (named) { 77 switch (named) {
47 case kSRGB_Named: { 78 case kSRGB_Named: {
48 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); 79 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor);
49 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50); 80 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50);
50 return sk_sp<SkColorSpace>(new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2 f), srgbToxyzD50, 81 return sk_ref_sp(sRGB.get([=]{
51 kSRGB_Named)); 82 return new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), srgbToxyzD50 , kSRGB_Named);
83 }));
52 } 84 }
53 default: 85 default:
54 break; 86 break;
55 } 87 }
56 return nullptr; 88 return nullptr;
57 } 89 }
58 90
59 //////////////////////////////////////////////////////////////////////////////// /////////////////// 91 //////////////////////////////////////////////////////////////////////////////// ///////////////////
60 92
61 #include "SkFixed.h" 93 #include "SkFixed.h"
(...skipping 20 matching lines...) Expand all
82 } 114 }
83 115
84 static uint32_t read_big_endian_uint(const uint8_t* ptr) { 116 static uint32_t read_big_endian_uint(const uint8_t* ptr) {
85 return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3]; 117 return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
86 } 118 }
87 119
88 static int32_t read_big_endian_int(const uint8_t* ptr) { 120 static int32_t read_big_endian_int(const uint8_t* ptr) {
89 return (int32_t) read_big_endian_uint(ptr); 121 return (int32_t) read_big_endian_uint(ptr);
90 } 122 }
91 123
92 static bool color_space_almost_equal(float a, float b) {
93 return SkTAbs(a - b) < 0.01f;
94 }
95
96 // This is equal to the header size according to the ICC specification (128) 124 // This is equal to the header size according to the ICC specification (128)
97 // plus the size of the tag count (4). We include the tag count since we 125 // plus the size of the tag count (4). We include the tag count since we
98 // always require it to be present anyway. 126 // always require it to be present anyway.
99 static const size_t kICCHeaderSize = 132; 127 static const size_t kICCHeaderSize = 132;
100 128
101 // Contains a signature (4), offset (4), and size (4). 129 // Contains a signature (4), offset (4), and size (4).
102 static const size_t kICCTagTableEntrySize = 12; 130 static const size_t kICCTagTableEntrySize = 12;
103 131
104 static const uint32_t kRGB_ColorSpace = SkSetFourByteTag('R', 'G', 'B', ' '); 132 static const uint32_t kRGB_ColorSpace = SkSetFourByteTag('R', 'G', 'B', ' ');
105 133
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 SkColorSpacePrintf("Failed to read R gamma tag.\n"); 598 SkColorSpacePrintf("Failed to read R gamma tag.\n");
571 } 599 }
572 if (!g || !SkColorSpace::LoadGammas(&gammas.fGreen, 1, 600 if (!g || !SkColorSpace::LoadGammas(&gammas.fGreen, 1,
573 g->addr((const uint8_t*) bas e), g->fLength)) { 601 g->addr((const uint8_t*) bas e), g->fLength)) {
574 SkColorSpacePrintf("Failed to read G gamma tag.\n"); 602 SkColorSpacePrintf("Failed to read G gamma tag.\n");
575 } 603 }
576 if (!b || !SkColorSpace::LoadGammas(&gammas.fBlue, 1, 604 if (!b || !SkColorSpace::LoadGammas(&gammas.fBlue, 1,
577 b->addr((const uint8_t*) bas e), b->fLength)) { 605 b->addr((const uint8_t*) bas e), b->fLength)) {
578 SkColorSpacePrintf("Failed to read B gamma tag.\n"); 606 SkColorSpacePrintf("Failed to read B gamma tag.\n");
579 } 607 }
608
580 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor); 609 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
581 mat.set3x3ColMajorf(toXYZ); 610 mat.set3x3ColMajorf(toXYZ);
582 return SkColorSpace::NewRGB(mat, std::move(gammas)); 611 return SkColorSpace::NewRGB(std::move(gammas), mat);
583 } 612 }
584 613
585 // Recognize color profile specified by A2B0 tag. 614 // Recognize color profile specified by A2B0 tag.
586 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); 615 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0);
587 if (a2b0) { 616 if (a2b0) {
588 SkColorLookUpTable colorLUT; 617 SkColorLookUpTable colorLUT;
589 SkGammas gammas; 618 SkGammas gammas;
590 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); 619 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
591 if (!SkColorSpace::LoadA2B0(&colorLUT, &gammas, &toXYZ, 620 if (!SkColorSpace::LoadA2B0(&colorLUT, &gammas, &toXYZ,
592 a2b0->addr((const uint8_t*) base), a 2b0->fLength)) { 621 a2b0->addr((const uint8_t*) base), a 2b0->fLength)) {
593 return_null("Failed to parse A2B0 tag"); 622 return_null("Failed to parse A2B0 tag");
594 } 623 }
595 624
625 // If there is no colorLUT, use NewRGB. This allows us to check if the
626 // profile is sRGB.
627 if (!colorLUT.fTable) {
628 return SkColorSpace::NewRGB(std::move(gammas), toXYZ);
629 }
630
596 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), std::move(gammas), 631 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(colorLUT), std::move(gammas),
597 toXYZ)); 632 toXYZ));
598 } 633 }
599 634
600 } 635 }
601 default: 636 default:
602 break; 637 break;
603 } 638 }
604 639
605 return_null("ICC profile contains unsupported colorspace"); 640 return_null("ICC profile contains unsupported colorspace");
606 } 641 }
OLDNEW
« no previous file with comments | « src/core/SkColorSpace.h ('k') | tests/ColorSpaceTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698