From 13bad33ef859f9c0d0796d3461d315c7c09b28c5 Mon Sep 17 00:00:00 2001 From: "Mort (Tianqi) Guo" Date: Thu, 8 Feb 2018 10:49:27 -0800 Subject: [PATCH] external/skia: Take Fast Jpeg Decoding Path For smaller pictures, we use fast upsampler. To do so, we disable fancy upsampler. However, when fancy upsampler disabled, libjpeg-turbo may choose to use merged upsampler, causing unwanted behavior. We need to make sure merged upsampler is disabled so that only fast upsampler will be used. We only use fast upsampler for smaller pictures because the visual difference(if there is any) will be even less noticeable. Change-Id: Id4031df1d5cd2be566c1de8f345993ef8880dcc3 Signed-off-by: Jason Edson --- src/codec/SkJpegCodec.cpp | 19 +++++++++++++++++++ src/codec/SkJpegCodec.h | 14 ++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp index ca3ac3b0417..49a18a46e2d 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -569,6 +569,21 @@ static inline bool needs_swizzler_to_convert_from_cmyk(J_COLOR_SPACE jpegColorTy return !hasCMYKColorSpace || !hasColorSpaceXform; } +void SkJpegCodec::setupJpegDecoding(jpeg_decompress_struct* dinfo) +{ + /* We only prefer speed over quality for small/medium pictures, + * where the difference will be even less noticeable. + */ + if(dinfo->image_width > kMedium_JpegDecodingSize || + dinfo->image_height > kMedium_JpegDecodingSize) { + return; + } + + dinfo->do_fancy_upsampling = FALSE; + dinfo->disable_merged_upsampling = TRUE; + dinfo->dct_method = JDCT_IFAST; +} + /* * Performs the jpeg decode */ @@ -590,6 +605,8 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo, return fDecoderMgr->returnFailure("setjmp", kInvalidInput); } + setupJpegDecoding(dinfo); + if (!jpeg_start_decompress(dinfo)) { return fDecoderMgr->returnFailure("startDecompress", kInvalidInput); } @@ -709,6 +726,8 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, return kInvalidInput; } + setupJpegDecoding(fDecoderMgr->dinfo()); + if (!jpeg_start_decompress(fDecoderMgr->dinfo())) { SkCodecPrintf("start decompress failed\n"); return kInvalidInput; diff --git a/src/codec/SkJpegCodec.h b/src/codec/SkJpegCodec.h index 5617c6bf346..420493defea 100644 --- a/src/codec/SkJpegCodec.h +++ b/src/codec/SkJpegCodec.h @@ -14,6 +14,10 @@ #include "SkStream.h" #include "SkTemplates.h" +extern "C" { + #include "jpeglib.h" +} + class JpegDecoderMgr; /* @@ -109,6 +113,16 @@ class SkJpegCodec : public SkCodec { void allocateStorage(const SkImageInfo& dstInfo); int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&); + /* + * Categorize JPEG image dimension. + * Can be used to apply different settings for different sizes. + */ + enum JpegDecodingSize: JDIMENSION { + kSmall_JpegDecodingSize = 400, + kMedium_JpegDecodingSize = 1600 + }; + static void setupJpegDecoding(jpeg_decompress_struct* dinfo); + /* * Scanline decoding. */