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; |
} |