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