blob: c2837aa2b4af65c489d8c12d11fcb79ebd46ccc7 [file] [log] [blame]
msarette16b04a2015-04-15 07:32:19 -07001/*
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"
msarettc1d03122016-03-25 08:58:55 -07009
10#include "SkJpegUtility.h"
msarette16b04a2015-04-15 07:32:19 -070011
12/*
13 * Print information, warning, and error messages
14 */
15static 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/*
msarett6dfe9ac2015-11-10 11:22:12 -080022 * Reporting function for error and warning messages.
msarette16b04a2015-04-15 07:32:19 -070023 */
msarette16b04a2015-04-15 07:32:19 -070024static void output_message(j_common_ptr info) {
25 print_message(info, "output_message");
26}
27
Matt Sarettdbdf6d22016-11-08 15:26:56 -050028static 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
msarette16b04a2015-04-15 07:32:19 -070039bool JpegDecoderMgr::returnFalse(const char caller[]) {
40 print_message((j_common_ptr) &fDInfo, caller);
41 return false;
42}
43
44SkCodec::Result JpegDecoderMgr::returnFailure(const char caller[], SkCodec::Result result) {
45 print_message((j_common_ptr) &fDInfo, caller);
46 return result;
47}
48
msarettac6c7502016-04-25 09:30:24 -070049bool JpegDecoderMgr::getEncodedColor(SkEncodedInfo::Color* outColor) {
msarette16b04a2015-04-15 07:32:19 -070050 switch (fDInfo.jpeg_color_space) {
msarette16b04a2015-04-15 07:32:19 -070051 case JCS_GRAYSCALE:
msarettac6c7502016-04-25 09:30:24 -070052 *outColor = SkEncodedInfo::kGray_Color;
53 return true;
msarettc30c4182016-04-20 11:53:35 -070054 case JCS_YCbCr:
msarettac6c7502016-04-25 09:30:24 -070055 *outColor = SkEncodedInfo::kYUV_Color;
56 return true;
msarettc30c4182016-04-20 11:53:35 -070057 case JCS_RGB:
msarettac6c7502016-04-25 09:30:24 -070058 *outColor = SkEncodedInfo::kRGB_Color;
59 return true;
msarettc30c4182016-04-20 11:53:35 -070060 case JCS_YCCK:
msarettac6c7502016-04-25 09:30:24 -070061 *outColor = SkEncodedInfo::kYCCK_Color;
62 return true;
msarettc30c4182016-04-20 11:53:35 -070063 case JCS_CMYK:
msarettac6c7502016-04-25 09:30:24 -070064 *outColor = SkEncodedInfo::kInvertedCMYK_Color;
65 return true;
msarette16b04a2015-04-15 07:32:19 -070066 default:
msarettac6c7502016-04-25 09:30:24 -070067 return false;
msarette16b04a2015-04-15 07:32:19 -070068 }
69}
70
71JpegDecoderMgr::JpegDecoderMgr(SkStream* stream)
Matt Sarett15f4d022017-06-06 17:58:33 +000072 : fSrcMgr(stream)
73 , fInit(false)
msarette16b04a2015-04-15 07:32:19 -070074{
75 // Error manager must be set before any calls to libjeg in order to handle failures
msarettfbccb592015-09-01 06:43:41 -070076 fDInfo.err = jpeg_std_error(&fErrorMgr);
msarette16b04a2015-04-15 07:32:19 -070077 fErrorMgr.error_exit = skjpeg_err_exit;
78}
79
80void JpegDecoderMgr::init() {
81 jpeg_create_decompress(&fDInfo);
82 fInit = true;
Matt Sarett15f4d022017-06-06 17:58:33 +000083 fDInfo.src = &fSrcMgr;
msarette16b04a2015-04-15 07:32:19 -070084 fDInfo.err->output_message = &output_message;
Matt Sarettdbdf6d22016-11-08 15:26:56 -050085 fDInfo.progress = &fProgressMgr;
86 fProgressMgr.progress_monitor = &progress_monitor;
msarette16b04a2015-04-15 07:32:19 -070087}
88
89JpegDecoderMgr::~JpegDecoderMgr() {
90 if (fInit) {
91 jpeg_destroy_decompress(&fDInfo);
92 }
93}
94
95jmp_buf& JpegDecoderMgr::getJmpBuf() {
96 return fErrorMgr.fJmpBuf;
97}
98
99jpeg_decompress_struct* JpegDecoderMgr::dinfo() {
100 return &fDInfo;
101}