| 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" | 8 #include "SkAtomics.h" |
| 9 #include "SkColorSpace.h" | 9 #include "SkColorSpace.h" |
| 10 #include "SkColorSpacePriv.h" | 10 #include "SkColorSpacePriv.h" |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 array[10] = SkFixedToFloat(read_big_endian_int(src + 32)); | 547 array[10] = SkFixedToFloat(read_big_endian_int(src + 32)); |
| 548 array[11] = 0; | 548 array[11] = 0; |
| 549 array[12] = SkFixedToFloat(read_big_endian_int(src + 36)); // translate R | 549 array[12] = SkFixedToFloat(read_big_endian_int(src + 36)); // translate R |
| 550 array[13] = SkFixedToFloat(read_big_endian_int(src + 40)); // translate G | 550 array[13] = SkFixedToFloat(read_big_endian_int(src + 40)); // translate G |
| 551 array[14] = SkFixedToFloat(read_big_endian_int(src + 44)); | 551 array[14] = SkFixedToFloat(read_big_endian_int(src + 44)); |
| 552 array[15] = 1; | 552 array[15] = 1; |
| 553 toXYZ->setColMajorf(array); | 553 toXYZ->setColMajorf(array); |
| 554 return true; | 554 return true; |
| 555 } | 555 } |
| 556 | 556 |
| 557 bool SkColorSpace::LoadA2B0(SkColorLookUpTable* colorLUT, sk_sp<SkGammas> gammas
, SkMatrix44* toXYZ, | 557 bool SkColorSpace::LoadA2B0(SkColorLookUpTable* colorLUT, SkGammaCurve* gammas,
SkMatrix44* toXYZ, |
| 558 const uint8_t* src, size_t len) { | 558 const uint8_t* src, size_t len) { |
| 559 if (len < 32) { | 559 if (len < 32) { |
| 560 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len); | 560 SkColorSpacePrintf("A to B tag is too small (%d bytes).", len); |
| 561 return false; | 561 return false; |
| 562 } | 562 } |
| 563 | 563 |
| 564 uint32_t type = read_big_endian_uint(src); | 564 uint32_t type = read_big_endian_uint(src); |
| 565 if (kTAG_AtoBType != type) { | 565 if (kTAG_AtoBType != type) { |
| 566 // FIXME (msarett): Need to support lut8Type and lut16Type. | 566 // FIXME (msarett): Need to support lut8Type and lut16Type. |
| 567 SkColorSpacePrintf("Unsupported A to B tag type.\n"); | 567 SkColorSpacePrintf("Unsupported A to B tag type.\n"); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 597 uint32_t offsetToColorLUT = read_big_endian_int(src + 24); | 597 uint32_t offsetToColorLUT = read_big_endian_int(src + 24); |
| 598 if (0 != offsetToColorLUT && offsetToColorLUT < len) { | 598 if (0 != offsetToColorLUT && offsetToColorLUT < len) { |
| 599 if (!SkColorSpace::LoadColorLUT(colorLUT, inputChannels, outputChannels, | 599 if (!SkColorSpace::LoadColorLUT(colorLUT, inputChannels, outputChannels, |
| 600 src + offsetToColorLUT, len - offsetToCo
lorLUT)) { | 600 src + offsetToColorLUT, len - offsetToCo
lorLUT)) { |
| 601 SkColorSpacePrintf("Failed to read color LUT from A to B tag.\n"); | 601 SkColorSpacePrintf("Failed to read color LUT from A to B tag.\n"); |
| 602 } | 602 } |
| 603 } | 603 } |
| 604 | 604 |
| 605 uint32_t offsetToMCurves = read_big_endian_int(src + 20); | 605 uint32_t offsetToMCurves = read_big_endian_int(src + 20); |
| 606 if (0 != offsetToMCurves && offsetToMCurves < len) { | 606 if (0 != offsetToMCurves && offsetToMCurves < len) { |
| 607 if (!SkColorSpace::LoadGammas(&gammas->fRed, outputChannels, src + offse
tToMCurves, | 607 if (!SkColorSpace::LoadGammas(gammas, outputChannels, src + offsetToMCur
ves, |
| 608 len - offsetToMCurves)) { | 608 len - offsetToMCurves)) { |
| 609 SkColorSpacePrintf("Failed to read M curves from A to B tag.\n"); | 609 SkColorSpacePrintf("Failed to read M curves from A to B tag.\n"); |
| 610 } | 610 } |
| 611 } | 611 } |
| 612 | 612 |
| 613 uint32_t offsetToMatrix = read_big_endian_int(src + 16); | 613 uint32_t offsetToMatrix = read_big_endian_int(src + 16); |
| 614 if (0 != offsetToMatrix && offsetToMatrix < len) { | 614 if (0 != offsetToMatrix && offsetToMatrix < len) { |
| 615 if (!load_matrix(toXYZ, src + offsetToMatrix, len - offsetToMatrix)) { | 615 if (!load_matrix(toXYZ, src + offsetToMatrix, len - offsetToMatrix)) { |
| 616 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n"); | 616 SkColorSpacePrintf("Failed to read matrix from A to B tag.\n"); |
| 617 } | 617 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 float toXYZ[9]; | 673 float toXYZ[9]; |
| 674 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) || |
| 675 !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) || |
| 676 !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)) |
| 677 { | 677 { |
| 678 return_null("Need valid rgb tags for XYZ space"); | 678 return_null("Need valid rgb tags for XYZ space"); |
| 679 } | 679 } |
| 680 | 680 |
| 681 // 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 |
| 682 // that we should use unit gamma. | 682 // that we should use unit gamma. |
| 683 sk_sp<SkGammas> gammas(new SkGammas()); | 683 SkGammaCurve curves[3]; |
| 684 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC); | 684 r = ICCTag::Find(tags.get(), tagCount, kTAG_rTRC); |
| 685 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC); | 685 g = ICCTag::Find(tags.get(), tagCount, kTAG_gTRC); |
| 686 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC); | 686 b = ICCTag::Find(tags.get(), tagCount, kTAG_bTRC); |
| 687 if (!r || !SkColorSpace::LoadGammas(&gammas->fRed, 1, | 687 if (!r || !SkColorSpace::LoadGammas(&curves[0], 1, |
| 688 r->addr((const uint8_t*) bas
e), r->fLength)) { | 688 r->addr((const uint8_t*) bas
e), r->fLength)) { |
| 689 SkColorSpacePrintf("Failed to read R gamma tag.\n"); | 689 SkColorSpacePrintf("Failed to read R gamma tag.\n"); |
| 690 } | 690 } |
| 691 if (!g || !SkColorSpace::LoadGammas(&gammas->fGreen, 1, | 691 if (!g || !SkColorSpace::LoadGammas(&curves[1], 1, |
| 692 g->addr((const uint8_t*) bas
e), g->fLength)) { | 692 g->addr((const uint8_t*) bas
e), g->fLength)) { |
| 693 SkColorSpacePrintf("Failed to read G gamma tag.\n"); | 693 SkColorSpacePrintf("Failed to read G gamma tag.\n"); |
| 694 } | 694 } |
| 695 if (!b || !SkColorSpace::LoadGammas(&gammas->fBlue, 1, | 695 if (!b || !SkColorSpace::LoadGammas(&curves[2], 1, |
| 696 b->addr((const uint8_t*) bas
e), b->fLength)) { | 696 b->addr((const uint8_t*) bas
e), b->fLength)) { |
| 697 SkColorSpacePrintf("Failed to read B gamma tag.\n"); | 697 SkColorSpacePrintf("Failed to read B gamma tag.\n"); |
| 698 } | 698 } |
| 699 | 699 |
| 700 sk_sp<SkGammas> gammas(new SkGammas(std::move(curves[0]), std::m
ove(curves[1]), |
| 701 std::move(curves[2]))); |
| 700 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor); | 702 SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor); |
| 701 mat.set3x3ColMajorf(toXYZ); | 703 mat.set3x3ColMajorf(toXYZ); |
| 702 if (gammas->isValues()) { | 704 if (gammas->isValues()) { |
| 703 // When we have values, take advantage of the NewFromRGB ini
tializer. | 705 // When we have values, take advantage of the NewFromRGB ini
tializer. |
| 704 // This allows us to check for canonical sRGB and Adobe RGB. | 706 // This allows us to check for canonical sRGB and Adobe RGB. |
| 705 float gammaVals[3]; | 707 float gammaVals[3]; |
| 706 gammaVals[0] = gammas->fRed.fValue; | 708 gammaVals[0] = gammas->fRed.fValue; |
| 707 gammaVals[1] = gammas->fGreen.fValue; | 709 gammaVals[1] = gammas->fGreen.fValue; |
| 708 gammaVals[2] = gammas->fBlue.fValue; | 710 gammaVals[2] = gammas->fBlue.fValue; |
| 709 return SkColorSpace::NewRGB(gammaVals, mat); | 711 return SkColorSpace::NewRGB(gammaVals, mat); |
| 710 } else { | 712 } else { |
| 711 return sk_sp<SkColorSpace>(new SkColorSpace(gammas, mat, kUn
known_Named)); | 713 return sk_sp<SkColorSpace>(new SkColorSpace(gammas, mat, kUn
known_Named)); |
| 712 } | 714 } |
| 713 } | 715 } |
| 714 | 716 |
| 715 // Recognize color profile specified by A2B0 tag. | 717 // Recognize color profile specified by A2B0 tag. |
| 716 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); | 718 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); |
| 717 if (a2b0) { | 719 if (a2b0) { |
| 718 SkAutoTDelete<SkColorLookUpTable> colorLUT(new SkColorLookUpTabl
e()); | 720 SkAutoTDelete<SkColorLookUpTable> colorLUT(new SkColorLookUpTabl
e()); |
| 719 sk_sp<SkGammas> gammas(new SkGammas()); | 721 SkGammaCurve curves[3]; |
| 720 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); | 722 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); |
| 721 if (!SkColorSpace::LoadA2B0(colorLUT, gammas, &toXYZ, | 723 if (!SkColorSpace::LoadA2B0(colorLUT, curves, &toXYZ, |
| 722 a2b0->addr((const uint8_t*) base), a
2b0->fLength)) { | 724 a2b0->addr((const uint8_t*) base), a
2b0->fLength)) { |
| 723 return_null("Failed to parse A2B0 tag"); | 725 return_null("Failed to parse A2B0 tag"); |
| 724 } | 726 } |
| 725 | 727 |
| 728 sk_sp<SkGammas> gammas(new SkGammas(std::move(curves[0]), std::m
ove(curves[1]), |
| 729 std::move(curves[2]))); |
| 726 if (colorLUT->fTable) { | 730 if (colorLUT->fTable) { |
| 727 return sk_sp<SkColorSpace>(new SkColorSpace(colorLUT.release
(), gammas, toXYZ)); | 731 return sk_sp<SkColorSpace>(new SkColorSpace(colorLUT.release
(), gammas, toXYZ)); |
| 728 } else if (gammas->isValues()) { | 732 } else if (gammas->isValues()) { |
| 729 // When we have values, take advantage of the NewFromRGB ini
tializer. | 733 // When we have values, take advantage of the NewFromRGB ini
tializer. |
| 730 // This allows us to check for canonical sRGB and Adobe RGB. | 734 // This allows us to check for canonical sRGB and Adobe RGB. |
| 731 float gammaVals[3]; | 735 float gammaVals[3]; |
| 732 gammaVals[0] = gammas->fRed.fValue; | 736 gammaVals[0] = gammas->fRed.fValue; |
| 733 gammaVals[1] = gammas->fGreen.fValue; | 737 gammaVals[1] = gammas->fGreen.fValue; |
| 734 gammaVals[2] = gammas->fBlue.fValue; | 738 gammaVals[2] = gammas->fBlue.fValue; |
| 735 return SkColorSpace::NewRGB(gammaVals, toXYZ); | 739 return SkColorSpace::NewRGB(gammaVals, toXYZ); |
| 736 } else { | 740 } else { |
| 737 return sk_sp<SkColorSpace>(new SkColorSpace(gammas, toXYZ, k
Unknown_Named)); | 741 return sk_sp<SkColorSpace>(new SkColorSpace(gammas, toXYZ, k
Unknown_Named)); |
| 738 } | 742 } |
| 739 } | 743 } |
| 740 | 744 |
| 741 } | 745 } |
| 742 default: | 746 default: |
| 743 break; | 747 break; |
| 744 } | 748 } |
| 745 | 749 |
| 746 return_null("ICC profile contains unsupported colorspace"); | 750 return_null("ICC profile contains unsupported colorspace"); |
| 747 } | 751 } |
| OLD | NEW |