aboutsummaryrefslogtreecommitdiffhomepage
path: root/dm/DMSrcSink.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dm/DMSrcSink.cpp')
-rw-r--r--dm/DMSrcSink.cpp68
1 files changed, 46 insertions, 22 deletions
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index f8c9bc0b58..755bae378e 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -432,31 +432,55 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
break;
}
case kScanline_Mode: {
- if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL, colorPtr,
- &colorCount)) {
- return "Could not start scanline decoder";
- }
-
void* dst = pixels.get();
uint32_t height = decodeInfo.height();
- switch (codec->getScanlineOrder()) {
- case SkCodec::kTopDown_SkScanlineOrder:
- case SkCodec::kBottomUp_SkScanlineOrder:
- case SkCodec::kNone_SkScanlineOrder:
- // We do not need to check the return value. On an incomplete
- // image, memory will be filled with a default value.
- codec->getScanlines(dst, height, rowBytes);
- break;
- case SkCodec::kOutOfOrder_SkScanlineOrder: {
- for (int y = 0; y < decodeInfo.height(); y++) {
- int dstY = codec->outputScanline(y);
- void* dstPtr = SkTAddOffset<void>(dst, rowBytes * dstY);
- // We complete the loop, even if this call begins to fail
- // due to an incomplete image. This ensures any uninitialized
- // memory will be filled with the proper value.
- codec->getScanlines(dstPtr, 1, rowBytes);
+ const bool png = fPath.endsWith("png");
+ const bool ico = fPath.endsWith("ico");
+ bool useOldScanlineMethod = !png && !ico;
+ if (png || ico) {
+ if (SkCodec::kSuccess == codec->startIncrementalDecode(decodeInfo, dst,
+ rowBytes, nullptr, colorPtr, &colorCount)) {
+ int rowsDecoded;
+ if (SkCodec::kIncompleteInput == codec->incrementalDecode(&rowsDecoded)) {
+ codec->fillIncompleteImage(decodeInfo, dst, rowBytes,
+ SkCodec::kNo_ZeroInitialized, height,
+ rowsDecoded);
+ }
+ } else {
+ if (png) {
+ // Error: PNG should support incremental decode.
+ return "Could not start incremental decode";
+ }
+ // Otherwise, this is an ICO. Since incremental failed, it must contain a BMP,
+ // which should work via startScanlineDecode
+ useOldScanlineMethod = true;
+ }
+ }
+
+ if (useOldScanlineMethod) {
+ if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL, colorPtr,
+ &colorCount)) {
+ return "Could not start scanline decoder";
+ }
+
+ switch (codec->getScanlineOrder()) {
+ case SkCodec::kTopDown_SkScanlineOrder:
+ case SkCodec::kBottomUp_SkScanlineOrder:
+ // We do not need to check the return value. On an incomplete
+ // image, memory will be filled with a default value.
+ codec->getScanlines(dst, height, rowBytes);
+ break;
+ case SkCodec::kOutOfOrder_SkScanlineOrder: {
+ for (int y = 0; y < decodeInfo.height(); y++) {
+ int dstY = codec->outputScanline(y);
+ void* dstPtr = SkTAddOffset<void>(dst, rowBytes * dstY);
+ // We complete the loop, even if this call begins to fail
+ // due to an incomplete image. This ensures any uninitialized
+ // memory will be filled with the proper value.
+ codec->getScanlines(dstPtr, 1, rowBytes);
+ }
+ break;
}
- break;
}
}