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