Index: src/codec/SkJpegCodec.cpp |
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp |
index 7db772da6386ad9a3b0002d5334598a625fd6fa2..34b5b5a826ce953b631704563e98bcbe2e751a4e 100644 |
--- a/src/codec/SkJpegCodec.cpp |
+++ b/src/codec/SkJpegCodec.cpp |
@@ -348,7 +348,13 @@ void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& |
} |
} |
- fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, dstInfo, options)); |
+ Options swizzlerOptions = options; |
+ if (options.fSubset) { |
+ // Use fSwizzlerSubset if this is a subset decode. This is necessary in the case |
+ // where libjpeg-turbo provides a subset and then we need to subset it further. |
+ swizzlerOptions.fSubset = &fSwizzlerSubset; |
+ } |
+ fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, dstInfo, swizzlerOptions)); |
fStorage.reset(get_row_bytes(fDecoderMgr->dinfo())); |
fSrcRow = fStorage.get(); |
} |
@@ -387,11 +393,50 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, |
return kInvalidInput; |
} |
+ if (options.fSubset) { |
+ fSwizzlerSubset = *options.fSubset; |
+ } |
+ |
+#ifdef TURBO_HAS_SUBSET |
+ if (options.fSubset) { |
+ uint32_t startX = options.fSubset->x(); |
+ uint32_t width = options.fSubset->width(); |
+ |
+ // libjpeg-turbo may need to align startX to a multiple of the IDCT |
+ // block size. If this is the case, it will decrease the value of |
+ // startX to the appropriate alignment and also increase the value |
+ // of width so that the right edge of the requested subset remains |
+ // the same. |
+ jpeg_set_partial_scanline(fDecoderMgr->dinfo(), &startX, &width); |
+ |
+ SkASSERT(startX <= (uint32_t) options.fSubset->x()); |
+ SkASSERT(width >= (uint32_t) options.fSubset->width()); |
+ SkASSERT(startX + width >= (uint32_t) options.fSubset->right()); |
+ |
+ // Instruct the swizzler (if it is necessary) to further subset the |
+ // output provided by libjpeg-turbo |
+ fSwizzlerSubset.setXYWH(options.fSubset->x() - startX, 0, |
+ options.fSubset->width(), options.fSubset->height()); |
+ |
+ // We will need a swizzler if libjpeg-turbo cannot provide the exact |
+ // subset that we request. Or if we are converting from CMYK. |
+ if (startX != (uint32_t) options.fSubset->x() || |
+ width != (uint32_t) options.fSubset->width()) { |
+ this->initializeSwizzler(dstInfo, options); |
+ } |
+ } |
+ |
+ // Make sure we have a swizzler if we are converting from CMYK. |
+ if (!fSwizzler && JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) { |
+ this->initializeSwizzler(dstInfo, options); |
+ } |
+#else |
// We will need a swizzler if we are performing a subset decode or |
// converting from CMYK. |
if (options.fSubset || JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) { |
this->initializeSwizzler(dstInfo, options); |
} |
+#endif |
return kSuccess; |
} |