diff options
Diffstat (limited to 'src/images/SkJpegEncoder.cpp')
-rw-r--r-- | src/images/SkJpegEncoder.cpp | 48 |
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; } |