OLD | NEW |
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" | |
9 #include "SkColorSpace.h" | 8 #include "SkColorSpace.h" |
10 #include "SkColorSpacePriv.h" | 9 #include "SkColorSpace_Base.h" |
11 #include "SkOnce.h" | 10 #include "SkOnce.h" |
12 | 11 |
13 static bool color_space_almost_equal(float a, float b) { | 12 static bool color_space_almost_equal(float a, float b) { |
14 return SkTAbs(a - b) < 0.01f; | 13 return SkTAbs(a - b) < 0.01f; |
15 } | 14 } |
16 | 15 |
17 ////////////////////////////////////////////////////////////////////////////////
////////////////// | 16 ////////////////////////////////////////////////////////////////////////////////
////////////////// |
18 | 17 |
19 static int32_t gUniqueColorSpaceID; | 18 SkColorSpace::SkColorSpace(GammaNamed gammaNamed, const SkMatrix44& toXYZD50, Na
med named) |
20 | 19 : fGammaNamed(kNonStandard_GammaNamed) |
21 SkColorSpace::SkColorSpace(sk_sp<SkGammas> gammas, const SkMatrix44& toXYZD50, N
amed named) | |
22 : fGammas(gammas) | |
23 , fToXYZD50(toXYZD50) | 20 , fToXYZD50(toXYZD50) |
24 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) | |
25 , fNamed(named) | 21 , fNamed(named) |
26 {} | 22 {} |
27 | 23 |
28 SkColorSpace::SkColorSpace(SkColorLookUpTable* colorLUT, sk_sp<SkGammas> gammas, | 24 SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkGammas> gammas, const SkMatrix44& t
oXYZD50, |
29 const SkMatrix44& toXYZD50) | 25 Named named) |
30 : fColorLUT(colorLUT) | 26 : INHERITED(kNonStandard_GammaNamed, toXYZD50, named) |
31 , fGammas(gammas) | 27 , fGammas(gammas) |
32 , fToXYZD50(toXYZD50) | 28 {} |
33 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) | 29 |
34 , fNamed(kUnknown_Named) | 30 SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkGammas> gammas, GammaNamed gammaNam
ed, |
| 31 const SkMatrix44& toXYZD50, Named named) |
| 32 : INHERITED(gammaNamed, toXYZD50, named) |
| 33 , fGammas(gammas) |
| 34 {} |
| 35 |
| 36 SkColorSpace_Base::SkColorSpace_Base(SkColorLookUpTable* colorLUT, sk_sp<SkGamma
s> gammas, |
| 37 const SkMatrix44& toXYZD50) |
| 38 : INHERITED(kNonStandard_GammaNamed, toXYZD50, kUnknown_Named) |
| 39 , fColorLUT(colorLUT) |
| 40 , fGammas(gammas) |
35 {} | 41 {} |
36 | 42 |
37 const float gSRGB_toXYZD50[] { | 43 const float gSRGB_toXYZD50[] { |
38 0.4358f, 0.2224f, 0.0139f, // * R | 44 0.4358f, 0.2224f, 0.0139f, // * R |
39 0.3853f, 0.7170f, 0.0971f, // * G | 45 0.3853f, 0.7170f, 0.0971f, // * G |
40 0.1430f, 0.0606f, 0.7139f, // * B | 46 0.1430f, 0.0606f, 0.7139f, // * B |
41 }; | 47 }; |
42 | 48 |
43 const float gAdobeRGB_toXYZD50[] { | 49 const float gAdobeRGB_toXYZD50[] { |
44 0.6098f, 0.3111f, 0.0195f, // * R | 50 0.6098f, 0.3111f, 0.0195f, // * R |
(...skipping 19 matching lines...) Expand all Loading... |
64 color_space_almost_equal(toXYZD50.getFloat(2, 2), standard[8]) && | 70 color_space_almost_equal(toXYZD50.getFloat(2, 2), standard[8]) && |
65 color_space_almost_equal(toXYZD50.getFloat(0, 3), 0.0f) && | 71 color_space_almost_equal(toXYZD50.getFloat(0, 3), 0.0f) && |
66 color_space_almost_equal(toXYZD50.getFloat(1, 3), 0.0f) && | 72 color_space_almost_equal(toXYZD50.getFloat(1, 3), 0.0f) && |
67 color_space_almost_equal(toXYZD50.getFloat(2, 3), 0.0f) && | 73 color_space_almost_equal(toXYZD50.getFloat(2, 3), 0.0f) && |
68 color_space_almost_equal(toXYZD50.getFloat(3, 0), 0.0f) && | 74 color_space_almost_equal(toXYZD50.getFloat(3, 0), 0.0f) && |
69 color_space_almost_equal(toXYZD50.getFloat(3, 1), 0.0f) && | 75 color_space_almost_equal(toXYZD50.getFloat(3, 1), 0.0f) && |
70 color_space_almost_equal(toXYZD50.getFloat(3, 2), 0.0f) && | 76 color_space_almost_equal(toXYZD50.getFloat(3, 2), 0.0f) && |
71 color_space_almost_equal(toXYZD50.getFloat(3, 3), 1.0f); | 77 color_space_almost_equal(toXYZD50.getFloat(3, 3), 1.0f); |
72 } | 78 } |
73 | 79 |
74 static SkOnce gStandardGammasOnce; | 80 static SkOnce g2Dot2CurveGammasOnce; |
75 static SkGammas* gStandardGammas; | 81 static SkGammas* g2Dot2CurveGammas; |
| 82 static SkOnce gLinearGammasOnce; |
| 83 static SkGammas* gLinearGammas; |
76 | 84 |
77 sk_sp<SkColorSpace> SkColorSpace::NewRGB(float gammaVals[3], const SkMatrix44& t
oXYZD50) { | 85 sk_sp<SkColorSpace> SkColorSpace::NewRGB(float gammaVals[3], const SkMatrix44& t
oXYZD50) { |
78 sk_sp<SkGammas> gammas = nullptr; | 86 sk_sp<SkGammas> gammas = nullptr; |
| 87 GammaNamed gammaNamed = kNonStandard_GammaNamed; |
79 | 88 |
80 // Check if we really have sRGB or Adobe RGB | 89 // Check if we really have sRGB or Adobe RGB |
81 if (color_space_almost_equal(2.2f, gammaVals[0]) && | 90 if (color_space_almost_equal(2.2f, gammaVals[0]) && |
82 color_space_almost_equal(2.2f, gammaVals[1]) && | 91 color_space_almost_equal(2.2f, gammaVals[1]) && |
83 color_space_almost_equal(2.2f, gammaVals[2])) | 92 color_space_almost_equal(2.2f, gammaVals[2])) |
84 { | 93 { |
85 gStandardGammasOnce([] { | 94 g2Dot2CurveGammasOnce([] { |
86 gStandardGammas = new SkGammas(2.2f, 2.2f, 2.2f); | 95 g2Dot2CurveGammas = new SkGammas(2.2f, 2.2f, 2.2f); |
87 }); | 96 }); |
88 gammas = sk_ref_sp(gStandardGammas); | 97 gammas = sk_ref_sp(g2Dot2CurveGammas); |
| 98 gammaNamed = k2Dot2Curve_GammaNamed; |
89 | 99 |
90 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { | 100 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { |
91 return SkColorSpace::NewNamed(kSRGB_Named); | 101 return SkColorSpace::NewNamed(kSRGB_Named); |
92 } else if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) { | 102 } else if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) { |
93 return SkColorSpace::NewNamed(kAdobeRGB_Named); | 103 return SkColorSpace::NewNamed(kAdobeRGB_Named); |
94 } | 104 } |
| 105 } else if (color_space_almost_equal(1.0f, gammaVals[0]) && |
| 106 color_space_almost_equal(1.0f, gammaVals[1]) && |
| 107 color_space_almost_equal(1.0f, gammaVals[2])) |
| 108 { |
| 109 gLinearGammasOnce([] { |
| 110 gLinearGammas = new SkGammas(1.0f, 1.0f, 1.0f); |
| 111 }); |
| 112 gammas = sk_ref_sp(gLinearGammas); |
| 113 gammaNamed = kLinear_GammaNamed; |
95 } | 114 } |
96 | 115 |
97 if (!gammas) { | 116 if (!gammas) { |
98 gammas = sk_sp<SkGammas>(new SkGammas(gammaVals[0], gammaVals[1], gammaV
als[2])); | 117 gammas = sk_sp<SkGammas>(new SkGammas(gammaVals[0], gammaVals[1], gammaV
als[2])); |
99 } | 118 } |
100 return sk_sp<SkColorSpace>(new SkColorSpace(gammas, toXYZD50, kUnknown_Named
)); | 119 return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammas, gammaNamed, toXYZD5
0, kUnknown_Named)); |
101 } | 120 } |
102 | 121 |
103 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { | 122 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { |
104 static SkOnce sRGBOnce; | 123 static SkOnce sRGBOnce; |
105 static SkColorSpace* sRGB; | 124 static SkColorSpace* sRGB; |
106 static SkOnce adobeRGBOnce; | 125 static SkOnce adobeRGBOnce; |
107 static SkColorSpace* adobeRGB; | 126 static SkColorSpace* adobeRGB; |
108 | 127 |
109 switch (named) { | 128 switch (named) { |
110 case kSRGB_Named: { | 129 case kSRGB_Named: { |
111 gStandardGammasOnce([] { | 130 g2Dot2CurveGammasOnce([] { |
112 gStandardGammas = new SkGammas(2.2f, 2.2f, 2.2f); | 131 g2Dot2CurveGammas = new SkGammas(2.2f, 2.2f, 2.2f); |
113 }); | 132 }); |
114 | 133 |
115 sRGBOnce([] { | 134 sRGBOnce([] { |
116 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); | 135 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); |
117 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50); | 136 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50); |
118 sRGB = new SkColorSpace(sk_ref_sp(gStandardGammas), srgbToxyzD50
, kSRGB_Named); | 137 sRGB = new SkColorSpace_Base(sk_ref_sp(g2Dot2CurveGammas), k2Dot
2Curve_GammaNamed, |
| 138 srgbToxyzD50, kSRGB_Named); |
119 }); | 139 }); |
120 return sk_ref_sp(sRGB); | 140 return sk_ref_sp(sRGB); |
121 } | 141 } |
122 case kAdobeRGB_Named: { | 142 case kAdobeRGB_Named: { |
123 gStandardGammasOnce([] { | 143 g2Dot2CurveGammasOnce([] { |
124 gStandardGammas = new SkGammas(2.2f, 2.2f, 2.2f); | 144 g2Dot2CurveGammas = new SkGammas(2.2f, 2.2f, 2.2f); |
125 }); | 145 }); |
126 | 146 |
127 adobeRGBOnce([] { | 147 adobeRGBOnce([] { |
128 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct
or); | 148 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct
or); |
129 adobergbToxyzD50.set3x3ColMajorf(gAdobeRGB_toXYZD50); | 149 adobergbToxyzD50.set3x3ColMajorf(gAdobeRGB_toXYZD50); |
130 adobeRGB = new SkColorSpace(sk_ref_sp(gStandardGammas), adobergb
ToxyzD50, | 150 adobeRGB = new SkColorSpace_Base(sk_ref_sp(g2Dot2CurveGammas), |
131 kAdobeRGB_Named); | 151 k2Dot2Curve_GammaNamed, adoberg
bToxyzD50, |
| 152 kAdobeRGB_Named); |
132 }); | 153 }); |
133 return sk_ref_sp(adobeRGB); | 154 return sk_ref_sp(adobeRGB); |
134 } | 155 } |
135 default: | 156 default: |
136 break; | 157 break; |
137 } | 158 } |
138 return nullptr; | 159 return nullptr; |
139 } | 160 } |
140 | 161 |
141 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 162 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 dst[0] = SkFixedToFloat(read_big_endian_int(src + 8)); | 350 dst[0] = SkFixedToFloat(read_big_endian_int(src + 8)); |
330 dst[1] = SkFixedToFloat(read_big_endian_int(src + 12)); | 351 dst[1] = SkFixedToFloat(read_big_endian_int(src + 12)); |
331 dst[2] = SkFixedToFloat(read_big_endian_int(src + 16)); | 352 dst[2] = SkFixedToFloat(read_big_endian_int(src + 16)); |
332 SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]); | 353 SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]); |
333 return true; | 354 return true; |
334 } | 355 } |
335 | 356 |
336 static const uint32_t kTAG_CurveType = SkSetFourByteTag('c', 'u', 'r', 'v'); | 357 static const uint32_t kTAG_CurveType = SkSetFourByteTag('c', 'u', 'r', 'v'); |
337 static const uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', 'a'); | 358 static const uint32_t kTAG_ParaCurveType = SkSetFourByteTag('p', 'a', 'r', 'a'); |
338 | 359 |
339 bool SkColorSpace::LoadGammas(SkGammaCurve* gammas, uint32_t numGammas, const ui
nt8_t* src, | 360 bool load_gammas(SkGammaCurve* gammas, uint32_t numGammas, const uint8_t* src, s
ize_t len) { |
340 size_t len) { | |
341 for (uint32_t i = 0; i < numGammas; i++) { | 361 for (uint32_t i = 0; i < numGammas; i++) { |
342 if (len < 12) { | 362 if (len < 12) { |
343 // FIXME (msarett): | 363 // FIXME (msarett): |
344 // We could potentially return false here after correctly parsing *s
ome* of the | 364 // We could potentially return false here after correctly parsing *s
ome* of the |
345 // gammas correctly. Should we somehow try to indicate a partial su
ccess? | 365 // gammas correctly. Should we somehow try to indicate a partial su
ccess? |
346 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len); | 366 SkColorSpacePrintf("gamma tag is too small (%d bytes)", len); |
347 return false; | 367 return false; |
348 } | 368 } |
349 | 369 |
350 // We need to count the number of bytes in the tag, so we are able to mo
ve to the | 370 // We need to count the number of bytes in the tag, so we are able to mo
ve to the |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 src += tagBytes; | 492 src += tagBytes; |
473 len -= tagBytes; | 493 len -= tagBytes; |
474 } | 494 } |
475 } | 495 } |
476 | 496 |
477 return true; | 497 return true; |
478 } | 498 } |
479 | 499 |
480 static const uint32_t kTAG_AtoBType = SkSetFourByteTag('m', 'A', 'B', ' '); | 500 static const uint32_t kTAG_AtoBType = SkSetFourByteTag('m', 'A', 'B', ' '); |
481 | 501 |
482 bool SkColorSpace::LoadColorLUT(SkColorLookUpTable* colorLUT, uint32_t inputChan
nels, | 502 bool load_color_lut(SkColorLookUpTable* colorLUT, uint32_t inputChannels, uint32
_t outputChannels, |
483 uint32_t outputChannels, const uint8_t* src, siz
e_t len) { | 503 const uint8_t* src, size_t len) { |
484 if (len < 20) { | 504 if (len < 20) { |
485 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len); | 505 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len); |
486 return false; | 506 return false; |
487 } | 507 } |
488 | 508 |
489 SkASSERT(inputChannels <= SkColorLookUpTable::kMaxChannels && 3 == outputCha
nnels); | 509 SkASSERT(inputChannels <= SkColorLookUpTable::kMaxChannels && 3 == outputCha
nnels); |
490 colorLUT->fInputChannels = inputChannels; | 510 colorLUT->fInputChannels = inputChannels; |
491 colorLUT->fOutputChannels = outputChannels; | 511 colorLUT->fOutputChannels = outputChannels; |
492 uint32_t numEntries = 1; | 512 uint32_t numEntries = 1; |
493 for (uint32_t i = 0; i < inputChannels; i++) { | 513 for (uint32_t i = 0; i < inputChannels; i++) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 array[10] = SkFixedToFloat(read_big_endian_int(src + 32)); | 567 array[10] = SkFixedToFloat(read_big_endian_int(src + 32)); |
548 array[11] = 0; | 568 array[11] = 0; |
549 array[12] = SkFixedToFloat(read_big_endian_int(src + 36)); // translate R | 569 array[12] = SkFixedToFloat(read_big_endian_int(src + 36)); // translate R |
550 array[13] = SkFixedToFloat(read_big_endian_int(src + 40)); // translate G | 570 array[13] = SkFixedToFloat(read_big_endian_int(src + 40)); // translate G |
551 array[14] = SkFixedToFloat(read_big_endian_int(src + 44)); | 571 array[14] = SkFixedToFloat(read_big_endian_int(src + 44)); |
552 array[15] = 1; | 572 array[15] = 1; |
553 toXYZ->setColMajorf(array); | 573 toXYZ->setColMajorf(array); |
554 return true; | 574 return true; |
555 } | 575 } |
556 | 576 |
557 bool SkColorSpace::LoadA2B0(SkColorLookUpTable* colorLUT, SkGammaCurve* gammas,
SkMatrix44* toXYZ, | 577 bool load_a2b0(SkColorLookUpTable* colorLUT, SkGammaCurve* gammas, SkMatrix44* t
oXYZ, |
558 const uint8_t* src, size_t len) { | 578 const uint8_t* src, size_t len) { |
559 if (len < 32) { | 579 if (len < 32) { |
560 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len); | 580 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len); |
561 return false; | 581 return false; |
562 } | 582 } |
563 | 583 |
564 uint32_t type = read_big_endian_uint(src); | 584 uint32_t type = read_big_endian_uint(src); |
565 if (kTAG_AtoBType != type) { | 585 if (kTAG_AtoBType != type) { |
566 // FIXME (msarett): Need to support lut8Type and lut16Type. | 586 // FIXME (msarett): Need to support lut8Type and lut16Type. |
567 SkColorSpacePrintf("Unsupported A to B tag type.\n"); | 587 SkColorSpacePrintf("Unsupported A to B tag type.\n"); |
568 return false; | 588 return false; |
(...skipping 20 matching lines...) Expand all Loading... |
589 if ((0 != offsetToACurves) || (0 != offsetToBCurves)) { | 609 if ((0 != offsetToACurves) || (0 != offsetToBCurves)) { |
590 // FIXME (msarett): Handle A and B curves. | 610 // FIXME (msarett): Handle A and B curves. |
591 // Note that the A curve is technically required in order to have a colo
r LUT. | 611 // Note that the A curve is technically required in order to have a colo
r LUT. |
592 // However, all the A curves I have seen so far have are just placeholde
rs that | 612 // However, all the A curves I have seen so far have are just placeholde
rs that |
593 // don't actually transform the data. | 613 // don't actually transform the data. |
594 SkColorSpacePrintf("Ignoring A and/or B curve. Output may be wrong.\n")
; | 614 SkColorSpacePrintf("Ignoring A and/or B curve. Output may be wrong.\n")
; |
595 } | 615 } |
596 | 616 |
597 uint32_t offsetToColorLUT = read_big_endian_int(src + 24); | 617 uint32_t offsetToColorLUT = read_big_endian_int(src + 24); |
598 if (0 != offsetToColorLUT && offsetToColorLUT < len) { | 618 if (0 != offsetToColorLUT && offsetToColorLUT < len) { |
599 if (!SkColorSpace::LoadColorLUT(colorLUT, inputChannels, outputChannels, | 619 if (!load_color_lut(colorLUT, inputChannels, outputChannels, src + offse
tToColorLUT, |
600 src + offsetToColorLUT, len - offsetToCo
lorLUT)) { | 620 len - offsetToColorLUT)) { |
601 SkColorSpacePrintf("Failed to read color LUT from A to B tag.\n"); | 621 SkColorSpacePrintf("Failed to read color LUT from A to B tag.\n"); |
602 } | 622 } |
603 } | 623 } |
604 | 624 |
605 uint32_t offsetToMCurves = read_big_endian_int(src + 20); | 625 uint32_t offsetToMCurves = read_big_endian_int(src + 20); |
606 if (0 != offsetToMCurves && offsetToMCurves < len) { | 626 if (0 != offsetToMCurves && offsetToMCurves < len) { |
607 if (!SkColorSpace::LoadGammas(gammas, outputChannels, src + offsetToMCur
ves, | 627 if (!load_gammas(gammas, outputChannels, src + offsetToMCurves, len - of
fsetToMCurves)) { |
608 len - offsetToMCurves)) { | |
609 SkColorSpacePrintf("Failed to read M curves from A to B tag.\n"); | 628 SkColorSpacePrintf("Failed to read M curves from A to B tag.\n"); |
610 } | 629 } |
611 } | 630 } |
612 | 631 |
613 uint32_t offsetToMatrix = read_big_endian_int(src + 16); | 632 uint32_t offsetToMatrix = read_big_endian_int(src + 16); |
614 if (0 != offsetToMatrix && offsetToMatrix < len) { | 633 if (0 != offsetToMatrix && offsetToMatrix < len) { |
615 if (!load_matrix(toXYZ, src + offsetToMatrix, len - offsetToMatrix)) { | 634 if (!load_matrix(toXYZ, src + offsetToMatrix, len - offsetToMatrix)) { |
616 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n"); | 635 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n"); |
617 } | 636 } |
618 } | 637 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 { | 696 { |
678 return_null("Need valid rgb tags for XYZ space"); | 697 return_null("Need valid rgb tags for XYZ space"); |
679 } | 698 } |
680 | 699 |
681 // It is not uncommon to see missing or empty gamma tags. This
indicates | 700 // It is not uncommon to see missing or empty gamma tags. This
indicates |
682 // that we should use unit gamma. | 701 // that we should use unit gamma. |
683 SkGammaCurve curves[3]; | 702 SkGammaCurve curves[3]; |
684 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC); | 703 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC); |
685 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC); | 704 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC); |
686 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC); | 705 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC); |
687 if (!r || !SkColorSpace::LoadGammas(&curves[0], 1, | 706 if (!r || !load_gammas(&curves[0], 1, r->addr((const uint8_t*) b
ase), r->fLength)) |
688 r->addr((const uint8_t*) bas
e), r->fLength)) { | 707 { |
689 SkColorSpacePrintf("Failed to read R gamma tag.\n"); | 708 SkColorSpacePrintf("Failed to read R gamma tag.\n"); |
690 } | 709 } |
691 if (!g || !SkColorSpace::LoadGammas(&curves[1], 1, | 710 if (!g || !load_gammas(&curves[1], 1, g->addr((const uint8_t*) b
ase), g->fLength)) |
692 g->addr((const uint8_t*) bas
e), g->fLength)) { | 711 { |
693 SkColorSpacePrintf("Failed to read G gamma tag.\n"); | 712 SkColorSpacePrintf("Failed to read G gamma tag.\n"); |
694 } | 713 } |
695 if (!b || !SkColorSpace::LoadGammas(&curves[2], 1, | 714 if (!b || !load_gammas(&curves[2], 1, b->addr((const uint8_t*) b
ase), b->fLength)) |
696 b->addr((const uint8_t*) bas
e), b->fLength)) { | 715 { |
697 SkColorSpacePrintf("Failed to read B gamma tag.\n"); | 716 SkColorSpacePrintf("Failed to read B gamma tag.\n"); |
698 } | 717 } |
699 | 718 |
700 sk_sp<SkGammas> gammas(new SkGammas(std::move(curves[0]), std::m
ove(curves[1]), | 719 sk_sp<SkGammas> gammas(new SkGammas(std::move(curves[0]), std::m
ove(curves[1]), |
701 std::move(curves[2]))); | 720 std::move(curves[2]))); |
702 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor); | 721 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor); |
703 mat.set3x3ColMajorf(toXYZ); | 722 mat.set3x3ColMajorf(toXYZ); |
704 if (gammas->isValues()) { | 723 if (gammas->isValues()) { |
705 // When we have values, take advantage of the NewFromRGB ini
tializer. | 724 // When we have values, take advantage of the NewFromRGB ini
tializer. |
706 // This allows us to check for canonical sRGB and Adobe RGB. | 725 // This allows us to check for canonical sRGB and Adobe RGB. |
707 float gammaVals[3]; | 726 float gammaVals[3]; |
708 gammaVals[0] = gammas->fRed.fValue; | 727 gammaVals[0] = gammas->fRed.fValue; |
709 gammaVals[1] = gammas->fGreen.fValue; | 728 gammaVals[1] = gammas->fGreen.fValue; |
710 gammaVals[2] = gammas->fBlue.fValue; | 729 gammaVals[2] = gammas->fBlue.fValue; |
711 return SkColorSpace::NewRGB(gammaVals, mat); | 730 return SkColorSpace::NewRGB(gammaVals, mat); |
712 } else { | 731 } else { |
713 return sk_sp<SkColorSpace>(new SkColorSpace(gammas, mat, kUn
known_Named)); | 732 return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammas, mat
, kUnknown_Named)); |
714 } | 733 } |
715 } | 734 } |
716 | 735 |
717 // Recognize color profile specified by A2B0 tag. | 736 // Recognize color profile specified by A2B0 tag. |
718 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); | 737 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); |
719 if (a2b0) { | 738 if (a2b0) { |
720 SkAutoTDelete<SkColorLookUpTable> colorLUT(new SkColorLookUpTabl
e()); | 739 SkAutoTDelete<SkColorLookUpTable> colorLUT(new SkColorLookUpTabl
e()); |
721 SkGammaCurve curves[3]; | 740 SkGammaCurve curves[3]; |
722 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); | 741 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); |
723 if (!SkColorSpace::LoadA2B0(colorLUT, curves, &toXYZ, | 742 if (!load_a2b0(colorLUT, curves, &toXYZ, a2b0->addr((const uint8
_t*) base), |
724 a2b0->addr((const uint8_t*) base), a
2b0->fLength)) { | 743 a2b0->fLength)) { |
725 return_null("Failed to parse A2B0 tag"); | 744 return_null("Failed to parse A2B0 tag"); |
726 } | 745 } |
727 | 746 |
728 sk_sp<SkGammas> gammas(new SkGammas(std::move(curves[0]), std::m
ove(curves[1]), | 747 sk_sp<SkGammas> gammas(new SkGammas(std::move(curves[0]), std::m
ove(curves[1]), |
729 std::move(curves[2]))); | 748 std::move(curves[2]))); |
730 if (colorLUT->fTable) { | 749 if (colorLUT->fTable) { |
731 return sk_sp<SkColorSpace>(new SkColorSpace(colorLUT.release
(), gammas, toXYZ)); | 750 return sk_sp<SkColorSpace>(new SkColorSpace_Base(colorLUT.re
lease(), gammas, |
| 751 toXYZ)); |
732 } else if (gammas->isValues()) { | 752 } else if (gammas->isValues()) { |
733 // When we have values, take advantage of the NewFromRGB ini
tializer. | 753 // When we have values, take advantage of the NewFromRGB ini
tializer. |
734 // This allows us to check for canonical sRGB and Adobe RGB. | 754 // This allows us to check for canonical sRGB and Adobe RGB. |
735 float gammaVals[3]; | 755 float gammaVals[3]; |
736 gammaVals[0] = gammas->fRed.fValue; | 756 gammaVals[0] = gammas->fRed.fValue; |
737 gammaVals[1] = gammas->fGreen.fValue; | 757 gammaVals[1] = gammas->fGreen.fValue; |
738 gammaVals[2] = gammas->fBlue.fValue; | 758 gammaVals[2] = gammas->fBlue.fValue; |
739 return SkColorSpace::NewRGB(gammaVals, toXYZ); | 759 return SkColorSpace::NewRGB(gammaVals, toXYZ); |
740 } else { | 760 } else { |
741 return sk_sp<SkColorSpace>(new SkColorSpace(gammas, toXYZ, k
Unknown_Named)); | 761 return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammas, toX
YZ, |
| 762 kUnknown_Na
med)); |
742 } | 763 } |
743 } | 764 } |
744 | 765 |
745 } | 766 } |
746 default: | 767 default: |
747 break; | 768 break; |
748 } | 769 } |
749 | 770 |
750 return_null("ICC profile contains unsupported colorspace"); | 771 return_null("ICC profile contains unsupported colorspace"); |
751 } | 772 } |
OLD | NEW |