Chromium Code Reviews| Index: dm/DMSrcSink.cpp |
| diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp |
| index 38597b6946994c06d8cc24971dc018163ff41b14..7f553c9ad35c3bb126a61c69fe58afcdcbb9ffc3 100644 |
| --- a/dm/DMSrcSink.cpp |
| +++ b/dm/DMSrcSink.cpp |
| @@ -355,6 +355,70 @@ Error CodecSrc::draw(SkCanvas* canvas) const { |
| canvas->drawBitmap(bitmap, 0, 0); |
| break; |
| } |
| + case kSubset_Mode: { |
| + // Arbitrarily choose a divisor. |
| + int divisor = 2; |
| + // Total width/height of the image. |
| + const int W = codec->getInfo().width(); |
| + const int H = codec->getInfo().height(); |
| + if (divisor > W || divisor > H) { |
| + return Error::Nonfatal(SkStringPrintf("Cannot codec subset: divisor %d is too big " |
| + "for %s with dimensions (%d x %d)", divisor, |
| + fPath.c_str(), W, H)); |
| + } |
| + // subset dimensions |
| + // SkWebpCodec, the only one that supports subsets, requires even top/left boundaries. |
| + const int w = SkAlign2(W / divisor); |
| + const int h = SkAlign2(H / divisor); |
| + SkCodec::Options opts; |
| + SkBitmap subsetBm; |
| + // We will reuse pixel memory from bitmap. |
| + void* pixels = bitmap.getPixels(); |
| + // Keep track of left and top (for drawing subsetBm into canvas). We could use |
| + // fScale * x and fScale * y, but we want integers such that the next subset will start |
| + // where the last one ended. So we'll add decodeInfo.width() and height(). |
| + int left = 0; |
| + for (int x = 0; x < W; x += w) { |
| + int top = 0; |
| + for (int y = 0; y < H; y+= h) { |
| + // Do not make the subset go off the edge of the image. |
| + decodeInfo = decodeInfo.makeWH(SkTMin(w, W - x), SkTMin(h, H - y)); |
| + opts.fSubset.setXYWH(x, y, decodeInfo.width(), decodeInfo.height()); |
| + // And scale |
| + decodeInfo = decodeInfo.makeWH(decodeInfo.width() * fScale, |
|
emmaleer
2015/07/17 22:31:05
You could only call decodeInfo.makeWH() once inste
scroggo
2015/07/20 14:25:42
SkImageInfo::makeWH() is likely pretty cheap (func
|
| + decodeInfo.height() * fScale); |
| + size_t rowBytes = decodeInfo.minRowBytes(); |
| + if (!subsetBm.installPixels(decodeInfo, pixels, rowBytes, colorTable.get(), |
| + NULL, NULL)) { |
| + return SkStringPrintf("could not install pixels for %s.", fPath.c_str()); |
| + } |
| + const SkCodec::Result result = codec->getPixels(decodeInfo, pixels, rowBytes, |
| + &opts, colorPtr, colorCountPtr); |
| + switch (result) { |
| + case SkCodec::kSuccess: |
| + break; |
|
emmaleer
2015/07/17 22:31:05
What about the case SkCodec::kIncompleteInput.
All
scroggo
2015/07/20 14:25:42
I think this goes back to my general concern about
|
| + case SkCodec::kUnimplemented: |
| + if (0 == (x|y)) { |
| + // First subset is okay to return unimplemented. |
| + return Error::Nonfatal("subset codec not supported"); |
| + } |
| + // If the first subset succeeded, why would a later one fail? |
| + // fall through to failure |
| + default: |
| + return SkStringPrintf("subset codec failed to decode (%d, %d, %d, %d) " |
| + "from %s with dimensions (%d x %d)\t error %d", |
| + x, y, decodeInfo.width(), decodeInfo.height(), |
| + fPath.c_str(), W, H, result); |
| + } |
| + canvas->drawBitmap(subsetBm, left, top); |
| + // translate by the scaled height. |
| + top += decodeInfo.height(); |
| + } |
| + // translate by the scaled width. |
| + left += decodeInfo.width(); |
| + } |
| + return ""; |
| + } |
| } |
| return ""; |
| } |