Support the non-native (RGBA/BGRA) swizzle
authormsarett <msarett@google.com>
Fri, 22 Apr 2016 23:27:24 +0000 (16:27 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 22 Apr 2016 23:27:24 +0000 (16:27 -0700)
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

16 files changed:
dm/DM.cpp
dm/DMSrcSink.cpp
dm/DMSrcSink.h
src/codec/SkBmpRLECodec.cpp
src/codec/SkBmpRLECodec.h
src/codec/SkBmpStandardCodec.cpp
src/codec/SkBmpStandardCodec.h
src/codec/SkCodecPriv.h
src/codec/SkGifCodec.cpp
src/codec/SkJpegCodec.cpp
src/codec/SkMaskSwizzler.cpp
src/codec/SkPngCodec.cpp
src/codec/SkPngCodec.h
src/codec/SkSampler.cpp
src/codec/SkSwizzler.cpp
src/codec/SkWbmpCodec.cpp

index 58cb773..e77c99c 100644 (file)
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -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);
index c99f326..dcbd220 100644 (file)
@@ -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 "";
         }
index 743bd1e..6f4eac7 100644 (file)
@@ -117,6 +117,7 @@ public:
         kGetFromCanvas_DstColorType,
         kIndex8_Always_DstColorType,
         kGrayscale_Always_DstColorType,
+        kNonNative8888_Always_DstColorType,
     };
     CodecSrc(Path, Mode, DstColorType, SkAlphaType, float);
 
index d80dd1a..02b42f6 100644 (file)
@@ -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);
     }
index e0afccd..c5236a8 100644 (file)
@@ -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();
 
index b2d8fc9..358da05 100644 (file)
@@ -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
index b2b53df..506742b 100644 (file)
@@ -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);
 
index 8dde60f..1694784 100644 (file)
@@ -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
index 774131f..75e9d63 100644 (file)
@@ -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);
         }
     }
index 8d32f2b..0799e81 100644 (file)
@@ -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
index 7630a7b..2df10ee 100644 (file)
@@ -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;
index 240902d..a5ff9fc 100644 (file)
@@ -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;
         }
     }
index 934513a..0a88783 100644 (file)
@@ -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;
index c69d003..ccfe400 100644 (file)
@@ -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) {
index a4b3028..f242421 100644 (file)
@@ -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 = &copy;
+                        }
+                    }
+                    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 = &copy;
+                        }
+                    }
+                    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 = &copy;
                     break;
-                case kN32_SkColorType:
+                case kRGBA_8888_SkColorType:
+                case kBGRA_8888_SkColorType:
                     proc = &sample4;
                     fastProc = &copy;
                     break;
index 1e165b4..527565f 100644 (file)
@@ -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: