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 "SkBmpRLECodec.h" | 8 #include "SkBmpRLECodec.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 SkBmpRLECodec::SkBmpRLECodec(const SkImageInfo& info, SkStream* stream, | 18 SkBmpRLECodec::SkBmpRLECodec(const SkImageInfo& info, |
19 uint16_t bitsPerPixel, uint32_t numColors, | 19 SkStream* stream, |
20 uint32_t bytesPerColor, uint32_t offset, | 20 uint16_t bitsPerPixel, |
21 SkBmpCodec::RowOrder rowOrder, size_t RLEBytes) | 21 uint32_t numColors, |
| 22 uint32_t bytesPerColor, |
| 23 uint32_t offset, |
| 24 SkBmpCodec::RowOrder rowOrder, |
| 25 size_t RLEBytes) |
22 : INHERITED(info, stream, bitsPerPixel, rowOrder) | 26 : INHERITED(info, stream, bitsPerPixel, rowOrder) |
23 , fColorTable(NULL) | 27 , fColorTable(NULL) |
24 , fNumColors(this->computeNumColors(numColors)) | 28 , fNumColors(this->computeNumColors(numColors)) |
25 , fBytesPerColor(bytesPerColor) | 29 , fBytesPerColor(bytesPerColor) |
26 , fOffset(offset) | 30 , fOffset(offset) |
27 , fStreamBuffer(SkNEW_ARRAY(uint8_t, RLEBytes)) | 31 , fStreamBuffer(new uint8_t[RLEBytes]) |
28 , fRLEBytes(RLEBytes) | 32 , fRLEBytes(RLEBytes) |
29 , fCurrRLEByte(0) | 33 , fCurrRLEByte(0) {} |
30 {} | |
31 | 34 |
32 /* | 35 /* |
33 * Initiates the bitmap decode | 36 * Initiates the bitmap decode |
34 */ | 37 */ |
35 SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo, | 38 SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo, |
36 void* dst, size_t dstRowBytes, | 39 void* dst, size_t dstRowBytes, |
37 const Options& opts, | 40 const Options& opts, |
38 SkPMColor* inputColorPtr, | 41 SkPMColor* inputColorPtr, |
39 int* inputColorCount) { | 42 int* inputColorCount) { |
40 if (!this->rewindIfNeeded()) { | 43 if (!this->rewindIfNeeded()) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 uint32_t maxColors = 1 << this->bitsPerPixel(); | 88 uint32_t maxColors = 1 << this->bitsPerPixel(); |
86 if (NULL != numColors) { | 89 if (NULL != numColors) { |
87 // We set the number of colors to maxColors in order to ensure | 90 // We set the number of colors to maxColors in order to ensure |
88 // safe memory accesses. Otherwise, an invalid pixel could | 91 // safe memory accesses. Otherwise, an invalid pixel could |
89 // access memory outside of our color table array. | 92 // access memory outside of our color table array. |
90 *numColors = maxColors; | 93 *numColors = maxColors; |
91 } | 94 } |
92 | 95 |
93 // Read the color table from the stream | 96 // Read the color table from the stream |
94 colorBytes = fNumColors * fBytesPerColor; | 97 colorBytes = fNumColors * fBytesPerColor; |
95 SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes)); | 98 SkAutoTDeleteArray<uint8_t> cBuffer(new uint8_t[colorBytes]); |
96 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { | 99 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { |
97 SkCodecPrintf("Error: unable to read color table.\n"); | 100 SkCodecPrintf("Error: unable to read color table.\n"); |
98 return false; | 101 return false; |
99 } | 102 } |
100 | 103 |
101 // Fill in the color table | 104 // Fill in the color table |
102 uint32_t i = 0; | 105 uint32_t i = 0; |
103 for (; i < fNumColors; i++) { | 106 for (; i < fNumColors; i++) { |
104 uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor); | 107 uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor); |
105 uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1); | 108 uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1); |
106 uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2); | 109 uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2); |
107 colorTable[i] = SkPackARGB32NoCheck(0xFF, red, green, blue); | 110 colorTable[i] = SkPackARGB32NoCheck(0xFF, red, green, blue); |
108 } | 111 } |
109 | 112 |
110 // To avoid segmentation faults on bad pixel data, fill the end of the | 113 // To avoid segmentation faults on bad pixel data, fill the end of the |
111 // color table with black. This is the same the behavior as the | 114 // color table with black. This is the same the behavior as the |
112 // chromium decoder. | 115 // chromium decoder. |
113 for (; i < maxColors; i++) { | 116 for (; i < maxColors; i++) { |
114 colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0); | 117 colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0); |
115 } | 118 } |
116 | 119 |
117 // Set the color table | 120 // Set the color table |
118 fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorTable, maxColors))); | 121 fColorTable.reset(new SkColorTable(colorTable, maxColors)); |
119 } | 122 } |
120 | 123 |
121 // Check that we have not read past the pixel array offset | 124 // Check that we have not read past the pixel array offset |
122 if(fOffset < colorBytes) { | 125 if(fOffset < colorBytes) { |
123 // This may occur on OS 2.1 and other old versions where the color | 126 // This may occur on OS 2.1 and other old versions where the color |
124 // table defaults to max size, and the bmp tries to use a smaller | 127 // table defaults to max size, and the bmp tries to use a smaller |
125 // color table. This is invalid, and our decision is to indicate | 128 // color table. This is invalid, and our decision is to indicate |
126 // an error, rather than try to guess the intended size of the | 129 // an error, rather than try to guess the intended size of the |
127 // color table. | 130 // color table. |
128 SkCodecPrintf("Error: pixel data offset less than color table size.\n"); | 131 SkCodecPrintf("Error: pixel data offset less than color table size.\n"); |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 // Set the indicated number of pixels | 452 // Set the indicated number of pixels |
450 for (int which = 0; x < endX; x++) { | 453 for (int which = 0; x < endX; x++) { |
451 setPixel(dst, dstRowBytes, dstInfo, x, y, | 454 setPixel(dst, dstRowBytes, dstInfo, x, y, |
452 indices[which]); | 455 indices[which]); |
453 which = !which; | 456 which = !which; |
454 } | 457 } |
455 } | 458 } |
456 } | 459 } |
457 } | 460 } |
458 } | 461 } |
OLD | NEW |