| 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 "SkColorSpace.h" | 8 #include "SkColorSpace.h" |
| 9 #include "SkColorSpace_Base.h" | 9 #include "SkColorSpace_Base.h" |
| 10 #include "SkEndian.h" | 10 #include "SkEndian.h" |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 if (arg1 >= 0 && arg2 <= std::numeric_limits<T>::max() - arg1) { | 312 if (arg1 >= 0 && arg2 <= std::numeric_limits<T>::max() - arg1) { |
| 313 T sum = arg1 + arg2; | 313 T sum = arg1 + arg2; |
| 314 if (sum <= std::numeric_limits<size_t>::max()) { | 314 if (sum <= std::numeric_limits<size_t>::max()) { |
| 315 *result = static_cast<size_t>(sum); | 315 *result = static_cast<size_t>(sum); |
| 316 return true; | 316 return true; |
| 317 } | 317 } |
| 318 } | 318 } |
| 319 return false; | 319 return false; |
| 320 } | 320 } |
| 321 | 321 |
| 322 static bool safe_mul(uint32_t arg1, uint32_t arg2, uint32_t* result) { |
| 323 uint64_t product64 = (uint64_t) arg1 * (uint64_t) arg2; |
| 324 uint32_t product32 = (uint32_t) product64; |
| 325 if (product32 != product64) { |
| 326 return false; |
| 327 } |
| 328 |
| 329 *result = product32; |
| 330 return true; |
| 331 } |
| 332 |
| 322 struct ICCTag { | 333 struct ICCTag { |
| 323 uint32_t fSignature; | 334 uint32_t fSignature; |
| 324 uint32_t fOffset; | 335 uint32_t fOffset; |
| 325 uint32_t fLength; | 336 uint32_t fLength; |
| 326 | 337 |
| 327 const uint8_t* init(const uint8_t* src) { | 338 const uint8_t* init(const uint8_t* src) { |
| 328 fSignature = read_big_endian_uint(src); | 339 fSignature = read_big_endian_uint(src); |
| 329 fOffset = read_big_endian_uint(src + 4); | 340 fOffset = read_big_endian_uint(src + 4); |
| 330 fLength = read_big_endian_uint(src + 8); | 341 fLength = read_big_endian_uint(src + 8); |
| 331 return src + 12; | 342 return src + 12; |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 } | 662 } |
| 652 } | 663 } |
| 653 | 664 |
| 654 return true; | 665 return true; |
| 655 } | 666 } |
| 656 | 667 |
| 657 static constexpr uint32_t kTAG_AtoBType = SkSetFourByteTag('m', 'A', 'B', ' '); | 668 static constexpr uint32_t kTAG_AtoBType = SkSetFourByteTag('m', 'A', 'B', ' '); |
| 658 | 669 |
| 659 bool load_color_lut(SkColorLookUpTable* colorLUT, uint32_t inputChannels, uint32
_t outputChannels, | 670 bool load_color_lut(SkColorLookUpTable* colorLUT, uint32_t inputChannels, uint32
_t outputChannels, |
| 660 const uint8_t* src, size_t len) { | 671 const uint8_t* src, size_t len) { |
| 661 if (len < 20) { | 672 // 16 bytes reserved for grid points, 2 for precision, 2 for padding. |
| 673 // The color LUT data follows after this header. |
| 674 static constexpr uint32_t kColorLUTHeaderSize = 20; |
| 675 if (len < kColorLUTHeaderSize) { |
| 662 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len); | 676 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len); |
| 663 return false; | 677 return false; |
| 664 } | 678 } |
| 679 size_t dataLen = len - kColorLUTHeaderSize; |
| 665 | 680 |
| 666 SkASSERT(inputChannels <= SkColorLookUpTable::kMaxChannels && 3 == outputCha
nnels); | 681 SkASSERT(inputChannels <= SkColorLookUpTable::kMaxChannels && 3 == outputCha
nnels); |
| 667 colorLUT->fInputChannels = inputChannels; | 682 colorLUT->fInputChannels = inputChannels; |
| 668 colorLUT->fOutputChannels = outputChannels; | 683 colorLUT->fOutputChannels = outputChannels; |
| 669 uint32_t numEntries = 1; | 684 uint32_t numEntries = 1; |
| 670 for (uint32_t i = 0; i < inputChannels; i++) { | 685 for (uint32_t i = 0; i < inputChannels; i++) { |
| 671 colorLUT->fGridPoints[i] = src[i]; | 686 colorLUT->fGridPoints[i] = src[i]; |
| 672 numEntries *= src[i]; | 687 if (0 == src[i]) { |
| 688 SkColorSpacePrintf("Each input channel must have at least one grid p
oint."); |
| 689 return false; |
| 690 } |
| 691 |
| 692 if (!safe_mul(numEntries, src[i], &numEntries)) { |
| 693 SkColorSpacePrintf("Too many entries in Color LUT."); |
| 694 return false; |
| 695 } |
| 673 } | 696 } |
| 674 numEntries *= outputChannels; | 697 |
| 698 if (!safe_mul(numEntries, outputChannels, &numEntries)) { |
| 699 SkColorSpacePrintf("Too many entries in Color LUT."); |
| 700 return false; |
| 701 } |
| 675 | 702 |
| 676 // Space is provided for a maximum of the 16 input channels. Now we determi
ne the precision | 703 // Space is provided for a maximum of the 16 input channels. Now we determi
ne the precision |
| 677 // of the table values. | 704 // of the table values. |
| 678 uint8_t precision = src[16]; | 705 uint8_t precision = src[16]; |
| 679 switch (precision) { | 706 switch (precision) { |
| 680 case 1: // 8-bit data | 707 case 1: // 8-bit data |
| 681 case 2: // 16-bit data | 708 case 2: // 16-bit data |
| 682 break; | 709 break; |
| 683 default: | 710 default: |
| 684 SkColorSpacePrintf("Color LUT precision must be 8-bit or 16-bit.\n",
len); | 711 SkColorSpacePrintf("Color LUT precision must be 8-bit or 16-bit.\n")
; |
| 685 return false; | 712 return false; |
| 686 } | 713 } |
| 687 | 714 |
| 688 if (len < 20 + numEntries * precision) { | 715 uint32_t clutBytes; |
| 716 if (!safe_mul(numEntries, precision, &clutBytes)) { |
| 717 SkColorSpacePrintf("Too many entries in Color LUT."); |
| 718 return false; |
| 719 } |
| 720 |
| 721 if (dataLen < clutBytes) { |
| 689 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len); | 722 SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", len); |
| 690 return false; | 723 return false; |
| 691 } | 724 } |
| 692 | 725 |
| 693 // Movable struct colorLUT has ownership of fTable. | 726 // Movable struct colorLUT has ownership of fTable. |
| 694 colorLUT->fTable = std::unique_ptr<float[]>(new float[numEntries]); | 727 colorLUT->fTable = std::unique_ptr<float[]>(new float[numEntries]); |
| 695 const uint8_t* ptr = src + 20; | 728 const uint8_t* ptr = src + kColorLUTHeaderSize; |
| 696 for (uint32_t i = 0; i < numEntries; i++, ptr += precision) { | 729 for (uint32_t i = 0; i < numEntries; i++, ptr += precision) { |
| 697 if (1 == precision) { | 730 if (1 == precision) { |
| 698 colorLUT->fTable[i] = ((float) ptr[i]) / 255.0f; | 731 colorLUT->fTable[i] = ((float) ptr[i]) / 255.0f; |
| 699 } else { | 732 } else { |
| 700 colorLUT->fTable[i] = ((float) read_big_endian_short(ptr)) / 65535.0
f; | 733 colorLUT->fTable[i] = ((float) read_big_endian_short(ptr)) / 65535.0
f; |
| 701 } | 734 } |
| 702 } | 735 } |
| 703 | 736 |
| 704 return true; | 737 return true; |
| 705 } | 738 } |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 ptr32[4] = SkEndian_SwapBE32(0x000116cc); | 1201 ptr32[4] = SkEndian_SwapBE32(0x000116cc); |
| 1169 ptr += kTAG_XYZ_Bytes; | 1202 ptr += kTAG_XYZ_Bytes; |
| 1170 | 1203 |
| 1171 // Write copyright tag | 1204 // Write copyright tag |
| 1172 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); | 1205 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); |
| 1173 | 1206 |
| 1174 // TODO (msarett): Should we try to hold onto the data so we can return imme
diately if | 1207 // TODO (msarett): Should we try to hold onto the data so we can return imme
diately if |
| 1175 // the client calls again? | 1208 // the client calls again? |
| 1176 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); | 1209 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); |
| 1177 } | 1210 } |
| OLD | NEW |