diff options
author | Leon Scroggins III <scroggo@google.com> | 2018-10-24 12:17:22 -0400 |
---|---|---|
committer | Leon Scroggins <scroggo@google.com> | 2018-11-28 13:54:13 +0000 |
commit | 41220b678b22b1b4da3603985c1fb03a61dc5fe2 (patch) | |
tree | d1f7e9a13e764f9849c5eff7dad4c3dda494f53f | |
parent | 923c96332f97c0fca6e3808312296f22ffb121f7 (diff) | |
download | skia-41220b678b22b1b4da3603985c1fb03a61dc5fe2.tar.gz |
RESTRICT AUTOMERGE: Fix bug decoding JCS_RGB jpeg files
Bug: 118372692
Test: I6364b836db6bee98572ed0864e3dde6d2ca2d1b2
Merged-In: I1f1a8a6c84db4640d6a964dc9402faa9f3425361
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.
Change-Id: Ic8deab8f3639b65b3f6d35e8fe3cb68fd78f04e5
Reviewed-on: https://skia-review.googlesource.com/c/164619
Merged-In: I1f1a8a6c84db4640d6a964dc9402faa9f3425361
Add SafetNet Logging for JCS_RGB jpegs
Bug: 118372692
-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 | 28 | ||||
-rw-r--r-- | src/codec/SkRawCodec.cpp | 4 | ||||
-rw-r--r-- | src/codec/SkSwizzler.cpp | 693 | ||||
-rw-r--r-- | src/codec/SkSwizzler.h | 31 | ||||
-rw-r--r-- | src/codec/SkWbmpCodec.cpp | 9 | ||||
-rw-r--r-- | src/codec/SkWbmpCodec.h | 5 |
11 files changed, 426 insertions, 403 deletions
diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp index 46a5715dc9..8a515745c6 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 7b31a618ea..6a85662e85 100644 --- a/src/codec/SkGifCodec.cpp +++ b/src/codec/SkGifCodec.cpp @@ -272,8 +272,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 7c1f494f3a..f0471cf64d 100644 --- a/src/codec/SkHeifCodec.cpp +++ b/src/codec/SkHeifCodec.cpp @@ -323,16 +323,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 f3dbdf199c..78fc799b16 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -638,13 +638,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 @@ -661,8 +654,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 560b5bfe6b..2b0d93d18f 100644 --- a/src/codec/SkPngCodec.cpp +++ b/src/codec/SkPngCodec.cpp @@ -1045,9 +1045,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 d23eec0de6..78c475b945 100644 --- a/src/codec/SkRawCodec.cpp +++ b/src/codec/SkRawCodec.cpp @@ -709,8 +709,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 884916a145..d024403a65 100644 --- a/src/codec/SkSwizzler.cpp +++ b/src/codec/SkSwizzler.cpp @@ -767,393 +767,368 @@ 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 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; + 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; - 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_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; - 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; @@ -1170,8 +1145,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 eea5e4babc..b111346f06 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; } @@ -122,7 +118,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 @@ -191,7 +188,7 @@ SkCodec::Result SkWbmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, } // 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 f81b428e4f..d849ab93aa 100644 --- a/src/codec/SkWbmpCodec.h +++ b/src/codec/SkWbmpCodec.h @@ -29,11 +29,6 @@ protected: const Options&, int*) override; bool onRewind() override; 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(); |