diff options
author | Leon Scroggins III <scroggo@google.com> | 2017-04-24 15:44:45 -0400 |
---|---|---|
committer | Leon Scroggins <scroggo@google.com> | 2017-04-25 11:45:15 +0000 |
commit | 600effbdc7d8fb1cfb1b9dcecf785a2e42cc1cc3 (patch) | |
tree | 764972ccf52d5642df5c484668799ae3689afab1 /src | |
parent | dd3b3f41829d32d7eaf3eb4903570d49c2ba9ff8 (diff) |
Improve the Codec_end test and add fixes
Better imitate the original Android bug. Create a stream with
multiple images in it, and verify that it successfully decodes after
decoding once.
This exposes a bug in SkPngCodec, which did not work for interlaced
images.
Test more formats that also happen to succeed: ICO, BMP, and WBMP
This explicitly does *not* attempt to fix sampled or subset
decodes, which already stopped early when decoding as an
optimization.
Change-Id: Ib0b8918f14ba3fb0fa31e9c71c8100dcbeeb465f
Reviewed-on: https://skia-review.googlesource.com/14104
Reviewed-by: Matt Sarett <msarett@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/codec/SkPngCodec.cpp | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp index 1f69159ee6..b6f418fd49 100644 --- a/src/codec/SkPngCodec.cpp +++ b/src/codec/SkPngCodec.cpp @@ -647,7 +647,7 @@ private: // as expensive as the subset version of non-interlaced, but it still does extra // work. void interlacedRowCallback(png_bytep row, int rowNum, int pass) { - if (rowNum < fFirstRow || rowNum > fLastRow) { + if (rowNum < fFirstRow || rowNum > fLastRow || fInterlacedComplete) { // Ignore this row return; } @@ -663,12 +663,16 @@ private: } else { SkASSERT(fLinesDecoded == fLastRow - fFirstRow + 1); if (fNumberPasses - 1 == pass && rowNum == fLastRow) { - // Last pass, and we have read all of the rows we care about. Note that - // we do not care about reading anything beyond the end of the image (or - // beyond the last scanline requested). + // Last pass, and we have read all of the rows we care about. fInterlacedComplete = true; - // Fake error to stop decoding scanlines. - longjmp(PNG_JMPBUF(this->png_ptr()), kStopDecoding); + if (fLastRow != this->getInfo().height() - 1 || + (this->swizzler() && this->swizzler()->sampleY() != 1)) { + // Fake error to stop decoding scanlines. Only stop if we're not decoding the + // whole image, in which case processing the rest of the image might be + // expensive. When decoding the whole image, read through the IEND chunk to + // preserve Android behavior of leaving the input stream in the right place. + longjmp(PNG_JMPBUF(this->png_ptr()), kStopDecoding); + } } } } |