Index: dm/DMSrcSink.cpp |
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp |
index 4598a4894b7956ed681d6b199b569ee58572bf12..65f2d43d4d1df011dc8c0a16e6476cf057ab1f53 100644 |
--- a/dm/DMSrcSink.cpp |
+++ b/dm/DMSrcSink.cpp |
@@ -140,7 +140,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { |
} |
switch (fMode) { |
- case kNormal_Mode: |
+ case kNormal_Mode: { |
switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBytes(), NULL, |
colorPtr, colorCountPtr)) { |
case SkImageGenerator::kSuccess: |
@@ -156,23 +156,22 @@ Error CodecSrc::draw(SkCanvas* canvas) const { |
} |
canvas->drawBitmap(bitmap, 0, 0); |
break; |
+ } |
case kScanline_Mode: { |
SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder(decodeInfo, NULL, |
colorPtr, colorCountPtr); |
if (NULL == scanlineDecoder) { |
return Error::Nonfatal("Cannot use scanline decoder for all images"); |
} |
- for (int y = 0; y < decodeInfo.height(); ++y) { |
- const SkImageGenerator::Result result = scanlineDecoder->getScanlines( |
- bitmap.getAddr(0, y), 1, 0); |
- switch (result) { |
- case SkImageGenerator::kSuccess: |
- case SkImageGenerator::kIncompleteInput: |
- break; |
- default: |
- return SkStringPrintf("%s failed after %d scanlines with error message %d", |
- fPath.c_str(), y-1, (int) result); |
- } |
+ const SkImageGenerator::Result result = scanlineDecoder->getScanlines( |
+ bitmap.getAddr(0, 0), decodeInfo.height(), bitmap.rowBytes()); |
+ switch (result) { |
+ case SkImageGenerator::kSuccess: |
+ case SkImageGenerator::kIncompleteInput: |
+ break; |
+ default: |
+ return SkStringPrintf("%s failed with error message %d", |
+ fPath.c_str(), (int) result); |
} |
canvas->drawBitmap(bitmap, 0, 0); |
break; |
@@ -210,8 +209,9 @@ Error CodecSrc::draw(SkCanvas* canvas) const { |
return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str(), |
largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo.height()); |
} |
- char* line = SkNEW_ARRAY(char, decodeInfo.minRowBytes()); |
- SkAutoTDeleteArray<char> lineDeleter(line); |
+ const size_t rowBytes = decodeInfo.minRowBytes(); |
+ char* buffer = SkNEW_ARRAY(char, largestSubsetDecodeInfo.height() * rowBytes); |
+ SkAutoTDeleteArray<char> lineDeleter(buffer); |
for (int col = 0; col < divisor; col++) { |
//currentSubsetWidth may be larger than subsetWidth for rightmost subsets |
const int currentSubsetWidth = (col + 1 == divisor) ? |
@@ -250,21 +250,33 @@ Error CodecSrc::draw(SkCanvas* canvas) const { |
bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight); |
SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, bounds)); |
SkAutoLockPixels autlockSubsetBm(subsetBm, true); |
+ const SkImageGenerator::Result subsetResult = |
+ subsetScanlineDecoder->getScanlines(buffer, currentSubsetHeight, rowBytes); |
+ switch (subsetResult) { |
+ case SkImageGenerator::kSuccess: |
+ case SkImageGenerator::kIncompleteInput: |
+ break; |
+ default: |
+ return SkStringPrintf("%s failed with error message %d", |
+ fPath.c_str(), (int) subsetResult); |
+ } |
+ const size_t bpp = decodeInfo.bytesPerPixel(); |
+ /* |
+ * we copy all the lines at once becuase when calling getScanlines for |
+ * interlaced pngs the entire image must be read regardless of the number |
+ * of lines requested. Reading an interlaced png in a loop, line-by-line, would |
+ * decode the entire image height times, which is very slow |
+ * it is aknowledged that copying each line as you read it in a loop |
+ * may be faster for other types of images. Since this is a correctness test |
+ * that's okay. |
+ */ |
+ char* bufferRow = buffer; |
for (int subsetY = 0; subsetY < currentSubsetHeight; ++subsetY) { |
- const SkImageGenerator::Result subsetResult = |
- subsetScanlineDecoder->getScanlines(line, 1, 0); |
- const size_t bpp = decodeInfo.bytesPerPixel(); |
- //copy section of line based on x value |
- memcpy(subsetBm.getAddr(0, subsetY), line + x*bpp, currentSubsetWidth*bpp); |
- switch (subsetResult) { |
- case SkImageGenerator::kSuccess: |
- case SkImageGenerator::kIncompleteInput: |
- break; |
- default: |
- return SkStringPrintf("%s failed after %d scanlines with error" |
- "message %d", fPath.c_str(), y-1, (int) subsetResult); |
- } |
+ memcpy(subsetBm.getAddr(0, subsetY), bufferRow + x*bpp, |
+ currentSubsetWidth*bpp); |
+ bufferRow += rowBytes; |
} |
+ |
canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar(y)); |
} |
} |
@@ -344,6 +356,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { |
} |
} |
canvas->drawBitmap(bitmap, 0, 0); |
+ break; |
} |
} |
return ""; |