Chromium Code Reviews| Index: dm/DMSrcSink.cpp |
| diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp |
| index 0a90e03103dc23b087a3269f24434ec925f90d05..940a646063525769c89f12764620799429759350 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 { |
| @@ -195,7 +196,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 +227,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 +263,57 @@ Error CodecSrc::draw(SkCanvas* canvas) const { |
| } |
| break; |
| } |
| + // This mode tests scaling and skipping. The decode is performed for the scaled image |
| + // dimensions using stripes. |
|
scroggo
2015/06/11 15:50:02
It is curious to me that we combine scaling with s
msarett
2015/06/11 19:29:36
Yes this was an odd decision that didn't make much
|
| + case kScale_Mode: { |
| + SkISize size = codec->getScaledDimensions(fScale); |
| + SkImageInfo info = decodeInfo.makeWH(size.width(), size.height()); |
| + int width = info.width(); |
| + int height = info.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; |
| + |
| + // Create bitmap |
| + SkBitmap bitmap; |
| + if (!bitmap.tryAllocPixels(info, NULL, colorTable.get())) { |
| + return SkStringPrintf("Cannot allocate pixels for %s %dx%d", fPath.c_str(), |
| + width, height); |
| + } |
| + |
| + // Decode odd stripes |
| + SkScanlineDecoder* decoder = codec->getScanlineDecoder(info, 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); |
| + decoder->skipScanlines(linesToSkip); |
| + |
| + // Read a stripe |
| + const int startY = SkTMin((i + 1) * stripeHeight, height - 1); |
| + const int linesToRead = SkTMax(0, SkTMin(stripeHeight, height - startY)); |
| + decoder->getScanlines(bitmap.getAddr(0, startY), linesToRead, bitmap.rowBytes()); |
| + } |
| + |
| + // Decode even stripes |
| + decoder = codec->getScanlineDecoder(info, NULL, colorPtr, colorCountPtr); |
| + for (int i = 0; i < numStripes; i += 2) { |
| + // Read a stripe |
| + const int startY = i * stripeHeight; |
| + const int linesToRead = SkTMin(stripeHeight, height - startY); |
| + decoder->getScanlines(bitmap.getAddr(0, startY), linesToRead, bitmap.rowBytes()); |
| + |
| + // Skip a stripe |
| + const int linesToSkip = SkTMax(0, SkTMin(stripeHeight, |
| + height - (i + 1) * stripeHeight)); |
| + decoder->skipScanlines(linesToSkip); |
| + } |
| + canvas->drawBitmap(bitmap, 0, 0); |
| + } |
| } |
| return ""; |
| } |
| @@ -270,14 +322,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); |
|
scroggo
2015/06/11 15:50:02
For png (for example) this will return the origina
msarett
2015/06/11 19:29:36
We are now returning Error::Nonfatal for tests whe
|
| + 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); |
| + } |
| } |
| /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ |