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
This commit is contained in:
msarett 2016-04-22 16:27:24 -07:00 committed by Commit bot
parent a45a668fa5
commit 34e0ec40b1
16 changed files with 578 additions and 216 deletions

View File

@ -365,6 +365,9 @@ static void push_codec_src(Path path, CodecSrc::Mode mode, CodecSrc::DstColorTyp
case CodecSrc::kIndex8_Always_DstColorType: case CodecSrc::kIndex8_Always_DstColorType:
folder.append("_kIndex8"); folder.append("_kIndex8");
break; break;
case CodecSrc::kNonNative8888_Always_DstColorType:
folder.append("_kNonNative");
break;
default: default:
break; break;
} }
@ -410,6 +413,9 @@ static void push_android_codec_src(Path path, AndroidCodecSrc::Mode mode,
case CodecSrc::kIndex8_Always_DstColorType: case CodecSrc::kIndex8_Always_DstColorType:
folder.append("_kIndex8"); folder.append("_kIndex8");
break; break;
case CodecSrc::kNonNative8888_Always_DstColorType:
folder.append("_kNonNative");
break;
default: default:
break; break;
} }
@ -508,6 +514,7 @@ static void push_codec_srcs(Path path) {
SkTArray<CodecSrc::DstColorType> colorTypes; SkTArray<CodecSrc::DstColorType> colorTypes;
colorTypes.push_back(CodecSrc::kGetFromCanvas_DstColorType); colorTypes.push_back(CodecSrc::kGetFromCanvas_DstColorType);
colorTypes.push_back(CodecSrc::kNonNative8888_Always_DstColorType);
switch (codec->getInfo().colorType()) { switch (codec->getInfo().colorType()) {
case kGray_8_SkColorType: case kGray_8_SkColorType:
colorTypes.push_back(CodecSrc::kGrayscale_Always_DstColorType); colorTypes.push_back(CodecSrc::kGrayscale_Always_DstColorType);

View File

@ -110,6 +110,9 @@ Error BRDSrc::draw(SkCanvas* canvas) const {
case CodecSrc::kGrayscale_Always_DstColorType: case CodecSrc::kGrayscale_Always_DstColorType:
colorType = kGray_8_SkColorType; colorType = kGray_8_SkColorType;
break; break;
default:
SkASSERT(false);
break;
} }
SkAutoTDelete<SkBitmapRegionDecoder> brd(create_brd(fPath, fStrategy)); 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; 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. // FIXME: Currently we cannot draw unpremultiplied sources. skbug.com/3338 and skbug.com/3339.
// This allows us to still test unpremultiplied decodes. // This allows us to still test unpremultiplied decodes.
void premultiply_if_necessary(SkBitmap& bitmap) { void premultiply_if_necessary(SkBitmap& bitmap) {
@ -317,6 +332,16 @@ bool get_decode_info(SkImageInfo* decodeInfo, SkColorType canvasColorType,
} }
*decodeInfo = decodeInfo->makeColorType(kGray_8_SkColorType); *decodeInfo = decodeInfo->makeColorType(kGray_8_SkColorType);
break; 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: default:
if (kRGB_565_SkColorType == canvasColorType && if (kRGB_565_SkColorType == canvasColorType &&
kOpaque_SkAlphaType != decodeInfo->alphaType()) { kOpaque_SkAlphaType != decodeInfo->alphaType()) {
@ -378,7 +403,13 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
factory = &zeroFactory; factory = &zeroFactory;
options.fZeroInitialized = SkCodec::kYes_ZeroInitialized; 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(), return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(),
decodeInfo.width(), decodeInfo.height()); decodeInfo.width(), decodeInfo.height());
} }
@ -398,6 +429,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str()); return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str());
} }
premultiply_if_necessary(bitmap); premultiply_if_necessary(bitmap);
swap_rb_if_necessary(bitmap, fDstColorType);
canvas->drawBitmap(bitmap, 0, 0); canvas->drawBitmap(bitmap, 0, 0);
break; break;
} }
@ -432,6 +464,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
} }
premultiply_if_necessary(bitmap); premultiply_if_necessary(bitmap);
swap_rb_if_necessary(bitmap, fDstColorType);
canvas->drawBitmap(bitmap, 0, 0); canvas->drawBitmap(bitmap, 0, 0);
break; break;
} }
@ -487,6 +520,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
} }
} }
premultiply_if_necessary(bitmap); premultiply_if_necessary(bitmap);
swap_rb_if_necessary(bitmap, fDstColorType);
canvas->drawBitmap(bitmap, 0, 0); canvas->drawBitmap(bitmap, 0, 0);
break; break;
} }
@ -512,6 +546,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
} }
premultiply_if_necessary(bitmap); premultiply_if_necessary(bitmap);
swap_rb_if_necessary(bitmap, fDstColorType);
canvas->drawBitmap(bitmap, 0, 0); canvas->drawBitmap(bitmap, 0, 0);
break; break;
} }
@ -571,6 +606,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const {
fPath.c_str(), W, H, result); fPath.c_str(), W, H, result);
} }
premultiply_if_necessary(subsetBm); premultiply_if_necessary(subsetBm);
swap_rb_if_necessary(bitmap, fDstColorType);
canvas->drawBitmap(subsetBm, SkIntToScalar(left), SkIntToScalar(top)); canvas->drawBitmap(subsetBm, SkIntToScalar(left), SkIntToScalar(top));
// translate by the scaled height. // translate by the scaled height.
top += decodeInfo.height(); top += decodeInfo.height();
@ -659,7 +695,12 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const {
} }
SkBitmap bitmap; 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(), return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(),
decodeInfo.width(), decodeInfo.height()); decodeInfo.width(), decodeInfo.height());
} }
@ -681,6 +722,7 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const {
return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str()); return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str());
} }
premultiply_if_necessary(bitmap); premultiply_if_necessary(bitmap);
swap_rb_if_necessary(bitmap, fDstColorType);
canvas->drawBitmap(bitmap, 0, 0); canvas->drawBitmap(bitmap, 0, 0);
return ""; return "";
} }
@ -739,6 +781,7 @@ Error AndroidCodecSrc::draw(SkCanvas* canvas) const {
SkRect rect = SkRect::MakeXYWH(0, 0, (SkScalar) finalScaledWidth, SkRect rect = SkRect::MakeXYWH(0, 0, (SkScalar) finalScaledWidth,
(SkScalar) finalScaledHeight); (SkScalar) finalScaledHeight);
premultiply_if_necessary(bitmap); premultiply_if_necessary(bitmap);
swap_rb_if_necessary(bitmap, fDstColorType);
canvas->drawBitmapRect(bitmap, rect, rect, nullptr); canvas->drawBitmapRect(bitmap, rect, rect, nullptr);
return ""; return "";
} }

