aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/images/SkJpegEncoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/images/SkJpegEncoder.cpp')
-rw-r--r--src/images/SkJpegEncoder.cpp48
1 files changed, 42 insertions, 6 deletions
diff --git a/src/images/SkJpegEncoder.cpp b/src/images/SkJpegEncoder.cpp
index fd88a5c8f6..d87fed81bc 100644
--- a/src/images/SkJpegEncoder.cpp
+++ b/src/images/SkJpegEncoder.cpp
@@ -35,7 +35,7 @@ public:
return std::unique_ptr<SkJpegEncoderMgr>(new SkJpegEncoderMgr(stream));
}
- bool setParams(const SkImageInfo& srcInfo);
+ bool setParams(const SkImageInfo& srcInfo, const SkJpegEncoder::Options& options);
jpeg_compress_struct* cinfo() { return &fCInfo; }
@@ -65,15 +65,36 @@ private:
transform_scanline_proc fProc;
};
-bool SkJpegEncoderMgr::setParams(const SkImageInfo& srcInfo) {
+bool SkJpegEncoderMgr::setParams(const SkImageInfo& srcInfo, const SkJpegEncoder::Options& options)
+{
+ auto chooseProc8888 = [&]() {
+ if (kUnpremul_SkAlphaType != srcInfo.alphaType() ||
+ SkJpegEncoder::AlphaOption::kIgnore == options.fAlphaOption)
+ {
+ return (transform_scanline_proc) nullptr;
+ }
+
+ // Note that kRespect mode is only supported with sRGB or linear transfer functions.
+ // The legacy code path is incidentally correct when the transfer function is linear.
+ const bool isSRGBTransferFn = srcInfo.gammaCloseToSRGB() &&
+ (SkTransferFunctionBehavior::kRespect == options.fBlendBehavior);
+ if (isSRGBTransferFn) {
+ return transform_scanline_to_premul_linear;
+ } else {
+ return transform_scanline_to_premul_legacy;
+ }
+ };
+
J_COLOR_SPACE jpegColorType = JCS_EXT_RGBA;
int numComponents = 0;
switch (srcInfo.colorType()) {
case kRGBA_8888_SkColorType:
+ fProc = chooseProc8888();
jpegColorType = JCS_EXT_RGBA;
numComponents = 4;
break;
case kBGRA_8888_SkColorType:
+ fProc = chooseProc8888();
jpegColorType = JCS_EXT_BGRA;
numComponents = 4;
break;
@@ -83,11 +104,19 @@ bool SkJpegEncoderMgr::setParams(const SkImageInfo& srcInfo) {
numComponents = 3;
break;
case kARGB_4444_SkColorType:
+ if (SkJpegEncoder::AlphaOption::kBlendOnBlack == options.fAlphaOption) {
+ return false;
+ }
+
fProc = transform_scanline_444;
jpegColorType = JCS_RGB;
numComponents = 3;
break;
case kIndex_8_SkColorType:
+ if (SkJpegEncoder::AlphaOption::kBlendOnBlack == options.fAlphaOption) {
+ return false;
+ }
+
fProc = transform_scanline_index8_opaque;
jpegColorType = JCS_RGB;
numComponents = 3;
@@ -98,11 +127,18 @@ bool SkJpegEncoderMgr::setParams(const SkImageInfo& srcInfo) {
numComponents = 1;
break;
case kRGBA_F16_SkColorType:
- if (!srcInfo.colorSpace() || !srcInfo.colorSpace()->gammaIsLinear()) {
+ if (!srcInfo.colorSpace() || !srcInfo.colorSpace()->gammaIsLinear() ||
+ SkTransferFunctionBehavior::kRespect != options.fBlendBehavior) {
return false;
}
- fProc = transform_scanline_F16_to_8888;
+ if (kUnpremul_SkAlphaType != srcInfo.alphaType() ||
+ SkJpegEncoder::AlphaOption::kIgnore == options.fAlphaOption)
+ {
+ fProc = transform_scanline_F16_to_8888;
+ } else {
+ fProc = transform_scanline_F16_to_premul_8888;
+ }
jpegColorType = JCS_EXT_RGBA;
numComponents = 4;
break;
@@ -125,7 +161,7 @@ bool SkJpegEncoderMgr::setParams(const SkImageInfo& srcInfo) {
std::unique_ptr<SkJpegEncoder> SkJpegEncoder::Make(SkWStream* dst, const SkPixmap& src,
const Options& options) {
- if (!SkPixmapIsValid(src, SkTransferFunctionBehavior::kIgnore)) {
+ if (!SkPixmapIsValid(src, options.fBlendBehavior)) {
return nullptr;
}
@@ -134,7 +170,7 @@ std::unique_ptr<SkJpegEncoder> SkJpegEncoder::Make(SkWStream* dst, const SkPixma
return nullptr;
}
- if (!encoderMgr->setParams(src.info())) {
+ if (!encoderMgr->setParams(src.info(), options)) {
return nullptr;
}