aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Sarett <msarett@google.com>2016-07-21 09:19:47 -0400
committergitbuildkicker <android-build@google.com>2016-08-31 22:20:23 -0700
commit30ae0721bf9caaf31ddde08db680094e98e1230a (patch)
treeef5c050e75481fd2ce8be549961651094859886b
parent3906c7fd66aa70385d73a0dba51944bd3db74e93 (diff)
downloadskia-android-7.0.0_r14.tar.gz
Fix rewinding bug in SkJpegCodec (cherry picked from Skia)android-7.0.0_r14android-7.0.0_r13android-7.0.0_r12nougat-bugfix-release
Performing a sampled and/or subset decode will create some state in SkJpegCodec. If we fail to clean up this state properly, subsequent decodes may try to reuse (and potentailly overflow) the leftover memory. Committed: https://skia.googlesource.com/skia/+/2812f03d54b7fa4fd3d724505155d44a5343d91b BUG:30190637 BUG:30081412 Change-Id: I3fc2220c1cf5b6e2bc68e87e19cf54576e2b7a74 (cherry picked from commit 63a53c1e4b347775d4a36c0826fcd249d0b98f20) (cherry picked from commit 52d00b3be74144019413d7aac734e012c00c87c5)
-rw-r--r--src/codec/SkJpegCodec.cpp11
-rw-r--r--tests/CodexTest.cpp29
2 files changed, 35 insertions, 5 deletions
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index d36051511c..77ad5ddb72 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -80,6 +80,7 @@ SkJpegCodec::SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream,
: INHERITED(srcInfo, stream)
, fDecoderMgr(decoderMgr)
, fReadyState(decoderMgr->dinfo()->global_state)
+ , fSrcRow(nullptr)
, fSwizzlerSubset(SkIRect::MakeEmpty())
{}
@@ -155,6 +156,11 @@ bool SkJpegCodec::onRewind() {
}
SkASSERT(nullptr != decoderMgr);
fDecoderMgr.reset(decoderMgr);
+
+ fSwizzler.reset(nullptr);
+ fSrcRow = nullptr;
+ fStorage.free();
+
return true;
}
@@ -410,11 +416,6 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
return kInvalidConversion;
}
- // Remove objects used for sampling.
- fSwizzler.reset(nullptr);
- fSrcRow = nullptr;
- fStorage.free();
-
// Now, given valid output dimensions, we can start the decompress
if (!jpeg_start_decompress(fDecoderMgr->dinfo())) {
SkCodecPrintf("start decompress failed\n");
diff --git a/tests/CodexTest.cpp b/tests/CodexTest.cpp
index 51e41235cb..8ce63029a6 100644
--- a/tests/CodexTest.cpp
+++ b/tests/CodexTest.cpp
@@ -971,3 +971,32 @@ DEF_TEST(Codec_wbmp_max_size, r) {
REPORTER_ASSERT(r, !codec);
}
+
+DEF_TEST(Codec_jpeg_rewind, r) {
+ const char* path = "mandrill_512_q075.jpg";
+ SkAutoTDelete<SkStream> stream(resource(path));
+ if (!stream) {
+ SkDebugf("Missing resource '%s'\n", path);
+ return;
+ }
+ SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(stream.release()));
+ if (!codec) {
+ ERRORF(r, "Unable to create codec '%s'.", path);
+ return;
+ }
+
+ const int width = codec->getInfo().width();
+ const int height = codec->getInfo().height();
+ size_t rowBytes = sizeof(SkPMColor) * width;
+ SkAutoMalloc pixelStorage(height * rowBytes);
+
+ // Perform a sampled decode.
+ SkAndroidCodec::AndroidOptions opts;
+ opts.fSampleSize = 12;
+ codec->getAndroidPixels(codec->getInfo().makeWH(width / 12, height / 12), pixelStorage.get(),
+ rowBytes, &opts);
+
+ // Rewind the codec and perform a full image decode.
+ SkCodec::Result result = codec->getPixels(codec->getInfo(), pixelStorage.get(), rowBytes);
+ REPORTER_ASSERT(r, SkCodec::kSuccess == result);
+}