diff options
author | Leon Scroggins III <scroggo@google.com> | 2018-10-24 12:17:22 -0400 |
---|---|---|
committer | JP Sugarbroad <jpsugar@google.com> | 2018-12-06 00:20:21 -0800 |
commit | a923def974a6e2d3dfde53be8a9a7cf50a2697d7 (patch) | |
tree | 65649b8d7a84d8a24f3d908acf17dfcc7863b6a9 | |
parent | 5fe3f0317be161559361b627af628993384a9e0b (diff) | |
download | skia-oreo-security-release.tar.gz |
RESTRICT AUTOMERGE: Fix bug decoding JCS_RGB jpeg filesandroid-security-8.0.0_r54android-security-8.0.0_r53android-security-8.0.0_r52android-8.0.0_r51android-8.0.0_r50android-8.0.0_r49android-8.0.0_r48android-8.0.0_r47android-8.0.0_r46android-8.0.0_r45android-8.0.0_r44android-8.0.0_r43android-8.0.0_r42android-8.0.0_r41android-8.0.0_r40android-8.0.0_r39android-8.0.0_r38android-8.0.0_r37security-oc-releaseoreo-security-release
Bug: 118372692
Test: I90586f1518fdc501608f28f33c6d90d145922560
Cherry-picked from
https://skia-review.googlesource.com/c/164619
Remove conflicting changes in infra. Resolved conflicts in:
- src/codec/SkHeifCodec.cpp
- src/codec/SkJpegCodec.cpp
- src/codec/SkSwizzler.cpp
Use old version of SkEncodedInfo::Make
Remove references to SkEncodedInfo::kXAlpha_Color and ::k565_Color
which are unused by Android.
Also include SafetyNet logging from
https://skia-review.googlesource.com/c/skia/+/171222.
Original message follows:
Bug: chromium:897031
Bug: chromium:896776
Prior to this fix, we would treat the output from such a JPEG
as if it were a 16 bit per component RGB PNG. We hit an assert
in debug, but in release mode we do the wrong thing.
Split up SkSwizzler::CreateSwizzler into two public factories
(and a private one) based on whether format conversion is desired.
Without format conversion, we may have already converted (as is
the case with this JPEG), so the SkEncodedInfo::Color is not relevant.
That flavor of the factory just needs to know the bytes per pixel,
so provide that info instead.
Add a test file to Google Storage: apron.jpg, from Chromium's
benchmark files.
Conflicts:
- src/codec/SkHeifCodec.cpp
- Does not exist here
- TODO: Cherry-pick separately to oc-mr1-dev
- src/codec/SkSwizzler.cpp
- src/codec/SkWbmpCodec.cpp
- src/codec/SkWbmpCodec.h
- conflicts due to removing kIndex8 in P
Change-Id: If1a35947d48c0139d6e93e420309725b79c4163a
Merged-In: Idc55ecb1be7ba53455ca60bbca30477eb321a702
(cherry picked from commit a65763e69aed2d97ca80f8e2fc30c168f055c0c2)
-rw-r--r-- | src/codec/SkBmpStandardCodec.cpp | 4 | ||||
-rw-r--r-- | src/codec/SkGifCodec.cpp | 4 | ||||
-rw-r--r-- | src/codec/SkJpegCodec.cpp | 34 | ||||
-rw-r--r-- | src/codec/SkJpegDecoderMgr.cpp | 7 | ||||
-rw-r--r-- | src/codec/SkPngCodec.cpp | 28 | ||||
-rw-r--r-- | src/codec/SkRawCodec.cpp | 4 | ||||
-rw-r--r-- | src/codec/SkSwizzler.cpp | 713 | ||||
-rw-r--r-- | src/codec/SkSwizzler.h | 31 | ||||
-rw-r--r-- | src/codec/SkWbmpCodec.cpp | 11 | ||||
-rw-r--r-- | src/codec/SkWbmpCodec.h | 5 |
10 files changed, 431 insertions, 410 deletions
diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp index a0ad7875eb..9f2d359354 100644 --- a/src/codec/SkBmpStandardCodec.cpp +++ b/src/codec/SkBmpStandardCodec.cpp @@ -191,9 +191,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 40339b52c6..081c52f1ea 100644 --- a/src/codec/SkGifCodec.cpp +++ b/src/codec/SkGifCodec.cpp @@ -292,8 +292,8 @@ void SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, size_t frameInde // - 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/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp index 75fe11337c..fd8d258d0c 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -641,13 +641,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 @@ -664,8 +657,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 c2837aa2b4..20810b3b2c 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 b6f418fd49..b4bc499cd7 100644 --- a/src/codec/SkPngCodec.cpp +++ b/src/codec/SkPngCodec.cpp @@ -1076,9 +1076,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 272f737f18..24051d1429 100644 --- a/src/codec/SkRawCodec.cpp +++ b/src/codec/SkRawCodec.cpp @@ -705,8 +705,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/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp index bf9c5496a6..546a6bae28 100644 --- a/src/codec/SkSwizzler.cpp +++ b/src/codec/SkSwizzler.cpp @@ -809,403 +809,378 @@ 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 = SkColorTypeBytesPerPixel(dstInfo.colorType()); - 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 kIndex_8_SkColorType: - proc = &swizzle_bit_to_index; - 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 kIndex_8_SkColorType: + proc = &swizzle_bit_to_index; + 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; + 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; + case kIndex_8_SkColorType: + proc = &swizzle_small_index_to_index; + 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; + case kIndex_8_SkColorType: + proc = &sample1; + fastProc = © + 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; - 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; - case kIndex_8_SkColorType: - proc = &swizzle_small_index_to_index; - break; - default: - return nullptr; - } + } + + 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; - 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; - case kIndex_8_SkColorType: - proc = &sample1; - fastProc = © - 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; - 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; + } + + 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; - 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; @@ -1222,8 +1197,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, 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 d59789b66e..96f75291d3 100644 --- a/src/codec/SkWbmpCodec.cpp +++ b/src/codec/SkWbmpCodec.cpp @@ -97,11 +97,6 @@ bool SkWbmpCodec::onRewind() { return read_header(this->stream(), nullptr); } -SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info, const SkPMColor* ctable, - const Options& opts) { - return SkSwizzler::CreateSwizzler(this->getEncodedInfo(), ctable, info, opts); -} - bool SkWbmpCodec::readRow(uint8_t* row) { return this->stream()->read(row, fSrcRowBytes) == fSrcRowBytes; } @@ -137,7 +132,8 @@ SkCodec::Result SkWbmpCodec::onGetPixels(const SkImageInfo& info, setup_color_table(info.colorType(), ctable, ctableCount); // Initialize the swizzler - std::unique_ptr<SkSwizzler> swizzler(this->initializeSwizzler(info, ctable, options)); + std::unique_ptr<SkSwizzler> swizzler = SkSwizzler::Make(this->getEncodedInfo(), nullptr, info, + options); SkASSERT(swizzler); // Perform the decode @@ -210,7 +206,8 @@ SkCodec::Result SkWbmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, } // Initialize the swizzler - fSwizzler.reset(this->initializeSwizzler(dstInfo, get_color_ptr(fColorTable.get()), options)); + fSwizzler = SkSwizzler::Make(this->getEncodedInfo(), get_color_ptr(fColorTable.get()), + dstInfo, options); SkASSERT(fSwizzler); fSrcBuffer.reset(fSrcRowBytes); diff --git a/src/codec/SkWbmpCodec.h b/src/codec/SkWbmpCodec.h index 40f507e9f3..c37b493836 100644 --- a/src/codec/SkWbmpCodec.h +++ b/src/codec/SkWbmpCodec.h @@ -29,11 +29,6 @@ protected: const Options&, SkPMColor[], int*, int*) override; bool onRewind() override; private: - /* - * Returns a swizzler on success, nullptr on failure - */ - SkSwizzler* initializeSwizzler(const SkImageInfo& info, const SkPMColor* ctable, - const Options& opts); SkSampler* getSampler(bool createIfNecessary) override { SkASSERT(fSwizzler || !createIfNecessary); return fSwizzler.get(); |