| 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 |