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>
diff --git a/src/codec/SkAndroidCodec.cpp b/src/codec/SkAndroidCodec.cpp
index 76ad0f9..3a4d2b3 100644
--- a/src/codec/SkAndroidCodec.cpp
+++ b/src/codec/SkAndroidCodec.cpp
@@ -179,18 +179,15 @@
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 354bee6..3d3782b 100644
--- a/src/codec/SkBmpCodec.cpp
+++ b/src/codec/SkBmpCodec.cpp
@@ -615,7 +615,9 @@
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 e9eeb45..5bdb3e2 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 @@
}
}
-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 026120f..5bf0272 100644
--- a/src/codec/SkCodecPriv.h
+++ b/src/codec/SkCodecPriv.h
@@ -301,7 +301,7 @@
}
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 @@
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 2903717..a70f7be 100644
--- a/src/codec/SkGifCodec.cpp
+++ b/src/codec/SkGifCodec.cpp
@@ -183,7 +183,9 @@
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 624bc25..213c587 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -583,7 +583,7 @@
return fDecoderMgr->returnFailure("setjmp", kInvalidInput);
}
- if (!this->initializeColorXform(dstInfo)) {
+ if (!this->initializeColorXform(dstInfo, options.fPremulBehavior)) {
return kInvalidConversion;
}
@@ -692,7 +692,7 @@
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 b6258ab..901f55f 100644
--- a/src/codec/SkPngCodec.cpp
+++ b/src/codec/SkPngCodec.cpp
@@ -1093,7 +1093,7 @@
// 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 97baa9c..272f737 100644
--- a/src/codec/SkRawCodec.cpp
+++ b/src/codec/SkRawCodec.cpp
@@ -690,7 +690,9 @@
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 1d9953b..2b6483b 100644
--- a/src/codec/SkSampledCodec.cpp
+++ b/src/codec/SkSampledCodec.cpp
@@ -75,6 +75,7 @@
// 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 @@
// 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 5aefe5d..cf1f0e0 100644
--- a/src/codec/SkWebpAdapterCodec.cpp
+++ b/src/codec/SkWebpAdapterCodec.cpp
@@ -40,6 +40,7 @@
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 c602fcd..ae8668b 100644
--- a/src/codec/SkWebpCodec.cpp
+++ b/src/codec/SkWebpCodec.cpp
@@ -194,11 +194,9 @@
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;
}