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 |