1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkJpegDecoderMgr.h" 9 10 #include "SkJpegUtility.h" 11 12 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 13 #include "SkAndroidFrameworkUtils.h" 14 #endif 15 16 /* 17 * Print information, warning, and error messages 18 */ 19 static void print_message(const j_common_ptr info, const char caller[]) { 20 char buffer[JMSG_LENGTH_MAX]; 21 info->err->format_message(info, buffer); 22 SkCodecPrintf("libjpeg error %d <%s> from %s\n", info->err->msg_code, buffer, caller); 23 } 24 25 /* 26 * Reporting function for error and warning messages. 27 */ 28 static void output_message(j_common_ptr info) { 29 print_message(info, "output_message"); 30 } 31 32 static void progress_monitor(j_common_ptr info) { 33 int scan = ((j_decompress_ptr)info)->input_scan_number; 34 // Progressive images with a very large number of scans can cause the 35 // decoder to hang. Here we use the progress monitor to abort on 36 // a very large number of scans. 100 is arbitrary, but much larger 37 // than the number of scans we might expect in a normal image. 38 if (scan >= 100) { 39 skjpeg_err_exit(info); 40 } 41 } 42 43 bool JpegDecoderMgr::returnFalse(const char caller[]) { 44 print_message((j_common_ptr) &fDInfo, caller); 45 return false; 46 } 47 48 SkCodec::Result JpegDecoderMgr::returnFailure(const char caller[], SkCodec::Result result) { 49 print_message((j_common_ptr) &fDInfo, caller); 50 return result; 51 } 52 53 bool JpegDecoderMgr::getEncodedColor(SkEncodedInfo::Color* outColor) { 54 switch (fDInfo.jpeg_color_space) { 55 case JCS_GRAYSCALE: 56 *outColor = SkEncodedInfo::kGray_Color; 57 return true; 58 case JCS_YCbCr: 59 *outColor = SkEncodedInfo::kYUV_Color; 60 return true; 61 case JCS_RGB: 62 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 63 SkAndroidFrameworkUtils::SafetyNetLog("118372692"); 64 #endif 65 *outColor = SkEncodedInfo::kRGB_Color; 66 return true; 67 case JCS_YCCK: 68 *outColor = SkEncodedInfo::kYCCK_Color; 69 return true; 70 case JCS_CMYK: 71 *outColor = SkEncodedInfo::kInvertedCMYK_Color; 72 return true; 73 default: 74 return false; 75 } 76 } 77 78 JpegDecoderMgr::JpegDecoderMgr(SkStream* stream) 79 : fSrcMgr(stream) 80 , fInit(false) 81 { 82 // Error manager must be set before any calls to libjeg in order to handle failures 83 fDInfo.err = jpeg_std_error(&fErrorMgr); 84 fErrorMgr.error_exit = skjpeg_err_exit; 85 } 86 87 void JpegDecoderMgr::init() { 88 jpeg_create_decompress(&fDInfo); 89 fInit = true; 90 fDInfo.src = &fSrcMgr; 91 fDInfo.err->output_message = &output_message; 92 fDInfo.progress = &fProgressMgr; 93 fProgressMgr.progress_monitor = &progress_monitor; 94 } 95 96 JpegDecoderMgr::~JpegDecoderMgr() { 97 if (fInit) { 98 jpeg_destroy_decompress(&fDInfo); 99 } 100 } 101