aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/codec/SkCodec.cpp13
-rw-r--r--src/codec/SkJpegCodec.cpp40
-rw-r--r--src/codec/SkJpegCodec.h2
-rw-r--r--src/codec/SkPngCodec.cpp37
-rw-r--r--src/codec/SkPngCodec.h1
-rw-r--r--src/codec/SkWebpCodec.cpp16
6 files changed, 56 insertions, 53 deletions
diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp
index 84afc2bdee..b6ce65e7b2 100644
--- a/src/codec/SkCodec.cpp
+++ b/src/codec/SkCodec.cpp
@@ -9,6 +9,7 @@
#include "SkCodec.h"
#include "SkCodecPriv.h"
#include "SkColorSpace.h"
+#include "SkColorSpaceXform.h"
#include "SkData.h"
#include "SkGifCodec.h"
#include "SkHalf.h"
@@ -483,3 +484,15 @@ void SkCodec::fillIncompleteImage(const SkImageInfo& info, void* dst, size_t row
}
}
}
+
+bool SkCodec::initializeColorXform(const SkImageInfo& dstInfo) {
+ fColorXform = nullptr;
+ if (needs_color_xform(dstInfo, fSrcInfo)) {
+ fColorXform = SkColorSpaceXform::New(fSrcInfo.colorSpace(), dstInfo.colorSpace());
+ if (!fColorXform) {
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index 6863855d3b..b9ae454a62 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -347,7 +347,6 @@ bool SkJpegCodec::onRewind() {
fSwizzleSrcRow = nullptr;
fColorXformSrcRow = nullptr;
fStorage.reset();
- fColorXform.reset(nullptr);
return true;
}
@@ -384,7 +383,7 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dstInfo) {
case kBGRA_8888_SkColorType:
if (isCMYK) {
fDecoderMgr->dinfo()->out_color_space = JCS_CMYK;
- } else if (fColorXform) {
+ } else if (this->colorXform()) {
// Our color transformation code requires RGBA order inputs, but it'll swizzle
// to BGRA for us.
fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
@@ -393,7 +392,7 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dstInfo) {
}
return true;
case kRGB_565_SkColorType:
- if (fColorXform) {
+ if (this->colorXform()) {
return false;
}
@@ -405,16 +404,15 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dstInfo) {
}
return true;
case kGray_8_SkColorType:
- if (fColorXform || JCS_GRAYSCALE != encodedColorType) {
+ if (this->colorXform() || JCS_GRAYSCALE != encodedColorType) {
return false;
}
fDecoderMgr->dinfo()->out_color_space = JCS_GRAYSCALE;
return true;
case kRGBA_F16_SkColorType:
- if (!fColorXform) {
- return false;
- }
+ SkASSERT(this->colorXform());
+
if (!dstInfo.colorSpace()->gammaIsLinear()) {
return false;
}
@@ -483,7 +481,7 @@ int SkJpegCodec::readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes
// subsetting.
// When fColorXformSrcRow is non-null, it means that we need to color xform and that
// we cannot color xform "in place" (many times we can, but not when the dst is F16).
- // In this case, we will color xform from fColorXformSrc into the dst.
+ // In this case, we will color xform from fColorXformSrcRow into the dst.
JSAMPLE* decodeDst = (JSAMPLE*) dst;
uint32_t* swizzleDst = (uint32_t*) dst;
size_t decodeDstRowBytes = rowBytes;
@@ -518,10 +516,10 @@ int SkJpegCodec::readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes
fSwizzler->swizzle(swizzleDst, decodeDst);
}
- if (fColorXform) {
- SkAssertResult(fColorXform->apply(select_xform_format(dstInfo.colorType()), dst,
- SkColorSpaceXform::kRGBA_8888_ColorFormat, swizzleDst,
- dstWidth, kOpaque_SkAlphaType));
+ if (this->colorXform()) {
+ SkAssertResult(this->colorXform()->apply(select_xform_format(dstInfo.colorType()), dst,
+ SkColorSpaceXform::kRGBA_8888_ColorFormat, swizzleDst, dstWidth,
+ kOpaque_SkAlphaType));
dst = SkTAddOffset<void>(dst, rowBytes);
}
@@ -552,7 +550,9 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
}
- this->initializeColorXform(dstInfo);
+ if (!this->initializeColorXform(dstInfo)) {
+ return kInvalidConversion;
+ }
// Check if we can decode to the requested destination and set the output color space
if (!this->setOutputColorSpace(dstInfo)) {
@@ -590,12 +590,12 @@ void SkJpegCodec::allocateStorage(const SkImageInfo& dstInfo) {
if (fSwizzler) {
swizzleBytes = get_row_bytes(fDecoderMgr->dinfo());
dstWidth = fSwizzler->swizzleWidth();
- SkASSERT(!fColorXform || SkIsAlign4(swizzleBytes));
+ SkASSERT(!this->colorXform() || SkIsAlign4(swizzleBytes));
}
size_t xformBytes = 0;
if (kRGBA_F16_SkColorType == dstInfo.colorType()) {
- SkASSERT(fColorXform);
+ SkASSERT(this->colorXform());
xformBytes = dstWidth * sizeof(uint32_t);
}
@@ -634,12 +634,6 @@ void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options&
SkASSERT(fSwizzler);
}
-void SkJpegCodec::initializeColorXform(const SkImageInfo& dstInfo) {
- if (needs_color_xform(dstInfo, this->getInfo())) {
- fColorXform = SkColorSpaceXform::New(this->getInfo().colorSpace(), dstInfo.colorSpace());
- }
-}
-
SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) {
if (!createIfNecessary || fSwizzler) {
SkASSERT(!fSwizzler || (fSwizzleSrcRow && fStorage.get() == fSwizzleSrcRow));
@@ -659,7 +653,9 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
return kInvalidInput;
}
- this->initializeColorXform(dstInfo);
+ if (!this->initializeColorXform(dstInfo)) {
+ return kInvalidConversion;
+ }
// Check if we can decode to the requested destination and set the output color space
if (!this->setOutputColorSpace(dstInfo)) {
diff --git a/src/codec/SkJpegCodec.h b/src/codec/SkJpegCodec.h
index 30425eea3f..402f466b79 100644
--- a/src/codec/SkJpegCodec.h
+++ b/src/codec/SkJpegCodec.h
@@ -107,7 +107,6 @@ private:
bool setOutputColorSpace(const SkImageInfo& dst);
void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options);
- void initializeColorXform(const SkImageInfo& dstInfo);
void allocateStorage(const SkImageInfo& dstInfo);
int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count);
@@ -137,7 +136,6 @@ private:
SkIRect fSwizzlerSubset;
SkAutoTDelete<SkSwizzler> fSwizzler;
- std::unique_ptr<SkColorSpaceXform> fColorXform;
sk_sp<SkData> fICCData;
diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp
index 50c107172a..23c74e2122 100644
--- a/src/codec/SkPngCodec.cpp
+++ b/src/codec/SkPngCodec.cpp
@@ -224,14 +224,14 @@ 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 = fColorXform ? kRGBA_8888_SkColorType : dstInfo.colorType();
+ SkColorType tableColorType = this->colorXform() ? kRGBA_8888_SkColorType : dstInfo.colorType();
png_bytep alphas;
int numColorsWithAlpha = 0;
if (png_get_tRNS(fPng_ptr, fInfo_ptr, &alphas, &numColorsWithAlpha, nullptr)) {
// If we are performing a color xform, it will handle the premultiply. Otherwise,
// we'll do it here.
- bool premultiply = !fColorXform && needs_premul(dstInfo, this->getInfo());
+ bool premultiply = !this->colorXform() && needs_premul(dstInfo, this->getInfo());
// 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.
@@ -266,15 +266,14 @@ 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 (fColorXform && kRGBA_F16_SkColorType != dstInfo.colorType()) {
+ if (this->colorXform() && kRGBA_F16_SkColorType != dstInfo.colorType()) {
SkColorSpaceXform::ColorFormat xformColorFormat = is_rgba(dstInfo.colorType()) ?
SkColorSpaceXform::kRGBA_8888_ColorFormat :
SkColorSpaceXform::kBGRA_8888_ColorFormat;
SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
- SkAssertResult(fColorXform->apply(xformColorFormat, colorTable,
- SkColorSpaceXform::kRGBA_8888_ColorFormat, colorTable,
- numColors, xformAlphaType));
+ SkAssertResult(this->colorXform()->apply(xformColorFormat, colorTable,
+ SkColorSpaceXform::kRGBA_8888_ColorFormat, colorTable, numColors, xformAlphaType));
}
// Pad the color table with the last color in the table (or black) in the case that
@@ -442,13 +441,13 @@ void SkPngCodec::applyXformRow(void* dst, const void* src) {
fSwizzler->swizzle(dst, (const uint8_t*) src);
break;
case kColorOnly_XformMode:
- SkAssertResult(fColorXform->apply(fXformColorFormat, dst, srcColorFormat, src,
- fXformWidth, fXformAlphaType));
+ SkAssertResult(this->colorXform()->apply(fXformColorFormat, dst, srcColorFormat, src,
+ fXformWidth, fXformAlphaType));
break;
case kSwizzleColor_XformMode:
fSwizzler->swizzle(fColorXformSrcRow, (const uint8_t*) src);
- SkAssertResult(fColorXform->apply(fXformColorFormat, dst, srcColorFormat, fColorXformSrcRow,
- fXformWidth, fXformAlphaType));
+ SkAssertResult(this->colorXform()->apply(fXformColorFormat, dst, srcColorFormat,
+ fColorXformSrcRow, fXformWidth, fXformAlphaType));
break;
}
}
@@ -1065,20 +1064,18 @@ bool SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const Options& opt
}
png_read_update_info(fPng_ptr, fInfo_ptr);
- // Reset fSwizzler and fColorXform. We can't do this in onRewind() because the
+ // Reset fSwizzler and this->colorXform(). We can't do this in onRewind() because the
// interlaced scanline decoder may need to rewind.
fSwizzler.reset(nullptr);
- fColorXform = nullptr;
- if (needs_color_xform(dstInfo, this->getInfo())) {
- fColorXform = SkColorSpaceXform::New(this->getInfo().colorSpace(), dstInfo.colorSpace());
- SkASSERT(fColorXform);
+ if (!this->initializeColorXform(dstInfo)) {
+ return false;
}
// If the image is RGBA and we have a color xform, we can skip the swizzler.
// FIXME (msarett):
- // Support more input types to fColorXform (ex: RGB, Gray) and skip the swizzler more often.
- if (fColorXform && SkEncodedInfo::kRGBA_Color == this->getEncodedInfo().color() &&
+ // 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)
{
fXformMode = kColorOnly_XformMode;
@@ -1126,7 +1123,9 @@ void SkPngCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& o
SkImageInfo swizzlerInfo = dstInfo;
Options swizzlerOptions = options;
fXformMode = kSwizzleOnly_XformMode;
- if (fColorXform && apply_xform_on_decode(dstInfo.colorType(), this->getEncodedInfo().color())) {
+ if (this->colorXform() &&
+ apply_xform_on_decode(dstInfo.colorType(), this->getEncodedInfo().color()))
+ {
swizzlerInfo = swizzlerInfo.makeColorType(kRGBA_8888_SkColorType);
if (kPremul_SkAlphaType == dstInfo.alphaType()) {
swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
@@ -1247,7 +1246,7 @@ uint64_t SkPngCodec::onGetFillValue(const SkImageInfo& dstInfo) const {
SkAlphaType alphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
return get_color_table_fill_value(dstInfo.colorType(), alphaType, colorPtr, 0,
- fColorXform.get());
+ this->colorXform());
}
return INHERITED::onGetFillValue(dstInfo);
}
diff --git a/src/codec/SkPngCodec.h b/src/codec/SkPngCodec.h
index 1fc451757e..c10f17464c 100644
--- a/src/codec/SkPngCodec.h
+++ b/src/codec/SkPngCodec.h
@@ -98,7 +98,6 @@ protected:
// These are stored here so they can be used both by normal decoding and scanline decoding.
SkAutoTUnref<SkColorTable> fColorTable; // May be unpremul.
SkAutoTDelete<SkSwizzler> fSwizzler;
- std::unique_ptr<SkColorSpaceXform> fColorXform;
SkAutoTMalloc<uint8_t> fStorage;
uint32_t* fColorXformSrcRow;
const int fBitDepth;
diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp
index 443a4a0732..746e9b79ad 100644
--- a/src/codec/SkWebpCodec.cpp
+++ b/src/codec/SkWebpCodec.cpp
@@ -197,10 +197,8 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
return kInvalidConversion;
}
- std::unique_ptr<SkColorSpaceXform> colorXform = nullptr;
- if (needs_color_xform(dstInfo, this->getInfo())) {
- colorXform = SkColorSpaceXform::New(this->getInfo().colorSpace(), dstInfo.colorSpace());
- SkASSERT(colorXform);
+ if (!this->initializeColorXform(dstInfo)) {
+ return kInvalidConversion;
}
WebPDecoderConfig config;
@@ -262,7 +260,7 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
// color transform swizzle if necessary.
// Lossy webp is encoded as YUV (so RGBA and BGRA are the same cost). Lossless webp is
// encoded as BGRA. This means decoding to BGRA is either faster or the same cost as RGBA.
- config.output.colorspace = colorXform ? MODE_BGRA :
+ config.output.colorspace = this->colorXform() ? MODE_BGRA :
webp_decode_mode(dstInfo.colorType(), dstInfo.alphaType() == kPremul_SkAlphaType);
config.output.is_external_memory = 1;
@@ -307,7 +305,7 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
return kInvalidInput;
}
- if (colorXform) {
+ if (this->colorXform()) {
SkColorSpaceXform::ColorFormat dstColorFormat = select_xform_format(dstInfo.colorType());
SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
@@ -315,9 +313,9 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
uint32_t* src = (uint32_t*) config.output.u.RGBA.rgba;
size_t srcRowBytes = config.output.u.RGBA.stride;
for (int y = 0; y < rowsDecoded; y++) {
- SkAssertResult(colorXform->apply(dstColorFormat, dst,
- SkColorSpaceXform::kBGRA_8888_ColorFormat, src,
- dstInfo.width(), xformAlphaType));
+ SkAssertResult(this->colorXform()->apply(dstColorFormat, dst,
+ SkColorSpaceXform::kBGRA_8888_ColorFormat, src, dstInfo.width(),
+ xformAlphaType));
dst = SkTAddOffset<void>(dst, rowBytes);
src = SkTAddOffset<uint32_t>(src, srcRowBytes);
}