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 "SkBmpStandardCodec.h" | 8 #include "SkBmpStandardCodec.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 if (rows != dstInfo.height()) { | 60 if (rows != dstInfo.height()) { |
61 *rowsDecoded = rows; | 61 *rowsDecoded = rows; |
62 return kIncompleteInput; | 62 return kIncompleteInput; |
63 } | 63 } |
64 return kSuccess; | 64 return kSuccess; |
65 } | 65 } |
66 | 66 |
67 /* | 67 /* |
68 * Process the color table for the bmp input | 68 * Process the color table for the bmp input |
69 */ | 69 */ |
70 bool SkBmpStandardCodec::createColorTable(SkAlphaType alphaType, int* numColors
) { | 70 bool SkBmpStandardCodec::createColorTable(SkAlphaType dstAlphaType, int* numCol
ors) { |
71 // Allocate memory for color table | 71 // Allocate memory for color table |
72 uint32_t colorBytes = 0; | 72 uint32_t colorBytes = 0; |
73 SkPMColor colorTable[256]; | 73 SkPMColor colorTable[256]; |
74 if (this->bitsPerPixel() <= 8) { | 74 if (this->bitsPerPixel() <= 8) { |
75 // Inform the caller of the number of colors | 75 // Inform the caller of the number of colors |
76 uint32_t maxColors = 1 << this->bitsPerPixel(); | 76 uint32_t maxColors = 1 << this->bitsPerPixel(); |
77 if (nullptr != numColors) { | 77 if (nullptr != numColors) { |
78 // We set the number of colors to maxColors in order to ensure | 78 // We set the number of colors to maxColors in order to ensure |
79 // safe memory accesses. Otherwise, an invalid pixel could | 79 // safe memory accesses. Otherwise, an invalid pixel could |
80 // access memory outside of our color table array. | 80 // access memory outside of our color table array. |
81 *numColors = maxColors; | 81 *numColors = maxColors; |
82 } | 82 } |
83 // Don't bother reading more than maxColors. | 83 // Don't bother reading more than maxColors. |
84 const uint32_t numColorsToRead = | 84 const uint32_t numColorsToRead = |
85 fNumColors == 0 ? maxColors : SkTMin(fNumColors, maxColors); | 85 fNumColors == 0 ? maxColors : SkTMin(fNumColors, maxColors); |
86 | 86 |
87 // Read the color table from the stream | 87 // Read the color table from the stream |
88 colorBytes = numColorsToRead * fBytesPerColor; | 88 colorBytes = numColorsToRead * fBytesPerColor; |
89 SkAutoTDeleteArray<uint8_t> cBuffer(new uint8_t[colorBytes]); | 89 SkAutoTDeleteArray<uint8_t> cBuffer(new uint8_t[colorBytes]); |
90 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { | 90 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { |
91 SkCodecPrintf("Error: unable to read color table.\n"); | 91 SkCodecPrintf("Error: unable to read color table.\n"); |
92 return false; | 92 return false; |
93 } | 93 } |
94 | 94 |
95 // Choose the proper packing function | 95 // Choose the proper packing function |
96 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t); | 96 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t); |
97 switch (alphaType) { | 97 SkAlphaType encodedAlphaType = this->getInfo().alphaType(); |
98 case kOpaque_SkAlphaType: | 98 if (kOpaque_SkAlphaType == encodedAlphaType || kUnpremul_SkAlphaType ==
dstAlphaType) { |
99 case kUnpremul_SkAlphaType: | 99 packARGB = &SkPackARGB32NoCheck; |
100 packARGB = &SkPackARGB32NoCheck; | 100 } else { |
101 break; | 101 packARGB = &SkPremultiplyARGBInline; |
102 case kPremul_SkAlphaType: | |
103 packARGB = &SkPreMultiplyARGB; | |
104 break; | |
105 default: | |
106 // This should not be reached because conversion possible | |
107 // should fail if the alpha type is not one of the above | |
108 // values. | |
109 SkASSERT(false); | |
110 packARGB = nullptr; | |
111 break; | |
112 } | 102 } |
113 | 103 |
114 // Fill in the color table | 104 // Fill in the color table |
115 uint32_t i = 0; | 105 uint32_t i = 0; |
116 for (; i < numColorsToRead; i++) { | 106 for (; i < numColorsToRead; i++) { |
117 uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor); | 107 uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor); |
118 uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1); | 108 uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1); |
119 uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2); | 109 uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2); |
120 uint8_t alpha; | 110 uint8_t alpha; |
121 if (kOpaque_SkAlphaType == alphaType) { | 111 if (kOpaque_SkAlphaType == encodedAlphaType) { |
122 alpha = 0xFF; | 112 alpha = 0xFF; |
123 } else { | 113 } else { |
124 alpha = get_byte(cBuffer.get(), i*fBytesPerColor + 3); | 114 alpha = get_byte(cBuffer.get(), i*fBytesPerColor + 3); |
125 } | 115 } |
126 colorTable[i] = packARGB(alpha, red, green, blue); | 116 colorTable[i] = packARGB(alpha, red, green, blue); |
127 } | 117 } |
128 | 118 |
129 // To avoid segmentation faults on bad pixel data, fill the end of the | 119 // To avoid segmentation faults on bad pixel data, fill the end of the |
130 // color table with black. This is the same the behavior as the | 120 // color table with black. This is the same the behavior as the |
131 // chromium decoder. | 121 // chromium decoder. |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 } | 327 } |
338 } | 328 } |
339 | 329 |
340 uint32_t SkBmpStandardCodec::onGetFillValue(SkColorType colorType) const { | 330 uint32_t SkBmpStandardCodec::onGetFillValue(SkColorType colorType) const { |
341 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); | 331 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); |
342 if (colorPtr) { | 332 if (colorPtr) { |
343 return get_color_table_fill_value(colorType, colorPtr, 0); | 333 return get_color_table_fill_value(colorType, colorPtr, 0); |
344 } | 334 } |
345 return INHERITED::onGetFillValue(colorType); | 335 return INHERITED::onGetFillValue(colorType); |
346 } | 336 } |
OLD | NEW |