| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "SkCodec_libbmp.h" | 8 #include "SkCodec_libbmp.h" |
| 9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 607 if (kIndex_8_SkColorType == dstInfo.colorType()) { | 607 if (kIndex_8_SkColorType == dstInfo.colorType()) { |
| 608 SkASSERT(NULL != inputColorPtr); | 608 SkASSERT(NULL != inputColorPtr); |
| 609 SkASSERT(NULL != inputColorCount); | 609 SkASSERT(NULL != inputColorCount); |
| 610 SkASSERT(NULL != fColorTable.get()); | 610 SkASSERT(NULL != fColorTable.get()); |
| 611 sk_memcpy32(inputColorPtr, fColorTable->readColors(), *inputColorCount); | 611 sk_memcpy32(inputColorPtr, fColorTable->readColors(), *inputColorCount); |
| 612 } | 612 } |
| 613 | 613 |
| 614 // Perform the decode | 614 // Perform the decode |
| 615 switch (fInputFormat) { | 615 switch (fInputFormat) { |
| 616 case kBitMask_BitmapInputFormat: | 616 case kBitMask_BitmapInputFormat: |
| 617 return decodeMask(dstInfo, dst, dstRowBytes); | 617 return decodeMask(dstInfo, dst, dstRowBytes, opts); |
| 618 case kRLE_BitmapInputFormat: | 618 case kRLE_BitmapInputFormat: |
| 619 return decodeRLE(dstInfo, dst, dstRowBytes, opts); | 619 return decodeRLE(dstInfo, dst, dstRowBytes, opts); |
| 620 case kStandard_BitmapInputFormat: | 620 case kStandard_BitmapInputFormat: |
| 621 return decode(dstInfo, dst, dstRowBytes); | 621 return decode(dstInfo, dst, dstRowBytes, opts); |
| 622 default: | 622 default: |
| 623 SkASSERT(false); | 623 SkASSERT(false); |
| 624 return kInvalidInput; | 624 return kInvalidInput; |
| 625 } | 625 } |
| 626 } | 626 } |
| 627 | 627 |
| 628 /* | 628 /* |
| 629 * | 629 * |
| 630 * Process the color table for the bmp input | 630 * Process the color table for the bmp input |
| 631 * | 631 * |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 } | 694 } |
| 695 colorTable[i] = packARGB(alpha, red, green, blue); | 695 colorTable[i] = packARGB(alpha, red, green, blue); |
| 696 } | 696 } |
| 697 | 697 |
| 698 // To avoid segmentation faults on bad pixel data, fill the end of the | 698 // To avoid segmentation faults on bad pixel data, fill the end of the |
| 699 // color table with black. This is the same the behavior as the | 699 // color table with black. This is the same the behavior as the |
| 700 // chromium decoder. | 700 // chromium decoder. |
| 701 for (; i < maxColors; i++) { | 701 for (; i < maxColors; i++) { |
| 702 colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0); | 702 colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0); |
| 703 } | 703 } |
| 704 |
| 705 // Set the color table |
| 706 fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorTable, maxColors))); |
| 704 } | 707 } |
| 705 | 708 |
| 706 // Bmp-in-Ico files do not use an offset to indicate where the pixel data | 709 // Bmp-in-Ico files do not use an offset to indicate where the pixel data |
| 707 // begins. Pixel data always begins immediately after the color table. | 710 // begins. Pixel data always begins immediately after the color table. |
| 708 if (!fIsIco) { | 711 if (!fIsIco) { |
| 709 // Check that we have not read past the pixel array offset | 712 // Check that we have not read past the pixel array offset |
| 710 if(fOffset < colorBytes) { | 713 if(fOffset < colorBytes) { |
| 711 // This may occur on OS 2.1 and other old versions where the color | 714 // This may occur on OS 2.1 and other old versions where the color |
| 712 // table defaults to max size, and the bmp tries to use a smaller | 715 // table defaults to max size, and the bmp tries to use a smaller |
| 713 // color table. This is invalid, and our decision is to indicate | 716 // color table. This is invalid, and our decision is to indicate |
| 714 // an error, rather than try to guess the intended size of the | 717 // an error, rather than try to guess the intended size of the |
| 715 // color table. | 718 // color table. |
| 716 SkCodecPrintf("Error: pixel data offset less than color table size.\
n"); | 719 SkCodecPrintf("Error: pixel data offset less than color table size.\
n"); |
| 717 return false; | 720 return false; |
| 718 } | 721 } |
| 719 | 722 |
| 720 // After reading the color table, skip to the start of the pixel array | 723 // After reading the color table, skip to the start of the pixel array |
| 721 if (stream()->skip(fOffset - colorBytes) != fOffset - colorBytes) { | 724 if (stream()->skip(fOffset - colorBytes) != fOffset - colorBytes) { |
| 722 SkCodecPrintf("Error: unable to skip to image data.\n"); | 725 SkCodecPrintf("Error: unable to skip to image data.\n"); |
| 723 return false; | 726 return false; |
| 724 } | 727 } |
| 725 } | 728 } |
| 726 | 729 |
| 727 // Set the color table and return true on success | 730 // Return true on success |
| 728 fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorTable, maxColors))); | |
| 729 return true; | 731 return true; |
| 730 } | 732 } |
| 731 | 733 |
| 732 /* | 734 /* |
| 733 * | 735 * |
| 736 * Get the destination row to start filling from |
| 737 * Used to fill the remainder of the image on incomplete input |
| 738 * |
| 739 */ |
| 740 static inline void* get_dst_start_row(void* dst, size_t dstRowBytes, int32_t y, |
| 741 SkBmpCodec::RowOrder rowOrder) { |
| 742 return (SkBmpCodec::kTopDown_RowOrder == rowOrder) ? |
| 743 SkTAddOffset<void*>(dst, y * dstRowBytes) : dst; |
| 744 } |
| 745 |
| 746 /* |
| 747 * |
| 734 * Performs the bitmap decoding for bit masks input format | 748 * Performs the bitmap decoding for bit masks input format |
| 735 * | 749 * |
| 736 */ | 750 */ |
| 737 SkCodec::Result SkBmpCodec::decodeMask(const SkImageInfo& dstInfo, | 751 SkCodec::Result SkBmpCodec::decodeMask(const SkImageInfo& dstInfo, |
| 738 void* dst, size_t dstRowBytes) { | 752 void* dst, size_t dstRowBytes, |
| 753 const Options& opts) { |
| 739 // Set constant values | 754 // Set constant values |
| 740 const int width = dstInfo.width(); | 755 const int width = dstInfo.width(); |
| 741 const int height = dstInfo.height(); | 756 const int height = dstInfo.height(); |
| 742 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel)); | 757 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel)); |
| 743 | 758 |
| 744 // Allocate a buffer large enough to hold the full image | 759 // Allocate a buffer large enough to hold the full image |
| 745 SkAutoTDeleteArray<uint8_t> | 760 SkAutoTDeleteArray<uint8_t> |
| 746 srcBuffer(SkNEW_ARRAY(uint8_t, height*rowBytes)); | 761 srcBuffer(SkNEW_ARRAY(uint8_t, height*rowBytes)); |
| 747 uint8_t* srcRow = srcBuffer.get(); | 762 uint8_t* srcRow = srcBuffer.get(); |
| 748 | 763 |
| 749 // Create the swizzler | 764 // Create the swizzler |
| 750 SkAutoTDelete<SkMaskSwizzler> maskSwizzler( | 765 SkAutoTDelete<SkMaskSwizzler> maskSwizzler( |
| 751 SkMaskSwizzler::CreateMaskSwizzler(dstInfo, dst, dstRowBytes, | 766 SkMaskSwizzler::CreateMaskSwizzler(dstInfo, dst, dstRowBytes, |
| 752 fMasks, fBitsPerPixel)); | 767 fMasks, fBitsPerPixel)); |
| 753 | 768 |
| 754 // Iterate over rows of the image | 769 // Iterate over rows of the image |
| 755 bool transparent = true; | 770 bool transparent = true; |
| 756 for (int y = 0; y < height; y++) { | 771 for (int y = 0; y < height; y++) { |
| 757 // Read a row of the input | 772 // Read a row of the input |
| 758 if (stream()->read(srcRow, rowBytes) != rowBytes) { | 773 if (stream()->read(srcRow, rowBytes) != rowBytes) { |
| 759 SkCodecPrintf("Warning: incomplete input stream.\n"); | 774 SkCodecPrintf("Warning: incomplete input stream.\n"); |
| 775 // Fill the destination image on failure |
| 776 // By using zero as the fill value, we will fill with transparent |
| 777 // pixels for non-opaque images and white for opaque images. |
| 778 // These are arbitrary choices but allow for consistent behavior. |
| 779 if (kNo_ZeroInitialized == opts.fZeroInitialized) { |
| 780 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde
r); |
| 781 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height(
) - y, 0, NULL); |
| 782 } |
| 760 return kIncompleteInput; | 783 return kIncompleteInput; |
| 761 } | 784 } |
| 762 | 785 |
| 763 // Decode the row in destination format | 786 // Decode the row in destination format |
| 764 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y; | 787 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y; |
| 765 SkSwizzler::ResultAlpha r = maskSwizzler->next(srcRow, row); | 788 SkSwizzler::ResultAlpha r = maskSwizzler->next(srcRow, row); |
| 766 transparent &= SkSwizzler::IsTransparent(r); | 789 transparent &= SkSwizzler::IsTransparent(r); |
| 767 | 790 |
| 768 // Move to the next row | 791 // Move to the next row |
| 769 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes); | 792 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 // Destination parameters | 915 // Destination parameters |
| 893 int x = 0; | 916 int x = 0; |
| 894 int y = 0; | 917 int y = 0; |
| 895 | 918 |
| 896 // Set the background as transparent. Then, if the RLE code skips pixels, | 919 // Set the background as transparent. Then, if the RLE code skips pixels, |
| 897 // the skipped pixels will be transparent. | 920 // the skipped pixels will be transparent. |
| 898 // Because of the need for transparent pixels, kN32 is the only color | 921 // Because of the need for transparent pixels, kN32 is the only color |
| 899 // type that makes sense for the destination format. | 922 // type that makes sense for the destination format. |
| 900 SkASSERT(kN32_SkColorType == dstInfo.colorType()); | 923 SkASSERT(kN32_SkColorType == dstInfo.colorType()); |
| 901 if (kNo_ZeroInitialized == opts.fZeroInitialized) { | 924 if (kNo_ZeroInitialized == opts.fZeroInitialized) { |
| 902 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, 0, SK_ColorTRANSPARENT, NULL
); | 925 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, SK_ColorTRANSPARENT,
NULL); |
| 903 } | 926 } |
| 904 | 927 |
| 905 while (true) { | 928 while (true) { |
| 906 // Every entry takes at least two bytes | 929 // Every entry takes at least two bytes |
| 907 if ((int) totalBytes - currByte < 2) { | 930 if ((int) totalBytes - currByte < 2) { |
| 908 SkCodecPrintf("Warning: incomplete RLE input.\n"); | 931 SkCodecPrintf("Warning: incomplete RLE input.\n"); |
| 909 return kIncompleteInput; | 932 return kIncompleteInput; |
| 910 } | 933 } |
| 911 | 934 |
| 912 // Read the next two bytes. These bytes have different meanings | 935 // Read the next two bytes. These bytes have different meanings |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 } | 1076 } |
| 1054 } | 1077 } |
| 1055 } | 1078 } |
| 1056 | 1079 |
| 1057 /* | 1080 /* |
| 1058 * | 1081 * |
| 1059 * Performs the bitmap decoding for standard input format | 1082 * Performs the bitmap decoding for standard input format |
| 1060 * | 1083 * |
| 1061 */ | 1084 */ |
| 1062 SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo, | 1085 SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo, |
| 1063 void* dst, size_t dstRowBytes) { | 1086 void* dst, size_t dstRowBytes, |
| 1087 const Options& opts) { |
| 1064 // Set constant values | 1088 // Set constant values |
| 1065 const int width = dstInfo.width(); | 1089 const int width = dstInfo.width(); |
| 1066 const int height = dstInfo.height(); | 1090 const int height = dstInfo.height(); |
| 1067 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel)); | 1091 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel)); |
| 1068 | 1092 |
| 1069 // Get swizzler configuration | 1093 // Get swizzler configuration |
| 1070 SkSwizzler::SrcConfig config; | 1094 SkSwizzler::SrcConfig config; |
| 1071 switch (fBitsPerPixel) { | 1095 switch (fBitsPerPixel) { |
| 1072 case 1: | 1096 case 1: |
| 1073 config = SkSwizzler::kIndex1; | 1097 config = SkSwizzler::kIndex1; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1089 config = SkSwizzler::kBGRX; | 1113 config = SkSwizzler::kBGRX; |
| 1090 } else { | 1114 } else { |
| 1091 config = SkSwizzler::kBGRA; | 1115 config = SkSwizzler::kBGRA; |
| 1092 } | 1116 } |
| 1093 break; | 1117 break; |
| 1094 default: | 1118 default: |
| 1095 SkASSERT(false); | 1119 SkASSERT(false); |
| 1096 return kInvalidInput; | 1120 return kInvalidInput; |
| 1097 } | 1121 } |
| 1098 | 1122 |
| 1123 // Get a pointer to the color table if it exists |
| 1124 const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readCol
ors() : NULL; |
| 1125 |
| 1099 // Create swizzler | 1126 // Create swizzler |
| 1100 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config, | 1127 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config, |
| 1101 fColorTable->readColors(), dstInfo, dst, dstRowBytes, | 1128 colorPtr, dstInfo, dst, dstRowBytes, |
| 1102 SkImageGenerator::kNo_ZeroInitialized)); | 1129 SkImageGenerator::kNo_ZeroInitialized)); |
| 1103 | 1130 |
| 1104 // Allocate space for a row buffer and a source for the swizzler | 1131 // Allocate space for a row buffer and a source for the swizzler |
| 1105 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes)); | 1132 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes)); |
| 1106 | 1133 |
| 1107 // Iterate over rows of the image | 1134 // Iterate over rows of the image |
| 1108 // FIXME: bool transparent = true; | 1135 // FIXME: bool transparent = true; |
| 1109 for (int y = 0; y < height; y++) { | 1136 for (int y = 0; y < height; y++) { |
| 1110 // Read a row of the input | 1137 // Read a row of the input |
| 1111 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) { | 1138 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) { |
| 1112 SkCodecPrintf("Warning: incomplete input stream.\n"); | 1139 SkCodecPrintf("Warning: incomplete input stream.\n"); |
| 1140 // Fill the destination image on failure |
| 1141 // By using zero as the fill value, we will fill with the first |
| 1142 // color in the color table for palette images, transparent |
| 1143 // pixels for non-opaque images, and white for opaque images. |
| 1144 // These are arbitrary choices but allow for consistent behavior. |
| 1145 if (kNo_ZeroInitialized == opts.fZeroInitialized) { |
| 1146 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde
r); |
| 1147 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height(
) - y, 0, |
| 1148 colorPtr); |
| 1149 } |
| 1113 return kIncompleteInput; | 1150 return kIncompleteInput; |
| 1114 } | 1151 } |
| 1115 | 1152 |
| 1116 // Decode the row in destination format | 1153 // Decode the row in destination format |
| 1117 uint32_t row; | 1154 uint32_t row; |
| 1118 if (kTopDown_RowOrder == fRowOrder) { | 1155 if (kTopDown_RowOrder == fRowOrder) { |
| 1119 row = y; | 1156 row = y; |
| 1120 } else { | 1157 } else { |
| 1121 row = height - 1 - y; | 1158 row = height - 1 - y; |
| 1122 } | 1159 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1184 uint32_t alphaBit = | 1221 uint32_t alphaBit = |
| 1185 (srcBuffer.get()[quotient] >> shift) & 0x1; | 1222 (srcBuffer.get()[quotient] >> shift) & 0x1; |
| 1186 dstRow[x] &= alphaBit - 1; | 1223 dstRow[x] &= alphaBit - 1; |
| 1187 } | 1224 } |
| 1188 } | 1225 } |
| 1189 } | 1226 } |
| 1190 | 1227 |
| 1191 // Finished decoding the entire image | 1228 // Finished decoding the entire image |
| 1192 return kSuccess; | 1229 return kSuccess; |
| 1193 } | 1230 } |
| OLD | NEW |