Refactor RGBA/BGRA xform logic in SkCodecs

BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4554

Change-Id: Ic9105a2806b915fc56b6810a80dd444561d0d959
Reviewed-on: https://skia-review.googlesource.com/4554
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
This commit is contained in:
Matt Sarett 2016-11-08 16:13:43 -05:00 committed by Skia Commit-Bot
parent 1d3ab12b82
commit 562e681e5c
9 changed files with 38 additions and 28 deletions

View File

@ -636,10 +636,10 @@ bool SkBmpCodec::onSkipScanlines(int count) {
void SkBmpCodec::applyColorXform(const SkImageInfo& dstInfo, void* dst, void* src) const {
SkColorSpaceXform* xform = this->colorXform();
if (xform) {
SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
SkColorSpaceXform::ColorFormat srcFormat = SkColorSpaceXform::kBGRA_8888_ColorFormat;
SkAlphaType alphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
const SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
const SkColorSpaceXform::ColorFormat srcFormat = select_xform_format(kXformSrcColorType);
const SkAlphaType alphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
SkAssertResult(xform->apply(dstFormat, dst, srcFormat, src, dstInfo.width(),
alphaType));
}

View File

@ -110,6 +110,12 @@ protected:
uint32_t* xformBuffer() const { return fXformBuffer.get(); }
void resetXformBuffer(int count) { fXformBuffer.reset(new uint32_t[count]); }
/*
* BMPs are typically encoded as BGRA/BGR so this is a more efficient choice
* than RGBA.
*/
static const SkColorType kXformSrcColorType = kBGRA_8888_SkColorType;
private:
/*

View File

@ -60,7 +60,7 @@ SkCodec::Result SkBmpMaskCodec::onPrepareToDecode(const SkImageInfo& dstInfo,
SkImageInfo swizzlerInfo = dstInfo;
if (this->colorXform()) {
swizzlerInfo = swizzlerInfo.makeColorType(kBGRA_8888_SkColorType);
swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
if (kPremul_SkAlphaType == dstInfo.alphaType()) {
swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
}

View File

@ -341,7 +341,7 @@ int SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowB
SkImageInfo decodeInfo = dstInfo;
if (decodeDst) {
if (this->colorXform()) {
decodeInfo = decodeInfo.makeColorType(kBGRA_8888_SkColorType);
decodeInfo = decodeInfo.makeColorType(kXformSrcColorType);
if (kRGBA_F16_SkColorType == dstInfo.colorType()) {
int count = height * dstInfo.width();
this->resetXformBuffer(count);

View File

@ -183,7 +183,7 @@ void SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Op
SkImageInfo swizzlerInfo = dstInfo;
SkCodec::Options swizzlerOptions = opts;
if (this->colorXform()) {
swizzlerInfo = swizzlerInfo.makeColorType(kBGRA_8888_SkColorType);
swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
if (kPremul_SkAlphaType == dstInfo.alphaType()) {
swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
}

View File

@ -144,10 +144,12 @@ int SkGifCodec::onGetRepetitionCount() {
return fReader->loopCount();
}
static const SkColorType kXformSrcColorType = kRGBA_8888_SkColorType;
void SkGifCodec::initializeColorTable(const SkImageInfo& dstInfo, size_t frameIndex) {
SkColorType colorTableColorType = dstInfo.colorType();
if (this->colorXform()) {
colorTableColorType = kRGBA_8888_SkColorType;
colorTableColorType = kXformSrcColorType;
}
sk_sp<SkColorTable> currColorTable = fReader->getColorTable(colorTableColorType, frameIndex);
@ -158,10 +160,10 @@ void SkGifCodec::initializeColorTable(const SkImageInfo& dstInfo, size_t frameIn
fCurrColorTable.reset(new SkColorTable(&color, 1));
} else if (this->colorXform() && !fXformOnDecode) {
SkPMColor dstColors[256];
SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
SkColorSpaceXform::ColorFormat srcFormat = SkColorSpaceXform::kRGBA_8888_ColorFormat;
SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
const SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
const SkColorSpaceXform::ColorFormat srcFormat = select_xform_format(kXformSrcColorType);
const SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
SkAssertResult(this->colorXform()->apply(dstFormat, dstColors, srcFormat,
currColorTable->readColors(),
currColorTable->count(), xformAlphaType));
@ -261,7 +263,7 @@ void SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, size_t frameInde
SkImageInfo swizzlerInfo = dstInfo;
if (this->colorXform()) {
swizzlerInfo = swizzlerInfo.makeColorType(kRGBA_8888_SkColorType);
swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
if (kPremul_SkAlphaType == dstInfo.alphaType()) {
swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
}
@ -470,7 +472,7 @@ void SkGifCodec::applyXformRow(const SkImageInfo& dstInfo, void* dst, const uint
fSwizzler->swizzle(fXformBuffer.get(), src);
const SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
const SkColorSpaceXform::ColorFormat srcFormat = SkColorSpaceXform::kRGBA_8888_ColorFormat;
const SkColorSpaceXform::ColorFormat srcFormat = select_xform_format(kXformSrcColorType);
const SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
const int xformWidth = get_scaled_dimension(dstInfo.width(), fSwizzler->sampleX());

View File

@ -385,8 +385,8 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dstInfo) {
if (isCMYK) {
fDecoderMgr->dinfo()->out_color_space = JCS_CMYK;
} else if (this->colorXform()) {
// Our color transformation code requires RGBA order inputs, but it'll swizzle
// to BGRA for us.
// Always using RGBA as the input format for color xforms makes the
// implementation a little simpler.
fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
} else {
fDecoderMgr->dinfo()->out_color_space = JCS_EXT_BGRA;

View File

@ -212,6 +212,8 @@ void SkPngCodec::processData() {
}
}
static const SkColorType kXformSrcColorType = kRGBA_8888_SkColorType;
// Note: SkColorTable claims to store SkPMColors, which is not necessarily the case here.
bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo, int* ctableCount) {
@ -224,7 +226,7 @@ bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo, int* ctableCount)
// Contents depend on tableColorType and our choice of if/when to premultiply:
// { kPremul, kUnpremul, kOpaque } x { RGBA, BGRA }
SkPMColor colorTable[256];
SkColorType tableColorType = this->colorXform() ? kRGBA_8888_SkColorType : dstInfo.colorType();
SkColorType tableColorType = this->colorXform() ? kXformSrcColorType : dstInfo.colorType();
png_bytep alphas;
int numColorsWithAlpha = 0;
@ -267,11 +269,12 @@ bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo, int* ctableCount)
// If we are not decoding to F16, we can color xform now and store the results
// in the color table.
if (this->colorXform() && kRGBA_F16_SkColorType != dstInfo.colorType()) {
SkColorSpaceXform::ColorFormat xformColorFormat = select_xform_format(dstInfo.colorType());
SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
SkAssertResult(this->colorXform()->apply(xformColorFormat, colorTable,
SkColorSpaceXform::kRGBA_8888_ColorFormat, colorTable, numColors, xformAlphaType));
const SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
const SkColorSpaceXform::ColorFormat srcFormat = select_xform_format(kXformSrcColorType);
const SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
SkAssertResult(this->colorXform()->apply(dstFormat, colorTable, srcFormat, colorTable,
numColors, xformAlphaType));
}
// Pad the color table with the last color in the table (or black) in the case that
@ -430,7 +433,7 @@ void SkPngCodec::allocateStorage(const SkImageInfo& dstInfo) {
}
void SkPngCodec::applyXformRow(void* dst, const void* src) {
const SkColorSpaceXform::ColorFormat srcColorFormat = SkColorSpaceXform::kRGBA_8888_ColorFormat;
const SkColorSpaceXform::ColorFormat srcColorFormat = select_xform_format(kXformSrcColorType);
switch (fXformMode) {
case kSwizzleOnly_XformMode:
fSwizzler->swizzle(dst, (const uint8_t*) src);
@ -1068,8 +1071,6 @@ bool SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const Options& opt
}
// If the image is RGBA and we have a color xform, we can skip the swizzler.
// FIXME (msarett):
// Support more input types to this->colorXform() (ex: RGB, Gray) and skip the swizzler more often.
if (this->colorXform() && SkEncodedInfo::kRGBA_Color == this->getEncodedInfo().color() &&
!options.fSubset)
{
@ -1116,7 +1117,7 @@ void SkPngCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& o
if (this->colorXform() &&
apply_xform_on_decode(dstInfo.colorType(), this->getEncodedInfo().color()))
{
swizzlerInfo = swizzlerInfo.makeColorType(kRGBA_8888_SkColorType);
swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
if (kPremul_SkAlphaType == dstInfo.alphaType()) {
swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
}

View File

@ -688,10 +688,11 @@ SkCodec::Result SkRawCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
return kInvalidConversion;
}
static const SkColorType kXformSrcColorType = kRGBA_8888_SkColorType;
SkImageInfo swizzlerInfo = dstInfo;
std::unique_ptr<uint32_t[]> xformBuffer = nullptr;
if (this->colorXform()) {
swizzlerInfo = swizzlerInfo.makeColorType(kRGBA_8888_SkColorType);
swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
xformBuffer.reset(new uint32_t[dstInfo.width()]);
}
@ -742,7 +743,7 @@ SkCodec::Result SkRawCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
swizzler->swizzle(xformBuffer.get(), &srcRow[0]);
const SkColorSpaceXform::ColorFormat srcFormat =
SkColorSpaceXform::kRGBA_8888_ColorFormat;
select_xform_format(kXformSrcColorType);
const SkColorSpaceXform::ColorFormat dstFormat =
select_xform_format(dstInfo.colorType());
this->colorXform()->apply(dstFormat, dstRow, srcFormat, xformBuffer.get(),