| Index: src/codec/SkSwizzler.cpp
|
| diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp
|
| index 242866db441da201e2827d8d106b2960beab8b21..d783380294ab81f18a5c67e2d66bf8e5a33db2d4 100644
|
| --- a/src/codec/SkSwizzler.cpp
|
| +++ b/src/codec/SkSwizzler.cpp
|
| @@ -594,7 +594,8 @@ static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
|
| SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
|
| const SkPMColor* ctable,
|
| const SkImageInfo& dstInfo,
|
| - const SkCodec::Options& options) {
|
| + const SkCodec::Options& options,
|
| + const SkIRect* frame) {
|
| if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) {
|
| return nullptr;
|
| }
|
| @@ -776,43 +777,59 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
|
| }
|
|
|
| // Store bpp in bytes if it is an even multiple, otherwise use bits
|
| - int bpp = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc);
|
| + int srcBPP = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc);
|
| + int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType());
|
|
|
| int srcOffset = 0;
|
| int srcWidth = dstInfo.width();
|
| + int dstOffset = 0;
|
| + int dstWidth = srcWidth;
|
| if (options.fSubset) {
|
| + // We do not currently support subset decodes for image types that may have
|
| + // frames (gif).
|
| + SkASSERT(!frame);
|
| srcOffset = options.fSubset->left();
|
| srcWidth = options.fSubset->width();
|
| + dstWidth = srcWidth;
|
| + } else if (frame) {
|
| + dstOffset = frame->left();
|
| + srcWidth = frame->width();
|
| }
|
|
|
| - return new SkSwizzler(proc, ctable, srcOffset, srcWidth, bpp);
|
| + return new SkSwizzler(proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth, srcBPP, dstBPP);
|
| }
|
|
|
| -SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcOffset, int subsetWidth,
|
| - int bpp)
|
| +SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcOffset, int srcWidth,
|
| + int dstOffset, int dstWidth, int srcBPP, int dstBPP)
|
| : fRowProc(proc)
|
| , fColorTable(ctable)
|
| , fSrcOffset(srcOffset)
|
| - , fX0(srcOffset)
|
| - , fSubsetWidth(subsetWidth)
|
| - , fDstWidth(subsetWidth)
|
| + , fDstOffset(dstOffset)
|
| + , fSrcOffsetUnits(srcOffset * srcBPP)
|
| + , fDstOffsetBytes(dstOffset * dstBPP)
|
| + , fSrcWidth(srcWidth)
|
| + , fDstWidth(dstWidth)
|
| + , fSwizzleWidth(srcWidth)
|
| + , fAllocatedWidth(dstWidth)
|
| , fSampleX(1)
|
| - , fBPP(bpp)
|
| + , fSrcBPP(srcBPP)
|
| + , fDstBPP(dstBPP)
|
| {}
|
|
|
| int SkSwizzler::onSetSampleX(int sampleX) {
|
| SkASSERT(sampleX > 0); // Surely there is an upper limit? Should there be
|
| // way to report failure?
|
| fSampleX = sampleX;
|
| - fX0 = get_start_coord(sampleX) + fSrcOffset;
|
| - fDstWidth = get_scaled_dimension(fSubsetWidth, sampleX);
|
| + fSrcOffsetUnits = (get_start_coord(sampleX) + fSrcOffset) * fSrcBPP;
|
| + fDstOffsetBytes = (fDstOffset / sampleX) * fDstBPP;
|
| + fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX);
|
| + fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX);
|
|
|
| - // check that fX0 is valid
|
| - SkASSERT(fX0 >= 0);
|
| - return fDstWidth;
|
| + return fAllocatedWidth;
|
| }
|
|
|
| SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
|
| SkASSERT(nullptr != dst && nullptr != src);
|
| - return fRowProc(dst, src, fDstWidth, fBPP, fSampleX * fBPP, fX0 * fBPP, fColorTable);
|
| + return fRowProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcBPP,
|
| + fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable);
|
| }
|
|
|