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 #include "SkJpegUtility.h"
     10 
     11 /*
     12  * Print information, warning, and error messages
     13  */
     14 static void print_message(const j_common_ptr info, const char caller[]) {
     15     char buffer[JMSG_LENGTH_MAX];
     16     info->err->format_message(info, buffer);
     17     SkCodecPrintf("libjpeg error %d <%s> from %s\n", info->err->msg_code, buffer, caller);
     18 }
     19 
     20 /*
     21  * Reporting functions for libjpeg
     22  */
     23 static void emit_message(j_common_ptr info, int) {
     24     print_message(info, "emit_message");
     25 }
     26 static void output_message(j_common_ptr info) {
     27     print_message(info, "output_message");
     28 }
     29 
     30 /*
     31  * Choose the size of the memory buffer on Android
     32  */
     33 static void overwrite_mem_buffer_size(jpeg_decompress_struct* dinfo) {
     34 #ifdef SK_BUILD_FOR_ANDROID
     35 
     36 // Use 30 MB for devices with a large amount of system memory and 5MB otherwise
     37 // TODO: (msarett) This matches SkImageDecoder.  Why were these values chosen?
     38 #ifdef ANDROID_LARGE_MEMORY_DEVICE
     39     dinfo->mem->max_memory_to_use = 30 * 1024 * 1024;
     40 #else
     41     dinfo->mem->max_memory_to_use = 5 * 1024 * 1024;
     42 #endif
     43 
     44 #endif // SK_BUILD_FOR_ANDROID
     45 }
     46 
     47 bool JpegDecoderMgr::returnFalse(const char caller[]) {
     48     print_message((j_common_ptr) &fDInfo, caller);
     49     return false;
     50 }
     51 
     52 SkCodec::Result JpegDecoderMgr::returnFailure(const char caller[], SkCodec::Result result) {
     53     print_message((j_common_ptr) &fDInfo, caller);
     54     return result;
     55 }
     56 
     57 SkColorType JpegDecoderMgr::getColorType() {
     58     switch (fDInfo.jpeg_color_space) {
     59         case JCS_CMYK:
     60         case JCS_YCCK:
     61             // libjpeg cannot convert from CMYK or YCCK to RGB.
     62             // Here, we ask libjpeg to give us CMYK samples back and
     63             // we will later manually convert them to RGB.
     64             fDInfo.out_color_space = JCS_CMYK;
     65             return kN32_SkColorType;
     66         case JCS_GRAYSCALE:
     67             fDInfo.out_color_space = JCS_GRAYSCALE;
     68             return kGray_8_SkColorType;
     69         default:
     70 #ifdef ANDROID_RGB
     71             fDInfo.out_color_space = JCS_RGBA_8888;
     72 #else
     73             fDInfo.out_color_space = JCS_RGB;
     74 #endif
     75             return kN32_SkColorType;
     76     }
     77 }
     78 
     79 JpegDecoderMgr::JpegDecoderMgr(SkStream* stream)
     80     : fSrcMgr(stream)
     81     , fInit(false)
     82 {
     83     // Error manager must be set before any calls to libjeg in order to handle failures
     84     fDInfo.err = jpeg_std_error(&fErrorMgr);
     85     fErrorMgr.error_exit = skjpeg_err_exit;
     86 }
     87 
     88 void JpegDecoderMgr::init() {
     89     jpeg_create_decompress(&fDInfo);
     90     fInit = true;
     91     fDInfo.src = &fSrcMgr;
     92     overwrite_mem_buffer_size(&fDInfo);
     93     fDInfo.err->emit_message = &emit_message;
     94     fDInfo.err->output_message = &output_message;
     95 }
     96 
     97 JpegDecoderMgr::~JpegDecoderMgr() {
     98     if (fInit) {
     99         jpeg_destroy_decompress(&fDInfo);
    100     }
    101 }
    102 
    103 jmp_buf& JpegDecoderMgr::getJmpBuf() {
    104     return fErrorMgr.fJmpBuf;
    105 }
    106 
    107 jpeg_decompress_struct* JpegDecoderMgr::dinfo() {
    108     return &fDInfo;
    109 }
    110