aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Leon Scroggins III <scroggo@google.com>2017-04-24 15:44:45 -0400
committerGravatar Leon Scroggins <scroggo@google.com>2017-04-25 11:45:15 +0000
commit600effbdc7d8fb1cfb1b9dcecf785a2e42cc1cc3 (patch)
tree764972ccf52d5642df5c484668799ae3689afab1 /src
parentdd3b3f41829d32d7eaf3eb4903570d49c2ba9ff8 (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.cpp16
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);
+ }
}
}
}