Chromium Code Reviews| Index: src/codec/SkScaledCodec.cpp |
| diff --git a/src/codec/SkScaledCodec.cpp b/src/codec/SkScaledCodec.cpp |
| index e0158b6b4ef005d035ac6ef54576debdb28b7b98..23a0082c595ac36e8cf762c1f433d4697bd4b9dc 100644 |
| --- a/src/codec/SkScaledCodec.cpp |
| +++ b/src/codec/SkScaledCodec.cpp |
| @@ -133,6 +133,13 @@ static bool scaling_supported(const SkImageInfo& dstInfo, const SkImageInfo& src |
| return true; |
| } |
| +static bool is_row_necessary(int srcY, int startY, int sampleY) { |
|
scroggo
2015/08/26 22:40:09
nit: Can you add comments explaining this function
|
| + if (srcY < startY) { |
| + return false; |
| + } |
| + return ((srcY - startY) % sampleY) == 0; |
| +} |
| + |
| // calculates sampleSize in x and y direction |
| void SkScaledCodec::ComputeSampleSize(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo, |
| int* sampleXPtr, int* sampleYPtr) { |
| @@ -221,41 +228,63 @@ SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi |
| if (kSuccess != result) { |
| return result; |
| } |
| - |
| - const bool requiresPostYSampling = fScanlineDecoder->requiresPostYSampling(); |
| - |
| - if (requiresPostYSampling) { |
| - SkAutoMalloc storage(srcHeight * rowBytes); |
| - uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); |
| - result = fScanlineDecoder->getScanlines(storagePtr, srcHeight, rowBytes); |
| - if (kSuccess != result) { |
| - return result; |
| - } |
| - storagePtr += Y0 * rowBytes; |
| - for (int y = 0; y < dstHeight; y++) { |
| - memcpy(dst, storagePtr, rowBytes); |
| - storagePtr += sampleY * rowBytes; |
| - dst = SkTAddOffset<void>(dst, rowBytes); |
| - } |
| - } else { |
| - // does not require post y sampling |
| - result = fScanlineDecoder->skipScanlines(Y0); |
| - if (kSuccess != result) { |
| - return result; |
| - } |
| - for (int y = 0; y < dstHeight; y++) { |
| - result = fScanlineDecoder->getScanlines(dst, 1, rowBytes); |
| + |
| + switch(fScanlineDecoder->getScanlineOrder()) { |
| + case SkScanlineDecoder::kTopDown_SkScanlineOrder: { |
| + result = fScanlineDecoder->skipScanlines(Y0); |
| if (kSuccess != result) { |
| return result; |
| } |
| - if (y < dstHeight - 1) { |
| - result = fScanlineDecoder->skipScanlines(sampleY - 1); |
| + for (int y = 0; y < dstHeight; y++) { |
| + result = fScanlineDecoder->getScanlines(dst, 1, rowBytes); |
| if (kSuccess != result) { |
| return result; |
| } |
| + if (y < dstHeight - 1) { |
| + result = fScanlineDecoder->skipScanlines(sampleY - 1); |
| + if (kSuccess != result) { |
| + return result; |
| + } |
| + } |
| + dst = SkTAddOffset<void>(dst, rowBytes); |
| + } |
| + return kSuccess; |
| + } |
| + case SkScanlineDecoder::kOutOfOrder_SkScanlineOrder: { |
| + for (int y = 0; y < srcHeight; y++) { |
| + int srcY = fScanlineDecoder->getY(); |
| + if (is_row_necessary(srcY, Y0, sampleY)) { |
| + void* dstPtr = SkTAddOffset<void>(dst, rowBytes * (srcY / sampleY)); |
| + result = fScanlineDecoder->getScanlines(dstPtr, 1, rowBytes); |
| + if (kSuccess != result) { |
| + return result; |
| + } |
| + } else { |
| + result = fScanlineDecoder->skipScanlines(1); |
| + if (kSuccess != result) { |
| + return result; |
| + } |
| + } |
| + } |
| + return kSuccess; |
| + } |
| + case SkScanlineDecoder::kNone_SkScanlineOrder: { |
| + SkAutoMalloc storage(srcHeight * rowBytes); |
| + uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); |
| + result = fScanlineDecoder->getScanlines(storagePtr, srcHeight, rowBytes); |
| + if (kSuccess != result) { |
| + return result; |
| + } |
| + storagePtr += Y0 * rowBytes; |
| + for (int y = 0; y < dstHeight; y++) { |
| + memcpy(dst, storagePtr, rowBytes); |
| + storagePtr += sampleY * rowBytes; |
| + dst = SkTAddOffset<void>(dst, rowBytes); |
| } |
| - dst = SkTAddOffset<void>(dst, rowBytes); |
| + return kSuccess; |
| } |
| + default: |
| + SkASSERT(false); |
| + return kUnimplemented; |
| } |
| - return kSuccess; |
| } |