OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2007 The Android Open Source Project | 2 * Copyright 2007 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "SkImageDecoder.h" | 9 #include "SkImageDecoder.h" |
10 #include "SkImageEncoder.h" | 10 #include "SkImageEncoder.h" |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 * Common code for setting the error manager. | 216 * Common code for setting the error manager. |
217 */ | 217 */ |
218 static void set_error_mgr(jpeg_decompress_struct* cinfo, skjpeg_error_mgr* error
Manager) { | 218 static void set_error_mgr(jpeg_decompress_struct* cinfo, skjpeg_error_mgr* error
Manager) { |
219 SkASSERT(cinfo != nullptr); | 219 SkASSERT(cinfo != nullptr); |
220 SkASSERT(errorManager != nullptr); | 220 SkASSERT(errorManager != nullptr); |
221 cinfo->err = jpeg_std_error(errorManager); | 221 cinfo->err = jpeg_std_error(errorManager); |
222 errorManager->error_exit = skjpeg_error_exit; | 222 errorManager->error_exit = skjpeg_error_exit; |
223 } | 223 } |
224 | 224 |
225 /** | 225 /** |
226 * Common code for turning off upsampling and smoothing. Turning these | |
227 * off helps performance without showing noticable differences in the | |
228 * resulting bitmap. | |
229 */ | |
230 static void turn_off_visual_optimizations(jpeg_decompress_struct* cinfo) { | |
231 SkASSERT(cinfo != nullptr); | |
232 /* this gives about 30% performance improvement. In theory it may | |
233 reduce the visual quality, in practice I'm not seeing a difference | |
234 */ | |
235 cinfo->do_fancy_upsampling = 0; | |
236 | |
237 /* this gives another few percents */ | |
238 cinfo->do_block_smoothing = 0; | |
239 } | |
240 | |
241 /** | |
242 * Common code for setting the dct method. | 226 * Common code for setting the dct method. |
243 */ | 227 */ |
244 static void set_dct_method(const SkImageDecoder& decoder, jpeg_decompress_struct
* cinfo) { | 228 static void set_dct_method(const SkImageDecoder& decoder, jpeg_decompress_struct
* cinfo) { |
245 SkASSERT(cinfo != nullptr); | 229 SkASSERT(cinfo != nullptr); |
246 #ifdef DCT_IFAST_SUPPORTED | |
247 if (decoder.getPreferQualityOverSpeed()) { | |
248 cinfo->dct_method = JDCT_ISLOW; | |
249 } else { | |
250 cinfo->dct_method = JDCT_IFAST; | |
251 } | |
252 #else | |
253 cinfo->dct_method = JDCT_ISLOW; | 230 cinfo->dct_method = JDCT_ISLOW; |
254 #endif | |
255 } | 231 } |
256 | 232 |
257 SkColorType SkJPEGImageDecoder::getBitmapColorType(jpeg_decompress_struct* cinfo
) { | 233 SkColorType SkJPEGImageDecoder::getBitmapColorType(jpeg_decompress_struct* cinfo
) { |
258 SkASSERT(cinfo != nullptr); | 234 SkASSERT(cinfo != nullptr); |
259 | 235 |
260 SrcDepth srcDepth = k32Bit_SrcDepth; | 236 SrcDepth srcDepth = k32Bit_SrcDepth; |
261 if (JCS_GRAYSCALE == cinfo->jpeg_color_space) { | 237 if (JCS_GRAYSCALE == cinfo->jpeg_color_space) { |
262 srcDepth = k8BitGray_SrcDepth; | 238 srcDepth = k8BitGray_SrcDepth; |
263 } | 239 } |
264 | 240 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 can) much faster that we, just use their num/denom api to approximate | 389 can) much faster that we, just use their num/denom api to approximate |
414 the size. | 390 the size. |
415 */ | 391 */ |
416 int sampleSize = this->getSampleSize(); | 392 int sampleSize = this->getSampleSize(); |
417 | 393 |
418 set_dct_method(*this, &cinfo); | 394 set_dct_method(*this, &cinfo); |
419 | 395 |
420 SkASSERT(1 == cinfo.scale_num); | 396 SkASSERT(1 == cinfo.scale_num); |
421 cinfo.scale_denom = sampleSize; | 397 cinfo.scale_denom = sampleSize; |
422 | 398 |
423 turn_off_visual_optimizations(&cinfo); | |
424 | |
425 const SkColorType colorType = this->getBitmapColorType(&cinfo); | 399 const SkColorType colorType = this->getBitmapColorType(&cinfo); |
426 const SkAlphaType alphaType = kAlpha_8_SkColorType == colorType ? | 400 const SkAlphaType alphaType = kAlpha_8_SkColorType == colorType ? |
427 kPremul_SkAlphaType : kOpaque_SkAlphaType; | 401 kPremul_SkAlphaType : kOpaque_SkAlphaType; |
428 | 402 |
429 adjust_out_color_space_and_dither(&cinfo, colorType, *this); | 403 adjust_out_color_space_and_dither(&cinfo, colorType, *this); |
430 | 404 |
431 if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) { | 405 if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) { |
432 // Assume an A8 bitmap is not opaque to avoid the check of each | 406 // Assume an A8 bitmap is not opaque to avoid the check of each |
433 // individual pixel. It is very unlikely to be opaque, since | 407 // individual pixel. It is very unlikely to be opaque, since |
434 // an opaque A8 bitmap would not be very interesting. | 408 // an opaque A8 bitmap would not be very interesting. |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 if (!planes || !planes[0] || !rowBytes || !rowBytes[0]) { // Compute size on
ly | 714 if (!planes || !planes[0] || !rowBytes || !rowBytes[0]) { // Compute size on
ly |
741 update_components_sizes(cinfo, componentSizes, kSizeForMemoryAllocation_
SizeType); | 715 update_components_sizes(cinfo, componentSizes, kSizeForMemoryAllocation_
SizeType); |
742 return true; | 716 return true; |
743 } | 717 } |
744 | 718 |
745 set_dct_method(*this, &cinfo); | 719 set_dct_method(*this, &cinfo); |
746 | 720 |
747 SkASSERT(1 == cinfo.scale_num); | 721 SkASSERT(1 == cinfo.scale_num); |
748 cinfo.scale_denom = 1; | 722 cinfo.scale_denom = 1; |
749 | 723 |
750 turn_off_visual_optimizations(&cinfo); | |
751 | |
752 #ifdef ANDROID_RGB | 724 #ifdef ANDROID_RGB |
753 cinfo.dither_mode = JDITHER_NONE; | 725 cinfo.dither_mode = JDITHER_NONE; |
754 #endif | 726 #endif |
755 | 727 |
756 /* image_width and image_height are the original dimensions, available | 728 /* image_width and image_height are the original dimensions, available |
757 after jpeg_read_header(). To see the scaled dimensions, we have to call | 729 after jpeg_read_header(). To see the scaled dimensions, we have to call |
758 jpeg_start_decompress(), and then read output_width and output_height. | 730 jpeg_start_decompress(), and then read output_width and output_height. |
759 */ | 731 */ |
760 if (!jpeg_start_decompress(&cinfo)) { | 732 if (!jpeg_start_decompress(&cinfo)) { |
761 return return_false(cinfo, "start_decompress YUV8"); | 733 return return_false(cinfo, "start_decompress YUV8"); |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1056 return SkImageDecoder::kUnknown_Format; | 1028 return SkImageDecoder::kUnknown_Format; |
1057 } | 1029 } |
1058 | 1030 |
1059 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { | 1031 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { |
1060 return (SkImageEncoder::kJPEG_Type == t) ? new SkJPEGImageEncoder : nullptr; | 1032 return (SkImageEncoder::kJPEG_Type == t) ? new SkJPEGImageEncoder : nullptr; |
1061 } | 1033 } |
1062 | 1034 |
1063 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); | 1035 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); |
1064 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); | 1036 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); |
1065 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); | 1037 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); |
OLD | NEW |