Index: dm/DMSrcSink.cpp |
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp |
index 0a90e03103dc23b087a3269f24434ec925f90d05..c89ffd1b7121839f880edf9a0fdab803dffe9881 100644 |
--- a/dm/DMSrcSink.cpp |
+++ b/dm/DMSrcSink.cpp |
@@ -64,10 +64,11 @@ void GMSrc::modifyGrContextOptions(GrContextOptions* options) const { |
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ |
-CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType) |
+CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType, float scale) |
: fPath(path) |
, fMode(mode) |
, fDstColorType(dstColorType) |
+ , fScale(scale) |
{} |
Error CodecSrc::draw(SkCanvas* canvas) const { |
@@ -108,6 +109,13 @@ Error CodecSrc::draw(SkCanvas* canvas) const { |
break; |
} |
+ // Try to scale the image if it is desired |
+ SkISize size = codec->getScaledDimensions(fScale); |
+ if (size == decodeInfo.dimensions() && 1.0f != fScale) { |
+ return Error::Nonfatal("Test without scaling is uninteresting."); |
+ } |
+ decodeInfo = decodeInfo.makeWH(size.width(), size.height()); |
+ |
// Construct a color table for the decode if necessary |
SkAutoTUnref<SkColorTable> colorTable(NULL); |
SkPMColor* colorPtr = NULL; |
@@ -195,7 +203,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { |
* subsetBm's size is determined based on the current subset and may be larger for end |
* subsets. |
*/ |
- SkImageInfo largestSubsetDecodeInfo = |
+ SkImageInfo largestSubsetDecodeInfo = |
decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extraY); |
SkBitmap largestSubsetBm; |
if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, colorTable.get())) { |
@@ -226,7 +234,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { |
} |
} |
//skip to first line of subset |
- const SkImageGenerator::Result skipResult = |
+ const SkImageGenerator::Result skipResult = |
subsetScanlineDecoder->skipScanlines(y); |
switch (skipResult) { |
case SkImageGenerator::kSuccess: |
@@ -262,6 +270,80 @@ Error CodecSrc::draw(SkCanvas* canvas) const { |
} |
break; |
} |
+ case kStripe_Mode: { |
+ const int height = decodeInfo.height(); |
+ // This value is chosen arbitrarily. We exercise more cases by choosing a value that |
+ // does not align with image blocks. |
+ const int stripeHeight = 37; |
+ const int numStripes = (height + stripeHeight - 1) / stripeHeight; |
+ |
+ // Decode odd stripes |
+ SkScanlineDecoder* decoder = codec->getScanlineDecoder(decodeInfo, NULL, colorPtr, |
+ colorCountPtr); |
+ if (NULL == decoder) { |
+ return Error::Nonfatal("Cannot use scanline decoder for all images"); |
+ } |
+ for (int i = 0; i < numStripes; i += 2) { |
+ // Skip a stripe |
+ const int linesToSkip = SkTMin(stripeHeight, height - i * stripeHeight); |
+ SkImageGenerator::Result result = decoder->skipScanlines(linesToSkip); |
+ switch (result) { |
+ case SkImageGenerator::kSuccess: |
+ case SkImageGenerator::kIncompleteInput: |
+ break; |
+ default: |
+ return SkStringPrintf("Cannot skip scanlines for %s.", fPath.c_str()); |
+ } |
+ |
+ // Read a stripe |
+ const int startY = (i + 1) * stripeHeight; |
+ const int linesToRead = SkTMin(stripeHeight, height - startY); |
+ if (linesToRead > 0) { |
+ result = decoder->getScanlines(bitmap.getAddr(0, startY), |
+ linesToRead, bitmap.rowBytes()); |
+ switch (result) { |
+ case SkImageGenerator::kSuccess: |
+ case SkImageGenerator::kIncompleteInput: |
+ break; |
+ default: |
+ return SkStringPrintf("Cannot get scanlines for %s.", fPath.c_str()); |
+ } |
+ } |
+ } |
+ |
+ // Decode even stripes |
+ decoder = codec->getScanlineDecoder(decodeInfo, NULL, colorPtr, colorCountPtr); |
+ if (NULL == decoder) { |
+ return "Failed to create second scanline decoder."; |
+ } |
+ for (int i = 0; i < numStripes; i += 2) { |
+ // Read a stripe |
+ const int startY = i * stripeHeight; |
+ const int linesToRead = SkTMin(stripeHeight, height - startY); |
+ SkImageGenerator::Result result = decoder->getScanlines(bitmap.getAddr(0, startY), |
+ linesToRead, bitmap.rowBytes()); |
+ switch (result) { |
+ case SkImageGenerator::kSuccess: |
+ case SkImageGenerator::kIncompleteInput: |
+ break; |
+ default: |
+ return SkStringPrintf("Cannot get scanlines for %s.", fPath.c_str()); |
+ } |
+ |
+ // Skip a stripe |
+ const int linesToSkip = SkTMax(0, SkTMin(stripeHeight, |
+ height - (i + 1) * stripeHeight)); |
+ result = decoder->skipScanlines(linesToSkip); |
+ switch (result) { |
+ case SkImageGenerator::kSuccess: |
+ case SkImageGenerator::kIncompleteInput: |
+ break; |
+ default: |
+ return SkStringPrintf("Cannot skip scanlines for %s.", fPath.c_str()); |
+ } |
+ } |
+ canvas->drawBitmap(bitmap, 0, 0); |
+ } |
} |
return ""; |
} |
@@ -270,14 +352,19 @@ SkISize CodecSrc::size() const { |
SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
if (NULL != codec) { |
- return codec->getInfo().dimensions(); |
+ SkISize size = codec->getScaledDimensions(fScale); |
+ return size; |
} else { |
return SkISize::Make(0, 0); |
} |
} |
Name CodecSrc::name() const { |
- return SkOSPath::Basename(fPath.c_str()); |
+ if (1.0f == fScale) { |
+ return SkOSPath::Basename(fPath.c_str()); |
+ } else { |
+ return SkStringPrintf("%s_%.3f", SkOSPath::Basename(fPath.c_str()).c_str(), fScale); |
+ } |
} |
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ |