Add fuzzing for decoding animated images

Add a new mode to decode all frames of an animated image. Use
incremental decoding, rather than getPixels, since the primary client
uses incremental decoding.

Do not decode animated as index 8, which is only supported for the
first frame.

Change-Id: I5d7ed1a81c1ef37df3701c483486d4beff0f62a7
Reviewed-on: https://skia-review.googlesource.com/5679
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
This commit is contained in:
Leon Scroggins III 2016-12-08 09:07:56 -05:00 committed by Skia Commit-Bot
parent 64d8be00b8
commit c5a8366d99

View File

@ -135,8 +135,8 @@ int fuzz_img(sk_sp<SkData> bytes, uint8_t scale, uint8_t mode) {
float fscale = (float)pow(2.0f, scale);
SkDebugf("Scaling factor: %f\n", fscale);
// We have 4 different modes of decoding, just like DM.
mode = mode % 4;
// We have 5 different modes of decoding.
mode = mode % 5;
SkDebugf("Mode: %d\n", mode);
// This is mostly copied from DMSrcSink's CodecSrc::draw method.
@ -148,6 +148,11 @@ int fuzz_img(sk_sp<SkData> bytes, uint8_t scale, uint8_t mode) {
}
SkImageInfo decodeInfo = codec->getInfo();
if (4 == mode && decodeInfo.colorType() == kIndex_8_SkColorType) {
// 4 means animated. Frames beyond the first cannot be decoded to
// index 8.
decodeInfo = decodeInfo.makeColorType(kN32_SkColorType);
}
SkISize size = codec->getScaledDimensions(fscale);
decodeInfo = decodeInfo.makeWH(size.width(), size.height());
@ -352,6 +357,40 @@ int fuzz_img(sk_sp<SkData> bytes, uint8_t scale, uint8_t mode) {
SkDebugf("[terminated] Success!\n");
break;
}
case 4: { //kAnimated_Mode
std::vector<SkCodec::FrameInfo> frameInfos = codec->getFrameInfo();
if (frameInfos.size() == 0) {
SkDebugf("[terminated] Not an animated image\n");
break;
}
for (size_t i = 0; i < frameInfos.size(); i++) {
options.fFrameIndex = i;
auto result = codec->startIncrementalDecode(decodeInfo, bitmap.getPixels(),
bitmap.rowBytes(), &options);
if (SkCodec::kSuccess != result) {
SkDebugf("[terminated] failed to start incremental decode "
"in frame %d with error %d\n", i, result);
return 15;
}
result = codec->incrementalDecode();
if (result == SkCodec::kIncompleteInput) {
SkDebugf("okay\n");
// Frames beyond this one will not decode.
break;
}
if (result == SkCodec::kSuccess) {
SkDebugf("okay - decoded frame %d\n", i);
} else {
SkDebugf("[terminated] incremental decode failed with "
"error %d\n", result);
return 16;
}
}
SkDebugf("[terminated] Success!\n");
break;
}
default:
SkDebugf("[terminated] Mode not implemented yet\n");
}