Index: src/codec/SkScaledCodec.cpp |
diff --git a/src/codec/SkScaledCodec.cpp b/src/codec/SkScaledCodec.cpp |
index 6db09fb5ceefaea49d0e97ef659d4bc9b8e8e076..03b1b375b3501363b1fc536601e540c6c84ec586 100644 |
--- a/src/codec/SkScaledCodec.cpp |
+++ b/src/codec/SkScaledCodec.cpp |
@@ -44,15 +44,6 @@ SkScaledCodec::SkScaledCodec(SkScanlineDecoder* scanlineDecoder) |
SkScaledCodec::~SkScaledCodec() {} |
-// returns a scaled dimension based on the original dimension and the sampleSize |
-// NOTE: we round down here for scaled dimension to match the behavior of SkImageDecoder |
-static int get_scaled_dimension(int srcDimension, int sampleSize) { |
- if (sampleSize > srcDimension) { |
- return 1; |
- } |
- return srcDimension / sampleSize; |
-} |
- |
static SkISize best_scaled_dimensions(const SkISize& origDims, const SkISize& nativeDims, |
const SkISize& scaledCodecDims, float desiredScale) { |
if (nativeDims == scaledCodecDims) { |
@@ -98,8 +89,8 @@ SkISize SkScaledCodec::onGetScaledDimensions(float desiredScale) const { |
// Ex: sampleSize = 2, sample every second pixel in x and y directions |
int sampleSize = int(1 / desiredScale); |
- int scaledWidth = get_scaled_dimension(this->getInfo().width(), sampleSize); |
- int scaledHeight = get_scaled_dimension(this->getInfo().height(), sampleSize); |
+ int scaledWidth = SkScaledCodec::GetScaledDimension(this->getInfo().width(), sampleSize); |
+ int scaledHeight = SkScaledCodec::GetScaledDimension(this->getInfo().height(), sampleSize); |
// Return the calculated output dimensions for the given scale |
scaledCodecDimensions = SkISize::Make(scaledWidth, scaledHeight); |
@@ -121,11 +112,11 @@ static bool scaling_supported(const SkImageInfo& dstInfo, const SkImageInfo& src |
return false; |
} |
// check that srcWidth is scaled down by an integer value |
- if (get_scaled_dimension(srcWidth, *sampleX) != dstWidth) { |
+ if (SkScaledCodec::GetScaledDimension(srcWidth, *sampleX) != dstWidth) { |
return false; |
} |
// check that src height is scaled down by an integer value |
- if (get_scaled_dimension(srcHeight, *sampleY) != dstHeight) { |
+ if (SkScaledCodec::GetScaledDimension(srcHeight, *sampleY) != dstHeight) { |
return false; |
} |
// sampleX and sampleY should be equal unless the original sampleSize requested was larger |
@@ -139,6 +130,15 @@ static bool scaling_supported(const SkImageInfo& dstInfo, const SkImageInfo& src |
return true; |
} |
+// returns a scaled dimension based on the original dimension and the sampleSize |
+// NOTE: we round down here for scaled dimension to match the behavior of SkImageDecoder |
+inline int SkScaledCodec::GetScaledDimension(int srcDimension, int sampleSize) { |
+ if (sampleSize > srcDimension) { |
+ return 1; |
+ } |
+ return srcDimension / sampleSize; |
+} |
+ |
inline int SkScaledCodec::GetStartCoord(int sampleFactor) { |
return sampleFactor / 2; |
} |
@@ -189,9 +189,9 @@ void SkScaledCodec::ComputeSampleSize(const SkImageInfo& dstInfo, const SkImageI |
// dstWidth = 7, dstHeight = 2, sampleX = 79/7 = 11, sampleY = 20/2 = 10 |
// correct for this rounding by comparing width to sampleY and height to sampleX |
- if (get_scaled_dimension(srcWidth, sampleY) == dstWidth) { |
+ if (SkScaledCodec::GetScaledDimension(srcWidth, sampleY) == dstWidth) { |
sampleX = sampleY; |
- } else if (get_scaled_dimension(srcHeight, sampleX) == dstHeight) { |
+ } else if (SkScaledCodec::GetScaledDimension(srcHeight, sampleX) == dstHeight) { |
sampleY = sampleX; |
} |
} |
@@ -219,7 +219,22 @@ SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi |
Result result = fScanlineDecoder->start(requestedInfo, &options, ctable, ctableCount); |
if (kSuccess == result) { |
// native decode supported |
- return fScanlineDecoder->getScanlines(dst, requestedInfo.height(), rowBytes); |
+ switch (fScanlineDecoder->getScanlineOrder()) { |
+ case SkScanlineDecoder::kTopDown_SkScanlineOrder: |
+ case SkScanlineDecoder::kNone_SkScanlineOrder: |
+ return fScanlineDecoder->getScanlines(dst, requestedInfo.height(), rowBytes); |
+ case SkScanlineDecoder::kOutOfOrder_SkScanlineOrder: { |
+ for (int y = 0; y < requestedInfo.height(); y++) { |
+ int dstY = fScanlineDecoder->getY(); |
+ void* dstPtr = SkTAddOffset<void>(dst, rowBytes * dstY); |
+ result = fScanlineDecoder->getScanlines(dstPtr, 1, rowBytes); |
+ if (kSuccess != result && kIncompleteInput != result) { |
+ return result; |
+ } |
+ } |
+ return kSuccess; |
+ } |
+ } |
} |
if (kInvalidScale != result) { |