| Index: dm/DMSrcSink.cpp | 
| diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp | 
| index 4137154e99ecc95b81e90d6791c45adf663a7c63..cf2a489a8712f37604a3d2309c65beb0c2e38132 100644 | 
| --- a/dm/DMSrcSink.cpp | 
| +++ b/dm/DMSrcSink.cpp | 
| @@ -249,7 +249,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { | 
| return SkStringPrintf("Couldn't read %s.", fPath.c_str()); | 
| } | 
| SkAutoTDelete<SkCodec> codec(NULL); | 
| -    if (kScaledCodec_Mode == fMode) { | 
| +    if (kScaledCodec_Mode == fMode || kSubset_Mode == fMode) { | 
| codec.reset(SkScaledCodec::NewFromData(encoded)); | 
| // TODO (msarett): This should fall through to a fatal error once we support scaled | 
| //                 codecs for all image types. | 
| @@ -512,12 +512,15 @@ Error CodecSrc::draw(SkCanvas* canvas) const { | 
| 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); | 
| +            const int w = W / divisor; | 
| +            const int h = H / divisor; | 
| SkIRect subset; | 
| +            SkISize scaledSize; | 
| +            SkIRect scaledSubset; | 
| SkCodec::Options opts; | 
| opts.fSubset = ⊂ | 
| +            opts.fScaledDimensions = &scaledSize; | 
| +            opts.fScaledSubset = &scaledSubset; | 
| SkBitmap subsetBm; | 
| // We will reuse pixel memory from bitmap. | 
| void* pixels = bitmap.getPixels(); | 
| @@ -533,11 +536,10 @@ Error CodecSrc::draw(SkCanvas* canvas) const { | 
| const int preScaleH = SkTMin(h, H - y); | 
| subset.setXYWH(x, y, preScaleW, preScaleH); | 
| // And scale | 
| -                    // FIXME: Should we have a version of getScaledDimensions that takes a subset | 
| -                    // into account? | 
| -                    decodeInfo = decodeInfo.makeWH( | 
| -                            SkTMax(1, SkScalarRoundToInt(preScaleW * fScale)), | 
| -                            SkTMax(1, SkScalarRoundToInt(preScaleH * fScale))); | 
| +                    if (!codec->getScaledSubsetDimensions(fScale, opts)) { | 
| +                        return Error::Nonfatal("Subsetting not supported.\n"); | 
| +                    } | 
| +                    decodeInfo = decodeInfo.makeWH(scaledSubset.width(), scaledSubset.height()); | 
| size_t rowBytes = decodeInfo.minRowBytes(); | 
| if (!subsetBm.installPixels(decodeInfo, pixels, rowBytes, colorTable.get(), | 
| nullptr, nullptr)) { | 
| @@ -551,18 +553,11 @@ Error CodecSrc::draw(SkCanvas* canvas) const { | 
| break; | 
| case SkCodec::kInvalidConversion: | 
| if (0 == (x|y)) { | 
| -                                // First subset is okay to return unimplemented. | 
| +                                // First subset is okay to return invalid conversion. | 
| return Error::Nonfatal("Incompatible colortype conversion"); | 
| } | 
| // If the first subset succeeded, a later one should not fail. | 
| // fall through to failure | 
| -                        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", | 
| @@ -586,7 +581,7 @@ SkISize CodecSrc::size() const { | 
| SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 
| SkAutoTDelete<SkCodec> codec(nullptr); | 
|  | 
| -    if (kScaledCodec_Mode == fMode) { | 
| +    if (kScaledCodec_Mode == fMode || kSubset_Mode == fMode) { | 
| codec.reset(SkScaledCodec::NewFromData(encoded)); | 
| } else { | 
| codec.reset(SkCodec::NewFromData(encoded)); | 
|  |