diff options
author | msarett <msarett@google.com> | 2016-04-22 16:27:24 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-04-22 16:27:24 -0700 |
commit | 34e0ec40b10320765d4a4432f56e090556f9c75e (patch) | |
tree | f7b05f9dce7e83b666fe0309519daeab4b8f3f1f | |
parent | a45a668fa57eb968e24f379eceb2e56324e2cca2 (diff) |
Support the non-native (RGBA/BGRA) swizzle
BUG=skia:4456
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1907593004
Review URL: https://codereview.chromium.org/1907593004
-rw-r--r-- | dm/DM.cpp | 7 | ||||
-rw-r--r-- | dm/DMSrcSink.cpp | 47 | ||||
-rw-r--r-- | dm/DMSrcSink.h | 1 | ||||
-rw-r--r-- | src/codec/SkBmpRLECodec.cpp | 22 | ||||
-rw-r--r-- | src/codec/SkBmpRLECodec.h | 2 | ||||
-rw-r--r-- | src/codec/SkBmpStandardCodec.cpp | 16 | ||||
-rw-r--r-- | src/codec/SkBmpStandardCodec.h | 2 | ||||
-rw-r--r-- | src/codec/SkCodecPriv.h | 54 | ||||
-rw-r--r-- | src/codec/SkGifCodec.cpp | 3 | ||||
-rw-r--r-- | src/codec/SkJpegCodec.cpp | 17 | ||||
-rw-r--r-- | src/codec/SkMaskSwizzler.cpp | 267 | ||||
-rw-r--r-- | src/codec/SkPngCodec.cpp | 28 | ||||
-rw-r--r-- | src/codec/SkPngCodec.h | 2 | ||||
-rw-r--r-- | src/codec/SkSampler.cpp | 3 | ||||
-rw-r--r-- | src/codec/SkSwizzler.cpp | 284 | ||||
-rw-r--r-- | src/codec/SkWbmpCodec.cpp | 3 |
16 files changed, 560 insertions, 198 deletions
@@ -365,6 +365,9 @@ static void push_codec_src(Path path, CodecSrc::Mode mode, CodecSrc::DstColorTyp case CodecSrc::kIndex8_Always_DstColorType: folder.append("_kIndex8"); break; + case CodecSrc::kNonNative8888_Always_DstColorType: + folder.append("_kNonNative"); + break; default: break; } @@ -410,6 +413,9 @@ static void push_android_codec_src(Path path, AndroidCodecSrc::Mode mode, case CodecSrc::kIndex8_Always_DstColorType: folder.append("_kIndex8"); break; + case CodecSrc::kNonNative8888_Always_DstColorType: + folder.append("_kNonNative"); + break; default: break; } @@ -508,6 +514,7 @@ static void push_codec_srcs(Path path) { SkTArray<CodecSrc::DstColorType> colorTypes; colorTypes.push_back(CodecSrc::kGetFromCanvas_DstColorType); + colorTypes.push_back(CodecSrc::kNonNative8888_Always_DstColorType); switch (codec->getInfo().colorType()) { case kGray_8_SkColorType: colorTypes.push_back(CodecSrc::kGrayscale_Always_DstColorType); diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index c99f326081..dcbd220275 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -110,6 +110,9 @@ Error BRDSrc::draw(SkCanvas* canvas) const { case CodecSrc::kGrayscale_Always_DstColorType: colorType = kGray_8_SkColorType; break; + default: + SkASSERT(false); + break; } SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath, fStrategy)); @@ -271,6 +274,18 @@ bool CodecSrc::veto(SinkFlags flags) const { return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDirect; } +// Allows us to test decodes to non-native 8888. +void swap_rb_if_necessary(SkBitmap& bitmap, CodecSrc::DstColorType dstColorType) { + if (CodecSrc::kNonNative8888_Always_DstColorType != dstColorType) { + return; + } + + for (int y = 0; y < bitmap.height(); y++) { + uint32_t* row = (uint32_t*) bitmap.getAddr(0, y); + SkOpts::RGBA_to_BGRA(row, row, bitmap.width()); + } +} + // FIXME: Currently we cannot draw unpremultiplied sources. skbug.com/3338 and skbug.com/3339. // This allows us to still test unpremultiplied decodes. void premultiply_if_necessary(SkBitmap& bitmap) { @@ -317,6 +332,16 @@ bool get_decode_info(SkImageInfo* decodeInfo, SkColorType canvasColorType, } *decodeInfo = decodeInfo->makeColorType(kGray_8_SkColorType); break; + case CodecSrc::kNonNative8888_Always_DstColorType: + if (kRGB_565_SkColorType == canvasColorType) { + return false; + } +#ifdef SK_PMCOLOR_IS_RGBA + *decodeInfo = decodeInfo->makeColorType(kBGRA_8888_SkColorType); +#else + *decodeInfo = decodeInfo->makeColorType(kRGBA_8888_SkColorType); +#endif + break; default: if (kRGB_565_SkColorType == canvasColorType && kOpaque_SkAlphaType != decodeInfo->alphaType()) { @@ -378,7 +403,13 @@ Error CodecSrc::draw(SkCanvas* canvas) const { factory = &zeroFactory; options.fZeroInitialized = SkCodec::kYes_ZeroInitialized; } - if (!bitmap.tryAllocPixels(decodeInfo, factory, colorTable.get())) { + + SkImageInfo bitmapInfo = decodeInfo; + if (kRGBA_8888_SkColorType == decodeInfo.colorType() || + kBGRA_8888_SkColorType == decodeInfo.colorType()) { + bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType); + } + if (!bitmap.tryAllocPixels(bitmapInfo, factory, colorTable.get())) { return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(), decodeInfo.width(), decodeInfo.height()); } @@ -398,6 +429,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str()); } premultiply_if_necessary(bitmap); + swap_rb_if_necessary(bitmap, fDstColorType); canvas->drawBitmap(bitmap, 0, 0); break; } @@ -432,6 +464,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { } premultiply_if_necessary(bitmap); + swap_rb_if_necessary(bitmap, fDstColorType); canvas->drawBitmap(bitmap, 0, 0); break; } @@ -487,6 +520,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { } } premultiply_if_necessary(bitmap); + swap_rb_if_necessary(bitmap, fDstColorType); canvas->drawBitmap(bitmap, 0, 0); break; } @@ -512,6 +546,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { } premultiply_if_necessary(bitmap); + swap_rb_if_necessary(bitmap, fDstColorType); canvas->drawBitmap(bitmap, 0, 0); break; } @@ -571,6 +606,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { fPath.c_str(), W, H, result); } premultiply_if_necessary(subsetBm); + swap_rb_if_necessary(bitmap, fDstColorType); canvas->drawBitmap(subsetBm, SkIntToScalar(left), SkIntToScalar(top)); // translate by the scaled height. top += decodeInfo.height(); @@ -659,7 +695,12 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const { } SkBitmap bitmap; - if (!bitmap.tryAllocPixels(decodeInfo, nullptr, colorTable.get())) { + SkImageInfo bitmapInfo = decodeInfo; + if (kRGBA_8888_SkColorType == decodeInfo.colorType() || + kBGRA_8888_SkColorType == decodeInfo.colorType()) { + bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType); + } + if (!bitmap.tryAllocPixels(bitmapInfo, nullptr, colorTable.get())) { return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(), decodeInfo.width(), decodeInfo.height()); } @@ -681,6 +722,7 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const { return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str()); } premultiply_if_necessary(bitmap); + swap_rb_if_necessary(bitmap, fDstColorType); canvas->drawBitmap(bitmap, 0, 0); return ""; } @@ -739,6 +781,7 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const { SkRect rect = SkRect::MakeXYWH(0, 0, (SkScalar) finalScaledWidth, (SkScalar) finalScaledHeight); premultiply_if_necessary(bitmap); + swap_rb_if_necessary(bitmap, fDstColorType); canvas->drawBitmapRect(bitmap, rect, rect, nullptr); return ""; } diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index 743bd1e467..6f4eac71f9 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -117,6 +117,7 @@ public: kGetFromCanvas_DstColorType, kIndex8_Always_DstColorType, kGrayscale_Always_DstColorType, + kNonNative8888_Always_DstColorType, }; CodecSrc(Path, Mode, DstColorType, SkAlphaType, float); diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp index d80dd1a18a..02b42f6d90 100644 --- a/src/codec/SkBmpRLECodec.cpp +++ b/src/codec/SkBmpRLECodec.cpp @@ -70,7 +70,7 @@ SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo, /* * Process the color table for the bmp input */ - bool SkBmpRLECodec::createColorTable(int* numColors) { + bool SkBmpRLECodec::createColorTable(SkColorType dstColorType, int* numColors) { // Allocate memory for color table uint32_t colorBytes = 0; SkPMColor colorTable[256]; @@ -96,12 +96,13 @@ SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo, } // Fill in the color table + PackColorProc packARGB = choose_pack_color_proc(false, dstColorType); uint32_t i = 0; for (; i < numColorsToRead; i++) { uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor); uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1); uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2); - colorTable[i] = SkPackARGB32NoCheck(0xFF, red, green, blue); + colorTable[i] = packARGB(0xFF, red, green, blue); } // To avoid segmentation faults on bad pixel data, fill the end of the @@ -208,7 +209,8 @@ void SkBmpRLECodec::setPixel(void* dst, size_t dstRowBytes, // Set the pixel based on destination color type const int dstX = get_dst_coord(x, fSampleX); switch (dstInfo.colorType()) { - case kN32_SkColorType: { + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: { SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (int) dstRowBytes); dstRow[dstX] = fColorTable->operator[](index); break; @@ -241,9 +243,14 @@ void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes, // Set the pixel based on destination color type const int dstX = get_dst_coord(x, fSampleX); switch (dstInfo.colorType()) { - case kN32_SkColorType: { + case kRGBA_8888_SkColorType: { SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (int) dstRowBytes); - dstRow[dstX] = SkPackARGB32NoCheck(0xFF, red, green, blue); + dstRow[dstX] = SkPackARGB_as_RGBA(0xFF, red, green, blue); + break; + } + case kBGRA_8888_SkColorType: { + SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (int) dstRowBytes); + dstRow[dstX] = SkPackARGB_as_BGRA(0xFF, red, green, blue); break; } case kRGB_565_SkColorType: { @@ -275,7 +282,7 @@ SkCodec::Result SkBmpRLECodec::prepareToDecode(const SkImageInfo& dstInfo, // Create the color table if necessary and prepare the stream for decode // Note that if it is non-NULL, inputColorCount will be modified - if (!this->createColorTable(inputColorCount)) { + if (!this->createColorTable(dstInfo.colorType(), inputColorCount)) { SkCodecPrintf("Error: could not create color table.\n"); return SkCodec::kInvalidInput; } @@ -315,7 +322,8 @@ int SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowB // the skipped pixels will be transparent. // Because of the need for transparent pixels, kN32 is the only color // type that makes sense for the destination format. - SkASSERT(kN32_SkColorType == dstInfo.colorType()); + SkASSERT(kRGBA_8888_SkColorType == dstInfo.colorType() || + kBGRA_8888_SkColorType == dstInfo.colorType()); if (dst) { SkSampler::Fill(dstInfo, dst, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroInitialized); } diff --git a/src/codec/SkBmpRLECodec.h b/src/codec/SkBmpRLECodec.h index e0afccd927..c5236a8100 100644 --- a/src/codec/SkBmpRLECodec.h +++ b/src/codec/SkBmpRLECodec.h @@ -58,7 +58,7 @@ private: * Creates the color table * Sets colorCount to the new color count if it is non-nullptr */ - bool createColorTable(int* colorCount); + bool createColorTable(SkColorType dstColorType, int* colorCount); bool initializeStreamBuffer(); diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp index b2d8fc9735..358da057c6 100644 --- a/src/codec/SkBmpStandardCodec.cpp +++ b/src/codec/SkBmpStandardCodec.cpp @@ -68,7 +68,8 @@ SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo, /* * Process the color table for the bmp input */ - bool SkBmpStandardCodec::createColorTable(SkAlphaType dstAlphaType, int* numColors) { + bool SkBmpStandardCodec::createColorTable(SkColorType dstColorType, SkAlphaType dstAlphaType, + int* numColors) { // Allocate memory for color table uint32_t colorBytes = 0; SkPMColor colorTable[256]; @@ -94,12 +95,8 @@ SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo, } // Choose the proper packing function - SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t); - if (fIsOpaque || kUnpremul_SkAlphaType == dstAlphaType) { - packARGB = &SkPackARGB32NoCheck; - } else { - packARGB = &SkPremultiplyARGBInline; - } + bool isPremul = (kPremul_SkAlphaType == dstAlphaType) && !fIsOpaque; + PackColorProc packARGB = choose_pack_color_proc(isPremul, dstColorType); // Fill in the color table uint32_t i = 0; @@ -174,7 +171,7 @@ SkCodec::Result SkBmpStandardCodec::prepareToDecode(const SkImageInfo& dstInfo, const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) { // Create the color table if necessary and prepare the stream for decode // Note that if it is non-NULL, inputColorCount will be modified - if (!this->createColorTable(dstInfo.alphaType(), inputColorCount)) { + if (!this->createColorTable(dstInfo.colorType(), dstInfo.alphaType(), inputColorCount)) { SkCodecPrintf("Error: could not create color table.\n"); return SkCodec::kInvalidInput; } @@ -263,7 +260,8 @@ void SkBmpStandardCodec::decodeIcoMask(SkStream* stream, const SkImageInfo& dstI // BMP in ICO have transparency, so this cannot be 565, and this mask // prevents us from using kIndex8. The below code depends on the output // being an SkPMColor. - SkASSERT(dstInfo.colorType() == kN32_SkColorType); + SkASSERT(kRGBA_8888_SkColorType == dstInfo.colorType() || + kBGRA_8888_SkColorType == dstInfo.colorType()); // If we are sampling, make sure that we only mask the sampled pixels. // We do not need to worry about sampling in the y-dimension because that diff --git a/src/codec/SkBmpStandardCodec.h b/src/codec/SkBmpStandardCodec.h index b2b53df6c8..506742b05c 100644 --- a/src/codec/SkBmpStandardCodec.h +++ b/src/codec/SkBmpStandardCodec.h @@ -70,7 +70,7 @@ private: * Creates the color table * Sets colorCount to the new color count if it is non-nullptr */ - bool createColorTable(SkAlphaType alphaType, int* colorCount); + bool createColorTable(SkColorType colorType, SkAlphaType alphaType, int* colorCount); void initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts); diff --git a/src/codec/SkCodecPriv.h b/src/codec/SkCodecPriv.h index 8dde60fcd3..1694784785 100644 --- a/src/codec/SkCodecPriv.h +++ b/src/codec/SkCodecPriv.h @@ -128,7 +128,8 @@ inline bool conversion_possible(const SkImageInfo& dst, const SkImageInfo& src) // Check for supported color types switch (dst.colorType()) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: return true; case kRGB_565_SkColorType: return kOpaque_SkAlphaType == dst.alphaType(); @@ -156,7 +157,8 @@ inline uint32_t get_color_table_fill_value(SkColorType colorType, const SkPMColo uint8_t fillIndex) { SkASSERT(nullptr != colorPtr); switch (colorType) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: return colorPtr[fillIndex]; case kRGB_565_SkColorType: return SkPixel32ToPixel16(colorPtr[fillIndex]); @@ -271,4 +273,52 @@ inline uint16_t get_endian_short(const uint8_t* data, bool littleEndian) { return (data[0] << 8) | (data[1]); } +inline SkPMColor premultiply_argb_as_rgba(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { + if (a != 255) { + r = SkMulDiv255Round(r, a); + g = SkMulDiv255Round(g, a); + b = SkMulDiv255Round(b, a); + } + + return SkPackARGB_as_RGBA(a, r, g, b); +} + +inline SkPMColor premultiply_argb_as_bgra(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { + if (a != 255) { + r = SkMulDiv255Round(r, a); + g = SkMulDiv255Round(g, a); + b = SkMulDiv255Round(b, a); + } + + return SkPackARGB_as_BGRA(a, r, g, b); +} + +inline bool is_rgba(SkColorType colorType) { +#ifdef SK_PMCOLOR_IS_RGBA + return (kBGRA_8888_SkColorType != colorType); +#else + return (kRGBA_8888_SkColorType == colorType); +#endif +} + +// Method for coverting to a 32 bit pixel. +typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); + +inline PackColorProc choose_pack_color_proc(bool isPremul, SkColorType colorType) { + bool isRGBA = is_rgba(colorType); + if (isPremul) { + if (isRGBA) { + return &premultiply_argb_as_rgba; + } else { + return &premultiply_argb_as_bgra; + } + } else { + if (isRGBA) { + return &SkPackARGB_as_RGBA; + } else { + return &SkPackARGB_as_BGRA; + } + } +} + #endif // SkCodecPriv_DEFINED diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp index 774131f648..75e9d63fa7 100644 --- a/src/codec/SkGifCodec.cpp +++ b/src/codec/SkGifCodec.cpp @@ -410,8 +410,9 @@ void SkGifCodec::initializeColorTable(const SkImageInfo& dstInfo, SkPMColor* inp // giflib guarantees these properties SkASSERT(colorCount == (unsigned) (1 << (colorMap->BitsPerPixel))); SkASSERT(colorCount <= 256); + PackColorProc proc = choose_pack_color_proc(false, dstInfo.colorType()); for (uint32_t i = 0; i < colorCount; i++) { - colorPtr[i] = SkPackARGB32(0xFF, colorMap->Colors[i].Red, + colorPtr[i] = proc(0xFF, colorMap->Colors[i].Red, colorMap->Colors[i].Green, colorMap->Colors[i].Blue); } } diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp index 8d32f2b44d..0799e81381 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -350,18 +350,23 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dst) { // Check for valid color types and set the output color space switch (dst.colorType()) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: if (isCMYK) { fDecoderMgr->dinfo()->out_color_space = JCS_CMYK; } else { #ifdef LIBJPEG_TURBO_VERSION - // Check the byte ordering of the RGBA color space for the - // current platform - #ifdef SK_PMCOLOR_IS_RGBA fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA; - #else +#else + fDecoderMgr->dinfo()->out_color_space = JCS_RGB; +#endif + } + return true; + case kBGRA_8888_SkColorType: + if (isCMYK) { + fDecoderMgr->dinfo()->out_color_space = JCS_CMYK; + } else { +#ifdef LIBJPEG_TURBO_VERSION fDecoderMgr->dinfo()->out_color_space = JCS_EXT_BGRA; - #endif #else fDecoderMgr->dinfo()->out_color_space = JCS_RGB; #endif diff --git a/src/codec/SkMaskSwizzler.cpp b/src/codec/SkMaskSwizzler.cpp index 7630a7b59f..2df10ee24c 100644 --- a/src/codec/SkMaskSwizzler.cpp +++ b/src/codec/SkMaskSwizzler.cpp @@ -9,7 +9,7 @@ #include "SkColorPriv.h" #include "SkMaskSwizzler.h" -static void swizzle_mask16_to_n32_opaque( +static void swizzle_mask16_to_rgba_opaque( void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, uint32_t startX, uint32_t sampleX) { @@ -21,12 +21,29 @@ static void swizzle_mask16_to_n32_opaque( uint8_t red = masks->getRed(p); uint8_t green = masks->getGreen(p); uint8_t blue = masks->getBlue(p); - dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue); + dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue); srcPtr += sampleX; } } -static void swizzle_mask16_to_n32_unpremul( +static void swizzle_mask16_to_bgra_opaque( + void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, + uint32_t startX, uint32_t sampleX) { + + // Use the masks to decode to the destination + uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; + SkPMColor* dstPtr = (SkPMColor*) dstRow; + for (int i = 0; i < width; i++) { + uint16_t p = srcPtr[0]; + uint8_t red = masks->getRed(p); + uint8_t green = masks->getGreen(p); + uint8_t blue = masks->getBlue(p); + dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue); + srcPtr += sampleX; + } +} + +static void swizzle_mask16_to_rgba_unpremul( void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, uint32_t startX, uint32_t sampleX) { @@ -39,12 +56,12 @@ static void swizzle_mask16_to_n32_unpremul( uint8_t green = masks->getGreen(p); uint8_t blue = masks->getBlue(p); uint8_t alpha = masks->getAlpha(p); - dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue); + dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue); srcPtr += sampleX; } } -static void swizzle_mask16_to_n32_premul( +static void swizzle_mask16_to_bgra_unpremul( void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, uint32_t startX, uint32_t sampleX) { @@ -57,7 +74,43 @@ static void swizzle_mask16_to_n32_premul( uint8_t green = masks->getGreen(p); uint8_t blue = masks->getBlue(p); uint8_t alpha = masks->getAlpha(p); - dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue); + dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue); + srcPtr += sampleX; + } +} + +static void swizzle_mask16_to_rgba_premul( + void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, + uint32_t startX, uint32_t sampleX) { + + // Use the masks to decode to the destination + uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; + SkPMColor* dstPtr = (SkPMColor*) dstRow; + for (int i = 0; i < width; i++) { + uint16_t p = srcPtr[0]; + uint8_t red = masks->getRed(p); + uint8_t green = masks->getGreen(p); + uint8_t blue = masks->getBlue(p); + uint8_t alpha = masks->getAlpha(p); + dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue); + srcPtr += sampleX; + } +} + +static void swizzle_mask16_to_bgra_premul( + void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, + uint32_t startX, uint32_t sampleX) { + + // Use the masks to decode to the destination + uint16_t* srcPtr = ((uint16_t*) srcRow) + startX; + SkPMColor* dstPtr = (SkPMColor*) dstRow; + for (int i = 0; i < width; i++) { + uint16_t p = srcPtr[0]; + uint8_t red = masks->getRed(p); + uint8_t green = masks->getGreen(p); + uint8_t blue = masks->getBlue(p); + uint8_t alpha = masks->getAlpha(p); + dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue); srcPtr += sampleX; } } @@ -81,7 +134,41 @@ static void swizzle_mask16_to_565( } } -static void swizzle_mask24_to_n32_opaque( +static void swizzle_mask24_to_rgba_opaque( + void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, + uint32_t startX, uint32_t sampleX) { + + // Use the masks to decode to the destination + srcRow += 3 * startX; + SkPMColor* dstPtr = (SkPMColor*) dstRow; + for (int i = 0; i < width; i++) { + uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; + uint8_t red = masks->getRed(p); + uint8_t green = masks->getGreen(p); + uint8_t blue = masks->getBlue(p); + dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue); + srcRow += 3 * sampleX; + } +} + +static void swizzle_mask24_to_bgra_opaque( + void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, + uint32_t startX, uint32_t sampleX) { + + // Use the masks to decode to the destination + srcRow += 3 * startX; + SkPMColor* dstPtr = (SkPMColor*) dstRow; + for (int i = 0; i < width; i++) { + uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; + uint8_t red = masks->getRed(p); + uint8_t green = masks->getGreen(p); + uint8_t blue = masks->getBlue(p); + dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue); + srcRow += 3 * sampleX; + } +} + +static void swizzle_mask24_to_rgba_unpremul( void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, uint32_t startX, uint32_t sampleX) { @@ -93,12 +180,13 @@ static void swizzle_mask24_to_n32_opaque( uint8_t red = masks->getRed(p); uint8_t green = masks->getGreen(p); uint8_t blue = masks->getBlue(p); - dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue); + uint8_t alpha = masks->getAlpha(p); + dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue); srcRow += 3 * sampleX; } } -static void swizzle_mask24_to_n32_unpremul( +static void swizzle_mask24_to_bgra_unpremul( void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, uint32_t startX, uint32_t sampleX) { @@ -111,12 +199,12 @@ static void swizzle_mask24_to_n32_unpremul( uint8_t green = masks->getGreen(p); uint8_t blue = masks->getBlue(p); uint8_t alpha = masks->getAlpha(p); - dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue); + dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue); srcRow += 3 * sampleX; } } -static void swizzle_mask24_to_n32_premul( +static void swizzle_mask24_to_rgba_premul( void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, uint32_t startX, uint32_t sampleX) { @@ -129,7 +217,25 @@ static void swizzle_mask24_to_n32_premul( uint8_t green = masks->getGreen(p); uint8_t blue = masks->getBlue(p); uint8_t alpha = masks->getAlpha(p); - dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue); + dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue); + srcRow += 3 * sampleX; + } +} + +static void swizzle_mask24_to_bgra_premul( + void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, + uint32_t startX, uint32_t sampleX) { + + // Use the masks to decode to the destination + srcRow += 3 * startX; + SkPMColor* dstPtr = (SkPMColor*) dstRow; + for (int i = 0; i < width; i++) { + uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16; + uint8_t red = masks->getRed(p); + uint8_t green = masks->getGreen(p); + uint8_t blue = masks->getBlue(p); + uint8_t alpha = masks->getAlpha(p); + dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue); srcRow += 3 * sampleX; } } @@ -151,7 +257,59 @@ static void swizzle_mask24_to_565( } } -static void swizzle_mask32_to_n32_opaque( +static void swizzle_mask32_to_rgba_opaque( + void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, + uint32_t startX, uint32_t sampleX) { + + // Use the masks to decode to the destination + uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; + SkPMColor* dstPtr = (SkPMColor*) dstRow; + for (int i = 0; i < width; i++) { + uint32_t p = srcPtr[0]; + uint8_t red = masks->getRed(p); + uint8_t green = masks->getGreen(p); + uint8_t blue = masks->getBlue(p); + dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue); + srcPtr += sampleX; + } +} + +static void swizzle_mask32_to_bgra_opaque( + void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, + uint32_t startX, uint32_t sampleX) { + + // Use the masks to decode to the destination + uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; + SkPMColor* dstPtr = (SkPMColor*) dstRow; + for (int i = 0; i < width; i++) { + uint32_t p = srcPtr[0]; + uint8_t red = masks->getRed(p); + uint8_t green = masks->getGreen(p); + uint8_t blue = masks->getBlue(p); + dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue); + srcPtr += sampleX; + } +} + +static void swizzle_mask32_to_rgba_unpremul( + void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, + uint32_t startX, uint32_t sampleX) { + + // Use the masks to decode to the destination + uint32_t* srcPtr = ((uint32_t*) srcRow) + startX; + SkPMColor* dstPtr = (SkPMColor*) dstRow; + for (int i = 0; i < width; i++) { + uint32_t p = srcPtr[0]; + uint8_t red = masks->getRed(p); + uint8_t green = masks->getGreen(p); + uint8_t blue = masks->getBlue(p); + uint8_t alpha = masks->getAlpha(p); + dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue); + srcPtr += sampleX; + } +} + +static void swizzle_mask32_to_bgra_unpremul( void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, uint32_t startX, uint32_t sampleX) { @@ -163,12 +321,13 @@ static void swizzle_mask32_to_n32_opaque( uint8_t red = masks->getRed(p); uint8_t green = masks->getGreen(p); uint8_t blue = masks->getBlue(p); - dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue); + uint8_t alpha = masks->getAlpha(p); + dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue); srcPtr += sampleX; } } -static void swizzle_mask32_to_n32_unpremul( +static void swizzle_mask32_to_rgba_premul( void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, uint32_t startX, uint32_t sampleX) { @@ -181,12 +340,12 @@ static void swizzle_mask32_to_n32_unpremul( uint8_t green = masks->getGreen(p); uint8_t blue = masks->getBlue(p); uint8_t alpha = masks->getAlpha(p); - dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue); + dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue); srcPtr += sampleX; } } -static void swizzle_mask32_to_n32_premul( +static void swizzle_mask32_to_bgra_premul( void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, uint32_t startX, uint32_t sampleX) { @@ -199,7 +358,7 @@ static void swizzle_mask32_to_n32_premul( uint8_t green = masks->getGreen(p); uint8_t blue = masks->getBlue(p); uint8_t alpha = masks->getAlpha(p); - dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue); + dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue); srcPtr += sampleX; } } @@ -234,16 +393,32 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo, switch (bitsPerPixel) { case 16: switch (dstInfo.colorType()) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + if (kOpaque_SkAlphaType == srcInfo.alphaType()) { + proc = &swizzle_mask16_to_rgba_opaque; + } else { + switch (dstInfo.alphaType()) { + case kUnpremul_SkAlphaType: + proc = &swizzle_mask16_to_rgba_unpremul; + break; + case kPremul_SkAlphaType: + proc = &swizzle_mask16_to_rgba_premul; + break; + default: + break; + } + } + break; + case kBGRA_8888_SkColorType: if (kOpaque_SkAlphaType == srcInfo.alphaType()) { - proc = &swizzle_mask16_to_n32_opaque; + proc = &swizzle_mask16_to_bgra_opaque; } else { switch (dstInfo.alphaType()) { case kUnpremul_SkAlphaType: - proc = &swizzle_mask16_to_n32_unpremul; + proc = &swizzle_mask16_to_bgra_unpremul; break; case kPremul_SkAlphaType: - proc = &swizzle_mask16_to_n32_premul; + proc = &swizzle_mask16_to_bgra_premul; break; default: break; @@ -259,16 +434,32 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo, break; case 24: switch (dstInfo.colorType()) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + if (kOpaque_SkAlphaType == srcInfo.alphaType()) { + proc = &swizzle_mask24_to_rgba_opaque; + } else { + switch (dstInfo.alphaType()) { + case kUnpremul_SkAlphaType: + proc = &swizzle_mask24_to_rgba_unpremul; + break; + case kPremul_SkAlphaType: + proc = &swizzle_mask24_to_rgba_premul; + break; + default: + break; + } + } + break; + case kBGRA_8888_SkColorType: if (kOpaque_SkAlphaType == srcInfo.alphaType()) { - proc = &swizzle_mask24_to_n32_opaque; + proc = &swizzle_mask24_to_bgra_opaque; } else { switch (dstInfo.alphaType()) { case kUnpremul_SkAlphaType: - proc = &swizzle_mask24_to_n32_unpremul; + proc = &swizzle_mask24_to_bgra_unpremul; break; case kPremul_SkAlphaType: - proc = &swizzle_mask24_to_n32_premul; + proc = &swizzle_mask24_to_bgra_premul; break; default: break; @@ -284,16 +475,32 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo, break; case 32: switch (dstInfo.colorType()) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + if (kOpaque_SkAlphaType == srcInfo.alphaType()) { + proc = &swizzle_mask32_to_rgba_opaque; + } else { + switch (dstInfo.alphaType()) { + case kUnpremul_SkAlphaType: + proc = &swizzle_mask32_to_rgba_unpremul; + break; + case kPremul_SkAlphaType: + proc = &swizzle_mask32_to_rgba_premul; + break; + default: + break; + } + } + break; + case kBGRA_8888_SkColorType: if (kOpaque_SkAlphaType == srcInfo.alphaType()) { - proc = &swizzle_mask32_to_n32_opaque; + proc = &swizzle_mask32_to_bgra_opaque; } else { switch (dstInfo.alphaType()) { case kUnpremul_SkAlphaType: - proc = &swizzle_mask32_to_n32_unpremul; + proc = &swizzle_mask32_to_bgra_unpremul; break; case kPremul_SkAlphaType: - proc = &swizzle_mask32_to_n32_premul; + proc = &swizzle_mask32_to_bgra_premul; break; default: break; diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp index 240902de30..a5ff9fcc96 100644 --- a/src/codec/SkPngCodec.cpp +++ b/src/codec/SkPngCodec.cpp @@ -86,14 +86,10 @@ private: }; #define AutoCleanPng(...) SK_REQUIRE_LOCAL_VAR(AutoCleanPng) -// Method for coverting to either an SkPMColor or a similarly packed -// unpremultiplied color. -typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); - // Note: SkColorTable claims to store SkPMColors, which is not necessarily // the case here. // TODO: If we add support for non-native swizzles, we'll need to handle that here. -bool SkPngCodec::decodePalette(bool premultiply, int* ctableCount) { +bool SkPngCodec::createColorTable(SkColorType dstColorType, bool premultiply, int* ctableCount) { int numColors; png_color* palette; @@ -109,12 +105,7 @@ bool SkPngCodec::decodePalette(bool premultiply, int* ctableCount) { if (png_get_tRNS(fPng_ptr, fInfo_ptr, &alphas, &numColorsWithAlpha, nullptr)) { // Choose which function to use to create the color table. If the final destination's // colortype is unpremultiplied, the color table will store unpremultiplied colors. - PackColorProc proc; - if (premultiply) { - proc = &SkPremultiplyARGBInline; - } else { - proc = &SkPackARGB32NoCheck; - } + PackColorProc proc = choose_pack_color_proc(premultiply, dstColorType); for (int i = 0; i < numColorsWithAlpha; i++) { // We don't have a function in SkOpts that combines a set of alphas with a set @@ -134,11 +125,13 @@ bool SkPngCodec::decodePalette(bool premultiply, int* ctableCount) { SkASSERT(&palette->green < &palette->blue); #endif -#ifdef SK_PMCOLOR_IS_RGBA - SkOpts::RGB_to_RGB1(colorPtr + numColorsWithAlpha, palette, numColors - numColorsWithAlpha); -#else - SkOpts::RGB_to_BGR1(colorPtr + numColorsWithAlpha, palette, numColors - numColorsWithAlpha); -#endif + if (is_rgba(dstColorType)) { + SkOpts::RGB_to_RGB1(colorPtr + numColorsWithAlpha, palette, + numColors - numColorsWithAlpha); + } else { + SkOpts::RGB_to_BGR1(colorPtr + numColorsWithAlpha, palette, + numColors - numColorsWithAlpha); + } } // Pad the color table with the last color in the table (or black) in the case that @@ -474,7 +467,8 @@ SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, png_read_update_info(fPng_ptr, fInfo_ptr); if (SkEncodedInfo::kPalette_Color == this->getEncodedInfo().color()) { - if (!this->decodePalette(kPremul_SkAlphaType == requestedInfo.alphaType(), ctableCount)) { + if (!this->createColorTable(requestedInfo.colorType(), + kPremul_SkAlphaType == requestedInfo.alphaType(), ctableCount)) { return kInvalidInput; } } diff --git a/src/codec/SkPngCodec.h b/src/codec/SkPngCodec.h index 934513a676..0a8878395a 100644 --- a/src/codec/SkPngCodec.h +++ b/src/codec/SkPngCodec.h @@ -60,7 +60,7 @@ private: const int fNumberPasses; int fBitDepth; - bool decodePalette(bool premultiply, int* ctableCount); + bool createColorTable(SkColorType dstColorType, bool premultiply, int* ctableCount); void destroyReadStruct(); typedef SkCodec INHERITED; diff --git a/src/codec/SkSampler.cpp b/src/codec/SkSampler.cpp index c69d003c0f..ccfe400ec9 100644 --- a/src/codec/SkSampler.cpp +++ b/src/codec/SkSampler.cpp @@ -21,7 +21,8 @@ void SkSampler::Fill(const SkImageInfo& info, void* dst, size_t rowBytes, // Use the proper memset routine to fill the remaining bytes switch (info.colorType()) { - case kN32_SkColorType: { + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: { // If memory is zero initialized, we may not need to fill uint32_t color = colorOrIndex; if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) { diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp index a4b30287c2..f242421424 100644 --- a/src/codec/SkSwizzler.cpp +++ b/src/codec/SkSwizzler.cpp @@ -348,21 +348,9 @@ static void fast_swizzle_grayalpha_to_n32_premul( SkOpts::grayA_to_rgbA((uint32_t*) dst, src + offset, width); } -// kBGRX +// kBGR -static void swizzle_bgrx_to_n32( - void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, - int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { - - src += offset; - SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; - for (int x = 0; x < dstWidth; x++) { - dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]); - src += deltaSrc; - } -} - -static void swizzle_bgrx_to_565( +static void swizzle_bgr_to_565( void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { @@ -374,79 +362,44 @@ static void swizzle_bgrx_to_565( } } -// kBGRA +// kRGB -static void swizzle_bgra_to_n32_unpremul( +static void swizzle_rgb_to_rgba( void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { src += offset; SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; for (int x = 0; x < dstWidth; x++) { - uint8_t alpha = src[3]; - dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]); + dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]); src += deltaSrc; } } -static void fast_swizzle_bgra_to_n32_unpremul( - 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 - // sampling, deltaSrc should equal bpp. - SkASSERT(deltaSrc == bpp); - -#ifdef SK_PMCOLOR_IS_RGBA - SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width); -#else - memcpy(dst, src + offset, width * bpp); -#endif -} - -static void swizzle_bgra_to_n32_premul( +static void swizzle_rgb_to_bgra( void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { src += offset; SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; for (int x = 0; x < dstWidth; x++) { - uint8_t alpha = src[3]; - dst[x] = SkPremultiplyARGBInline(alpha, src[2], src[1], src[0]); + dst[x] = SkPackARGB_as_BGRA(0xFF, src[0], src[1], src[2]); src += deltaSrc; } } -static void fast_swizzle_bgra_to_n32_premul( - void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, - const SkPMColor ctable[]) { +static void fast_swizzle_rgb_to_rgba( + 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 // sampling, deltaSrc should equal bpp. SkASSERT(deltaSrc == bpp); -#ifdef SK_PMCOLOR_IS_RGBA - SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width); -#else - SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width); -#endif -} - -// kRGB - -static void swizzle_rgb_to_n32( - void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, - int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { - - src += offset; - SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; - for (int x = 0; x < dstWidth; x++) { - dst[x] = SkPackARGB32NoCheck(0xFF, src[0], src[1], src[2]); - src += deltaSrc; - } + SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width); } -static void fast_swizzle_rgb_to_n32( +static void fast_swizzle_rgb_to_bgra( void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { @@ -454,11 +407,7 @@ static void fast_swizzle_rgb_to_n32( // sampling, deltaSrc should equal bpp. SkASSERT(deltaSrc == bpp); -#ifdef SK_PMCOLOR_IS_RGBA - SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width); -#else SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width); -#endif } static void swizzle_rgb_to_565( @@ -475,20 +424,31 @@ static void swizzle_rgb_to_565( // kRGBA -static void swizzle_rgba_to_n32_premul( +static void swizzle_rgba_to_rgba_premul( void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { src += offset; SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; for (int x = 0; x < dstWidth; x++) { - unsigned alpha = src[3]; - dst[x] = SkPremultiplyARGBInline(alpha, src[0], src[1], src[2]); + dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]); + src += deltaSrc; + } +} + +static void swizzle_rgba_to_bgra_premul( + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, + int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { + + src += offset; + SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; + for (int x = 0; x < dstWidth; x++) { + dst[x] = premultiply_argb_as_bgra(src[3], src[0], src[1], src[2]); src += deltaSrc; } } -static void fast_swizzle_rgba_to_n32_premul( +static void fast_swizzle_rgba_to_rgba_premul( void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { @@ -496,14 +456,21 @@ static void fast_swizzle_rgba_to_n32_premul( // sampling, deltaSrc should equal bpp. SkASSERT(deltaSrc == bpp); -#ifdef SK_PMCOLOR_IS_RGBA SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width); -#else +} + +static void fast_swizzle_rgba_to_bgra_premul( + 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 + // sampling, deltaSrc should equal bpp. + SkASSERT(deltaSrc == bpp); + SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width); -#endif } -static void swizzle_rgba_to_n32_unpremul( +static void swizzle_rgba_to_bgra_unpremul( void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { @@ -511,12 +478,12 @@ static void swizzle_rgba_to_n32_unpremul( uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); for (int x = 0; x < dstWidth; x++) { unsigned alpha = src[3]; - dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); + dst[x] = SkPackARGB_as_BGRA(alpha, src[0], src[1], src[2]); src += deltaSrc; } } -static void fast_swizzle_rgba_to_n32_unpremul( +static void fast_swizzle_rgba_to_bgra_unpremul( void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { @@ -524,11 +491,7 @@ static void fast_swizzle_rgba_to_n32_unpremul( // sampling, deltaSrc should equal bpp. SkASSERT(deltaSrc == bpp); -#ifdef SK_PMCOLOR_IS_RGBA - memcpy(dst, src + offset, width * bpp); -#else SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width); -#endif } // kCMYK @@ -576,7 +539,23 @@ static void fast_swizzle_rgba_to_n32_unpremul( // R = C * K / 255 // G = M * K / 255 // B = Y * K / 255 -static void swizzle_cmyk_to_n32( +static void swizzle_cmyk_to_rgba( + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, + int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { + + src += offset; + SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; + for (int x = 0; x < dstWidth; x++) { + const uint8_t r = SkMulDiv255Round(src[0], src[3]); + const uint8_t g = SkMulDiv255Round(src[1], src[3]); + const uint8_t b = SkMulDiv255Round(src[2], src[3]); + + dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b); + src += deltaSrc; + } +} + +static void swizzle_cmyk_to_bgra( void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { @@ -587,12 +566,12 @@ static void swizzle_cmyk_to_n32( const uint8_t g = SkMulDiv255Round(src[1], src[3]); const uint8_t b = SkMulDiv255Round(src[2], src[3]); - dst[x] = SkPackARGB32NoCheck(0xFF, r, g, b); + dst[x] = SkPackARGB_as_BGRA(0xFF, r, g, b); src += deltaSrc; } } -static void fast_swizzle_cmyk_to_n32( +static void fast_swizzle_cmyk_to_rgba( void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { @@ -600,11 +579,18 @@ static void fast_swizzle_cmyk_to_n32( // sampling, deltaSrc should equal bpp. SkASSERT(deltaSrc == bpp); -#ifdef SK_PMCOLOR_IS_RGBA SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width); -#else +} + +static void fast_swizzle_cmyk_to_bgra( + 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 + // sampling, deltaSrc should equal bpp. + SkASSERT(deltaSrc == bpp); + SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width); -#endif } static void swizzle_cmyk_to_565( @@ -680,7 +666,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, switch (encodedInfo.bitsPerComponent()) { case 1: switch (dstInfo.colorType()) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: proc = &swizzle_bit_to_n32; break; case kIndex_8_SkColorType: @@ -698,7 +685,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, break; case 8: switch (dstInfo.colorType()) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: proc = &swizzle_gray_to_n32; fastProc = &fast_swizzle_gray_to_n32; break; @@ -719,7 +707,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, break; case SkEncodedInfo::kGrayAlpha_Color: switch (dstInfo.colorType()) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: if (premultiply) { if (SkCodec::kYes_ZeroInitialized == zeroInit) { proc = &SkipLeadingGrayAlphaZerosThen<swizzle_grayalpha_to_n32_premul>; @@ -753,7 +742,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, case 2: case 4: switch (dstInfo.colorType()) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: proc = &swizzle_small_index_to_n32; break; case kRGB_565_SkColorType: @@ -768,7 +758,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, break; case 8: switch (dstInfo.colorType()) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: if (SkCodec::kYes_ZeroInitialized == zeroInit) { proc = &swizzle_index_to_n32_skipZ; } else { @@ -792,9 +783,13 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, break; case SkEncodedInfo::kRGB_Color: switch (dstInfo.colorType()) { - case kN32_SkColorType: - proc = &swizzle_rgb_to_n32; - fastProc = &fast_swizzle_rgb_to_n32; + case kRGBA_8888_SkColorType: + proc = &swizzle_rgb_to_rgba; + fastProc = &fast_swizzle_rgb_to_rgba; + break; + case kBGRA_8888_SkColorType: + proc = &swizzle_rgb_to_bgra; + fastProc = &fast_swizzle_rgb_to_bgra; break; case kRGB_565_SkColorType: proc = &swizzle_rgb_to_565; @@ -805,23 +800,42 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, break; case SkEncodedInfo::kRGBA_Color: switch (dstInfo.colorType()) { - case kN32_SkColorType: + case kRGBA_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; + } + } else { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeading8888ZerosThen<sample4>; + fastProc = &SkipLeading8888ZerosThen<copy>; + } else { + proc = &sample4; + fastProc = © + } + } + break; + case kBGRA_8888_SkColorType: if (premultiply) { if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_premul>; - fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_n32_premul>; + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>; + fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_bgra_premul>; } else { - proc = &swizzle_rgba_to_n32_premul; - fastProc = &fast_swizzle_rgba_to_n32_premul; + proc = &swizzle_rgba_to_bgra_premul; + fastProc = &fast_swizzle_rgba_to_bgra_premul; } } else { if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_unpremul>; + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>; fastProc = &SkipLeading8888ZerosThen - <fast_swizzle_rgba_to_n32_unpremul>; + <fast_swizzle_rgba_to_bgra_unpremul>; } else { - proc = &swizzle_rgba_to_n32_unpremul; - fastProc = &fast_swizzle_rgba_to_n32_unpremul; + proc = &swizzle_rgba_to_bgra_unpremul; + fastProc = &fast_swizzle_rgba_to_bgra_unpremul; } } break; @@ -831,11 +845,16 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, break; case SkEncodedInfo::kBGR_Color: switch (dstInfo.colorType()) { - case kN32_SkColorType: - proc = &swizzle_bgrx_to_n32; + 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_bgrx_to_565; + proc = &swizzle_bgr_to_565; break; default: return nullptr; @@ -843,11 +862,14 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, break; case SkEncodedInfo::kBGRX_Color: switch (dstInfo.colorType()) { - case kN32_SkColorType: - proc = &swizzle_bgrx_to_n32; + 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_bgrx_to_565; + proc = &swizzle_bgr_to_565; break; default: return nullptr; @@ -855,23 +877,42 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, break; case SkEncodedInfo::kBGRA_Color: switch (dstInfo.colorType()) { - case kN32_SkColorType: + 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; + } + } else { + if (SkCodec::kYes_ZeroInitialized == zeroInit) { + proc = &SkipLeading8888ZerosThen<sample4>; + fastProc = &SkipLeading8888ZerosThen<copy>; + } else { + proc = &sample4; + fastProc = © + } + } + break; + case kRGBA_8888_SkColorType: if (premultiply) { if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<swizzle_bgra_to_n32_premul>; - fastProc = &SkipLeading8888ZerosThen<fast_swizzle_bgra_to_n32_premul>; + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>; + fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_bgra_premul>; } else { - proc = &swizzle_bgra_to_n32_premul; - fastProc = &fast_swizzle_bgra_to_n32_premul; + proc = &swizzle_rgba_to_bgra_premul; + fastProc = &fast_swizzle_rgba_to_bgra_premul; } } else { if (SkCodec::kYes_ZeroInitialized == zeroInit) { - proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_unpremul>; + proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>; fastProc = &SkipLeading8888ZerosThen - <fast_swizzle_bgra_to_n32_unpremul>; + <fast_swizzle_rgba_to_bgra_unpremul>; } else { - proc = &swizzle_bgra_to_n32_unpremul; - fastProc = &fast_swizzle_bgra_to_n32_unpremul; + proc = &swizzle_rgba_to_bgra_unpremul; + fastProc = &fast_swizzle_rgba_to_bgra_unpremul; } } break; @@ -881,9 +922,13 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, break; case SkEncodedInfo::kInvertedCMYK_Color: switch (dstInfo.colorType()) { - case kN32_SkColorType: - proc = &swizzle_cmyk_to_n32; - fastProc = &fast_swizzle_cmyk_to_n32; + 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; @@ -902,7 +947,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, proc = &sample2; fastProc = © break; - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: proc = &sample4; fastProc = © break; diff --git a/src/codec/SkWbmpCodec.cpp b/src/codec/SkWbmpCodec.cpp index 1e165b4e1d..527565f6ab 100644 --- a/src/codec/SkWbmpCodec.cpp +++ b/src/codec/SkWbmpCodec.cpp @@ -32,7 +32,8 @@ static inline void setup_color_table(SkColorType colorType, static inline bool valid_color_type(SkColorType colorType, SkAlphaType alphaType) { switch (colorType) { - case kN32_SkColorType: + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: case kIndex_8_SkColorType: return true; case kGray_8_SkColorType: |