View File

@ -117,6 +117,7 @@ public:
kGetFromCanvas_DstColorType, kGetFromCanvas_DstColorType,
kIndex8_Always_DstColorType, kIndex8_Always_DstColorType,
kGrayscale_Always_DstColorType, kGrayscale_Always_DstColorType,
kNonNative8888_Always_DstColorType,
}; };
CodecSrc(Path, Mode, DstColorType, SkAlphaType, float); CodecSrc(Path, Mode, DstColorType, SkAlphaType, float);

View File

@ -70,7 +70,7 @@ SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo,
/* /*
* Process the color table for the bmp input * 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 // Allocate memory for color table
uint32_t colorBytes = 0; uint32_t colorBytes = 0;
SkPMColor colorTable[256]; SkPMColor colorTable[256];
@ -96,12 +96,13 @@ SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo,
} }
// Fill in the color table // Fill in the color table
PackColorProc packARGB = choose_pack_color_proc(false, dstColorType);
uint32_t i = 0; uint32_t i = 0;
for (; i < numColorsToRead; i++) { for (; i < numColorsToRead; i++) {
uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor); uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor);
uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1); uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1);
uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2); 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 // 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 // Set the pixel based on destination color type
const int dstX = get_dst_coord(x, fSampleX); const int dstX = get_dst_coord(x, fSampleX);
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: { case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType: {
SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (int) dstRowBytes); SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (int) dstRowBytes);
dstRow[dstX] = fColorTable->operator[](index); dstRow[dstX] = fColorTable->operator[](index);
break; break;
@ -241,9 +243,14 @@ void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes,
// Set the pixel based on destination color type // Set the pixel based on destination color type
const int dstX = get_dst_coord(x, fSampleX); const int dstX = get_dst_coord(x, fSampleX);
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: { case kRGBA_8888_SkColorType: {
SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (int) dstRowBytes); 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; break;
} }
case kRGB_565_SkColorType: { 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 // Create the color table if necessary and prepare the stream for decode
// Note that if it is non-NULL, inputColorCount will be modified // 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"); SkCodecPrintf("Error: could not create color table.\n");
return SkCodec::kInvalidInput; return SkCodec::kInvalidInput;
} }
@ -315,7 +322,8 @@ int SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowB
// the skipped pixels will be transparent. // the skipped pixels will be transparent.
// Because of the need for transparent pixels, kN32 is the only color // Because of the need for transparent pixels, kN32 is the only color
// type that makes sense for the destination format. // 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) { if (dst) {
SkSampler::Fill(dstInfo, dst, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroInitialized); SkSampler::Fill(dstInfo, dst, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroInitialized);
} }

View File

@ -58,7 +58,7 @@ private:
* Creates the color table * Creates the color table
* Sets colorCount to the new color count if it is non-nullptr * Sets colorCount to the new color count if it is non-nullptr
*/ */
bool createColorTable(int* colorCount); bool createColorTable(SkColorType dstColorType, int* colorCount);
bool initializeStreamBuffer(); bool initializeStreamBuffer();

View File

