Fix rewinding bug in SkJpegCodec
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. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2161593003 Committed: https://skia.googlesource.com/skia/+/4ecb8ab556214c9337f56bc36d50e4d7c655ac7a Review-Url: https://codereview.chromium.org/2161593003
This commit is contained in:
parent
401ae2d2a0
commit
2812f03d54
@ -263,6 +263,7 @@ SkJpegCodec::SkJpegCodec(int width, int height, const SkEncodedInfo& info, SkStr
|
||||
: INHERITED(width, height, info, stream, std::move(colorSpace), origin)
|
||||
, fDecoderMgr(decoderMgr)
|
||||
, fReadyState(decoderMgr->dinfo()->global_state)
|
||||
, fSrcRow(nullptr)
|
||||
, fSwizzlerSubset(SkIRect::MakeEmpty())
|
||||
, fICCData(std::move(iccData))
|
||||
{}
|
||||
@ -339,6 +340,11 @@ bool SkJpegCodec::onRewind() {
|
||||
}
|
||||
SkASSERT(nullptr != decoderMgr);
|
||||
fDecoderMgr.reset(decoderMgr);
|
||||
|
||||
fSwizzler.reset(nullptr);
|
||||
fSrcRow = nullptr;
|
||||
fStorage.reset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -588,11 +594,6 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
return kInvalidConversion;
|
||||
}
|
||||
|
||||
// Remove objects used for sampling.
|
||||
fSwizzler.reset(nullptr);
|
||||
fSrcRow = nullptr;
|
||||
fStorage.reset();
|
||||
|
||||
// Now, given valid output dimensions, we can start the decompress
|
||||
if (!jpeg_start_decompress(fDecoderMgr->dinfo())) {
|
||||
SkCodecPrintf("start decompress failed\n");
|
||||
|
@ -1012,3 +1012,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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user