aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Matt Sarett <msarett@google.com>2017-03-23 15:32:25 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-24 13:19:53 +0000
commitcf3f2347c8933596aeba873d4ece597a9339392f (patch)
treed340f5802bb11ffe902b5f95ea06c6b75c5ccd74
parenta3bdd44aff94974e720ed04b860fbfe24f8f431e (diff)
Add SkTransferFunctionBehavior flag: Use in codec and encoder
This is a step towards removing the non-linear blending flag from SkColorSpace. The flag on SkColorSpace used to control the premul behavior - now it is controlled by this option. BUG=skia: Change-Id: Ia29bd8c2b0596a93c6aa14332dcd9bd39e388a90 Reviewed-on: https://skia-review.googlesource.com/10008 Reviewed-by: Mike Reed <reed@google.com> Reviewed-by: Leon Scroggins <scroggo@google.com> Commit-Queue: Matt Sarett <msarett@google.com>
-rw-r--r--gm/encode-srgb.cpp2
-rw-r--r--include/codec/SkCodec.h20
-rw-r--r--include/core/SkColorSpace.h13
-rw-r--r--src/codec/SkAndroidCodec.cpp9
-rw-r--r--src/codec/SkBmpCodec.cpp4
-rw-r--r--src/codec/SkCodec.cpp13
-rw-r--r--src/codec/SkCodecPriv.h6
-rw-r--r--src/codec/SkGifCodec.cpp4
-rw-r--r--src/codec/SkJpegCodec.cpp4
-rw-r--r--src/codec/SkPngCodec.cpp2
-rw-r--r--src/codec/SkRawCodec.cpp4
-rw-r--r--src/codec/SkSampledCodec.cpp2
-rw-r--r--src/codec/SkWebpAdapterCodec.cpp1
-rw-r--r--src/codec/SkWebpCodec.cpp8
-rw-r--r--src/core/SkColorSpaceXform.cpp30
-rw-r--r--src/core/SkColorSpaceXform_A2B.h2
-rw-r--r--src/core/SkColorSpaceXform_Base.h23
-rw-r--r--src/images/SkImageEncoderPriv.h10
-rw-r--r--src/images/SkJPEGImageEncoder.cpp2
-rw-r--r--src/images/SkPNGImageEncoder.cpp2
-rw-r--r--src/images/SkWEBPImageEncoder.cpp2
-rw-r--r--tests/CodecTest.cpp2
22 files changed, 97 insertions, 68 deletions
diff --git a/gm/encode-srgb.cpp b/gm/encode-srgb.cpp
index 2a89ea3579..f62d48ae2c 100644
--- a/gm/encode-srgb.cpp
+++ b/gm/encode-srgb.cpp
@@ -119,7 +119,7 @@ static sk_sp<SkData> encode_data(const SkBitmap& bitmap, SkEncodedImageFormat fo
SkEncodeOptions options;
if (bitmap.colorSpace()) {
- options.fColorBehavior = SkEncodeOptions::ColorBehavior::kCorrect;
+ options.fUnpremulBehavior = SkTransferFunctionBehavior::kRespect;
}
switch (format) {
diff --git a/include/codec/SkCodec.h b/include/codec/SkCodec.h
index 13730e2a73..11d28ea8f2 100644
--- a/include/codec/SkCodec.h
+++ b/include/codec/SkCodec.h
@@ -249,9 +249,10 @@ public:
, fSubset(nullptr)
, fFrameIndex(0)
, fHasPriorFrame(false)
+ , fPremulBehavior(SkTransferFunctionBehavior::kRespect)
{}
- ZeroInitialized fZeroInitialized;
+ ZeroInitialized fZeroInitialized;
/**
* If not NULL, represents a subset of the original image to decode.
* Must be within the bounds returned by getInfo().
@@ -269,14 +270,14 @@ public:
* subset left and subset width to decode partial scanlines on calls
* to getScanlines().
*/
- const SkIRect* fSubset;
+ const SkIRect* fSubset;
/**
* The frame to decode.
*
* Only meaningful for multi-frame images.
*/
- size_t fFrameIndex;
+ size_t fFrameIndex;
/**
* If true, the dst already contains the prior frame.
@@ -295,7 +296,15 @@ public:
* codec needs to first decode the prior frame (which in turn may need
* to decode its prior frame).
*/
- bool fHasPriorFrame;
+ bool fHasPriorFrame;
+
+ /**
+ * Indicates whether we should do a linear premultiply or a legacy premultiply.
+ *
+ * In the case where the dst SkColorSpace is nullptr, this flag is ignored and
+ * we will always do a legacy premultiply.
+ */
+ SkTransferFunctionBehavior fPremulBehavior;
};
/**
@@ -781,7 +790,8 @@ protected:
virtual int onOutputScanline(int inputScanline) const;
- bool initializeColorXform(const SkImageInfo& dstInfo);
+ bool initializeColorXform(const SkImageInfo& dstInfo,
+ SkTransferFunctionBehavior premulBehavior);
SkColorSpaceXform* colorXform() const { return fColorXform.get(); }
virtual std::vector<FrameInfo> onGetFrameInfo() {
diff --git a/include/core/SkColorSpace.h b/include/core/SkColorSpace.h
index ebc0ca1d91..27288f76d8 100644
--- a/include/core/SkColorSpace.h
+++ b/include/core/SkColorSpace.h
@@ -174,4 +174,17 @@ protected:
SkColorSpace() {}
};
+enum class SkTransferFunctionBehavior {
+ /**
+ * Converts to a linear space before premultiplying, unpremultiplying, or blending.
+ */
+ kRespect,
+
+ /**
+ * Premultiplies, unpremultiplies, and blends ignoring the transfer function. Pixels are
+ * treated as if they are linear, regardless of their transfer function encoding.
+ */
+ kIgnore,
+};
+
#endif
diff --git a/src/codec/SkAndroidCodec.cpp b/src/codec/SkAndroidCodec.cpp
index 76ad0f94e7..3a4d2b3bbb 100644
--- a/src/codec/SkAndroidCodec.cpp
+++ b/src/codec/SkAndroidCodec.cpp
@@ -179,18 +179,15 @@ sk_sp<SkColorSpace> SkAndroidCodec::computeOutputColorSpace(SkColorType outputCo
if (encodedSpace->isNumericalTransferFn(&fn)) {
// Leave the pixels in the encoded color space. Color space conversion
// will be handled after decode time.
- return as_CSB(encodedSpace)->makeWithNonLinearBlending();
+ return sk_ref_sp(encodedSpace);
}
if (is_wide_gamut(encodedSpace)) {
return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
- SkColorSpace::kDCIP3_D65_Gamut,
- SkColorSpace::kNonLinearBlending_ColorSpaceFlag);
+ SkColorSpace::kDCIP3_D65_Gamut);
}
- return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
- SkColorSpace::kSRGB_Gamut,
- SkColorSpace::kNonLinearBlending_ColorSpaceFlag);
+ return SkColorSpace::MakeSRGB();
}
case kRGBA_F16_SkColorType:
return SkColorSpace::MakeSRGBLinear();
diff --git a/src/codec/SkBmpCodec.cpp b/src/codec/SkBmpCodec.cpp
index 354bee6f74..3d3782b4f5 100644
--- a/src/codec/SkBmpCodec.cpp
+++ b/src/codec/SkBmpCodec.cpp
@@ -615,7 +615,9 @@ int32_t SkBmpCodec::getDstRow(int32_t y, int32_t height) const {
SkCodec::Result SkBmpCodec::prepareToDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
- if (!conversion_possible(dstInfo, this->getInfo()) || !this->initializeColorXform(dstInfo)) {
+ if (!conversion_possible(dstInfo, this->getInfo()) ||
+ !this->initializeColorXform(dstInfo, options.fPremulBehavior))
+ {
return kInvalidConversion;
}
diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp
index e9eeb4529a..5bdb3e2b59 100644
--- a/src/codec/SkCodec.cpp
+++ b/src/codec/SkCodec.cpp
@@ -9,7 +9,7 @@
#include "SkCodec.h"
#include "SkCodecPriv.h"
#include "SkColorSpace.h"
-#include "SkColorSpaceXform.h"
+#include "SkColorSpaceXform_Base.h"
#include "SkData.h"
#include "SkGifCodec.h"
#include "SkHalf.h"
@@ -474,11 +474,14 @@ void SkCodec::fillIncompleteImage(const SkImageInfo& info, void* dst, size_t row
}
}
-bool SkCodec::initializeColorXform(const SkImageInfo& dstInfo) {
+bool SkCodec::initializeColorXform(const SkImageInfo& dstInfo,
+ SkTransferFunctionBehavior premulBehavior) {
fColorXform = nullptr;
- bool needsPremul = needs_premul(dstInfo, fEncodedInfo);
- if (needs_color_xform(dstInfo, fSrcInfo, needsPremul)) {
- fColorXform = SkColorSpaceXform::New(fSrcInfo.colorSpace(), dstInfo.colorSpace());
+ bool needsColorCorrectPremul = needs_premul(dstInfo, fEncodedInfo) &&
+ SkTransferFunctionBehavior::kRespect == premulBehavior;
+ if (needs_color_xform(dstInfo, fSrcInfo, needsColorCorrectPremul)) {
+ fColorXform = SkColorSpaceXform_Base::New(fSrcInfo.colorSpace(), dstInfo.colorSpace(),
+ premulBehavior);
if (!fColorXform) {
return false;
}
diff --git a/src/codec/SkCodecPriv.h b/src/codec/SkCodecPriv.h
index 026120fe79..5bf0272f6e 100644
--- a/src/codec/SkCodecPriv.h
+++ b/src/codec/SkCodecPriv.h
@@ -301,7 +301,7 @@ static inline bool needs_premul(const SkImageInfo& dstInfo, const SkEncodedInfo&
}
static inline bool needs_color_xform(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo,
- bool needsPremul) {
+ bool needsColorCorrectPremul) {
// We never perform a color xform in legacy mode.
if (!dstInfo.colorSpace()) {
return false;
@@ -314,10 +314,6 @@ static inline bool needs_color_xform(const SkImageInfo& dstInfo, const SkImageIn
bool srcDstNotEqual =
!SkColorSpace_Base::EqualsIgnoreFlags(srcInfo.colorSpace(), dstInfo.colorSpace());
- // We provide the option for both legacy premuls and color correct premuls.
- bool needsColorCorrectPremul =
- needsPremul && !as_CSB(dstInfo.colorSpace())->nonLinearBlending();
-
return needsColorCorrectPremul || isF16 || srcDstNotEqual;
}
diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp
index 2903717b48..a70f7be14e 100644
--- a/src/codec/SkGifCodec.cpp
+++ b/src/codec/SkGifCodec.cpp
@@ -183,7 +183,9 @@ void SkGifCodec::initializeColorTable(const SkImageInfo& dstInfo, size_t frameIn
SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColor* inputColorPtr,
int* inputColorCount, const Options& opts) {
// Check for valid input parameters
- if (!conversion_possible(dstInfo, this->getInfo()) || !this->initializeColorXform(dstInfo)) {
+ if (!conversion_possible(dstInfo, this->getInfo()) ||
+ !this->initializeColorXform(dstInfo, opts.fPremulBehavior))
+ {
return gif_error("Cannot convert input type to output type.\n", kInvalidConversion);
}
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index 624bc25845..213c5877fb 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -583,7 +583,7 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
}
- if (!this->initializeColorXform(dstInfo)) {
+ if (!this->initializeColorXform(dstInfo, options.fPremulBehavior)) {
return kInvalidConversion;
}
@@ -692,7 +692,7 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
return kInvalidInput;
}
- if (!this->initializeColorXform(dstInfo)) {
+ if (!this->initializeColorXform(dstInfo, options.fPremulBehavior)) {
return kInvalidConversion;
}
diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp
index b6258ab8b0..901f55f1e3 100644
--- a/src/codec/SkPngCodec.cpp
+++ b/src/codec/SkPngCodec.cpp
@@ -1093,7 +1093,7 @@ bool SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const Options& opt
// interlaced scanline decoder may need to rewind.
fSwizzler.reset(nullptr);
- if (!this->initializeColorXform(dstInfo)) {
+ if (!this->initializeColorXform(dstInfo, options.fPremulBehavior)) {
return false;
}
diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp
index 97baa9c2a7..272f737f18 100644
--- a/src/codec/SkRawCodec.cpp
+++ b/src/codec/SkRawCodec.cpp
@@ -690,7 +690,9 @@ SkCodec::Result SkRawCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
size_t dstRowBytes, const Options& options,
SkPMColor ctable[], int* ctableCount,
int* rowsDecoded) {
- if (!conversion_possible(dstInfo, this->getInfo()) || !this->initializeColorXform(dstInfo)) {
+ if (!conversion_possible(dstInfo, this->getInfo()) ||
+ !this->initializeColorXform(dstInfo, options.fPremulBehavior))
+ {
SkCodecPrintf("Error: cannot convert input type to output type.\n");
return kInvalidConversion;
}
diff --git a/src/codec/SkSampledCodec.cpp b/src/codec/SkSampledCodec.cpp
index 1d9953bb79..2b6483b058 100644
--- a/src/codec/SkSampledCodec.cpp
+++ b/src/codec/SkSampledCodec.cpp
@@ -75,6 +75,7 @@ SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void
// Create an Options struct for the codec.
SkCodec::Options codecOptions;
codecOptions.fZeroInitialized = options.fZeroInitialized;
+ codecOptions.fPremulBehavior = SkTransferFunctionBehavior::kIgnore;
SkIRect* subset = options.fSubset;
if (!subset || subset->size() == this->codec()->getInfo().dimensions()) {
@@ -171,6 +172,7 @@ SkCodec::Result SkSampledCodec::sampledDecode(const SkImageInfo& info, void* pix
// Create options struct for the codec.
SkCodec::Options sampledOptions;
sampledOptions.fZeroInitialized = options.fZeroInitialized;
+ sampledOptions.fPremulBehavior = SkTransferFunctionBehavior::kIgnore;
// FIXME: This was already called by onGetAndroidPixels. Can we reduce that?
int sampleSize = options.fSampleSize;
diff --git a/src/codec/SkWebpAdapterCodec.cpp b/src/codec/SkWebpAdapterCodec.cpp
index 5aefe5d805..cf1f0e0e1f 100644
--- a/src/codec/SkWebpAdapterCodec.cpp
+++ b/src/codec/SkWebpAdapterCodec.cpp
@@ -40,6 +40,7 @@ SkCodec::Result SkWebpAdapterCodec::onGetAndroidPixels(const SkImageInfo& info,
SkCodec::Options codecOptions;
codecOptions.fZeroInitialized = options.fZeroInitialized;
codecOptions.fSubset = options.fSubset;
+ codecOptions.fPremulBehavior = SkTransferFunctionBehavior::kIgnore;
return this->codec()->getPixels(info, pixels, rowBytes, &codecOptions, options.fColorPtr,
options.fColorCount);
}
diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp
index c602fcd784..ae8668bd06 100644
--- a/src/codec/SkWebpCodec.cpp
+++ b/src/codec/SkWebpCodec.cpp
@@ -194,11 +194,9 @@ bool SkWebpCodec::onGetValidSubset(SkIRect* desiredSubset) const {
SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
const Options& options, SkPMColor*, int*,
int* rowsDecodedPtr) {
- if (!conversion_possible(dstInfo, this->getInfo())) {
- return kInvalidConversion;
- }
-
- if (!this->initializeColorXform(dstInfo)) {
+ if (!conversion_possible(dstInfo, this->getInfo()) ||
+ !this->initializeColorXform(dstInfo, options.fPremulBehavior))
+ {
return kInvalidConversion;
}
diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp
index b81c23c6b7..317992036d 100644
--- a/src/core/SkColorSpaceXform.cpp
+++ b/src/core/SkColorSpaceXform.cpp
@@ -292,6 +292,12 @@ void SkColorSpaceXform_Base::BuildDstGammaTables(const uint8_t* dstGammaTables[3
std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(SkColorSpace* srcSpace,
SkColorSpace* dstSpace) {
+ return SkColorSpaceXform_Base::New(srcSpace, dstSpace, SkTransferFunctionBehavior::kRespect);
+}
+
+std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform_Base::New(SkColorSpace* srcSpace,
+ SkColorSpace* dstSpace, SkTransferFunctionBehavior premulBehavior) {
+
if (!srcSpace || !dstSpace) {
// Invalid input
return nullptr;
@@ -328,13 +334,13 @@ std::unique_ptr<SkColorSpaceXform> SkColorSpaceXform::New(SkColorSpace* srcSpace
switch (csm) {
case kNone_ColorSpaceMatch:
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
- <kNone_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
+ <kNone_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ, premulBehavior));
case kGamut_ColorSpaceMatch:
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
- <kGamut_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
+ <kGamut_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ, premulBehavior));
case kFull_ColorSpaceMatch:
return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
- <kFull_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ));
+ <kFull_ColorSpaceMatch>(srcSpaceXYZ, srcToDst, dstSpaceXYZ, premulBehavior));
default:
SkASSERT(false);
return nullptr;
@@ -931,8 +937,8 @@ static AI int num_tables(SkColorSpace_XYZ* space) {
template <ColorSpaceMatch kCSM>
SkColorSpaceXform_XYZ<kCSM>
::SkColorSpaceXform_XYZ(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst,
- SkColorSpace_XYZ* dstSpace)
- : fLinearBlending(!dstSpace->nonLinearBlending())
+ SkColorSpace_XYZ* dstSpace, SkTransferFunctionBehavior premulBehavior)
+ : fPremulBehavior(premulBehavior)
{
fSrcToDst[ 0] = srcToDst.get(0, 0);
fSrcToDst[ 1] = srcToDst.get(1, 0);
@@ -1227,7 +1233,8 @@ bool SkColorSpaceXform_XYZ<kCSM>
}
}
- if (kPremul_SkAlphaType == alphaType && fLinearBlending) {
+ if (kPremul_SkAlphaType == alphaType && SkTransferFunctionBehavior::kRespect == fPremulBehavior)
+ {
pipeline.append(SkRasterPipeline::premul);
}
@@ -1249,7 +1256,8 @@ bool SkColorSpaceXform_XYZ<kCSM>
break;
}
- if (kPremul_SkAlphaType == alphaType && !fLinearBlending) {
+ if (kPremul_SkAlphaType == alphaType && SkTransferFunctionBehavior::kIgnore == fPremulBehavior)
+ {
pipeline.append(SkRasterPipeline::premul);
}
@@ -1262,13 +1270,13 @@ bool SkColorSpaceXform_XYZ<kCSM>
pipeline.append(SkRasterPipeline::store_8888, &dst);
break;
case kRGBA_F16_ColorFormat:
- if (kLinear_DstGamma != fDstGamma || !fLinearBlending) {
+ if (kLinear_DstGamma != fDstGamma) {
return false;
}
pipeline.append(SkRasterPipeline::store_f16, &dst);
break;
case kRGBA_F32_ColorFormat:
- if (kLinear_DstGamma != fDstGamma || !fLinearBlending) {
+ if (kLinear_DstGamma != fDstGamma) {
return false;
}
pipeline.append(SkRasterPipeline::store_f32, &dst);
@@ -1284,6 +1292,6 @@ bool SkColorSpaceXform_XYZ<kCSM>
///////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space) {
- return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ
- <kNone_ColorSpaceMatch>(space, SkMatrix::I(), space));
+ return std::unique_ptr<SkColorSpaceXform>(new SkColorSpaceXform_XYZ<kNone_ColorSpaceMatch>
+ (space, SkMatrix::I(), space, SkTransferFunctionBehavior::kRespect));
}
diff --git a/src/core/SkColorSpaceXform_A2B.h b/src/core/SkColorSpaceXform_A2B.h
index 9376491fa1..937402026d 100644
--- a/src/core/SkColorSpaceXform_A2B.h
+++ b/src/core/SkColorSpaceXform_A2B.h
@@ -53,7 +53,7 @@ private:
std::forward_list<std::vector<float>> fTableStorage;
std::vector<sk_sp<const SkGammas>> fGammaRefs;
- friend class SkColorSpaceXform;
+ friend class SkColorSpaceXform_Base;
};
#endif
diff --git a/src/core/SkColorSpaceXform_Base.h b/src/core/SkColorSpaceXform_Base.h
index cb98c68567..f72ace0fb5 100644
--- a/src/core/SkColorSpaceXform_Base.h
+++ b/src/core/SkColorSpaceXform_Base.h
@@ -19,6 +19,9 @@ class SkColorSpaceXform_Base : public SkColorSpaceXform {
public:
static constexpr int kDstGammaTableSize = 1024;
+ static std::unique_ptr<SkColorSpaceXform> New(SkColorSpace* srcSpace, SkColorSpace* dstSpace,
+ SkTransferFunctionBehavior premulBehavior);
+
protected:
virtual bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src,
int count, SkAlphaType alphaType) const = 0;
@@ -61,22 +64,22 @@ private:
int count, SkAlphaType alphaType) const;
SkColorSpaceXform_XYZ(SkColorSpace_XYZ* srcSpace, const SkMatrix44& srcToDst,
- SkColorSpace_XYZ* dstSpace);
+ SkColorSpace_XYZ* dstSpace, SkTransferFunctionBehavior premulBehavior);
// Contain pointers into storage or pointers into precomputed tables.
- const float* fSrcGammaTables[3];
- SkAutoTMalloc<float> fSrcStorage;
- const uint8_t* fDstGammaTables[3];
- sk_sp<SkData> fDstStorage;
+ const float* fSrcGammaTables[3];
+ SkAutoTMalloc<float> fSrcStorage;
+ const uint8_t* fDstGammaTables[3];
+ sk_sp<SkData> fDstStorage;
// Holds a 3x4 matrix. Padding is useful for vector loading.
- float fSrcToDst[13];
+ float fSrcToDst[13];
- SrcGamma fSrcGamma;
- DstGamma fDstGamma;
- bool fLinearBlending;
+ SrcGamma fSrcGamma;
+ DstGamma fDstGamma;
+ SkTransferFunctionBehavior fPremulBehavior;
- friend class SkColorSpaceXform;
+ friend class SkColorSpaceXform_Base;
friend std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace_XYZ* space);
};
diff --git a/src/images/SkImageEncoderPriv.h b/src/images/SkImageEncoderPriv.h
index 69d45fbf8c..540d93093b 100644
--- a/src/images/SkImageEncoderPriv.h
+++ b/src/images/SkImageEncoderPriv.h
@@ -11,15 +11,7 @@
#include "SkImageEncoder.h"
struct SkEncodeOptions {
- enum class ColorBehavior {
- // Convert to a linear space before premultiplying or unpremultiplying.
- kCorrect,
-
- // Ignore the transfer function when premultiplying or unpremultiplying.
- kLegacy,
- };
-
- ColorBehavior fColorBehavior = ColorBehavior::kLegacy;
+ SkTransferFunctionBehavior fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore;
};
#ifdef SK_HAS_JPEG_LIBRARY
diff --git a/src/images/SkJPEGImageEncoder.cpp b/src/images/SkJPEGImageEncoder.cpp
index 014a0ae160..845673421c 100644
--- a/src/images/SkJPEGImageEncoder.cpp
+++ b/src/images/SkJPEGImageEncoder.cpp
@@ -86,7 +86,7 @@ bool SkEncodeImageAsJPEG(SkWStream* stream, const SkPixmap& pixmap, const SkEnco
pixmap.colorSpace()->gammaIsLinear());
SkPixmap src = pixmap;
- if (SkEncodeOptions::ColorBehavior::kLegacy == opts.fColorBehavior) {
+ if (SkTransferFunctionBehavior::kIgnore == opts.fUnpremulBehavior) {
src.setColorSpace(nullptr);
} else {
// kCorrect behavior requires a color space. It's not actually critical in the
diff --git a/src/images/SkPNGImageEncoder.cpp b/src/images/SkPNGImageEncoder.cpp
index e28ae12dc0..9f5ebd27ab 100644
--- a/src/images/SkPNGImageEncoder.cpp
+++ b/src/images/SkPNGImageEncoder.cpp
@@ -181,7 +181,7 @@ bool SkEncodeImageAsPNG(SkWStream* stream, const SkPixmap& src, const SkEncodeOp
src.colorSpace()->gammaIsLinear());
SkPixmap pixmap = src;
- if (SkEncodeOptions::ColorBehavior::kLegacy == opts.fColorBehavior) {
+ if (SkTransferFunctionBehavior::kIgnore == opts.fUnpremulBehavior) {
pixmap.setColorSpace(nullptr);
} else {
if (!pixmap.colorSpace()) {
diff --git a/src/images/SkWEBPImageEncoder.cpp b/src/images/SkWEBPImageEncoder.cpp
index a9fcc31265..28dff0569c 100644
--- a/src/images/SkWEBPImageEncoder.cpp
+++ b/src/images/SkWEBPImageEncoder.cpp
@@ -126,7 +126,7 @@ static bool do_encode(SkWStream* stream, const SkPixmap& srcPixmap, const SkEnco
srcPixmap.colorSpace()->gammaIsLinear());
SkPixmap pixmap = srcPixmap;
- if (SkEncodeOptions::ColorBehavior::kLegacy == opts.fColorBehavior) {
+ if (SkTransferFunctionBehavior::kIgnore == opts.fUnpremulBehavior) {
pixmap.setColorSpace(nullptr);
} else {
if (!pixmap.colorSpace()) {
diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp
index da75ffb414..dd11ff84fd 100644
--- a/tests/CodecTest.cpp
+++ b/tests/CodecTest.cpp
@@ -1555,7 +1555,7 @@ static void test_encode_icc(skiatest::Reporter* r, SkEncodedImageFormat format)
srgbBitmap.peekPixels(&pixmap);
SkDynamicMemoryWStream srgbBuf;
SkEncodeOptions opts;
- opts.fColorBehavior = SkEncodeOptions::ColorBehavior::kCorrect;
+ opts.fUnpremulBehavior = SkTransferFunctionBehavior::kRespect;
encode_format(&srgbBuf, pixmap, opts, format);
sk_sp<SkData> srgbData = srgbBuf.detachAsData();
std::unique_ptr<SkCodec> srgbCodec(SkCodec::NewFromData(srgbData));