diff options
Diffstat (limited to 'src/codec')
-rw-r--r-- | src/codec/SkBmpCodec.cpp | 4 | ||||
-rw-r--r-- | src/codec/SkBmpMaskCodec.cpp | 8 | ||||
-rw-r--r-- | src/codec/SkBmpMaskCodec.h | 2 | ||||
-rw-r--r-- | src/codec/SkBmpRLECodec.cpp | 6 | ||||
-rw-r--r-- | src/codec/SkBmpStandardCodec.cpp | 6 | ||||
-rw-r--r-- | src/codec/SkCodec.cpp | 14 | ||||
-rw-r--r-- | src/codec/SkCodec_libgif.cpp | 18 | ||||
-rw-r--r-- | src/codec/SkCodec_libgif.h | 6 | ||||
-rw-r--r-- | src/codec/SkCodec_libpng.cpp | 15 | ||||
-rw-r--r-- | src/codec/SkCodec_libpng.h | 3 | ||||
-rw-r--r-- | src/codec/SkCodec_wbmp.cpp | 10 | ||||
-rw-r--r-- | src/codec/SkJpegCodec.cpp | 47 | ||||
-rw-r--r-- | src/codec/SkJpegCodec.h | 3 | ||||
-rw-r--r-- | src/codec/SkMaskSwizzler.cpp | 26 | ||||
-rw-r--r-- | src/codec/SkMaskSwizzler.h | 12 | ||||
-rw-r--r-- | src/codec/SkSwizzler.cpp | 35 | ||||
-rw-r--r-- | src/codec/SkSwizzler.h | 20 | ||||
-rw-r--r-- | src/codec/SkWebpCodec.cpp | 4 |
18 files changed, 124 insertions, 115 deletions
diff --git a/src/codec/SkBmpCodec.cpp b/src/codec/SkBmpCodec.cpp index 1aa43f583c..0222c8ce9f 100644 --- a/src/codec/SkBmpCodec.cpp +++ b/src/codec/SkBmpCodec.cpp @@ -564,10 +564,6 @@ uint32_t SkBmpCodec::computeNumColors(uint32_t numColors) { SkCodec::Result SkBmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) { - if (options.fSubset) { - // Subsets are not supported. - return kUnimplemented; - } if (!conversion_possible(dstInfo, this->getInfo())) { SkCodecPrintf("Error: cannot convert input type to output type.\n"); return kInvalidConversion; diff --git a/src/codec/SkBmpMaskCodec.cpp b/src/codec/SkBmpMaskCodec.cpp index 336698d319..2bc47b5126 100644 --- a/src/codec/SkBmpMaskCodec.cpp +++ b/src/codec/SkBmpMaskCodec.cpp @@ -58,10 +58,10 @@ SkCodec::Result SkBmpMaskCodec::onGetPixels(const SkImageInfo& dstInfo, return kSuccess; } -bool SkBmpMaskCodec::initializeSwizzler(const SkImageInfo& dstInfo) { +bool SkBmpMaskCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options) { // Create the swizzler - fMaskSwizzler.reset(SkMaskSwizzler::CreateMaskSwizzler( - dstInfo, this->getInfo(), fMasks, this->bitsPerPixel())); + fMaskSwizzler.reset(SkMaskSwizzler::CreateMaskSwizzler(dstInfo, this->getInfo(), fMasks, + this->bitsPerPixel(), options)); if (nullptr == fMaskSwizzler.get()) { return false; @@ -73,7 +73,7 @@ bool SkBmpMaskCodec::initializeSwizzler(const SkImageInfo& dstInfo) { SkCodec::Result SkBmpMaskCodec::prepareToDecode(const SkImageInfo& dstInfo, const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) { // Initialize a the mask swizzler - if (!this->initializeSwizzler(dstInfo)) { + if (!this->initializeSwizzler(dstInfo, options)) { SkCodecPrintf("Error: cannot initialize swizzler.\n"); return SkCodec::kInvalidConversion; } diff --git a/src/codec/SkBmpMaskCodec.h b/src/codec/SkBmpMaskCodec.h index 1c1d1d8c11..4ec868db0e 100644 --- a/src/codec/SkBmpMaskCodec.h +++ b/src/codec/SkBmpMaskCodec.h @@ -44,7 +44,7 @@ protected: private: - bool initializeSwizzler(const SkImageInfo& dstInfo); + bool initializeSwizzler(const SkImageInfo& dstInfo, const Options& options); SkSampler* getSampler(bool createIfNecessary) override { SkASSERT(fMaskSwizzler); return fMaskSwizzler; diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp index 37af47600b..e215095266 100644 --- a/src/codec/SkBmpRLECodec.cpp +++ b/src/codec/SkBmpRLECodec.cpp @@ -259,6 +259,12 @@ void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes, SkCodec::Result SkBmpRLECodec::prepareToDecode(const SkImageInfo& dstInfo, const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) { + // FIXME: Support subsets for scanline decodes. + if (options.fSubset) { + // Subsets are not supported. + return kUnimplemented; + } + // Reset fSampleX. If it needs to be a value other than 1, it will get modified by // the sampler. fSampleX = 1; diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp index 938fe8c788..9557609360 100644 --- a/src/codec/SkBmpStandardCodec.cpp +++ b/src/codec/SkBmpStandardCodec.cpp @@ -161,8 +161,7 @@ SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo, return true; } -bool SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo, - const Options& opts) { +bool SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts) { // Get swizzler configuration SkSwizzler::SrcConfig config; switch (this->bitsPerPixel()) { @@ -197,8 +196,7 @@ bool SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo, const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); // Create swizzler - fSwizzler.reset(SkSwizzler::CreateSwizzler(config, - colorPtr, dstInfo, opts.fZeroInitialized)); + fSwizzler.reset(SkSwizzler::CreateSwizzler(config, colorPtr, dstInfo, opts)); if (nullptr == fSwizzler.get()) { return false; diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp index 0047d599ac..56f6a8de9e 100644 --- a/src/codec/SkCodec.cpp +++ b/src/codec/SkCodec.cpp @@ -220,11 +220,15 @@ SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo, if (nullptr == options) { options = &optsStorage; } else if (options->fSubset) { - SkIRect subset(*options->fSubset); - if (!this->onGetValidSubset(&subset) || subset != *options->fSubset) { - // FIXME: How to differentiate between not supporting subset at all - // and not supporting this particular subset? - return kUnimplemented; + SkIRect size = SkIRect::MakeSize(dstInfo.dimensions()); + if (!size.contains(*options->fSubset)) { + return kInvalidInput; + } + + // We only support subsetting in the x-dimension for scanline decoder. + // Subsetting in the y-dimension can be accomplished using skipScanlines(). + if (options->fSubset->top() != 0 || options->fSubset->height() != dstInfo.height()) { + return kInvalidInput; } } diff --git a/src/codec/SkCodec_libgif.cpp b/src/codec/SkCodec_libgif.cpp index 856f69ba3c..0187891558 100644 --- a/src/codec/SkCodec_libgif.cpp +++ b/src/codec/SkCodec_libgif.cpp @@ -435,10 +435,6 @@ void SkGifCodec::initializeColorTable(const SkImageInfo& dstInfo, SkPMColor* inp SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColor* inputColorPtr, int* inputColorCount, const Options& opts) { // Check for valid input parameters - if (opts.fSubset) { - // Subsets are not supported. - return kUnimplemented; - } if (!conversion_possible(dstInfo, this->getInfo())) { return gif_error("Cannot convert input type to output type.\n", kInvalidConversion); @@ -449,11 +445,9 @@ SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColo return kSuccess; } -SkCodec::Result SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, - ZeroInitialized zeroInit) { +SkCodec::Result SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts) { const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); - fSwizzler.reset(SkSwizzler::CreateSwizzler(SkSwizzler::kIndex, - colorPtr, dstInfo, zeroInit)); + fSwizzler.reset(SkSwizzler::CreateSwizzler(SkSwizzler::kIndex, colorPtr, dstInfo, opts)); if (nullptr != fSwizzler.get()) { return kSuccess; } @@ -485,7 +479,7 @@ SkCodec::Result SkGifCodec::onGetPixels(const SkImageInfo& dstInfo, // Initialize the swizzler if (fFrameIsSubset) { const SkImageInfo subsetDstInfo = dstInfo.makeWH(fFrameRect.width(), fFrameRect.height()); - if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts.fZeroInitialized)) { + if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts)) { return gif_error("Could not initialize swizzler.\n", kUnimplemented); } @@ -499,7 +493,7 @@ SkCodec::Result SkGifCodec::onGetPixels(const SkImageInfo& dstInfo, dst = SkTAddOffset<void*>(dst, dstRowBytes * fFrameRect.top() + dstBytesPerPixel * fFrameRect.left()); } else { - if (kSuccess != this->initializeSwizzler(dstInfo, opts.fZeroInitialized)) { + if (kSuccess != this->initializeSwizzler(dstInfo, opts)) { return gif_error("Could not initialize swizzler.\n", kUnimplemented); } } @@ -535,11 +529,11 @@ SkCodec::Result SkGifCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, // Initialize the swizzler if (fFrameIsSubset) { const SkImageInfo subsetDstInfo = dstInfo.makeWH(fFrameRect.width(), fFrameRect.height()); - if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts.fZeroInitialized)) { + if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts)) { return gif_error("Could not initialize swizzler.\n", kUnimplemented); } } else { - if (kSuccess != this->initializeSwizzler(dstInfo, opts.fZeroInitialized)) { + if (kSuccess != this->initializeSwizzler(dstInfo, opts)) { return gif_error("Could not initialize swizzler.\n", kUnimplemented); } } diff --git a/src/codec/SkCodec_libgif.h b/src/codec/SkCodec_libgif.h index 10fdac97f9..2e0c5a4a1d 100644 --- a/src/codec/SkCodec_libgif.h +++ b/src/codec/SkCodec_libgif.h @@ -129,9 +129,11 @@ private: * @param dstInfo Output image information. Dimensions may have been * adjusted if the image frame size does not match the size * indicated in the header. - * @param zeroInit Indicates if destination memory is zero initialized. + * @param options Informs the swizzler if destination memory is zero initialized. + * Contains subset information. */ - Result initializeSwizzler(const SkImageInfo& dstInfo, ZeroInitialized zeroInit); + Result initializeSwizzler(const SkImageInfo& dstInfo, + const Options& options); SkSampler* getSampler(bool createIfNecessary) override { SkASSERT(fSwizzler); diff --git a/src/codec/SkCodec_libpng.cpp b/src/codec/SkCodec_libpng.cpp index e828e24999..7d41623a88 100644 --- a/src/codec/SkCodec_libpng.cpp +++ b/src/codec/SkCodec_libpng.cpp @@ -435,8 +435,7 @@ SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, // Create the swizzler. SkPngCodec retains ownership of the color table. const SkPMColor* colors = get_color_ptr(fColorTable.get()); - fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo, - options.fZeroInitialized)); + fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo, options)); if (!fSwizzler) { // FIXME: CreateSwizzler could fail for another reason. return kUnimplemented; @@ -477,8 +476,7 @@ SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void* } // Note that ctable and ctableCount may be modified if there is a color table - const Result result = this->initializeSwizzler(requestedInfo, options, - ctable, ctableCount); + const Result result = this->initializeSwizzler(requestedInfo, options, ctable, ctableCount); if (result != kSuccess) { return result; } @@ -699,15 +697,14 @@ public: } Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options, - SkPMColor ctable[], int* ctableCount) override - { + SkPMColor ctable[], int* ctableCount) override { if (!conversion_possible(dstInfo, this->getInfo())) { return kInvalidConversion; } - const SkCodec::Result result = this->initializeSwizzler(dstInfo, options, ctable, - ctableCount); - if (result != SkCodec::kSuccess) { + const Result result = this->initializeSwizzler(dstInfo, options, ctable, + ctableCount); + if (result != kSuccess) { return result; } diff --git a/src/codec/SkCodec_libpng.h b/src/codec/SkCodec_libpng.h index 6bdf58065b..f003cbd4e0 100644 --- a/src/codec/SkCodec_libpng.h +++ b/src/codec/SkCodec_libpng.h @@ -18,7 +18,6 @@ #endif #include "png.h" -class SkScanlineDecoder; class SkStream; class SkPngCodec : public SkCodec { @@ -27,7 +26,6 @@ public: // Assume IsPng was called and returned true. static SkCodec* NewFromStream(SkStream*); - static SkScanlineDecoder* NewSDFromStream(SkStream*); virtual ~SkPngCodec(); @@ -78,7 +76,6 @@ private: SkSwizzler::SrcConfig fSrcConfig; const int fNumberPasses; int fBitDepth; - AlphaState fAlphaState; bool decodePalette(bool premultiply, int* ctableCount); diff --git a/src/codec/SkCodec_wbmp.cpp b/src/codec/SkCodec_wbmp.cpp index 14b720988f..19ae4eaf0e 100644 --- a/src/codec/SkCodec_wbmp.cpp +++ b/src/codec/SkCodec_wbmp.cpp @@ -70,8 +70,8 @@ bool SkWbmpCodec::onRewind() { return read_header(this->stream(), nullptr); } -SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info, - const SkPMColor* ctable, const Options& opts) { +SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info, const SkPMColor* ctable, + const Options& opts) { // Create the swizzler based on the desired color type switch (info.colorType()) { case kIndex_8_SkColorType: @@ -82,8 +82,7 @@ SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info, default: return nullptr; } - return SkSwizzler::CreateSwizzler(SkSwizzler::kBit, ctable, info, - opts.fZeroInitialized); + return SkSwizzler::CreateSwizzler(SkSwizzler::kBit, ctable, info, opts); } bool SkWbmpCodec::readRow(uint8_t* row) { @@ -188,8 +187,7 @@ SkCodec::Result SkWbmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, } // Initialize the swizzler - fSwizzler.reset(this->initializeSwizzler(dstInfo, - get_color_ptr(fColorTable.get()), options)); + fSwizzler.reset(this->initializeSwizzler(dstInfo, get_color_ptr(fColorTable.get()), options)); if (nullptr == fSwizzler.get()) { return kInvalidConversion; } diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp index 196543b682..d0d11b1a08 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -177,19 +177,19 @@ SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const { // support these as well unsigned int num; unsigned int denom = 8; - if (desiredScale > 0.875f) { + if (desiredScale >= 0.9375) { 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; @@ -380,15 +380,9 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo, return kSuccess; } -SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) { - if (!createIfNecessary || fSwizzler) { - SkASSERT(!fSwizzler || (fSrcRow && static_cast<uint8_t*>(fStorage.get()) == fSrcRow)); - return fSwizzler; - } - - const SkImageInfo& info = this->dstInfo(); +void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options) { SkSwizzler::SrcConfig srcConfig; - switch (info.colorType()) { + switch (dstInfo.colorType()) { case kGray_8_SkColorType: srcConfig = SkSwizzler::kGray; break; @@ -406,14 +400,18 @@ SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) { SkASSERT(false); } - fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, info, - this->options().fZeroInitialized)); - if (!fSwizzler) { - return nullptr; - } - + fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, dstInfo, options)); fStorage.reset(get_row_bytes(fDecoderMgr->dinfo())); fSrcRow = static_cast<uint8_t*>(fStorage.get()); +} + +SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) { + if (!createIfNecessary || fSwizzler) { + SkASSERT(!fSwizzler || (fSrcRow && static_cast<uint8_t*>(fStorage.get()) == fSrcRow)); + return fSwizzler; + } + + this->initializeSwizzler(this->dstInfo(), this->options()); return fSwizzler; } @@ -441,6 +439,11 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, return kInvalidInput; } + // We will need a swizzler if we are performing a subset decode + if (options.fSubset) { + this->initializeSwizzler(dstInfo, options); + } + return kSuccess; } @@ -452,7 +455,7 @@ int SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { // Read rows one at a time JSAMPLE* dstRow; if (fSwizzler) { - // write data to storage row, then sample using swizzler + // write data to storage row, then sample using swizzler dstRow = fSrcRow; } else { // write data directly to dst diff --git a/src/codec/SkJpegCodec.h b/src/codec/SkJpegCodec.h index 67680d66e8..687cf4b4b8 100644 --- a/src/codec/SkJpegCodec.h +++ b/src/codec/SkJpegCodec.h @@ -103,9 +103,10 @@ private: bool setOutputColorSpace(const SkImageInfo& dst); // scanline decoding + void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options); SkSampler* getSampler(bool createIfNecessary) override; Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options, - SkPMColor ctable[], int* ctableCount) override; + SkPMColor ctable[], int* ctableCount) override; int onGetScanlines(void* dst, int count, size_t rowBytes) override; bool onSkipScanlines(int count) override; diff --git a/src/codec/SkMaskSwizzler.cpp b/src/codec/SkMaskSwizzler.cpp index 9772d87e38..72dca28057 100644 --- a/src/codec/SkMaskSwizzler.cpp +++ b/src/codec/SkMaskSwizzler.cpp @@ -250,9 +250,9 @@ static SkSwizzler::ResultAlpha swizzle_mask32_to_565( * Create a new mask swizzler * */ -SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( - const SkImageInfo& dstInfo, const SkImageInfo& srcInfo, SkMasks* masks, - uint32_t bitsPerPixel) { +SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo, + const SkImageInfo& srcInfo, SkMasks* masks, uint32_t bitsPerPixel, + const SkCodec::Options& options) { // Choose the appropriate row procedure RowProc proc = nullptr; @@ -352,7 +352,14 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( return nullptr; } - return new SkMaskSwizzler(dstInfo.width(), masks, proc); + int srcOffset = 0; + int srcWidth = dstInfo.width(); + if (options.fSubset) { + srcOffset = options.fSubset->left(); + srcWidth = options.fSubset->width(); + } + + return new SkMaskSwizzler(masks, proc, srcOffset, srcWidth); } /* @@ -360,13 +367,14 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler( * Constructor for mask swizzler * */ -SkMaskSwizzler::SkMaskSwizzler(int width, SkMasks* masks, RowProc proc) +SkMaskSwizzler::SkMaskSwizzler(SkMasks* masks, RowProc proc, int srcOffset, int srcWidth) : fMasks(masks) , fRowProc(proc) - , fSrcWidth(width) - , fDstWidth(width) + , fSrcWidth(srcWidth) + , fDstWidth(srcWidth) , fSampleX(1) - , fX0(0) + , fSrcOffset(srcOffset) + , fX0(srcOffset) {} int SkMaskSwizzler::onSetSampleX(int sampleX) { @@ -374,7 +382,7 @@ int SkMaskSwizzler::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); + fX0 = get_start_coord(sampleX) + fSrcOffset; fDstWidth = get_scaled_dimension(fSrcWidth, sampleX); // check that fX0 is less than original width diff --git a/src/codec/SkMaskSwizzler.h b/src/codec/SkMaskSwizzler.h index 0513d838c7..9aea5d8d70 100644 --- a/src/codec/SkMaskSwizzler.h +++ b/src/codec/SkMaskSwizzler.h @@ -28,7 +28,8 @@ public: static SkMaskSwizzler* CreateMaskSwizzler(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo, SkMasks* masks, - uint32_t bitsPerPixel); + uint32_t bitsPerPixel, + const SkCodec::Options& options); /* * Swizzle a row @@ -49,14 +50,10 @@ private: /* * Row procedure used for swizzle */ - typedef SkSwizzler::ResultAlpha (*RowProc)( - void* dstRow, const uint8_t* srcRow, int width, + typedef SkSwizzler::ResultAlpha (*RowProc)(void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, uint32_t startX, uint32_t sampleX); - /* - * Constructor for mask swizzler - */ - SkMaskSwizzler(int width, SkMasks* masks, RowProc proc); + SkMaskSwizzler(SkMasks* masks, RowProc proc, int srcWidth, int srcOffset); int onSetSampleX(int) override; @@ -67,6 +64,7 @@ private: const int fSrcWidth; // Width of the source - i.e. before any sampling. int fDstWidth; // Width of dst, which may differ with sampling. int fSampleX; + int fSrcOffset; int fX0; }; diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp index 8d13e56bd2..95ed1d7b96 100644 --- a/src/codec/SkSwizzler.cpp +++ b/src/codec/SkSwizzler.cpp @@ -230,9 +230,6 @@ static SkSwizzler::ResultAlpha swizzle_index_to_index( // SkScaledBitmap sampler just guesses that it is opaque. This is dangerous // and probably wrong since gif and bmp (rarely) may have alpha. if (1 == deltaSrc) { - // A non-zero offset is only used when sampling, meaning that deltaSrc will be - // greater than 1. The below loop relies on the fact that src remains unchanged. - SkASSERT(0 == offset); memcpy(dst, src, dstWidth); for (int x = 0; x < dstWidth; x++) { UPDATE_RESULT_ALPHA(ctable[src[x]] >> SK_A32_SHIFT); @@ -514,8 +511,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, - SkCodec::ZeroInitialized zeroInit) { + const SkImageInfo& dstInfo, + const SkCodec::Options& options) { if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) { return nullptr; } @@ -524,7 +521,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, return nullptr; } RowProc proc = nullptr; - + SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized; switch (sc) { case kBit: switch (dstInfo.colorType()) { @@ -683,28 +680,35 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, return nullptr; } - // Store deltaSrc in bytes if it is an even multiple, otherwise use bits - int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc); + // Store bpp in bytes if it is an even multiple, otherwise use bits + int bpp = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc); + + int srcOffset = 0; + int srcWidth = dstInfo.width(); + if (options.fSubset) { + srcOffset = options.fSubset->left(); + srcWidth = options.fSubset->width(); + } - return new SkSwizzler(proc, ctable, deltaSrc, dstInfo.width()); + return new SkSwizzler(proc, ctable, srcOffset, srcWidth, bpp); } -SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, - int deltaSrc, int srcWidth) +SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcOffset, int srcWidth, int bpp) : fRowProc(proc) , fColorTable(ctable) - , fDeltaSrc(deltaSrc) + , fSrcOffset(srcOffset) + , fX0(srcOffset) , fSrcWidth(srcWidth) , fDstWidth(srcWidth) + , fBPP(bpp) , fSampleX(1) - , fX0(0) {} 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); + fX0 = get_start_coord(sampleX) + fSrcOffset; fDstWidth = get_scaled_dimension(fSrcWidth, sampleX); // check that fX0 is less than original width @@ -714,6 +718,5 @@ int SkSwizzler::onSetSampleX(int sampleX) { SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) { SkASSERT(nullptr != dst && nullptr != src); - return fRowProc(dst, src, fDstWidth, fDeltaSrc, fSampleX * fDeltaSrc, - fX0 * fDeltaSrc, fColorTable); + return fRowProc(dst, src, fDstWidth, fBPP, fSampleX * fBPP, fX0 * fBPP, fColorTable); } diff --git a/src/codec/SkSwizzler.h b/src/codec/SkSwizzler.h index d7f6337553..058044e420 100644 --- a/src/codec/SkSwizzler.h +++ b/src/codec/SkSwizzler.h @@ -121,13 +121,14 @@ public: * @param ctable Unowned pointer to an array of up to 256 colors for an * index source. * @param dstInfo Describes the destination. - * @param ZeroInitialized Whether dst is zero-initialized. The + * @param options Indicates if dst is zero-initialized. The * implementation may choose to skip writing zeroes * if set to kYes_ZeroInitialized. + * Contains subset information. * @return A new SkSwizzler or nullptr on failure. */ static SkSwizzler* CreateSwizzler(SrcConfig, const SkPMColor* ctable, - const SkImageInfo& dstInfo, SkCodec::ZeroInitialized); + const SkImageInfo& dstInfo, const SkCodec::Options&); /** * Swizzle a line. Generally this will be called height times, once @@ -173,16 +174,19 @@ private: const RowProc fRowProc; const SkPMColor* fColorTable; // Unowned pointer - const int fDeltaSrc; // if bitsPerPixel % 8 == 0 - // deltaSrc is bytesPerPixel - // else - // deltaSrc is bitsPerPixel + const int fSrcOffset; // Offset of the src in pixels, allows for partial + // scanline decodes. + int fX0; // Start coordinate for the src, may be different than + // fSrcOffset if we are sampling. const int fSrcWidth; // Width of the source - i.e. before any sampling. int fDstWidth; // Width of dst, which may differ with sampling. - int fX0; // first X coord to sample int fSampleX; // step between X samples + const int fBPP; // if bitsPerPixel % 8 == 0 + // fBPP is bytesPerPixel + // else + // fBPP is bitsPerPixel - SkSwizzler(RowProc proc, const SkPMColor* ctable, int deltaSrc, int srcWidth); + SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcOffset, int srcWidth, int bpp); int onSetSampleX(int) override; diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp index a0fab0a153..3c61b93762 100644 --- a/src/codec/SkWebpCodec.cpp +++ b/src/codec/SkWebpCodec.cpp @@ -144,8 +144,8 @@ bool SkWebpCodec::onGetValidSubset(SkIRect* desiredSubset) const { return false; } - SkIRect bounds = SkIRect::MakeSize(this->getInfo().dimensions()); - if (!desiredSubset->intersect(bounds)) { + SkIRect dimensions = SkIRect::MakeSize(this->getInfo().dimensions()); + if (!dimensions.contains(*desiredSubset)) { return false; } |