| Index: src/codec/SkBmpRLECodec.cpp
|
| diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp
|
| index e76a23ed14ad78ac93f9bd6b73a24ce69beb6f31..aff4a0616423d60d8bb74a149d213d8ed394d03e 100644
|
| --- a/src/codec/SkBmpRLECodec.cpp
|
| +++ b/src/codec/SkBmpRLECodec.cpp
|
| @@ -38,7 +38,8 @@ SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo,
|
| void* dst, size_t dstRowBytes,
|
| const Options& opts,
|
| SkPMColor* inputColorPtr,
|
| - int* inputColorCount) {
|
| + int* inputColorCount,
|
| + int* rowsDecoded) {
|
| if (opts.fSubset) {
|
| // Subsets are not supported.
|
| return kUnimplemented;
|
| @@ -58,7 +59,14 @@ SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo,
|
| }
|
|
|
| // Perform the decode
|
| - return this->decodeRows(dstInfo, dst, dstRowBytes, opts);
|
| + uint32_t rows = this->decodeRows(dstInfo, dst, dstRowBytes, opts);
|
| + if (rows != dstInfo.height()) {
|
| + // We set rowsDecoded equal to the height because the background has already
|
| + // been filled. RLE encodings sometimes skip pixels, so we always start by
|
| + // filling the background.
|
| + *rowsDecoded = dstInfo.height();
|
| + return kIncompleteInput;
|
| + }
|
| }
|
|
|
| /*
|
| @@ -278,9 +286,8 @@ SkCodec::Result SkBmpRLECodec::prepareToDecode(const SkImageInfo& dstInfo,
|
| * Performs the bitmap decoding for RLE input format
|
| * RLE decoding is performed all at once, rather than a one row at a time
|
| */
|
| -SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo,
|
| - void* dst, size_t dstRowBytes,
|
| - const Options& opts) {
|
| +uint32_t SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
|
| + const Options& opts) {
|
| // Set RLE flags
|
| static const uint8_t RLE_ESCAPE = 0;
|
| static const uint8_t RLE_EOL = 0;
|
| @@ -300,24 +307,23 @@ SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo,
|
| // Because of the need for transparent pixels, kN32 is the only color
|
| // type that makes sense for the destination format.
|
| SkASSERT(kN32_SkColorType == dstInfo.colorType());
|
| - SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, SK_ColorTRANSPARENT,
|
| - NULL, opts.fZeroInitialized);
|
| + SkSwizzler::Fill(dst, dstInfo, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroInitialized);
|
|
|
| while (true) {
|
| // If we have reached a row that is beyond the requested height, we have
|
| // succeeded.
|
| if (y >= height) {
|
| - // It would be better to check for the EOF marker before returning
|
| + // It would be better to check for the EOF marker before indicating
|
| // success, but we may be performing a scanline decode, which
|
| - // may require us to stop before decoding the full height.
|
| - return kSuccess;
|
| + // would require us to stop before decoding the full height.
|
| + return height;
|
| }
|
|
|
| // Every entry takes at least two bytes
|
| if ((int) fRLEBytes - fCurrRLEByte < 2) {
|
| SkCodecPrintf("Warning: might be incomplete RLE input.\n");
|
| if (this->checkForMoreData() < 2) {
|
| - return kIncompleteInput;
|
| + return y;
|
| }
|
| }
|
|
|
| @@ -342,7 +348,7 @@ SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo,
|
| if ((int) fRLEBytes - fCurrRLEByte < 2) {
|
| SkCodecPrintf("Warning: might be incomplete RLE input.\n");
|
| if (this->checkForMoreData() < 2) {
|
| - return kIncompleteInput;
|
| + return y;
|
| }
|
| }
|
| // Modify x and y
|
| @@ -352,7 +358,7 @@ SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo,
|
| y += dy;
|
| if (x > width || y > height) {
|
| SkCodecPrintf("Warning: invalid RLE input.\n");
|
| - return kInvalidInput;
|
| + return y - dy;
|
| }
|
| break;
|
| }
|
| @@ -368,14 +374,14 @@ SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo,
|
| // image.
|
| if (x + numPixels > width) {
|
| SkCodecPrintf("Warning: invalid RLE input.\n");
|
| - return kInvalidInput;
|
| + return y;
|
| }
|
| // Also abort if there are not enough bytes
|
| // remaining in the stream to set numPixels.
|
| if ((int) fRLEBytes - fCurrRLEByte < SkAlign2(rowBytes)) {
|
| SkCodecPrintf("Warning: might be incomplete RLE input.\n");
|
| if (this->checkForMoreData() < SkAlign2(rowBytes)) {
|
| - return kIncompleteInput;
|
| + return y;
|
| }
|
| }
|
| // Set numPixels number of pixels
|
| @@ -411,7 +417,7 @@ SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo,
|
| }
|
| default:
|
| SkASSERT(false);
|
| - return kInvalidInput;
|
| + return y;
|
| }
|
| }
|
| // Skip a byte if necessary to maintain alignment
|
| @@ -434,7 +440,7 @@ SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& dstInfo,
|
| if ((int) fRLEBytes - fCurrRLEByte < 2) {
|
| SkCodecPrintf("Warning: might be incomplete RLE input.\n");
|
| if (this->checkForMoreData() < 2) {
|
| - return kIncompleteInput;
|
| + return y;
|
| }
|
| }
|
|
|
|
|