Chromium Code Reviews| Index: src/codec/SkBmpRLECodec.cpp |
| diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp |
| index fe499c6a6d402b2628f088be11738ec164daa338..26f926a69ddd3842e8076aab74a74331e996d66a 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; |
| @@ -54,7 +55,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; |
| + } |
| } |
| /* |
| @@ -275,9 +283,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& info, |
| - void* dst, size_t dstRowBytes, |
| - const Options& opts) { |
| +int SkBmpRLECodec::decodeRows(const SkImageInfo& info, 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& info, |
| // 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); |
| + SkSampler::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& info, |
| 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& info, |
| 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& info, |
| // 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& info, |
| } |
| 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& info, |
| if ((int) fRLEBytes - fCurrRLEByte < 2) { |
| SkCodecPrintf("Warning: might be incomplete RLE input.\n"); |
| if (this->checkForMoreData() < 2) { |
| - return kIncompleteInput; |
| + return y; |
| } |
| } |
| @@ -467,6 +473,7 @@ SkCodec::Result SkBmpRLECodec::decodeRows(const SkImageInfo& info, |
| } |
| } |
| +// FIXME: Make SkBmpRLECodec have no knowledge of sampling. |
|
scroggo
2015/10/08 13:50:30
We might want the opposite - all sampling is done
msarett
2015/10/08 15:33:25
Done.
|
| class SkBmpRLESampler : public SkSampler { |
| public: |
| SkBmpRLESampler(SkBmpRLECodec* codec) |
| @@ -476,7 +483,7 @@ public: |
| } |
| private: |
| - int onSetSampleX(int sampleX) { |
| + int onSetSampleX(int sampleX) override { |
| return fCodec->setSampleX(sampleX); |
| } |
| @@ -484,15 +491,15 @@ private: |
| SkBmpRLECodec* fCodec; |
| }; |
| -SkSampler* SkBmpRLECodec::getSampler() { |
| - if (!fSampler) { |
| +SkSampler* SkBmpRLECodec::getSampler(bool createIfNecessary) { |
| + if (!fSampler && createIfNecessary) { |
| fSampler.reset(new SkBmpRLESampler(this)); |
| } |
| return fSampler; |
| } |
| -int SkBmpRLECodec::setSampleX(int sampleX) { |
| +int SkBmpRLECodec::setSampleX(int sampleX){ |
| fSampleX = sampleX; |
| return get_scaled_dimension(this->getInfo().width(), sampleX); |
| } |