Home | History | Annotate | Download | only in codec
      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  */
     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  */
     24 static void output_message(j_common_ptr info) {
     25     print_message(info, "output_message");
     26 }
     27 
     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 
     39 bool JpegDecoderMgr::returnFalse(const char caller[]) {
     40     print_message((j_common_ptr) &fDInfo, caller);
     41     return false;
     42 }
     43 
     44 SkCodec::Result JpegDecoderMgr::returnFailure(const char caller[], SkCodec::Result result) {
     45     print_message((j_common_ptr) &fDInfo, caller);
     46     return result;
     47 }
     48 
     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 
     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 
     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 
     89 JpegDecoderMgr::~JpegDecoderMgr() {
     90     if (fInit) {
     91         jpeg_destroy_decompress(&fDInfo);
     92     }
     93 }
     94