| Index: src/codec/SkScaledCodec.cpp
|
| diff --git a/src/codec/SkScaledCodec.cpp b/src/codec/SkScaledCodec.cpp
|
| index 36aeda98cf495ff2a84f1103d0612bb26d91ada1..078a0261a0c392c26e083532cddc358a9ac770b9 100644
|
| --- a/src/codec/SkScaledCodec.cpp
|
| +++ b/src/codec/SkScaledCodec.cpp
|
| @@ -100,13 +100,13 @@ SkISize SkScaledCodec::onGetScaledDimensions(float desiredScale) const {
|
| }
|
|
|
| // check if scaling to dstInfo size from srcInfo size using sampleSize is possible
|
| -static bool scaling_supported(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo,
|
| +static bool scaling_supported(const SkISize& dstDim, const SkISize& srcDim,
|
| int* sampleX, int* sampleY) {
|
| - SkScaledCodec::ComputeSampleSize(dstInfo, srcInfo, sampleX, sampleY);
|
| - const int dstWidth = dstInfo.width();
|
| - const int dstHeight = dstInfo.height();
|
| - const int srcWidth = srcInfo.width();
|
| - const int srcHeight = srcInfo.height();
|
| + SkScaledCodec::ComputeSampleSize(dstDim, srcDim, sampleX, sampleY);
|
| + const int dstWidth = dstDim.width();
|
| + const int dstHeight = dstDim.height();
|
| + const int srcWidth = srcDim.width();
|
| + const int srcHeight = srcDim.height();
|
| // only support down sampling, not up sampling
|
| if (dstWidth > srcWidth || dstHeight > srcHeight) {
|
| return false;
|
| @@ -130,13 +130,29 @@ static bool scaling_supported(const SkImageInfo& dstInfo, const SkImageInfo& src
|
| return true;
|
| }
|
|
|
| +bool SkScaledCodec::onDimensionsSupported(const SkISize& dim) {
|
| + // Check with fCodec first. No need to call the non-virtual version, which
|
| + // just checks if it matches the original, since a match means this method
|
| + // will not be called.
|
| + if (fCodec->onDimensionsSupported(dim)) {
|
| + return true;
|
| + }
|
| +
|
| + // FIXME: These variables are unused, but are needed by scaling_supported.
|
| + // This class could also cache these values, and avoid calling this in
|
| + // onGetPixels (since getPixels already calls it).
|
| + int sampleX;
|
| + int sampleY;
|
| + return scaling_supported(dim, this->getInfo().dimensions(), &sampleX, &sampleY);
|
| +}
|
| +
|
| // calculates sampleSize in x and y direction
|
| -void SkScaledCodec::ComputeSampleSize(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo,
|
| +void SkScaledCodec::ComputeSampleSize(const SkISize& dstDim, const SkISize& srcDim,
|
| int* sampleXPtr, int* sampleYPtr) {
|
| - int srcWidth = srcInfo.width();
|
| - int dstWidth = dstInfo.width();
|
| - int srcHeight = srcInfo.height();
|
| - int dstHeight = dstInfo.height();
|
| + int srcWidth = srcDim.width();
|
| + int dstWidth = dstDim.width();
|
| + int srcHeight = srcDim.height();
|
| + int dstHeight = dstDim.height();
|
|
|
| int sampleX = srcWidth / dstWidth;
|
| int sampleY = srcHeight / dstHeight;
|
| @@ -183,62 +199,46 @@ SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi
|
| if (options.fSubset) {
|
| // Subsets are not supported.
|
| return kUnimplemented;
|
| - }
|
| -
|
| - // FIXME: If no scaling/subsets are requested, we can call fCodec->getPixels.
|
| - Result result = fCodec->startScanlineDecode(requestedInfo, &options, ctable, ctableCount);
|
| - if (kSuccess == result) {
|
| - // native decode supported
|
| - switch (fCodec->getScanlineOrder()) {
|
| - case SkCodec::kTopDown_SkScanlineOrder:
|
| - case SkCodec::kBottomUp_SkScanlineOrder:
|
| - case SkCodec::kNone_SkScanlineOrder:
|
| - return fCodec->getScanlines(dst, requestedInfo.height(), rowBytes);
|
| - case SkCodec::kOutOfOrder_SkScanlineOrder: {
|
| - for (int y = 0; y < requestedInfo.height(); y++) {
|
| - int dstY = fCodec->nextScanline();
|
| - void* dstPtr = SkTAddOffset<void>(dst, rowBytes * dstY);
|
| - result = fCodec->getScanlines(dstPtr, 1, rowBytes);
|
| - // FIXME (msarett): Make the SkCodec base class take care of filling
|
| - // uninitialized pixels so we can return immediately on kIncompleteInput.
|
| - if (kSuccess != result && kIncompleteInput != result) {
|
| - return result;
|
| - }
|
| - }
|
| - return result;
|
| - }
|
| - }
|
| }
|
|
|
| - if (kInvalidScale != result) {
|
| - // no scaling requested
|
| - return result;
|
| + if (fCodec->dimensionsSupported(requestedInfo.dimensions())) {
|
| + return fCodec->getPixels(requestedInfo, dst, rowBytes, &options, ctable, ctableCount);
|
| }
|
|
|
| // scaling requested
|
| int sampleX;
|
| int sampleY;
|
| - if (!scaling_supported(requestedInfo, fCodec->getInfo(), &sampleX, &sampleY)) {
|
| + if (!scaling_supported(requestedInfo.dimensions(), fCodec->getInfo().dimensions(),
|
| + &sampleX, &sampleY)) {
|
| + // onDimensionsSupported would have returned false, meaning we should never reach here.
|
| + SkASSERT(false);
|
| return kInvalidScale;
|
| }
|
| +
|
| // set first sample pixel in y direction
|
| - int Y0 = get_start_coord(sampleY);
|
| -
|
| - int dstHeight = requestedInfo.height();
|
| - int srcHeight = fCodec->getInfo().height();
|
| -
|
| - SkImageInfo info = requestedInfo;
|
| - // use original height as codec does not support y sampling natively
|
| - info = info.makeWH(requestedInfo.width(), srcHeight);
|
| -
|
| - // update codec with new info
|
| - // FIXME: The previous call to start returned kInvalidScale. This call may
|
| - // require a rewind. (skbug.com/4284)
|
| - result = fCodec->startScanlineDecode(info, &options, ctable, ctableCount);
|
| + const int Y0 = get_start_coord(sampleY);
|
| +
|
| + const int dstHeight = requestedInfo.height();
|
| + const int srcWidth = fCodec->getInfo().width();
|
| + const int srcHeight = fCodec->getInfo().height();
|
| +
|
| + const SkImageInfo info = requestedInfo.makeWH(srcWidth, srcHeight);
|
| +
|
| + Result result = fCodec->startScanlineDecode(info, &options, ctable, ctableCount);
|
| +
|
| if (kSuccess != result) {
|
| return result;
|
| }
|
|
|
| + SkSampler* sampler = fCodec->getSampler();
|
| + if (!sampler) {
|
| + return kUnimplemented;
|
| + }
|
| +
|
| + if (sampler->setSampleX(sampleX) != requestedInfo.width()) {
|
| + return kInvalidScale;
|
| + }
|
| +
|
| switch(fCodec->getScanlineOrder()) {
|
| case SkCodec::kTopDown_SkScanlineOrder: {
|
| result = fCodec->skipScanlines(Y0);
|
|
|