Chromium Code Reviews| Index: src/codec/SkJpegCodec.cpp |
| diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp |
| index 8c0a5b68931f791e4db2df54301a8739e46c650b..071b9753c23f4086fd1e0b14e34b1d89754ec633 100644 |
| --- a/src/codec/SkJpegCodec.cpp |
| +++ b/src/codec/SkJpegCodec.cpp |
| @@ -163,19 +163,19 @@ SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const { |
| // support these as well |
| long num; |
| long denom = 8; |
| - if (desiredScale > 0.875f) { |
| + if (desiredScale >= 0.9375) { |
|
scroggo
2015/10/02 18:27:03
why did this change?
msarett
2015/10/06 23:01:27
IMO, it used to make sense to always round up, sin
|
| num = 8; |
| - } else if (desiredScale > 0.75f) { |
| + } else if (desiredScale >= 0.8125) { |
| num = 7; |
| - } else if (desiredScale > 0.625f) { |
| + } else if (desiredScale >= 0.6875f) { |
| num = 6; |
| - } else if (desiredScale > 0.5f) { |
| + } else if (desiredScale >= 0.5625f) { |
| num = 5; |
| - } else if (desiredScale > 0.375f) { |
| + } else if (desiredScale >= 0.4375f) { |
| num = 4; |
| - } else if (desiredScale > 0.25f) { |
| + } else if (desiredScale >= 0.3125f) { |
| num = 3; |
| - } else if (desiredScale > 0.125f) { |
| + } else if (desiredScale >= 0.1875f) { |
| num = 2; |
| } else { |
| num = 1; |
| @@ -368,7 +368,8 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo, |
| return kSuccess; |
| } |
| -SkCodec::Result SkJpegCodec::initializeSwizzler(const SkImageInfo& info, const Options& options) { |
| +SkCodec::Result SkJpegCodec::initializeSwizzler(const SkImageInfo& info, const Options& options, |
| + int subsetLeft, int subsetWidth) { |
| SkSwizzler::SrcConfig srcConfig; |
| switch (info.colorType()) { |
| case kGray_8_SkColorType: |
| @@ -388,8 +389,8 @@ SkCodec::Result SkJpegCodec::initializeSwizzler(const SkImageInfo& info, const O |
| SkASSERT(false); |
| } |
| - fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, info, options.fZeroInitialized, |
| - this->getInfo())); |
| + fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, info, options.fZeroInitialized, |
| + this->getInfo(), subsetLeft, subsetWidth)); |
| if (!fSwizzler) { |
| return SkCodec::kUnimplemented; |
| } |
| @@ -398,7 +399,8 @@ SkCodec::Result SkJpegCodec::initializeSwizzler(const SkImageInfo& info, const O |
| } |
| SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, |
| - const Options& options, SkPMColor ctable[], int* ctableCount) { |
| + const Options& options, SkPMColor ctable[], int* ctableCount, int subsetLeft, |
| + int subsetWidth) { |
| // Set the jump location for libjpeg errors |
| if (setjmp(fDecoderMgr->getJmpBuf())) { |
| SkCodecPrintf("setjmp: Error from libjpeg\n"); |
| @@ -417,13 +419,29 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, |
| if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstInfo)) { |
| return kInvalidScale; |
| } |
| + |
| // create swizzler for sampling |
| - Result result = this->initializeSwizzler(dstInfo, options); |
| - if (kSuccess != result) { |
| + SkCodec::Result result = this->initializeSwizzler(dstInfo, options, subsetLeft, |
| + subsetWidth); |
| + if (SkCodec::kSuccess != result) { |
| + SkCodecPrintf("failed to initialize the swizzler.\n"); |
| + return result; |
| + } |
| + fStorage.reset(get_row_bytes(this->fDecoderMgr->dinfo())); |
| + fSrcRow = static_cast<uint8_t*>(fStorage.get()); |
| + } else if (0 != subsetLeft || dstInfo.width() != subsetWidth) { |
| + // TODO (msarett): If we implement a read partial scanlines API in libjpeg-turbo, we |
| + // won't need to use the swizzler here. |
| + // Create swizzler for subsetting. We pass in the original info because scaling is |
| + // handlded natively. |
| + SkCodec::Result result = this->initializeSwizzler( |
| + dstInfo.makeWH(this->getInfo().width(), this->getInfo().height()), options, |
| + subsetLeft, subsetWidth); |
| + if (SkCodec::kSuccess != result) { |
| SkCodecPrintf("failed to initialize the swizzler.\n"); |
| return result; |
| } |
| - fStorage.reset(get_row_bytes(fDecoderMgr->dinfo())); |
| + fStorage.reset(get_row_bytes(this->fDecoderMgr->dinfo())); |
| fSrcRow = static_cast<uint8_t*>(fStorage.get()); |
| } else { |
| fSrcRow = nullptr; |