aboutsummaryrefslogtreecommitdiffhomepage
path: root/dm/DMSrcSink.cpp
diff options
context:
space:
mode:
authorGravatar msarett <msarett@google.com>2015-10-13 12:50:14 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-10-13 12:50:14 -0700
commitfdb47571a3b5e72469b67de44e32ac14d9352ab4 (patch)
treecc98e7952e756c3c8825e7f9af3b280b3fc7b449 /dm/DMSrcSink.cpp
parenteb85b8321bc917169ba26c8fce76b64d2e3dfe81 (diff)
Add subsetting to SkScanlineDecoder
This CL allows the SkScanlineDecoder to decode partial scanlines. This is a first step in efficiently implementing subsetting in SkScaledCodec. BUG=skia:4209 Review URL: https://codereview.chromium.org/1390213002
Diffstat (limited to 'dm/DMSrcSink.cpp')
-rw-r--r--dm/DMSrcSink.cpp28
1 files changed, 10 insertions, 18 deletions
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index c7b389d36d..4137154e99 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -404,9 +404,6 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str(),
largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo.height());
}
- const size_t rowBytes = decodeInfo.minRowBytes();
- char* buffer = new 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) ?
@@ -418,10 +415,13 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
subsetHeight + extraY : subsetHeight;
const int y = row * subsetHeight;
//create scanline decoder for each subset
- if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL, colorPtr,
- colorCountPtr)
- // TODO (msarett): Support this mode for all scanline orderings.
- || SkCodec::kTopDown_SkScanlineOrder != codec->getScanlineOrder()) {
+ SkCodec::Options options;
+ SkIRect subset = SkIRect::MakeXYWH(x, 0, currentSubsetWidth, h);
+ options.fSubset = &subset;
+ // TODO (msarett): Support this mode for all scanline orderings.
+ if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, &options,
+ colorPtr, colorCountPtr) ||
+ SkCodec::kTopDown_SkScanlineOrder != codec->getScanlineOrder()) {
if (x == 0 && y == 0) {
//first try, image may not be compatible
return Error::Nonfatal("Could not start top-down scanline decoder");
@@ -440,17 +440,9 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
SkBitmap subsetBm;
SkIRect bounds = SkIRect::MakeWH(currentSubsetWidth, currentSubsetHeight);
SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, bounds));
- SkAutoLockPixels autlockSubsetBm(subsetBm, true);
- codec->getScanlines(buffer, currentSubsetHeight, rowBytes);
-
- const size_t bpp = decodeInfo.bytesPerPixel();
- char* bufferRow = buffer;
- for (int subsetY = 0; subsetY < currentSubsetHeight; ++subsetY) {
- memcpy(subsetBm.getAddr(0, subsetY), bufferRow + x*bpp,
- currentSubsetWidth*bpp);
- bufferRow += rowBytes;
- }
-
+ SkAutoLockPixels autolock(subsetBm, true);
+ codec->getScanlines(subsetBm.getAddr(0, 0), currentSubsetHeight,
+ subsetBm.rowBytes());
subsetBm.notifyPixelsChanged();
canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar(y));
}