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>
diff --git a/src/codec/SkBmpCodec.cpp b/src/codec/SkBmpCodec.cpp
index 7cd1dfe..78f6b20 100644
--- a/src/codec/SkBmpCodec.cpp
+++ b/src/codec/SkBmpCodec.cpp
@@ -636,10 +636,10 @@
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));
}
diff --git a/src/codec/SkBmpCodec.h b/src/codec/SkBmpCodec.h
index a51bbce..0e38c84 100644
--- a/src/codec/SkBmpCodec.h
+++ b/src/codec/SkBmpCodec.h
@@ -110,6 +110,12 @@
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:
/*
diff --git a/src/codec/SkBmpMaskCodec.cpp b/src/codec/SkBmpMaskCodec.cpp
index 3ee1bb7..9612a23 100644
--- a/src/codec/SkBmpMaskCodec.cpp
+++ b/src/codec/SkBmpMaskCodec.cpp
@@ -60,7 +60,7 @@
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);
}
diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp
index 0bc6f60..c2574dd 100644
--- a/src/codec/SkBmpRLECodec.cpp
+++ b/src/codec/SkBmpRLECodec.cpp
@@ -341,7 +341,7 @@
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);
diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp
index 004c257..eeb3a1b 100644
--- a/src/codec/SkBmpStandardCodec.cpp
+++ b/src/codec/SkBmpStandardCodec.cpp
@@ -183,7 +183,7 @@
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);
}
diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp
index e773ed7..7fc3c98 100644
--- a/src/codec/SkGifCodec.cpp
+++ b/src/codec/SkGifCodec.cpp
@@ -144,10 +144,12 @@
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 @@
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 @@
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 @@
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());
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index 614cde9..69b8027 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -385,8 +385,8 @@
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;
diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp
index 3cf972d..758ffa5 100644
--- a/src/codec/SkPngCodec.cpp
+++ b/src/codec/SkPngCodec.cpp
@@ -212,6 +212,8 @@
}
}
+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 @@
// 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 @@
// 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::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 @@
}
// 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 @@
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);
}
diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp
index 1513632..93995c4 100644
--- a/src/codec/SkRawCodec.cpp
+++ b/src/codec/SkRawCodec.cpp
@@ -688,10 +688,11 @@
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 @@
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(),