diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-11-28 23:10:54 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-11-28 23:10:54 +0000 |
commit | 5abe29694a5dbedb06a85774bbec8388bf239430 (patch) | |
tree | c0c0db449af819d3075e537a5d0fd3becbc2baa0 | |
parent | dce5448b87cfd0d3a77231d5699d061cf76f072c (diff) | |
parent | 71550f62d236b32e28ba0a0706638b32eb7f98b1 (diff) | |
download | skia-5abe29694a5dbedb06a85774bbec8388bf239430.tar.gz |
Snap for 5153017 from 71550f62d236b32e28ba0a0706638b32eb7f98b1 to pi-b4s4-release
Change-Id: I8e44487d9d70e17c43b4838c9037ac4ee2fa8e33
-rw-r--r-- | include/android/SkAndroidFrameworkUtils.h | 6 | ||||
-rw-r--r-- | src/android/SkAndroidFrameworkUtils.cpp | 10 | ||||
-rw-r--r-- | src/android/SkBitmapRegionCodec.cpp | 14 | ||||
-rw-r--r-- | src/codec/SkBmpStandardCodec.cpp | 4 | ||||
-rw-r--r-- | src/codec/SkGifCodec.cpp | 4 | ||||
-rw-r--r-- | src/codec/SkHeifCodec.cpp | 10 | ||||
-rw-r--r-- | src/codec/SkJpegCodec.cpp | 34 | ||||
-rw-r--r-- | src/codec/SkJpegDecoderMgr.cpp | 7 | ||||
-rw-r--r-- | src/codec/SkPngCodec.cpp | 105 | ||||
-rw-r--r-- | src/codec/SkRawCodec.cpp | 4 | ||||
-rw-r--r-- | src/codec/SkSampledCodec.cpp | 8 | ||||
-rw-r--r-- | src/codec/SkSwizzler.cpp | 715 | ||||
-rw-r--r-- | src/codec/SkSwizzler.h | 31 | ||||
-rw-r--r-- | src/codec/SkWbmpCodec.cpp | 10 | ||||
-rw-r--r-- | src/codec/SkWbmpCodec.h | 5 |
15 files changed, 510 insertions, 457 deletions
diff --git a/include/android/SkAndroidFrameworkUtils.h b/include/android/SkAndroidFrameworkUtils.h index 0457d03534..46d251626e 100644 --- a/include/android/SkAndroidFrameworkUtils.h +++ b/include/android/SkAndroidFrameworkUtils.h @@ -10,7 +10,7 @@ #include "SkTypes.h" -#ifdef SK_BUILD_FOR_ANDROID +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK class SkCanvas; @@ -31,8 +31,10 @@ public: */ static bool clipWithStencil(SkCanvas* canvas); #endif //SK_SUPPORT_GPU + + static void SafetyNetLog(const char*); }; -#endif // SK_BUILD_FOR_ANDROID +#endif // SK_BUILD_FOR_ANDROID_FRAMEWORK #endif // SkAndroidFrameworkUtils_DEFINED diff --git a/src/android/SkAndroidFrameworkUtils.cpp b/src/android/SkAndroidFrameworkUtils.cpp index 5fbc2cae18..f0a7b8a2fc 100644 --- a/src/android/SkAndroidFrameworkUtils.cpp +++ b/src/android/SkAndroidFrameworkUtils.cpp @@ -17,7 +17,9 @@ #include "effects/GrDisableColorXP.h" #endif //SK_SUPPORT_GPU -#ifdef SK_BUILD_FOR_ANDROID +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + +#include <log/log.h> #if SK_SUPPORT_GPU bool SkAndroidFrameworkUtils::clipWithStencil(SkCanvas* canvas) { @@ -52,5 +54,9 @@ bool SkAndroidFrameworkUtils::clipWithStencil(SkCanvas* canvas) { } #endif //SK_SUPPORT_GPU -#endif // SK_BUILD_FOR_ANDROID +void SkAndroidFrameworkUtils::SafetyNetLog(const char* bugNumber) { + android_errorWriteLog(0x534e4554, bugNumber); +} + +#endif // SK_BUILD_FOR_ANDROID_FRAMEWORK diff --git a/src/android/SkBitmapRegionCodec.cpp b/src/android/SkBitmapRegionCodec.cpp index 6b17a9015d..682c70526a 100644 --- a/src/android/SkBitmapRegionCodec.cpp +++ b/src/android/SkBitmapRegionCodec.cpp @@ -106,10 +106,14 @@ bool SkBitmapRegionCodec::decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocat SkCodec::Result result = fCodec->getAndroidPixels(decodeInfo, dst, bitmap->rowBytes(), &options); - if (SkCodec::kSuccess != result && SkCodec::kIncompleteInput != result) { - SkCodecPrintf("Error: Could not get pixels.\n"); - return false; + switch (result) { + case SkCodec::kSuccess: + case SkCodec::kIncompleteInput: + case SkCodec::kErrorInInput: + return true; + default: + SkCodecPrintf("Error: Could not get pixels with message \"%s\".\n", + SkCodec::ResultToString(result)); + return false; } - - return true; } diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp index 0ddcbb529a..100dc784f0 100644 --- a/src/codec/SkBmpStandardCodec.cpp +++ b/src/codec/SkBmpStandardCodec.cpp @@ -175,9 +175,7 @@ void SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Op swizzlerOptions.fZeroInitialized = kNo_ZeroInitialized; } - - fSwizzler.reset(SkSwizzler::CreateSwizzler(encodedInfo, colorPtr, swizzlerInfo, - swizzlerOptions)); + fSwizzler = SkSwizzler::Make(encodedInfo, colorPtr, swizzlerInfo, swizzlerOptions); SkASSERT(fSwizzler); } diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp index dbff9287eb..6afb670f76 100644 --- a/src/codec/SkGifCodec.cpp +++ b/src/codec/SkGifCodec.cpp @@ -265,8 +265,8 @@ void SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, int frameIndex) // - the swizzler does not need to know about the frame. // We may not be able to use the real Options anyway, since getPixels does not store it (due to // a bug). - fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), - fCurrColorTable->readColors(), swizzlerInfo, Options(), &swizzleRect)); + fSwizzler = SkSwizzler::Make(this->getEncodedInfo(), fCurrColorTable->readColors(), + swizzlerInfo, Options(), &swizzleRect); SkASSERT(fSwizzler.get()); } diff --git a/src/codec/SkHeifCodec.cpp b/src/codec/SkHeifCodec.cpp index 6e82904115..c7b5f307ad 100644 --- a/src/codec/SkHeifCodec.cpp +++ b/src/codec/SkHeifCodec.cpp @@ -317,16 +317,18 @@ void SkHeifCodec::allocateStorage(const SkImageInfo& dstInfo) { void SkHeifCodec::initializeSwizzler( const SkImageInfo& dstInfo, const Options& options) { - SkEncodedInfo swizzlerInfo = this->getEncodedInfo(); - SkImageInfo swizzlerDstInfo = dstInfo; if (this->colorXform()) { // The color xform will be expecting RGBA 8888 input. swizzlerDstInfo = swizzlerDstInfo.makeColorType(kRGBA_8888_SkColorType); } - fSwizzler.reset(SkSwizzler::CreateSwizzler(swizzlerInfo, nullptr, - swizzlerDstInfo, options, nullptr, true)); + int srcBPP = 4; + if (dstInfo.colorType() == kRGB_565_SkColorType && !this->colorXform()) { + srcBPP = 2; + } + + fSwizzler = SkSwizzler::MakeSimple(srcBPP, swizzlerDstInfo, options); SkASSERT(fSwizzler); } diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp index 4f48886be2..0719472405 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -645,13 +645,6 @@ void SkJpegCodec::allocateStorage(const SkImageInfo& dstInfo) { void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options, bool needsCMYKToRGB) { - SkEncodedInfo swizzlerInfo = this->getEncodedInfo(); - if (needsCMYKToRGB) { - swizzlerInfo = SkEncodedInfo::Make(SkEncodedInfo::kInvertedCMYK_Color, - swizzlerInfo.alpha(), - swizzlerInfo.bitsPerComponent()); - } - Options swizzlerOptions = options; if (options.fSubset) { // Use fSwizzlerSubset if this is a subset decode. This is necessary in the case @@ -668,8 +661,31 @@ void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& swizzlerDstInfo = swizzlerDstInfo.makeColorType(kRGBA_8888_SkColorType); } - fSwizzler.reset(SkSwizzler::CreateSwizzler(swizzlerInfo, nullptr, swizzlerDstInfo, - swizzlerOptions, nullptr, !needsCMYKToRGB)); + if (needsCMYKToRGB) { + // The swizzler is used to convert to from CMYK. + auto swizzlerInfo = SkEncodedInfo::Make(SkEncodedInfo::kInvertedCMYK_Color, + SkEncodedInfo::kOpaque_Alpha, 8); + fSwizzler = SkSwizzler::Make(swizzlerInfo, nullptr, swizzlerDstInfo, swizzlerOptions); + } else { + int srcBPP = 0; + switch (fDecoderMgr->dinfo()->out_color_space) { + case JCS_EXT_RGBA: + case JCS_EXT_BGRA: + case JCS_CMYK: + srcBPP = 4; + break; + case JCS_RGB565: + srcBPP = 2; + break; + case JCS_GRAYSCALE: + srcBPP = 1; + break; + default: + SkASSERT(false); + break; + } + fSwizzler = SkSwizzler::MakeSimple(srcBPP, swizzlerDstInfo, swizzlerOptions); + } SkASSERT(fSwizzler); } diff --git a/src/codec/SkJpegDecoderMgr.cpp b/src/codec/SkJpegDecoderMgr.cpp index e8a31f94e6..0c2db528f1 100644 --- a/src/codec/SkJpegDecoderMgr.cpp +++ b/src/codec/SkJpegDecoderMgr.cpp @@ -9,6 +9,10 @@ #include "SkJpegUtility.h" +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + #include "SkAndroidFrameworkUtils.h" +#endif + /* * Print information, warning, and error messages */ @@ -55,6 +59,9 @@ bool JpegDecoderMgr::getEncodedColor(SkEncodedInfo::Color* outColor) { *outColor = SkEncodedInfo::kYUV_Color; return true; case JCS_RGB: +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + SkAndroidFrameworkUtils::SafetyNetLog("118372692"); +#endif *outColor = SkEncodedInfo::kRGB_Color; return true; case JCS_YCCK: diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp index 31a407c670..ebfe745f21 100644 --- a/src/codec/SkPngCodec.cpp +++ b/src/codec/SkPngCodec.cpp @@ -25,6 +25,10 @@ #include "png.h" #include <algorithm> +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + #include "SkAndroidFrameworkUtils.h" +#endif + // This warning triggers false postives way too often in here. #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic ignored "-Wclobbered" @@ -481,6 +485,14 @@ void SkPngCodec::applyXformRow(void* dst, const void* src) { } } +static SkCodec::Result log_and_return_error(bool success) { + if (success) return SkCodec::kIncompleteInput; +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + SkAndroidFrameworkUtils::SafetyNetLog("117838472"); +#endif + return SkCodec::kErrorInInput; +} + class SkPngNormalDecoder : public SkPngCodec { public: SkPngNormalDecoder(const SkEncodedInfo& info, const SkImageInfo& imageInfo, @@ -528,19 +540,16 @@ private: fFirstRow = 0; fLastRow = height - 1; - if (!this->processData()) { - return kErrorInInput; - } - - if (fRowsWrittenToOutput == height) { - return SkCodec::kSuccess; + const bool success = this->processData(); + if (success && fRowsWrittenToOutput == height) { + return kSuccess; } if (rowsDecoded) { *rowsDecoded = fRowsWrittenToOutput; } - return SkCodec::kIncompleteInput; + return log_and_return_error(success); } void allRowsCallback(png_bytep row, int rowNum) { @@ -560,25 +569,22 @@ private: fRowsNeeded = fLastRow - fFirstRow + 1; } - SkCodec::Result decode(int* rowsDecoded) override { + Result decode(int* rowsDecoded) override { if (this->swizzler()) { const int sampleY = this->swizzler()->sampleY(); fRowsNeeded = get_scaled_dimension(fLastRow - fFirstRow + 1, sampleY); } - if (!this->processData()) { - return kErrorInInput; - } - - if (fRowsWrittenToOutput == fRowsNeeded) { - return SkCodec::kSuccess; + const bool success = this->processData(); + if (success && fRowsWrittenToOutput == fRowsNeeded) { + return kSuccess; } if (rowsDecoded) { *rowsDecoded = fRowsWrittenToOutput; } - return SkCodec::kIncompleteInput; + return log_and_return_error(success); } void rowCallback(png_bytep row, int rowNum) { @@ -670,7 +676,7 @@ private: } } - SkCodec::Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) override { + Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) override { const int height = this->getInfo().height(); this->setUpInterlaceBuffer(height); png_set_progressive_read_fn(this->png_ptr(), this, nullptr, InterlacedRowCallback, @@ -680,10 +686,7 @@ private: fLastRow = height - 1; fLinesDecoded = 0; - if (!this->processData()) { - return kErrorInInput; - } - + const bool success = this->processData(); png_bytep srcRow = fInterlaceBuffer.get(); // FIXME: When resuming, this may rewrite rows that did not change. for (int rowNum = 0; rowNum < fLinesDecoded; rowNum++) { @@ -691,15 +694,15 @@ private: dst = SkTAddOffset<void>(dst, rowBytes); srcRow = SkTAddOffset<png_byte>(srcRow, fPng_rowbytes); } - if (fInterlacedComplete) { - return SkCodec::kSuccess; + if (success && fInterlacedComplete) { + return kSuccess; } if (rowsDecoded) { *rowsDecoded = fLinesDecoded; } - return SkCodec::kIncompleteInput; + return log_and_return_error(success); } void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) override { @@ -713,45 +716,45 @@ private: fLinesDecoded = 0; } - SkCodec::Result decode(int* rowsDecoded) override { - if (this->processData() == false) { - return kErrorInInput; - } + Result decode(int* rowsDecoded) override { + const bool success = this->processData(); // Now apply Xforms on all the rows that were decoded. if (!fLinesDecoded) { if (rowsDecoded) { *rowsDecoded = 0; } - return SkCodec::kIncompleteInput; + return log_and_return_error(success); } const int sampleY = this->swizzler() ? this->swizzler()->sampleY() : 1; const int rowsNeeded = get_scaled_dimension(fLastRow - fFirstRow + 1, sampleY); - int rowsWrittenToOutput = 0; // FIXME: For resuming interlace, we may swizzle a row that hasn't changed. But it // may be too tricky/expensive to handle that correctly. // Offset srcRow by get_start_coord rows. We do not need to account for fFirstRow, // since the first row in fInterlaceBuffer corresponds to fFirstRow. - png_bytep srcRow = SkTAddOffset<png_byte>(fInterlaceBuffer.get(), - fPng_rowbytes * get_start_coord(sampleY)); + int srcRow = get_start_coord(sampleY); void* dst = fDst; - for (; rowsWrittenToOutput < rowsNeeded; rowsWrittenToOutput++) { - this->applyXformRow(dst, srcRow); + int rowsWrittenToOutput = 0; + while (rowsWrittenToOutput < rowsNeeded && srcRow < fLinesDecoded) { + png_bytep src = SkTAddOffset<png_byte>(fInterlaceBuffer.get(), fPng_rowbytes * srcRow); + this->applyXformRow(dst, src); dst = SkTAddOffset<void>(dst, fRowBytes); - srcRow = SkTAddOffset<png_byte>(srcRow, fPng_rowbytes * sampleY); + + rowsWrittenToOutput++; + srcRow += sampleY; } - if (fInterlacedComplete) { - return SkCodec::kSuccess; + if (success && fInterlacedComplete) { + return kSuccess; } if (rowsDecoded) { *rowsDecoded = rowsWrittenToOutput; } - return SkCodec::kIncompleteInput; + return log_and_return_error(success); } void setUpInterlaceBuffer(int height) { @@ -1080,9 +1083,31 @@ void SkPngCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& o swizzlerOptions.fZeroInitialized = kNo_ZeroInitialized; } - const SkPMColor* colors = get_color_ptr(fColorTable.get()); - fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), colors, swizzlerInfo, - swizzlerOptions, nullptr, skipFormatConversion)); + if (skipFormatConversion) { + // We cannot skip format conversion when there is a color table. + SkASSERT(!fColorTable); + int srcBPP = 0; + switch (this->getEncodedInfo().color()) { + case SkEncodedInfo::kRGB_Color: + SkASSERT(this->getEncodedInfo().bitsPerComponent() == 16); + srcBPP = 6; + break; + case SkEncodedInfo::kRGBA_Color: + srcBPP = this->getEncodedInfo().bitsPerComponent() / 2; + break; + case SkEncodedInfo::kGray_Color: + srcBPP = 1; + break; + default: + SkASSERT(false); + break; + } + fSwizzler = SkSwizzler::MakeSimple(srcBPP, swizzlerInfo, swizzlerOptions); + } else { + const SkPMColor* colors = get_color_ptr(fColorTable.get()); + fSwizzler = SkSwizzler::Make(this->getEncodedInfo(), colors, swizzlerInfo, + swizzlerOptions); + } SkASSERT(fSwizzler); } diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp index 9eea78cf4b..e3f3557ae4 100644 --- a/src/codec/SkRawCodec.cpp +++ b/src/codec/SkRawCodec.cpp @@ -700,8 +700,8 @@ SkCodec::Result SkRawCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, xformBuffer.reset(new uint32_t[dstInfo.width()]); } - std::unique_ptr<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler( - this->getEncodedInfo(), nullptr, swizzlerInfo, options)); + std::unique_ptr<SkSwizzler> swizzler = SkSwizzler::Make( + this->getEncodedInfo(), nullptr, swizzlerInfo, options); SkASSERT(swizzler); const int width = dstInfo.width(); diff --git a/src/codec/SkSampledCodec.cpp b/src/codec/SkSampledCodec.cpp index ac0539fc74..2282d6beb4 100644 --- a/src/codec/SkSampledCodec.cpp +++ b/src/codec/SkSampledCodec.cpp @@ -113,17 +113,17 @@ SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void const SkCodec::Result startResult = this->codec()->startIncrementalDecode( scaledInfo, pixels, rowBytes, &codecOptions); if (SkCodec::kSuccess == startResult) { - int rowsDecoded; + int rowsDecoded = 0; const SkCodec::Result incResult = this->codec()->incrementalDecode(&rowsDecoded); if (incResult == SkCodec::kSuccess) { return SkCodec::kSuccess; } - SkASSERT(SkCodec::kIncompleteInput == incResult); + SkASSERT(incResult == SkCodec::kIncompleteInput || incResult == SkCodec::kErrorInInput); // FIXME: Can zero initialized be read from SkCodec::fOptions? this->codec()->fillIncompleteImage(scaledInfo, pixels, rowBytes, options.fZeroInitialized, scaledSubsetHeight, rowsDecoded); - return SkCodec::kIncompleteInput; + return incResult; } else if (startResult != SkCodec::kUnimplemented) { return startResult; } @@ -244,7 +244,7 @@ SkCodec::Result SkSampledCodec::sampledDecode(const SkImageInfo& info, void* pix sampler->setSampleY(sampleY); - int rowsDecoded; + int rowsDecoded = 0; const SkCodec::Result incResult = this->codec()->incrementalDecode(&rowsDecoded); if (incResult == SkCodec::kSuccess) { return SkCodec::kSuccess; diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp index 4b350c4ec4..ca82586c60 100644 --- a/src/codec/SkSwizzler.cpp +++ b/src/codec/SkSwizzler.cpp @@ -12,6 +12,10 @@ #include "SkSwizzler.h" #include "SkTemplates.h" +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + #include "SkAndroidFrameworkUtils.h" +#endif + static void copy(void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { // This function must not be called if we are sampling. If we are not @@ -773,396 +777,371 @@ void SkSwizzler::SkipLeading8888ZerosThen( proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable); } -SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, - const SkPMColor* ctable, - const SkImageInfo& dstInfo, - const SkCodec::Options& options, - const SkIRect* frame, - bool skipFormatConversion) { +std::unique_ptr<SkSwizzler> SkSwizzler::MakeSimple(int srcBPP, const SkImageInfo& dstInfo, + const SkCodec::Options& options) { + RowProc proc = nullptr; + switch (srcBPP) { + case 1: // kGray_8_SkColorType + proc = &sample1; + break; + case 2: // kRGB_565_SkColorType + proc = &sample2; + break; + case 4: // kRGBA_8888_SkColorType + // kBGRA_8888_SkColorType + proc = &sample4; + break; + case 6: // 16 bit PNG no alpha + proc = &sample6; + break; + case 8: // 16 bit PNG with alpha + proc = &sample8; + break; + default: + return nullptr; + } + + return Make(dstInfo, ©, proc, nullptr /*ctable*/, srcBPP, + dstInfo.bytesPerPixel(), options, nullptr /*frame*/); +} + +std::unique_ptr<SkSwizzler> SkSwizzler::Make(const SkEncodedInfo& encodedInfo, + const SkPMColor* ctable, + const SkImageInfo& dstInfo, + const SkCodec::Options& options, + const SkIRect* frame) { if (SkEncodedInfo::kPalette_Color == encodedInfo.color() && nullptr == ctable) { return nullptr; } RowProc fastProc = nullptr; RowProc proc = nullptr; - int srcBPP; - const int dstBPP = dstInfo.bytesPerPixel(); - if (skipFormatConversion) { - switch (encodedInfo.color()) { - case SkEncodedInfo::kGray_Color: - case SkEncodedInfo::kYUV_Color: - // We have a jpeg that has already been converted to the dstColorType. - srcBPP = dstBPP; - switch (dstInfo.colorType()) { - case kGray_8_SkColorType: - proc = &sample1; - fastProc = © - break; - case kRGB_565_SkColorType: - proc = &sample2; - fastProc = © - break; - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: - proc = &sample4; - fastProc = © - break; - default: - return nullptr; - } - break; - case SkEncodedInfo::kInvertedCMYK_Color: - case SkEncodedInfo::kYCCK_Color: - // We have a jpeg that remains in its original format. - srcBPP = 4; - proc = &sample4; - fastProc = © - break; - case SkEncodedInfo::kRGBA_Color: - // We have a png that should remain in its original format. - SkASSERT(16 == encodedInfo.bitsPerComponent() || - 8 == encodedInfo.bitsPerComponent()); - if (8 == encodedInfo.bitsPerComponent()) { - srcBPP = 4; - proc = &sample4; - } else { - srcBPP = 8; - proc = &sample8; - } - fastProc = © - break; - case SkEncodedInfo::kRGB_Color: - // We have a png that remains in its original format. - SkASSERT(16 == encodedInfo.bitsPerComponent()); - srcBPP = 6; - proc = &sample6; - fastProc = © - break; - default: - return nullptr; - } - } else { - SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized; - const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) && - (kPremul_SkAlphaType == dstInfo.alphaType()); - - switch (encodedInfo.color()) { - case SkEncodedInfo::kGray_Color: - switch (encodedInfo.bitsPerComponent()) { - case 1: - switch (dstInfo.colorType()) { - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: - proc = &swizzle_bit_to_n32; - break; - case kRGB_565_SkColorType: - proc = &swizzle_bit_to_565; - break; - case kGray_8_SkColorType: - proc = &swizzle_bit_to_grayscale; - break; - case kRGBA_F16_SkColorType: - proc = &swizzle_bit_to_f16; - break; - default: - return nullptr; - } - break; - case 8: - switch (dstInfo.colorType()) { - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: - proc = &swizzle_gray_to_n32; - fastProc = &fast_swizzle_gray_to_n32; - break; - case kGray_8_SkColorType: - proc = &sample1; - fastProc = © - break; - case kRGB_565_SkColorType: - proc = &swizzle_gray_to_565; - break; - default: - return nullptr; + SkCodec::ZeroInitialized zeroInit = options.fZeroInitialized; + const bool premultiply = (SkEncodedInfo::kOpaque_Alpha != encodedInfo.alpha()) && + (kPremul_SkAlphaType == dstInfo.alphaType()); + + switch (encodedInfo.color()) { + case SkEncodedInfo::kGray_Color: + switch (encodedInfo.bitsPerComponent()) { + case 1: + switch (dstInfo.colorType()) { + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: + proc = &swizzle_bit_to_n32; + break; + case kRGB_565_SkColorType: + proc = &swizzle_bit_to_565; + break; + case kGray_8_SkColorType: + proc = &swizzle_bit_to_grayscale; + break; + case kRGBA_F16_SkColorType: + proc = &swizzle_bit_to_f16; + break; + default: + return nullptr; + } + break; + case 8: + switch (dstInfo.colorType()) { + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: + proc = &swizzle_gray_to_n32; + fastProc = &fast_swizzle_gray_to_n32; + break; + case kGray_8_SkColorType: + proc = &sample1; + fastProc = © + break; + case kRGB_565_SkColorType: + proc = &swizzle_gray_to_565; + break; + default: + return nullptr; + } + break; + default: + return nullptr; + } + break; + case SkEncodedInfo::kGrayAlpha_Color: + switch (dstInfo.colorType()) { + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: + if (premultiply) { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeadingGrayAlphaZerosThen + <swizzle_grayalpha_to_n32_premul>; + fastProc = &SkipLeadingGrayAlphaZerosThen + <fast_swizzle_grayalpha_to_n32_premul>; + } else { + proc = &swizzle_grayalpha_to_n32_premul; + fastProc = &fast_swizzle_grayalpha_to_n32_premul; } - break; - default: - return nullptr; - } - break; - case SkEncodedInfo::kGrayAlpha_Color: - switch (dstInfo.colorType()) { - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: - if (premultiply) { - if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeadingGrayAlphaZerosThen - <swizzle_grayalpha_to_n32_premul>; - fastProc = &SkipLeadingGrayAlphaZerosThen - <fast_swizzle_grayalpha_to_n32_premul>; - } else { - proc = &swizzle_grayalpha_to_n32_premul; - fastProc = &fast_swizzle_grayalpha_to_n32_premul; - } + } else { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeadingGrayAlphaZerosThen + <swizzle_grayalpha_to_n32_unpremul>; + fastProc = &SkipLeadingGrayAlphaZerosThen + <fast_swizzle_grayalpha_to_n32_unpremul>; } else { + proc = &swizzle_grayalpha_to_n32_unpremul; + fastProc = &fast_swizzle_grayalpha_to_n32_unpremul; + } + } + break; + case kAlpha_8_SkColorType: + proc = &swizzle_grayalpha_to_a8; + break; + default: + return nullptr; + } + break; + case SkEncodedInfo::kPalette_Color: + // We assume that the color table is premultiplied and swizzled + // as desired. + switch (encodedInfo.bitsPerComponent()) { + case 1: + case 2: + case 4: + switch (dstInfo.colorType()) { + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: + proc = &swizzle_small_index_to_n32; + break; + case kRGB_565_SkColorType: + proc = &swizzle_small_index_to_565; + break; + default: + return nullptr; + } + break; + case 8: + switch (dstInfo.colorType()) { + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeadingGrayAlphaZerosThen - <swizzle_grayalpha_to_n32_unpremul>; - fastProc = &SkipLeadingGrayAlphaZerosThen - <fast_swizzle_grayalpha_to_n32_unpremul>; + proc = &swizzle_index_to_n32_skipZ; } else { - proc = &swizzle_grayalpha_to_n32_unpremul; - fastProc = &fast_swizzle_grayalpha_to_n32_unpremul; + proc = &swizzle_index_to_n32; } - } + break; + case kRGB_565_SkColorType: + proc = &swizzle_index_to_565; + break; + default: + return nullptr; + } + break; + default: + return nullptr; + } + break; + case SkEncodedInfo::kRGB_Color: + switch (dstInfo.colorType()) { + case kRGBA_8888_SkColorType: + if (16 == encodedInfo.bitsPerComponent()) { + proc = &swizzle_rgb16_to_rgba; break; - case kAlpha_8_SkColorType: - proc = &swizzle_grayalpha_to_a8; + } + + SkASSERT(8 == encodedInfo.bitsPerComponent()); + proc = &swizzle_rgb_to_rgba; + fastProc = &fast_swizzle_rgb_to_rgba; + break; + case kBGRA_8888_SkColorType: + if (16 == encodedInfo.bitsPerComponent()) { + proc = &swizzle_rgb16_to_bgra; break; - default: - return nullptr; - } - break; - case SkEncodedInfo::kPalette_Color: - // We assume that the color table is premultiplied and swizzled - // as desired. - switch (encodedInfo.bitsPerComponent()) { - case 1: - case 2: - case 4: - switch (dstInfo.colorType()) { - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: - proc = &swizzle_small_index_to_n32; - break; - case kRGB_565_SkColorType: - proc = &swizzle_small_index_to_565; - break; - default: - return nullptr; - } + } + + SkASSERT(8 == encodedInfo.bitsPerComponent()); + proc = &swizzle_rgb_to_bgra; + fastProc = &fast_swizzle_rgb_to_bgra; + break; + case kRGB_565_SkColorType: + if (16 == encodedInfo.bitsPerComponent()) { + proc = &swizzle_rgb16_to_565; break; - case 8: - switch (dstInfo.colorType()) { - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: - if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &swizzle_index_to_n32_skipZ; - } else { - proc = &swizzle_index_to_n32; - } - break; - case kRGB_565_SkColorType: - proc = &swizzle_index_to_565; - break; - default: - return nullptr; - } + } + + proc = &swizzle_rgb_to_565; + break; + default: + return nullptr; + } + break; + case SkEncodedInfo::kRGBA_Color: + switch (dstInfo.colorType()) { + case kRGBA_8888_SkColorType: + if (16 == encodedInfo.bitsPerComponent()) { + proc = premultiply ? &swizzle_rgba16_to_rgba_premul : + &swizzle_rgba16_to_rgba_unpremul; break; - default: - return nullptr; - } - break; - case SkEncodedInfo::kRGB_Color: - switch (dstInfo.colorType()) { - case kRGBA_8888_SkColorType: - if (16 == encodedInfo.bitsPerComponent()) { - proc = &swizzle_rgb16_to_rgba; - break; - } - - SkASSERT(8 == encodedInfo.bitsPerComponent()); - proc = &swizzle_rgb_to_rgba; - fastProc = &fast_swizzle_rgb_to_rgba; - break; - case kBGRA_8888_SkColorType: - if (16 == encodedInfo.bitsPerComponent()) { - proc = &swizzle_rgb16_to_bgra; - break; + } + + SkASSERT(8 == encodedInfo.bitsPerComponent()); + if (premultiply) { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>; + fastProc = &SkipLeading8888ZerosThen + <fast_swizzle_rgba_to_rgba_premul>; + } else { + proc = &swizzle_rgba_to_rgba_premul; + fastProc = &fast_swizzle_rgba_to_rgba_premul; } - - SkASSERT(8 == encodedInfo.bitsPerComponent()); - proc = &swizzle_rgb_to_bgra; - fastProc = &fast_swizzle_rgb_to_bgra; - break; - case kRGB_565_SkColorType: - if (16 == encodedInfo.bitsPerComponent()) { - proc = &swizzle_rgb16_to_565; - break; + } else { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeading8888ZerosThen<sample4>; + fastProc = &SkipLeading8888ZerosThen<copy>; + } else { + proc = &sample4; + fastProc = © } - - proc = &swizzle_rgb_to_565; + } + break; + case kBGRA_8888_SkColorType: + if (16 == encodedInfo.bitsPerComponent()) { + proc = premultiply ? &swizzle_rgba16_to_bgra_premul : + &swizzle_rgba16_to_bgra_unpremul; break; - default: - return nullptr; - } - break; - case SkEncodedInfo::kRGBA_Color: - switch (dstInfo.colorType()) { - case kRGBA_8888_SkColorType: - if (16 == encodedInfo.bitsPerComponent()) { - proc = premultiply ? &swizzle_rgba16_to_rgba_premul : - &swizzle_rgba16_to_rgba_unpremul; - break; + } + + SkASSERT(8 == encodedInfo.bitsPerComponent()); + if (premultiply) { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>; + fastProc = &SkipLeading8888ZerosThen + <fast_swizzle_rgba_to_bgra_premul>; + } else { + proc = &swizzle_rgba_to_bgra_premul; + fastProc = &fast_swizzle_rgba_to_bgra_premul; } - - SkASSERT(8 == encodedInfo.bitsPerComponent()); - if (premultiply) { - if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>; - fastProc = &SkipLeading8888ZerosThen - <fast_swizzle_rgba_to_rgba_premul>; - } else { - proc = &swizzle_rgba_to_rgba_premul; - fastProc = &fast_swizzle_rgba_to_rgba_premul; - } + } else { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>; + fastProc = &SkipLeading8888ZerosThen + <fast_swizzle_rgba_to_bgra_unpremul>; } else { - if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<sample4>; - fastProc = &SkipLeading8888ZerosThen<copy>; - } else { - proc = &sample4; - fastProc = © - } + proc = &swizzle_rgba_to_bgra_unpremul; + fastProc = &fast_swizzle_rgba_to_bgra_unpremul; } - break; - case kBGRA_8888_SkColorType: - if (16 == encodedInfo.bitsPerComponent()) { - proc = premultiply ? &swizzle_rgba16_to_bgra_premul : - &swizzle_rgba16_to_bgra_unpremul; - break; + } + break; + default: + return nullptr; + } + break; + case SkEncodedInfo::kBGR_Color: + switch (dstInfo.colorType()) { + case kBGRA_8888_SkColorType: + proc = &swizzle_rgb_to_rgba; + fastProc = &fast_swizzle_rgb_to_rgba; + break; + case kRGBA_8888_SkColorType: + proc = &swizzle_rgb_to_bgra; + fastProc = &fast_swizzle_rgb_to_bgra; + break; + case kRGB_565_SkColorType: + proc = &swizzle_bgr_to_565; + break; + default: + return nullptr; + } + break; + case SkEncodedInfo::kBGRX_Color: + switch (dstInfo.colorType()) { + case kBGRA_8888_SkColorType: + proc = &swizzle_rgb_to_rgba; + break; + case kRGBA_8888_SkColorType: + proc = &swizzle_rgb_to_bgra; + break; + case kRGB_565_SkColorType: + proc = &swizzle_bgr_to_565; + break; + default: + return nullptr; + } + break; + case SkEncodedInfo::kBGRA_Color: + switch (dstInfo.colorType()) { + case kBGRA_8888_SkColorType: + if (premultiply) { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>; + fastProc = &SkipLeading8888ZerosThen + <fast_swizzle_rgba_to_rgba_premul>; + } else { + proc = &swizzle_rgba_to_rgba_premul; + fastProc = &fast_swizzle_rgba_to_rgba_premul; } - - SkASSERT(8 == encodedInfo.bitsPerComponent()); - if (premultiply) { - if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>; - fastProc = &SkipLeading8888ZerosThen - <fast_swizzle_rgba_to_bgra_premul>; - } else { - proc = &swizzle_rgba_to_bgra_premul; - fastProc = &fast_swizzle_rgba_to_bgra_premul; - } + } else { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeading8888ZerosThen<sample4>; + fastProc = &SkipLeading8888ZerosThen<copy>; } else { - if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>; - fastProc = &SkipLeading8888ZerosThen - <fast_swizzle_rgba_to_bgra_unpremul>; - } else { - proc = &swizzle_rgba_to_bgra_unpremul; - fastProc = &fast_swizzle_rgba_to_bgra_unpremul; - } + proc = &sample4; + fastProc = © } - break; - default: - return nullptr; - } - break; - case SkEncodedInfo::kBGR_Color: - switch (dstInfo.colorType()) { - case kBGRA_8888_SkColorType: - proc = &swizzle_rgb_to_rgba; - fastProc = &fast_swizzle_rgb_to_rgba; - break; - case kRGBA_8888_SkColorType: - proc = &swizzle_rgb_to_bgra; - fastProc = &fast_swizzle_rgb_to_bgra; - break; - case kRGB_565_SkColorType: - proc = &swizzle_bgr_to_565; - break; - default: - return nullptr; - } - break; - case SkEncodedInfo::kBGRX_Color: - switch (dstInfo.colorType()) { - case kBGRA_8888_SkColorType: - proc = &swizzle_rgb_to_rgba; - break; - case kRGBA_8888_SkColorType: - proc = &swizzle_rgb_to_bgra; - break; - case kRGB_565_SkColorType: - proc = &swizzle_bgr_to_565; - break; - default: - return nullptr; - } - break; - case SkEncodedInfo::kBGRA_Color: - switch (dstInfo.colorType()) { - case kBGRA_8888_SkColorType: - if (premultiply) { - if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>; - fastProc = &SkipLeading8888ZerosThen - <fast_swizzle_rgba_to_rgba_premul>; - } else { - proc = &swizzle_rgba_to_rgba_premul; - fastProc = &fast_swizzle_rgba_to_rgba_premul; - } + } + break; + case kRGBA_8888_SkColorType: + if (premultiply) { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>; + fastProc = &SkipLeading8888ZerosThen + <fast_swizzle_rgba_to_bgra_premul>; } else { - if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<sample4>; - fastProc = &SkipLeading8888ZerosThen<copy>; - } else { - proc = &sample4; - fastProc = © - } + proc = &swizzle_rgba_to_bgra_premul; + fastProc = &fast_swizzle_rgba_to_bgra_premul; } - break; - case kRGBA_8888_SkColorType: - if (premultiply) { - if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>; - fastProc = &SkipLeading8888ZerosThen - <fast_swizzle_rgba_to_bgra_premul>; - } else { - proc = &swizzle_rgba_to_bgra_premul; - fastProc = &fast_swizzle_rgba_to_bgra_premul; - } + } else { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>; + fastProc = &SkipLeading8888ZerosThen + <fast_swizzle_rgba_to_bgra_unpremul>; } else { - if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>; - fastProc = &SkipLeading8888ZerosThen - <fast_swizzle_rgba_to_bgra_unpremul>; - } else { - proc = &swizzle_rgba_to_bgra_unpremul; - fastProc = &fast_swizzle_rgba_to_bgra_unpremul; - } + proc = &swizzle_rgba_to_bgra_unpremul; + fastProc = &fast_swizzle_rgba_to_bgra_unpremul; } - break; - default: - return nullptr; - } - break; - case SkEncodedInfo::kInvertedCMYK_Color: - switch (dstInfo.colorType()) { - case kRGBA_8888_SkColorType: - proc = &swizzle_cmyk_to_rgba; - fastProc = &fast_swizzle_cmyk_to_rgba; - break; - case kBGRA_8888_SkColorType: - proc = &swizzle_cmyk_to_bgra; - fastProc = &fast_swizzle_cmyk_to_bgra; - break; - case kRGB_565_SkColorType: - proc = &swizzle_cmyk_to_565; - break; - default: - return nullptr; - } - break; - default: - return nullptr; - } - - // Store bpp in bytes if it is an even multiple, otherwise use bits - uint8_t bitsPerPixel = encodedInfo.bitsPerPixel(); - srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel; + } + break; + default: + return nullptr; + } + break; + case SkEncodedInfo::kInvertedCMYK_Color: + switch (dstInfo.colorType()) { + case kRGBA_8888_SkColorType: + proc = &swizzle_cmyk_to_rgba; + fastProc = &fast_swizzle_cmyk_to_rgba; + break; + case kBGRA_8888_SkColorType: + proc = &swizzle_cmyk_to_bgra; + fastProc = &fast_swizzle_cmyk_to_bgra; + break; + case kRGB_565_SkColorType: + proc = &swizzle_cmyk_to_565; + break; + default: + return nullptr; + } + break; + default: + return nullptr; } + // Store bpp in bytes if it is an even multiple, otherwise use bits + uint8_t bitsPerPixel = encodedInfo.bitsPerPixel(); + int srcBPP = SkIsAlign8(bitsPerPixel) ? bitsPerPixel / 8 : bitsPerPixel; + int dstBPP = dstInfo.bytesPerPixel(); + return Make(dstInfo, fastProc, proc, ctable, srcBPP, dstBPP, options, frame); +} + +std::unique_ptr<SkSwizzler> SkSwizzler::Make(const SkImageInfo& dstInfo, + RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcBPP, + int dstBPP, const SkCodec::Options& options, const SkIRect* frame) { int srcOffset = 0; int srcWidth = dstInfo.width(); int dstOffset = 0; @@ -1179,8 +1158,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, srcWidth = frame->width(); } - return new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, dstOffset, dstWidth, - srcBPP, dstBPP); + return std::unique_ptr<SkSwizzler>(new SkSwizzler(fastProc, proc, ctable, srcOffset, srcWidth, + dstOffset, dstWidth, srcBPP, dstBPP)); } SkSwizzler::SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset, @@ -1211,6 +1190,18 @@ int SkSwizzler::onSetSampleX(int sampleX) { fSwizzleWidth = get_scaled_dimension(fSrcWidth, sampleX); fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX); + if (fDstOffsetBytes > 0) { + const size_t dstSwizzleBytes = fSwizzleWidth * fDstBPP; + const size_t dstAllocatedBytes = fAllocatedWidth * fDstBPP; + if (fDstOffsetBytes + dstSwizzleBytes > dstAllocatedBytes) { +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + SkAndroidFrameworkUtils::SafetyNetLog("118143775"); +#endif + SkASSERT(dstSwizzleBytes < dstAllocatedBytes); + fDstOffsetBytes = dstAllocatedBytes - dstSwizzleBytes; + } + } + // The optimized swizzler functions do not support sampling. Sampled swizzles // are already fast because they skip pixels. We haven't seen a situation // where speeding up sampling has a significant impact on total decode time. diff --git a/src/codec/SkSwizzler.h b/src/codec/SkSwizzler.h index ebaed7ea33..6eceddaa5a 100644 --- a/src/codec/SkSwizzler.h +++ b/src/codec/SkSwizzler.h @@ -21,14 +21,10 @@ public: * @param ctable Unowned pointer to an array of up to 256 colors for an * index source. * @param dstInfo Describes the destination. - * @param options Indicates if dst is zero-initialized. The - * implementation may choose to skip writing zeroes - * if set to kYes_ZeroInitialized. - * Contains partial scanline information. + * @param options Contains partial scanline information and whether the dst is zero- + * initialized. * @param frame Is non-NULL if the source pixels are part of an image * frame that is a subset of the full image. - * @param skipFormatConversion Indicates that we should skip format conversion. - * The swizzler only needs to sample and/or subset. * * Note that a deeper discussion of partial scanline subsets and image frame * subsets is below. Currently, we do not support both simultaneously. If @@ -36,10 +32,22 @@ public: * * @return A new SkSwizzler or nullptr on failure. */ - static SkSwizzler* CreateSwizzler(const SkEncodedInfo& encodedInfo, const SkPMColor* ctable, - const SkImageInfo& dstInfo, const SkCodec::Options&, - const SkIRect* frame = nullptr, - bool skipFormatConversion = false); + static std::unique_ptr<SkSwizzler> Make(const SkEncodedInfo& encodedInfo, + const SkPMColor* ctable, const SkImageInfo& dstInfo, const SkCodec::Options&, + const SkIRect* frame = nullptr); + + /** + * Create a simplified swizzler that does not need to do format conversion. The swizzler + * only needs to sample and/or subset. + * + * @param srcBPP Bytes per pixel of the source. + * @param dstInfo Describes the destination. + * @param options Contains partial scanline information and whether the dst is zero- + * initialized. + * @return A new SkSwizzler or nullptr on failure. + */ + static std::unique_ptr<SkSwizzler> MakeSimple(int srcBPP, const SkImageInfo& dstInfo, + const SkCodec::Options&); /** * Swizzle a line. Generally this will be called height times, once @@ -209,6 +217,9 @@ private: SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset, int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP); + static std::unique_ptr<SkSwizzler> Make(const SkImageInfo& dstInfo, RowProc fastProc, + RowProc proc, const SkPMColor* ctable, int srcBPP, int dstBPP, + const SkCodec::Options& options, const SkIRect* frame); int onSetSampleX(int) override; diff --git a/src/codec/SkWbmpCodec.cpp b/src/codec/SkWbmpCodec.cpp index d8b10287f6..171ae5271e 100644 --- a/src/codec/SkWbmpCodec.cpp +++ b/src/codec/SkWbmpCodec.cpp @@ -87,10 +87,6 @@ bool SkWbmpCodec::onRewind() { return read_header(this->stream(), nullptr); } -SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info, const Options& opts) { - return SkSwizzler::CreateSwizzler(this->getEncodedInfo(), nullptr, info, opts); -} - bool SkWbmpCodec::readRow(uint8_t* row) { return this->stream()->read(row, fSrcRowBytes) == fSrcRowBytes; } @@ -124,7 +120,8 @@ SkCodec::Result SkWbmpCodec::onGetPixels(const SkImageInfo& info, } // Initialize the swizzler - std::unique_ptr<SkSwizzler> swizzler(this->initializeSwizzler(info, options)); + std::unique_ptr<SkSwizzler> swizzler = SkSwizzler::Make(this->getEncodedInfo(), nullptr, info, + options); SkASSERT(swizzler); // Perform the decode @@ -187,8 +184,7 @@ SkCodec::Result SkWbmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, return kUnimplemented; } - // Initialize the swizzler - fSwizzler.reset(this->initializeSwizzler(dstInfo, options)); + fSwizzler = SkSwizzler::Make(this->getEncodedInfo(), nullptr, dstInfo, options); SkASSERT(fSwizzler); fSrcBuffer.reset(fSrcRowBytes); diff --git a/src/codec/SkWbmpCodec.h b/src/codec/SkWbmpCodec.h index 192189d1ec..7a14c5562f 100644 --- a/src/codec/SkWbmpCodec.h +++ b/src/codec/SkWbmpCodec.h @@ -33,11 +33,6 @@ protected: // No need to Xform; all pixels are either black or white. bool usesColorXform() const override { return false; } private: - /* - * Returns a swizzler on success, nullptr on failure - */ - SkSwizzler* initializeSwizzler(const SkImageInfo& info, - const Options& opts); SkSampler* getSampler(bool createIfNecessary) override { SkASSERT(fSwizzler || !createIfNecessary); return fSwizzler.get(); |