diff options
author | msarett <msarett@google.com> | 2015-04-15 07:32:19 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-15 07:32:20 -0700 |
commit | e16b04aa6041efb6507546547737e9603fa1606e (patch) | |
tree | 3bd78e41a9ff3df445c64d3c0429d83bb698570d /src/codec/SkJpegDecoderMgr.cpp | |
parent | f91e676f941c7e9ec91ac298eaa32e4bf8f52762 (diff) |
SkJpegCodec
Enables basic decoding for jpegs
Includes rewinding
565, YUV, and Jpeg encoding are not yet implemented
BUG=skia:3257
Review URL: https://codereview.chromium.org/1076923002
Diffstat (limited to 'src/codec/SkJpegDecoderMgr.cpp')
-rw-r--r-- | src/codec/SkJpegDecoderMgr.cpp | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/codec/SkJpegDecoderMgr.cpp b/src/codec/SkJpegDecoderMgr.cpp new file mode 100644 index 0000000000..c1f044c64f --- /dev/null +++ b/src/codec/SkJpegDecoderMgr.cpp @@ -0,0 +1,109 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkJpegDecoderMgr.h" +#include "SkJpegUtility.h" + +/* + * Print information, warning, and error messages + */ +static void print_message(const j_common_ptr info, const char caller[]) { + char buffer[JMSG_LENGTH_MAX]; + info->err->format_message(info, buffer); + SkCodecPrintf("libjpeg error %d <%s> from %s\n", info->err->msg_code, buffer, caller); +} + +/* + * Reporting functions for libjpeg + */ +static void emit_message(j_common_ptr info, int) { + print_message(info, "emit_message"); +} +static void output_message(j_common_ptr info) { + print_message(info, "output_message"); +} + +/* + * Choose the size of the memory buffer on Android + */ +static void overwrite_mem_buffer_size(jpeg_decompress_struct* dinfo) { +#ifdef SK_BUILD_FOR_ANDROID + +// Use 30 MB for devices with a large amount of system memory and 5MB otherwise +// TODO: (msarett) This matches SkImageDecoder. Why were these values chosen? +#ifdef ANDROID_LARGE_MEMORY_DEVICE + dinfo->mem->max_memory_to_use = 30 * 1024 * 1024; +#else + dinfo->mem->max_memory_to_use = 5 * 1024 * 1024; +#endif + +#endif // SK_BUILD_FOR_ANDROID +} + +bool JpegDecoderMgr::returnFalse(const char caller[]) { + print_message((j_common_ptr) &fDInfo, caller); + return false; +} + +SkCodec::Result JpegDecoderMgr::returnFailure(const char caller[], SkCodec::Result result) { + print_message((j_common_ptr) &fDInfo, caller); + return result; +} + +SkColorType JpegDecoderMgr::getColorType() { + switch (fDInfo.jpeg_color_space) { + case JCS_CMYK: + case JCS_YCCK: + // libjpeg cannot convert from CMYK or YCCK to RGB. + // Here, we ask libjpeg to give us CMYK samples back and + // we will later manually convert them to RGB. + fDInfo.out_color_space = JCS_CMYK; + return kN32_SkColorType; + case JCS_GRAYSCALE: + fDInfo.out_color_space = JCS_GRAYSCALE; + return kGray_8_SkColorType; + default: +#ifdef ANDROID_RGB + fDInfo.out_color_space = JCS_RGBA_8888; +#else + fDInfo.out_color_space = JCS_RGB; +#endif + return kN32_SkColorType; + } +} + +JpegDecoderMgr::JpegDecoderMgr(SkStream* stream) + : fSrcMgr(stream) + , fInit(false) +{ + // Error manager must be set before any calls to libjeg in order to handle failures + fDInfo.err = jpeg_std_error(&fErrorMgr); + fErrorMgr.error_exit = skjpeg_err_exit; +} + +void JpegDecoderMgr::init() { + jpeg_create_decompress(&fDInfo); + fInit = true; + fDInfo.src = &fSrcMgr; + overwrite_mem_buffer_size(&fDInfo); + fDInfo.err->emit_message = &emit_message; + fDInfo.err->output_message = &output_message; +} + +JpegDecoderMgr::~JpegDecoderMgr() { + if (fInit) { + jpeg_destroy_decompress(&fDInfo); + } +} + +jmp_buf& JpegDecoderMgr::getJmpBuf() { + return fErrorMgr.fJmpBuf; +} + +jpeg_decompress_struct* JpegDecoderMgr::dinfo() { + return &fDInfo; +} |