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:
parent
1d3ab12b82
commit
562e681e5c
@ -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));
|
||||
}
|
||||
|
@ -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:
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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(),
|
||||
|
Loading…
Reference in New Issue
Block a user