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" |
11 #include "SkScanlineDecoder.h" | 11 #include "SkScanlineDecoder.h" |
12 #include "SkStream.h" | 12 #include "SkStream.h" |
13 | 13 |
14 /* | 14 /* |
15 * Creates an instance of the decoder | 15 * Creates an instance of the decoder |
16 * Called only by NewFromStream | 16 * Called only by NewFromStream |
17 */ | 17 */ |
18 SkBmpStandardCodec::SkBmpStandardCodec(const SkImageInfo& info, SkStream* stream
, | 18 SkBmpStandardCodec::SkBmpStandardCodec(const SkImageInfo& info, SkStream* stream
, |
19 uint16_t bitsPerPixel, uint32_t numColors
, | 19 uint16_t bitsPerPixel, uint32_t numColors
, |
20 uint32_t bytesPerColor, uint32_t offset, | 20 uint32_t bytesPerColor, uint32_t offset, |
21 SkBmpCodec::RowOrder rowOrder, bool inIco
) | 21 SkBmpCodec::RowOrder rowOrder, bool inIco
) |
22 : INHERITED(info, stream, bitsPerPixel, rowOrder) | 22 : INHERITED(info, stream, bitsPerPixel, rowOrder) |
23 , fColorTable(NULL) | 23 , fColorTable(nullptr) |
24 , fNumColors(this->computeNumColors(numColors)) | 24 , fNumColors(this->computeNumColors(numColors)) |
25 , fBytesPerColor(bytesPerColor) | 25 , fBytesPerColor(bytesPerColor) |
26 , fOffset(offset) | 26 , fOffset(offset) |
27 , fSwizzler(NULL) | 27 , fSwizzler(nullptr) |
28 , fSrcBuffer(NULL) | 28 , fSrcBuffer(nullptr) |
29 , fInIco(inIco) | 29 , fInIco(inIco) |
30 {} | 30 {} |
31 | 31 |
32 /* | 32 /* |
33 * Initiates the bitmap decode | 33 * Initiates the bitmap decode |
34 */ | 34 */ |
35 SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo, | 35 SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo, |
36 void* dst, size_t dstRowBytes, | 36 void* dst, size_t dstRowBytes, |
37 const Options& opts, | 37 const Options& opts, |
38 SkPMColor* inputColorPtr, | 38 SkPMColor* inputColorPtr, |
39 int* inputColorCount) { | 39 int* inputColorCount) { |
40 if (!this->rewindIfNeeded()) { | 40 if (!this->rewindIfNeeded()) { |
41 return kCouldNotRewind; | 41 return kCouldNotRewind; |
42 } | 42 } |
43 if (opts.fSubset) { | 43 if (opts.fSubset) { |
44 // Subsets are not supported. | 44 // Subsets are not supported. |
45 return kUnimplemented; | 45 return kUnimplemented; |
46 } | 46 } |
47 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 47 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
48 SkCodecPrintf("Error: scaling not supported.\n"); | 48 SkCodecPrintf("Error: scaling not supported.\n"); |
49 return kInvalidScale; | 49 return kInvalidScale; |
50 } | 50 } |
51 if (!conversion_possible(dstInfo, this->getInfo())) { | 51 if (!conversion_possible(dstInfo, this->getInfo())) { |
52 SkCodecPrintf("Error: cannot convert input type to output type.\n"); | 52 SkCodecPrintf("Error: cannot convert input type to output type.\n"); |
53 return kInvalidConversion; | 53 return kInvalidConversion; |
54 } | 54 } |
55 | 55 |
56 // Create the color table if necessary and prepare the stream for decode | 56 // Create the color table if necessary and prepare the stream for decode |
57 // Note that if it is non-NULL, inputColorCount will be modified | 57 // Note that if it is non-nullptr, inputColorCount will be modified |
58 if (!this->createColorTable(dstInfo.alphaType(), inputColorCount)) { | 58 if (!this->createColorTable(dstInfo.alphaType(), inputColorCount)) { |
59 SkCodecPrintf("Error: could not create color table.\n"); | 59 SkCodecPrintf("Error: could not create color table.\n"); |
60 return kInvalidInput; | 60 return kInvalidInput; |
61 } | 61 } |
62 | 62 |
63 // Copy the color table to the client if necessary | 63 // Copy the color table to the client if necessary |
64 copy_color_table(dstInfo, fColorTable, inputColorPtr, inputColorCount); | 64 copy_color_table(dstInfo, fColorTable, inputColorPtr, inputColorCount); |
65 | 65 |
66 // Initialize a swizzler if necessary | 66 // Initialize a swizzler if necessary |
67 if (!this->initializeSwizzler(dstInfo, opts)) { | 67 if (!this->initializeSwizzler(dstInfo, opts)) { |
68 SkCodecPrintf("Error: cannot initialize swizzler.\n"); | 68 SkCodecPrintf("Error: cannot initialize swizzler.\n"); |
69 return kInvalidConversion; | 69 return kInvalidConversion; |
70 } | 70 } |
71 | 71 |
72 return this->decode(dstInfo, dst, dstRowBytes, opts); | 72 return this->decode(dstInfo, dst, dstRowBytes, opts); |
73 } | 73 } |
74 | 74 |
75 /* | 75 /* |
76 * Process the color table for the bmp input | 76 * Process the color table for the bmp input |
77 */ | 77 */ |
78 bool SkBmpStandardCodec::createColorTable(SkAlphaType alphaType, int* numColors
) { | 78 bool SkBmpStandardCodec::createColorTable(SkAlphaType alphaType, int* numColors
) { |
79 // Allocate memory for color table | 79 // Allocate memory for color table |
80 uint32_t colorBytes = 0; | 80 uint32_t colorBytes = 0; |
81 SkPMColor colorTable[256]; | 81 SkPMColor colorTable[256]; |
82 if (this->bitsPerPixel() <= 8) { | 82 if (this->bitsPerPixel() <= 8) { |
83 // Inform the caller of the number of colors | 83 // Inform the caller of the number of colors |
84 uint32_t maxColors = 1 << this->bitsPerPixel(); | 84 uint32_t maxColors = 1 << this->bitsPerPixel(); |
85 if (NULL != numColors) { | 85 if (nullptr != numColors) { |
86 // We set the number of colors to maxColors in order to ensure | 86 // We set the number of colors to maxColors in order to ensure |
87 // safe memory accesses. Otherwise, an invalid pixel could | 87 // safe memory accesses. Otherwise, an invalid pixel could |
88 // access memory outside of our color table array. | 88 // access memory outside of our color table array. |
89 *numColors = maxColors; | 89 *numColors = maxColors; |
90 } | 90 } |
91 | 91 |
92 // Read the color table from the stream | 92 // Read the color table from the stream |
93 colorBytes = fNumColors * fBytesPerColor; | 93 colorBytes = fNumColors * fBytesPerColor; |
94 SkAutoTDeleteArray<uint8_t> cBuffer(new uint8_t[colorBytes]); | 94 SkAutoTDeleteArray<uint8_t> cBuffer(new uint8_t[colorBytes]); |
95 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { | 95 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { |
96 SkCodecPrintf("Error: unable to read color table.\n"); | 96 SkCodecPrintf("Error: unable to read color table.\n"); |
97 return false; | 97 return false; |
98 } | 98 } |
99 | 99 |
100 // Choose the proper packing function | 100 // Choose the proper packing function |
101 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t); | 101 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t); |
102 switch (alphaType) { | 102 switch (alphaType) { |
103 case kOpaque_SkAlphaType: | 103 case kOpaque_SkAlphaType: |
104 case kUnpremul_SkAlphaType: | 104 case kUnpremul_SkAlphaType: |
105 packARGB = &SkPackARGB32NoCheck; | 105 packARGB = &SkPackARGB32NoCheck; |
106 break; | 106 break; |
107 case kPremul_SkAlphaType: | 107 case kPremul_SkAlphaType: |
108 packARGB = &SkPreMultiplyARGB; | 108 packARGB = &SkPreMultiplyARGB; |
109 break; | 109 break; |
110 default: | 110 default: |
111 // This should not be reached because conversion possible | 111 // This should not be reached because conversion possible |
112 // should fail if the alpha type is not one of the above | 112 // should fail if the alpha type is not one of the above |
113 // values. | 113 // values. |
114 SkASSERT(false); | 114 SkASSERT(false); |
115 packARGB = NULL; | 115 packARGB = nullptr; |
116 break; | 116 break; |
117 } | 117 } |
118 | 118 |
119 // Fill in the color table | 119 // Fill in the color table |
120 uint32_t i = 0; | 120 uint32_t i = 0; |
121 for (; i < fNumColors; i++) { | 121 for (; i < fNumColors; i++) { |
122 uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor); | 122 uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor); |
123 uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1); | 123 uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1); |
124 uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2); | 124 uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2); |
125 uint8_t alpha; | 125 uint8_t alpha; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 return false; | 203 return false; |
204 } | 204 } |
205 | 205 |
206 // Get a pointer to the color table if it exists | 206 // Get a pointer to the color table if it exists |
207 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); | 207 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); |
208 | 208 |
209 // Create swizzler | 209 // Create swizzler |
210 fSwizzler.reset(SkSwizzler::CreateSwizzler(config, | 210 fSwizzler.reset(SkSwizzler::CreateSwizzler(config, |
211 colorPtr, dstInfo, opts.fZeroInitialized, this->getInfo())); | 211 colorPtr, dstInfo, opts.fZeroInitialized, this->getInfo())); |
212 | 212 |
213 if (NULL == fSwizzler.get()) { | 213 if (nullptr == fSwizzler.get()) { |
214 return false; | 214 return false; |
215 } | 215 } |
216 return true; | 216 return true; |
217 } | 217 } |
218 | 218 |
219 /* | 219 /* |
220 * Choose a fill for failures due to an incomplete image. We will use zero as | 220 * Choose a fill for failures due to an incomplete image. We will use zero as |
221 * the default palette index, black for opaque images, and transparent for | 221 * the default palette index, black for opaque images, and transparent for |
222 * non-opaque images. | 222 * non-opaque images. |
223 */ | 223 */ |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 uint32_t alphaBit = | 328 uint32_t alphaBit = |
329 (fSrcBuffer.get()[quotient] >> shift) & 0x1; | 329 (fSrcBuffer.get()[quotient] >> shift) & 0x1; |
330 dstRow[x] &= alphaBit - 1; | 330 dstRow[x] &= alphaBit - 1; |
331 } | 331 } |
332 } | 332 } |
333 } | 333 } |
334 | 334 |
335 // Finished decoding the entire image | 335 // Finished decoding the entire image |
336 return kSuccess; | 336 return kSuccess; |
337 } | 337 } |
OLD | NEW |