| 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, | 18 SkBmpRLECodec::SkBmpRLECodec(const SkImageInfo& info, |
| 19 SkStream* stream, | 19 SkStream* stream, |
| 20 uint16_t bitsPerPixel, | 20 uint16_t bitsPerPixel, |
| 21 uint32_t numColors, | 21 uint32_t numColors, |
| 22 uint32_t bytesPerColor, | 22 uint32_t bytesPerColor, |
| 23 uint32_t offset, | 23 uint32_t offset, |
| 24 SkBmpCodec::RowOrder rowOrder, | 24 SkBmpCodec::RowOrder rowOrder, |
| 25 size_t RLEBytes) | 25 size_t RLEBytes) |
| 26 : INHERITED(info, stream, bitsPerPixel, rowOrder) | 26 : INHERITED(info, stream, bitsPerPixel, rowOrder) |
| 27 , fColorTable(NULL) | 27 , fColorTable(nullptr) |
| 28 , fNumColors(this->computeNumColors(numColors)) | 28 , fNumColors(this->computeNumColors(numColors)) |
| 29 , fBytesPerColor(bytesPerColor) | 29 , fBytesPerColor(bytesPerColor) |
| 30 , fOffset(offset) | 30 , fOffset(offset) |
| 31 , fStreamBuffer(new uint8_t[RLEBytes]) | 31 , fStreamBuffer(new uint8_t[RLEBytes]) |
| 32 , fRLEBytes(RLEBytes) | 32 , fRLEBytes(RLEBytes) |
| 33 , fCurrRLEByte(0) {} | 33 , fCurrRLEByte(0) {} |
| 34 | 34 |
| 35 /* | 35 /* |
| 36 * Initiates the bitmap decode | 36 * Initiates the bitmap decode |
| 37 */ | 37 */ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 50 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 50 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
| 51 SkCodecPrintf("Error: scaling not supported.\n"); | 51 SkCodecPrintf("Error: scaling not supported.\n"); |
| 52 return kInvalidScale; | 52 return kInvalidScale; |
| 53 } | 53 } |
| 54 if (!conversion_possible(dstInfo, this->getInfo())) { | 54 if (!conversion_possible(dstInfo, this->getInfo())) { |
| 55 SkCodecPrintf("Error: cannot convert input type to output type.\n"); | 55 SkCodecPrintf("Error: cannot convert input type to output type.\n"); |
| 56 return kInvalidConversion; | 56 return kInvalidConversion; |
| 57 } | 57 } |
| 58 | 58 |
| 59 // Create the color table if necessary and prepare the stream for decode | 59 // Create the color table if necessary and prepare the stream for decode |
| 60 // Note that if it is non-NULL, inputColorCount will be modified | 60 // Note that if it is non-nullptr, inputColorCount will be modified |
| 61 if (!this->createColorTable(inputColorCount)) { | 61 if (!this->createColorTable(inputColorCount)) { |
| 62 SkCodecPrintf("Error: could not create color table.\n"); | 62 SkCodecPrintf("Error: could not create color table.\n"); |
| 63 return kInvalidInput; | 63 return kInvalidInput; |
| 64 } | 64 } |
| 65 | 65 |
| 66 // Copy the color table to the client if necessary | 66 // Copy the color table to the client if necessary |
| 67 copy_color_table(dstInfo, fColorTable, inputColorPtr, inputColorCount); | 67 copy_color_table(dstInfo, fColorTable, inputColorPtr, inputColorCount); |
| 68 | 68 |
| 69 // Initialize a swizzler if necessary | 69 // Initialize a swizzler if necessary |
| 70 if (!this->initializeStreamBuffer()) { | 70 if (!this->initializeStreamBuffer()) { |
| 71 SkCodecPrintf("Error: cannot initialize swizzler.\n"); | 71 SkCodecPrintf("Error: cannot initialize swizzler.\n"); |
| 72 return kInvalidConversion; | 72 return kInvalidConversion; |
| 73 } | 73 } |
| 74 | 74 |
| 75 // Perform the decode | 75 // Perform the decode |
| 76 return decode(dstInfo, dst, dstRowBytes, opts); | 76 return decode(dstInfo, dst, dstRowBytes, opts); |
| 77 } | 77 } |
| 78 | 78 |
| 79 /* | 79 /* |
| 80 * Process the color table for the bmp input | 80 * Process the color table for the bmp input |
| 81 */ | 81 */ |
| 82 bool SkBmpRLECodec::createColorTable(int* numColors) { | 82 bool SkBmpRLECodec::createColorTable(int* numColors) { |
| 83 // Allocate memory for color table | 83 // Allocate memory for color table |
| 84 uint32_t colorBytes = 0; | 84 uint32_t colorBytes = 0; |
| 85 SkPMColor colorTable[256]; | 85 SkPMColor colorTable[256]; |
| 86 if (this->bitsPerPixel() <= 8) { | 86 if (this->bitsPerPixel() <= 8) { |
| 87 // Inform the caller of the number of colors | 87 // Inform the caller of the number of colors |
| 88 uint32_t maxColors = 1 << this->bitsPerPixel(); | 88 uint32_t maxColors = 1 << this->bitsPerPixel(); |
| 89 if (NULL != numColors) { | 89 if (nullptr != numColors) { |
| 90 // 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 |
| 91 // safe memory accesses. Otherwise, an invalid pixel could | 91 // safe memory accesses. Otherwise, an invalid pixel could |
| 92 // access memory outside of our color table array. | 92 // access memory outside of our color table array. |
| 93 *numColors = maxColors; | 93 *numColors = maxColors; |
| 94 } | 94 } |
| 95 | 95 |
| 96 // Read the color table from the stream | 96 // Read the color table from the stream |
| 97 colorBytes = fNumColors * fBytesPerColor; | 97 colorBytes = fNumColors * fBytesPerColor; |
| 98 SkAutoTDeleteArray<uint8_t> cBuffer(new uint8_t[colorBytes]); | 98 SkAutoTDeleteArray<uint8_t> cBuffer(new uint8_t[colorBytes]); |
| 99 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { | 99 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 // Destination parameters | 284 // Destination parameters |
| 285 int x = 0; | 285 int x = 0; |
| 286 int y = 0; | 286 int y = 0; |
| 287 | 287 |
| 288 // Set the background as transparent. Then, if the RLE code skips pixels, | 288 // Set the background as transparent. Then, if the RLE code skips pixels, |
| 289 // the skipped pixels will be transparent. | 289 // the skipped pixels will be transparent. |
| 290 // Because of the need for transparent pixels, kN32 is the only color | 290 // Because of the need for transparent pixels, kN32 is the only color |
| 291 // type that makes sense for the destination format. | 291 // type that makes sense for the destination format. |
| 292 SkASSERT(kN32_SkColorType == dstInfo.colorType()); | 292 SkASSERT(kN32_SkColorType == dstInfo.colorType()); |
| 293 if (kNo_ZeroInitialized == opts.fZeroInitialized) { | 293 if (kNo_ZeroInitialized == opts.fZeroInitialized) { |
| 294 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, SK_ColorTRANSPARENT,
NULL); | 294 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, SK_ColorTRANSPARENT,
nullptr); |
| 295 } | 295 } |
| 296 | 296 |
| 297 while (true) { | 297 while (true) { |
| 298 // If we have reached a row that is beyond the requested height, we have | 298 // If we have reached a row that is beyond the requested height, we have |
| 299 // succeeded. | 299 // succeeded. |
| 300 if (y >= height) { | 300 if (y >= height) { |
| 301 // It would be better to check for the EOF marker before returning | 301 // It would be better to check for the EOF marker before returning |
| 302 // success, but we may be performing a scanline decode, which | 302 // success, but we may be performing a scanline decode, which |
| 303 // may require us to stop before decoding the full height. | 303 // may require us to stop before decoding the full height. |
| 304 return kSuccess; | 304 return kSuccess; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 // Set the indicated number of pixels | 452 // Set the indicated number of pixels |
| 453 for (int which = 0; x < endX; x++) { | 453 for (int which = 0; x < endX; x++) { |
| 454 setPixel(dst, dstRowBytes, dstInfo, x, y, | 454 setPixel(dst, dstRowBytes, dstInfo, x, y, |
| 455 indices[which]); | 455 indices[which]); |
| 456 which = !which; | 456 which = !which; |
| 457 } | 457 } |
| 458 } | 458 } |
| 459 } | 459 } |
| 460 } | 460 } |
| 461 } | 461 } |
| OLD | NEW |