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 "src/codec/SkJpegDecoderMgr.h" 9 10#include "src/codec/SkJpegUtility.h" 11 12#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 13 #include "include/android/SkAndroidFrameworkUtils.h" 14#endif 15 16/* 17 * Print information, warning, and error messages 18 */ 19static 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 */ 28static void output_message(j_common_ptr info) { 29 print_message(info, "output_message"); 30} 31 32static 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 43bool JpegDecoderMgr::returnFalse(const char caller[]) { 44 print_message((j_common_ptr) &fDInfo, caller); 45 return false; 46} 47 48SkCodec::Result JpegDecoderMgr::returnFailure(const char caller[], SkCodec::Result result) { 49 print_message((j_common_ptr) &fDInfo, caller); 50 return result; 51} 52 53bool 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 78JpegDecoderMgr::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 87void 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 96JpegDecoderMgr::~JpegDecoderMgr() { 97 if (fInit) { 98 jpeg_destroy_decompress(&fDInfo); 99 } 100} 101