@ -68,7 +68,8 @@ SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo,
/* /*
* Process the color table for the bmp input * 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 // Allocate memory for color table
uint32_t colorBytes = 0; uint32_t colorBytes = 0;
SkPMColor colorTable[256]; SkPMColor colorTable[256];
@ -94,12 +95,8 @@ SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo,
} }
// Choose the proper packing function // Choose the proper packing function
SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t); bool isPremul = (kPremul_SkAlphaType == dstAlphaType) && !fIsOpaque;
if (fIsOpaque || kUnpremul_SkAlphaType == dstAlphaType) { PackColorProc packARGB = choose_pack_color_proc(isPremul, dstColorType);
packARGB = &SkPackARGB32NoCheck;
} else {
packARGB = &SkPremultiplyARGBInline;
}
// Fill in the color table // Fill in the color table
uint32_t i = 0; uint32_t i = 0;
@ -174,7 +171,7 @@ SkCodec::Result SkBmpStandardCodec::prepareToDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) { const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
// Create the color table if necessary and prepare the stream for decode // Create the color table if necessary and prepare the stream for decode
// Note that if it is non-NULL, inputColorCount will be modified // 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"); SkCodecPrintf("Error: could not create color table.\n");
return SkCodec::kInvalidInput; 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 // 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 // prevents us from using kIndex8. The below code depends on the output
// being an SkPMColor. // 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. // 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 // We do not need to worry about sampling in the y-dimension because that

View File

@ -70,7 +70,7 @@ private:
* Creates the color table * Creates the color table
* Sets colorCount to the new color count if it is non-nullptr * 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); void initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts);

View File

@ -128,7 +128,8 @@ inline bool conversion_possible(const SkImageInfo& dst, const SkImageInfo& src)
// Check for supported color types // Check for supported color types
switch (dst.colorType()) { switch (dst.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
return true; return true;
case kRGB_565_SkColorType: case kRGB_565_SkColorType:
return kOpaque_SkAlphaType == dst.alphaType(); return kOpaque_SkAlphaType == dst.alphaType();
@ -156,7 +157,8 @@ inline uint32_t get_color_table_fill_value(SkColorType colorType, const SkPMColo
uint8_t fillIndex) { uint8_t fillIndex) {
SkASSERT(nullptr != colorPtr); SkASSERT(nullptr != colorPtr);
switch (colorType) { switch (colorType) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
return colorPtr[fillIndex]; return colorPtr[fillIndex];
case kRGB_565_SkColorType: case kRGB_565_SkColorType:
return SkPixel32ToPixel16(colorPtr[fillIndex]); 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]); 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 #endif // SkCodecPriv_DEFINED

View File

@ -410,8 +410,9 @@ void SkGifCodec::initializeColorTable(const SkImageInfo& dstInfo, SkPMColor* inp
// giflib guarantees these properties // giflib guarantees these properties
SkASSERT(colorCount == (unsigned) (1 << (colorMap->BitsPerPixel))); SkASSERT(colorCount == (unsigned) (1 << (colorMap->BitsPerPixel)));
SkASSERT(colorCount <= 256); SkASSERT(colorCount <= 256);
PackColorProc proc = choose_pack_color_proc(false, dstInfo.colorType());
for (uint32_t i = 0; i < colorCount; i++) { 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); colorMap->Colors[i].Green, colorMap->Colors[i].Blue);
} }
} }

View File

@ -350,18 +350,23 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dst) {
// Check for valid color types and set the output color space // Check for valid color types and set the output color space
switch (dst.colorType()) { switch (dst.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
if (isCMYK) { if (isCMYK) {
fDecoderMgr->dinfo()->out_color_space = JCS_CMYK; fDecoderMgr->dinfo()->out_color_space = JCS_CMYK;
} else { } else {
#ifdef LIBJPEG_TURBO_VERSION #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; fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
#else #else
fDecoderMgr->dinfo()->out_color_space = JCS_EXT_BGRA; fDecoderMgr->dinfo()->out_color_space = JCS_RGB;
#endif #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;
#else #else
fDecoderMgr->dinfo()->out_color_space = JCS_RGB; fDecoderMgr->dinfo()->out_color_space = JCS_RGB;
#endif #endif

View File

@ -9,7 +9,7 @@
#include "SkColorPriv.h" #include "SkColorPriv.h"
#include "SkMaskSwizzler.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, void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
uint32_t startX, uint32_t sampleX) { 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 red = masks->getRed(p);
uint8_t green = masks->getGreen(p); uint8_t green = masks->getGreen(p);
uint8_t blue = masks->getBlue(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; 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, void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
uint32_t startX, uint32_t sampleX) { 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 green = masks->getGreen(p);
uint8_t blue = masks->getBlue(p); uint8_t blue = masks->getBlue(p);
uint8_t alpha = masks->getAlpha(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; 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, void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
uint32_t startX, uint32_t sampleX) { 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 green = masks->getGreen(p);
uint8_t blue = masks->getBlue(p); uint8_t blue = masks->getBlue(p);
uint8_t alpha = masks->getAlpha(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; srcPtr += sampleX;
} }
} }
@ -81,7 +134,7 @@ 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, void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
uint32_t startX, uint32_t sampleX) { uint32_t startX, uint32_t sampleX) {
@ -93,12 +146,29 @@ static void swizzle_mask24_to_n32_opaque(
uint8_t red = masks->getRed(p); uint8_t red = masks->getRed(p);
uint8_t green = masks->getGreen(p); uint8_t green = masks->getGreen(p);
uint8_t blue = masks->getBlue(p); uint8_t blue = masks->getBlue(p);
dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue); dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue);
srcRow += 3 * sampleX; srcRow += 3 * sampleX;
} }
} }
static void swizzle_mask24_to_n32_unpremul( 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, void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
uint32_t startX, uint32_t sampleX) { uint32_t startX, uint32_t sampleX) {
@ -111,12 +181,12 @@ static void swizzle_mask24_to_n32_unpremul(
uint8_t green = masks->getGreen(p); uint8_t green = masks->getGreen(p);
uint8_t blue = masks->getBlue(p); uint8_t blue = masks->getBlue(p);
uint8_t alpha = masks->getAlpha(p); uint8_t alpha = masks->getAlpha(p);
dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue); dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue);
srcRow += 3 * sampleX; srcRow += 3 * sampleX;
} }
} }
static void swizzle_mask24_to_n32_premul( static void swizzle_mask24_to_bgra_unpremul(
void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
uint32_t startX, uint32_t sampleX) { uint32_t startX, uint32_t sampleX) {
@ -129,7 +199,43 @@ static void swizzle_mask24_to_n32_premul(
uint8_t green = masks->getGreen(p); uint8_t green = masks->getGreen(p);
uint8_t blue = masks->getBlue(p); uint8_t blue = masks->getBlue(p);
uint8_t alpha = masks->getAlpha(p); uint8_t alpha = masks->getAlpha(p);
dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue); dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue);
srcRow += 3 * sampleX;
}
}
static void swizzle_mask24_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
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_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; srcRow += 3 * sampleX;
} }
} }
@ -151,7 +257,7 @@ 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, void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
uint32_t startX, uint32_t sampleX) { uint32_t startX, uint32_t sampleX) {
@ -163,12 +269,29 @@ static void swizzle_mask32_to_n32_opaque(
uint8_t red = masks->getRed(p); uint8_t red = masks->getRed(p);
uint8_t green = masks->getGreen(p); uint8_t green = masks->getGreen(p);
uint8_t blue = masks->getBlue(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; srcPtr += sampleX;
} }
} }
static void swizzle_mask32_to_n32_unpremul( 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, void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
uint32_t startX, uint32_t sampleX) { uint32_t startX, uint32_t sampleX) {
@ -181,12 +304,12 @@ static void swizzle_mask32_to_n32_unpremul(
uint8_t green = masks->getGreen(p); uint8_t green = masks->getGreen(p);
uint8_t blue = masks->getBlue(p); uint8_t blue = masks->getBlue(p);
uint8_t alpha = masks->getAlpha(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; srcPtr += sampleX;
} }
} }
static void swizzle_mask32_to_n32_premul( static void swizzle_mask32_to_bgra_unpremul(
void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks, void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
uint32_t startX, uint32_t sampleX) { uint32_t startX, uint32_t sampleX) {
@ -199,7 +322,43 @@ static void swizzle_mask32_to_n32_premul(
uint8_t green = masks->getGreen(p); uint8_t green = masks->getGreen(p);
uint8_t blue = masks->getBlue(p); uint8_t blue = masks->getBlue(p);
uint8_t alpha = masks->getAlpha(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_mask32_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
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] = premultiply_argb_as_rgba(alpha, red, green, blue);
srcPtr += sampleX;
}
}
static void swizzle_mask32_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
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] = premultiply_argb_as_bgra(alpha, red, green, blue);
srcPtr += sampleX; srcPtr += sampleX;
} }
} }
@ -234,16 +393,32 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo,
switch (bitsPerPixel) { switch (bitsPerPixel) {
case 16: case 16:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
if (kOpaque_SkAlphaType == srcInfo.alphaType()) { if (kOpaque_SkAlphaType == srcInfo.alphaType()) {
proc = &swizzle_mask16_to_n32_opaque; proc = &swizzle_mask16_to_rgba_opaque;
} else { } else {
switch (dstInfo.alphaType()) { switch (dstInfo.alphaType()) {
case kUnpremul_SkAlphaType: case kUnpremul_SkAlphaType:
proc = &swizzle_mask16_to_n32_unpremul; proc = &swizzle_mask16_to_rgba_unpremul;
break; break;
case kPremul_SkAlphaType: case kPremul_SkAlphaType:
proc = &swizzle_mask16_to_n32_premul; proc = &swizzle_mask16_to_rgba_premul;
break;
default:
break;
}
}
break;
case kBGRA_8888_SkColorType:
if (kOpaque_SkAlphaType == srcInfo.alphaType()) {
proc = &swizzle_mask16_to_bgra_opaque;
} else {
switch (dstInfo.alphaType()) {
case kUnpremul_SkAlphaType:
proc = &swizzle_mask16_to_bgra_unpremul;
break;
case kPremul_SkAlphaType:
proc = &swizzle_mask16_to_bgra_premul;
break; break;
default: default:
break; break;
@ -259,16 +434,32 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo,
break; break;
case 24: case 24:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
if (kOpaque_SkAlphaType == srcInfo.alphaType()) { if (kOpaque_SkAlphaType == srcInfo.alphaType()) {
proc = &swizzle_mask24_to_n32_opaque; proc = &swizzle_mask24_to_rgba_opaque;
} else { } else {
switch (dstInfo.alphaType()) { switch (dstInfo.alphaType()) {
case kUnpremul_SkAlphaType: case kUnpremul_SkAlphaType:
proc = &swizzle_mask24_to_n32_unpremul; proc = &swizzle_mask24_to_rgba_unpremul;
break; break;
case kPremul_SkAlphaType: case kPremul_SkAlphaType:
proc = &swizzle_mask24_to_n32_premul; proc = &swizzle_mask24_to_rgba_premul;
break;
default:
break;
}
}
break;
case kBGRA_8888_SkColorType:
if (kOpaque_SkAlphaType == srcInfo.alphaType()) {
proc = &swizzle_mask24_to_bgra_opaque;
} else {
switch (dstInfo.alphaType()) {
case kUnpremul_SkAlphaType:
proc = &swizzle_mask24_to_bgra_unpremul;
break;
case kPremul_SkAlphaType:
proc = &swizzle_mask24_to_bgra_premul;
break; break;
default: default:
break; break;
@ -284,16 +475,32 @@ SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo,
break; break;
case 32: case 32:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
if (kOpaque_SkAlphaType == srcInfo.alphaType()) { if (kOpaque_SkAlphaType == srcInfo.alphaType()) {
proc = &swizzle_mask32_to_n32_opaque; proc = &swizzle_mask32_to_rgba_opaque;
} else { } else {
switch (dstInfo.alphaType()) { switch (dstInfo.alphaType()) {
case kUnpremul_SkAlphaType: case kUnpremul_SkAlphaType:
proc = &swizzle_mask32_to_n32_unpremul; proc = &swizzle_mask32_to_rgba_unpremul;
break; break;
case kPremul_SkAlphaType: case kPremul_SkAlphaType:
proc = &swizzle_mask32_to_n32_premul; proc = &swizzle_mask32_to_rgba_premul;
break;
default:
break;
}
}
break;
case kBGRA_8888_SkColorType:
if (kOpaque_SkAlphaType == srcInfo.alphaType()) {
proc = &swizzle_mask32_to_bgra_opaque;
} else {
switch (dstInfo.alphaType()) {
case kUnpremul_SkAlphaType:
proc = &swizzle_mask32_to_bgra_unpremul;
break;
case kPremul_SkAlphaType:
proc = &swizzle_mask32_to_bgra_premul;
break; break;
default: default:
break; break;

View File

@ -86,14 +86,10 @@ private:
}; };
#define AutoCleanPng(...) SK_REQUIRE_LOCAL_VAR(AutoCleanPng) #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 // Note: SkColorTable claims to store SkPMColors, which is not necessarily
// the case here. // the case here.
// TODO: If we add support for non-native swizzles, we'll need to handle that 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; int numColors;
png_color* palette; 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)) { 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 // 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. // colortype is unpremultiplied, the color table will store unpremultiplied colors.
PackColorProc proc; PackColorProc proc = choose_pack_color_proc(premultiply, dstColorType);
if (premultiply) {
proc = &SkPremultiplyARGBInline;
} else {
proc = &SkPackARGB32NoCheck;
}
for (int i = 0; i < numColorsWithAlpha; i++) { for (int i = 0; i < numColorsWithAlpha; i++) {
// We don't have a function in SkOpts that combines a set of alphas with a set // 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); SkASSERT(&palette->green < &palette->blue);
#endif #endif
#ifdef SK_PMCOLOR_IS_RGBA if (is_rgba(dstColorType)) {
SkOpts::RGB_to_RGB1(colorPtr + numColorsWithAlpha, palette, numColors - numColorsWithAlpha); SkOpts::RGB_to_RGB1(colorPtr + numColorsWithAlpha, palette,
#else numColors - numColorsWithAlpha);
SkOpts::RGB_to_BGR1(colorPtr + numColorsWithAlpha, palette, numColors - numColorsWithAlpha); } else {
#endif 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 // 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); png_read_update_info(fPng_ptr, fInfo_ptr);
if (SkEncodedInfo::kPalette_Color == this->getEncodedInfo().color()) { 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; return kInvalidInput;
} }
} }

View File

@ -60,7 +60,7 @@ private:
const int fNumberPasses; const int fNumberPasses;
int fBitDepth; int fBitDepth;
bool decodePalette(bool premultiply, int* ctableCount); bool createColorTable(SkColorType dstColorType, bool premultiply, int* ctableCount);
void destroyReadStruct(); void destroyReadStruct();
typedef SkCodec INHERITED; typedef SkCodec INHERITED;

View 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 // Use the proper memset routine to fill the remaining bytes
switch (info.colorType()) { 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 // If memory is zero initialized, we may not need to fill
uint32_t color = colorOrIndex; uint32_t color = colorOrIndex;
if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) { if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) {

View File

@ -348,21 +348,9 @@ static void fast_swizzle_grayalpha_to_n32_premul(
SkOpts::grayA_to_rgbA((uint32_t*) dst, src + offset, width); SkOpts::grayA_to_rgbA((uint32_t*) dst, src + offset, width);
} }
// kBGRX // kBGR
static void swizzle_bgrx_to_n32( 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[]) {
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(
void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
@ -374,79 +362,33 @@ static void swizzle_bgrx_to_565(
} }
} }
// kBGRA
static void swizzle_bgra_to_n32_unpremul(
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]);
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(
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]);
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[]) {
// 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 // kRGB
static void swizzle_rgb_to_n32( static void swizzle_rgb_to_rgba(
void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
src += offset; src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
for (int x = 0; x < dstWidth; x++) { for (int x = 0; x < dstWidth; x++) {
dst[x] = SkPackARGB32NoCheck(0xFF, src[0], src[1], src[2]); dst[x] = SkPackARGB_as_RGBA(0xFF, src[0], src[1], src[2]);
src += deltaSrc; src += deltaSrc;
} }
} }
static void fast_swizzle_rgb_to_n32( 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++) {
dst[x] = SkPackARGB_as_BGRA(0xFF, src[0], src[1], src[2]);
src += deltaSrc;
}
}
static void fast_swizzle_rgb_to_rgba(
void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
int offset, const SkPMColor ctable[]) { int offset, const SkPMColor ctable[]) {
@ -454,11 +396,18 @@ static void fast_swizzle_rgb_to_n32(
// sampling, deltaSrc should equal bpp. // sampling, deltaSrc should equal bpp.
SkASSERT(deltaSrc == bpp); SkASSERT(deltaSrc == bpp);
#ifdef SK_PMCOLOR_IS_RGBA
SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width); SkOpts::RGB_to_RGB1((uint32_t*) dst, src + offset, width);
#else }
static void fast_swizzle_rgb_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::RGB_to_BGR1((uint32_t*) dst, src + offset, width); SkOpts::RGB_to_BGR1((uint32_t*) dst, src + offset, width);
#endif
} }
static void swizzle_rgb_to_565( static void swizzle_rgb_to_565(
@ -475,20 +424,31 @@ static void swizzle_rgb_to_565(
// kRGBA // 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, void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
src += offset; src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
for (int x = 0; x < dstWidth; x++) { for (int x = 0; x < dstWidth; x++) {
unsigned alpha = src[3]; dst[x] = premultiply_argb_as_rgba(src[3], src[0], src[1], src[2]);
dst[x] = SkPremultiplyARGBInline(alpha, src[0], src[1], src[2]);
src += deltaSrc; src += deltaSrc;
} }
} }
static void fast_swizzle_rgba_to_n32_premul( 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_rgba_premul(
void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, void* dst, const uint8_t* src, int width, int bpp, int deltaSrc,
int offset, const SkPMColor ctable[]) { int offset, const SkPMColor ctable[]) {
@ -496,14 +456,21 @@ static void fast_swizzle_rgba_to_n32_premul(
// sampling, deltaSrc should equal bpp. // sampling, deltaSrc should equal bpp.
SkASSERT(deltaSrc == bpp); SkASSERT(deltaSrc == bpp);
#ifdef SK_PMCOLOR_IS_RGBA
SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width); SkOpts::RGBA_to_rgbA((uint32_t*) dst, src + offset, width);
#else
SkOpts::RGBA_to_bgrA((uint32_t*) dst, src + offset, width);
#endif
} }
static void swizzle_rgba_to_n32_unpremul( 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);
}
static void swizzle_rgba_to_bgra_unpremul(
void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { 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); uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
for (int x = 0; x < dstWidth; x++) { for (int x = 0; x < dstWidth; x++) {
unsigned alpha = src[3]; 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; 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, void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
const SkPMColor ctable[]) { const SkPMColor ctable[]) {
@ -524,11 +491,7 @@ static void fast_swizzle_rgba_to_n32_unpremul(
// sampling, deltaSrc should equal bpp. // sampling, deltaSrc should equal bpp.
SkASSERT(deltaSrc == 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); SkOpts::RGBA_to_BGRA((uint32_t*) dst, src + offset, width);
#endif
} }
// kCMYK // kCMYK
@ -576,7 +539,7 @@ static void fast_swizzle_rgba_to_n32_unpremul(
// R = C * K / 255 // R = C * K / 255
// G = M * K / 255 // G = M * K / 255
// B = Y * 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, void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
@ -587,12 +550,28 @@ static void swizzle_cmyk_to_n32(
const uint8_t g = SkMulDiv255Round(src[1], src[3]); const uint8_t g = SkMulDiv255Round(src[1], src[3]);
const uint8_t b = SkMulDiv255Round(src[2], src[3]); const uint8_t b = SkMulDiv255Round(src[2], src[3]);
dst[x] = SkPackARGB32NoCheck(0xFF, r, g, b); dst[x] = SkPackARGB_as_RGBA(0xFF, r, g, b);
src += deltaSrc; src += deltaSrc;
} }
} }
static void fast_swizzle_cmyk_to_n32( 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[]) {
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_BGRA(0xFF, r, g, b);
src += deltaSrc;
}
}
static void fast_swizzle_cmyk_to_rgba(
void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset, void* dst, const uint8_t* src, int width, int bpp, int deltaSrc, int offset,
const SkPMColor ctable[]) { const SkPMColor ctable[]) {
@ -600,11 +579,18 @@ static void fast_swizzle_cmyk_to_n32(
// sampling, deltaSrc should equal bpp. // sampling, deltaSrc should equal bpp.
SkASSERT(deltaSrc == bpp); SkASSERT(deltaSrc == bpp);
#ifdef SK_PMCOLOR_IS_RGBA
SkOpts::inverted_CMYK_to_RGB1((uint32_t*) dst, src + offset, width); 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); SkOpts::inverted_CMYK_to_BGR1((uint32_t*) dst, src + offset, width);
#endif
} }
static void swizzle_cmyk_to_565( static void swizzle_cmyk_to_565(
@ -680,7 +666,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
switch (encodedInfo.bitsPerComponent()) { switch (encodedInfo.bitsPerComponent()) {
case 1: case 1:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
proc = &swizzle_bit_to_n32; proc = &swizzle_bit_to_n32;
break; break;
case kIndex_8_SkColorType: case kIndex_8_SkColorType:
@ -698,7 +685,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
break; break;
case 8: case 8:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
proc = &swizzle_gray_to_n32; proc = &swizzle_gray_to_n32;
fastProc = &fast_swizzle_gray_to_n32; fastProc = &fast_swizzle_gray_to_n32;
break; break;
@ -719,7 +707,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
break; break;
case SkEncodedInfo::kGrayAlpha_Color: case SkEncodedInfo::kGrayAlpha_Color:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
if (premultiply) { if (premultiply) {
if (SkCodec::kYes_ZeroInitialized == zeroInit) { if (SkCodec::kYes_ZeroInitialized == zeroInit) {
proc = &SkipLeadingGrayAlphaZerosThen<swizzle_grayalpha_to_n32_premul>; proc = &SkipLeadingGrayAlphaZerosThen<swizzle_grayalpha_to_n32_premul>;
@ -753,7 +742,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
case 2: case 2:
case 4: case 4:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
proc = &swizzle_small_index_to_n32; proc = &swizzle_small_index_to_n32;
break; break;
case kRGB_565_SkColorType: case kRGB_565_SkColorType:
@ -768,7 +758,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
break; break;
case 8: case 8:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
if (SkCodec::kYes_ZeroInitialized == zeroInit) { if (SkCodec::kYes_ZeroInitialized == zeroInit) {
proc = &swizzle_index_to_n32_skipZ; proc = &swizzle_index_to_n32_skipZ;
} else { } else {
@ -792,9 +783,13 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
break; break;
case SkEncodedInfo::kRGB_Color: case SkEncodedInfo::kRGB_Color:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
proc = &swizzle_rgb_to_n32; proc = &swizzle_rgb_to_rgba;
fastProc = &fast_swizzle_rgb_to_n32; fastProc = &fast_swizzle_rgb_to_rgba;
break;
case kBGRA_8888_SkColorType:
proc = &swizzle_rgb_to_bgra;
fastProc = &fast_swizzle_rgb_to_bgra;
break; break;
case kRGB_565_SkColorType: case kRGB_565_SkColorType:
proc = &swizzle_rgb_to_565; proc = &swizzle_rgb_to_565;
@ -805,23 +800,42 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
break; break;
case SkEncodedInfo::kRGBA_Color: case SkEncodedInfo::kRGBA_Color:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
if (premultiply) { if (premultiply) {
if (SkCodec::kYes_ZeroInitialized == zeroInit) { if (SkCodec::kYes_ZeroInitialized == zeroInit) {
proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_premul>; proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_n32_premul>; fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_rgba_premul>;
} else { } else {
proc = &swizzle_rgba_to_n32_premul; proc = &swizzle_rgba_to_rgba_premul;
fastProc = &fast_swizzle_rgba_to_n32_premul; fastProc = &fast_swizzle_rgba_to_rgba_premul;
} }
} else { } else {
if (SkCodec::kYes_ZeroInitialized == zeroInit) { if (SkCodec::kYes_ZeroInitialized == zeroInit) {
proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_unpremul>; proc = &SkipLeading8888ZerosThen<sample4>;
fastProc = &SkipLeading8888ZerosThen fastProc = &SkipLeading8888ZerosThen<copy>;
<fast_swizzle_rgba_to_n32_unpremul>;
} else { } else {
proc = &swizzle_rgba_to_n32_unpremul; proc = &sample4;
fastProc = &fast_swizzle_rgba_to_n32_unpremul; fastProc = &copy;
}
}
break;
case kBGRA_8888_SkColorType:
if (premultiply) {
if (SkCodec::kYes_ZeroInitialized == zeroInit) {
proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_bgra_premul>;
} else {
proc = &swizzle_rgba_to_bgra_premul;
fastProc = &fast_swizzle_rgba_to_bgra_premul;
}
} else {
if (SkCodec::kYes_ZeroInitialized == zeroInit) {
proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
fastProc = &SkipLeading8888ZerosThen
<fast_swizzle_rgba_to_bgra_unpremul>;
} else {
proc = &swizzle_rgba_to_bgra_unpremul;
fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
} }
} }
break; break;
@ -831,11 +845,16 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
break; break;
case SkEncodedInfo::kBGR_Color: case SkEncodedInfo::kBGR_Color:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kBGRA_8888_SkColorType:
proc = &swizzle_bgrx_to_n32; 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; break;
case kRGB_565_SkColorType: case kRGB_565_SkColorType:
proc = &swizzle_bgrx_to_565; proc = &swizzle_bgr_to_565;
break; break;
default: default:
return nullptr; return nullptr;
@ -843,11 +862,14 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
break; break;
case SkEncodedInfo::kBGRX_Color: case SkEncodedInfo::kBGRX_Color:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kBGRA_8888_SkColorType:
proc = &swizzle_bgrx_to_n32; proc = &swizzle_rgb_to_rgba;
break;
case kRGBA_8888_SkColorType:
proc = &swizzle_rgb_to_bgra;
break; break;
case kRGB_565_SkColorType: case kRGB_565_SkColorType:
proc = &swizzle_bgrx_to_565; proc = &swizzle_bgr_to_565;
break; break;
default: default:
return nullptr; return nullptr;
@ -855,23 +877,42 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
break; break;
case SkEncodedInfo::kBGRA_Color: case SkEncodedInfo::kBGRA_Color:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kBGRA_8888_SkColorType:
if (premultiply) { if (premultiply) {
if (SkCodec::kYes_ZeroInitialized == zeroInit) { if (SkCodec::kYes_ZeroInitialized == zeroInit) {
proc = &SkipLeading8888ZerosThen<swizzle_bgra_to_n32_premul>; proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_rgba_premul>;
fastProc = &SkipLeading8888ZerosThen<fast_swizzle_bgra_to_n32_premul>; fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_rgba_premul>;
} else { } else {
proc = &swizzle_bgra_to_n32_premul; proc = &swizzle_rgba_to_rgba_premul;
fastProc = &fast_swizzle_bgra_to_n32_premul; fastProc = &fast_swizzle_rgba_to_rgba_premul;
} }
} else { } else {
if (SkCodec::kYes_ZeroInitialized == zeroInit) { if (SkCodec::kYes_ZeroInitialized == zeroInit) {
proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32_unpremul>; proc = &SkipLeading8888ZerosThen<sample4>;
fastProc = &SkipLeading8888ZerosThen fastProc = &SkipLeading8888ZerosThen<copy>;
<fast_swizzle_bgra_to_n32_unpremul>;
} else { } else {
proc = &swizzle_bgra_to_n32_unpremul; proc = &sample4;
fastProc = &fast_swizzle_bgra_to_n32_unpremul; fastProc = &copy;
}
}
break;
case kRGBA_8888_SkColorType:
if (premultiply) {
if (SkCodec::kYes_ZeroInitialized == zeroInit) {
proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_premul>;
fastProc = &SkipLeading8888ZerosThen<fast_swizzle_rgba_to_bgra_premul>;
} else {
proc = &swizzle_rgba_to_bgra_premul;
fastProc = &fast_swizzle_rgba_to_bgra_premul;
}
} else {
if (SkCodec::kYes_ZeroInitialized == zeroInit) {
proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_bgra_unpremul>;
fastProc = &SkipLeading8888ZerosThen
<fast_swizzle_rgba_to_bgra_unpremul>;
} else {
proc = &swizzle_rgba_to_bgra_unpremul;
fastProc = &fast_swizzle_rgba_to_bgra_unpremul;
} }
} }
break; break;
@ -881,9 +922,13 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
break; break;
case SkEncodedInfo::kInvertedCMYK_Color: case SkEncodedInfo::kInvertedCMYK_Color:
switch (dstInfo.colorType()) { switch (dstInfo.colorType()) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
proc = &swizzle_cmyk_to_n32; proc = &swizzle_cmyk_to_rgba;
fastProc = &fast_swizzle_cmyk_to_n32; fastProc = &fast_swizzle_cmyk_to_rgba;
break;
case kBGRA_8888_SkColorType:
proc = &swizzle_cmyk_to_bgra;
fastProc = &fast_swizzle_cmyk_to_bgra;
break; break;
case kRGB_565_SkColorType: case kRGB_565_SkColorType:
proc = &swizzle_cmyk_to_565; proc = &swizzle_cmyk_to_565;
@ -902,7 +947,8 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo,
proc = &sample2; proc = &sample2;
fastProc = &copy; fastProc = &copy;
break; break;
case kN32_SkColorType: case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
proc = &sample4; proc = &sample4;
fastProc = &copy; fastProc = &copy;
break; break;

View File

@ -32,7 +32,8 @@ static inline void setup_color_table(SkColorType colorType,
static inline bool valid_color_type(SkColorType colorType, SkAlphaType alphaType) { static inline bool valid_color_type(SkColorType colorType, SkAlphaType alphaType) {
switch (colorType) { switch (colorType) {
case kN32_SkColorType: case kRGBA_8888_SkColorType:
case kBGRA_8888_SkColorType:
case kIndex_8_SkColorType: case kIndex_8_SkColorType:
return true; return true;
case kGray_8_SkColorType: case kGray_8_SkColorType: