| 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 |