1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/images/SkJpegUtility.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,170 @@ 1.4 +/* 1.5 + * Copyright 2010 The Android Open Source Project 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 + 1.12 +#include "SkJpegUtility.h" 1.13 + 1.14 +///////////////////////////////////////////////////////////////////// 1.15 +static void sk_init_source(j_decompress_ptr cinfo) { 1.16 + skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src; 1.17 + src->next_input_byte = (const JOCTET*)src->fBuffer; 1.18 + src->bytes_in_buffer = 0; 1.19 +#ifdef SK_BUILD_FOR_ANDROID 1.20 + src->current_offset = 0; 1.21 +#endif 1.22 + if (!src->fStream->rewind()) { 1.23 + SkDebugf("xxxxxxxxxxxxxx failure to rewind\n"); 1.24 + cinfo->err->error_exit((j_common_ptr)cinfo); 1.25 + } 1.26 +} 1.27 + 1.28 +#ifdef SK_BUILD_FOR_ANDROID 1.29 +static boolean sk_seek_input_data(j_decompress_ptr cinfo, long byte_offset) { 1.30 + skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src; 1.31 + size_t bo = (size_t) byte_offset; 1.32 + 1.33 + if (bo > src->current_offset) { 1.34 + (void)src->fStream->skip(bo - src->current_offset); 1.35 + } else { 1.36 + if (!src->fStream->rewind()) { 1.37 + SkDebugf("xxxxxxxxxxxxxx failure to rewind\n"); 1.38 + cinfo->err->error_exit((j_common_ptr)cinfo); 1.39 + return false; 1.40 + } 1.41 + (void)src->fStream->skip(bo); 1.42 + } 1.43 + 1.44 + src->current_offset = bo; 1.45 + src->next_input_byte = (const JOCTET*)src->fBuffer; 1.46 + src->bytes_in_buffer = 0; 1.47 + return true; 1.48 +} 1.49 +#endif 1.50 + 1.51 +static boolean sk_fill_input_buffer(j_decompress_ptr cinfo) { 1.52 + skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src; 1.53 + if (src->fDecoder != NULL && src->fDecoder->shouldCancelDecode()) { 1.54 + return FALSE; 1.55 + } 1.56 + size_t bytes = src->fStream->read(src->fBuffer, skjpeg_source_mgr::kBufferSize); 1.57 + // note that JPEG is happy with less than the full read, 1.58 + // as long as the result is non-zero 1.59 + if (bytes == 0) { 1.60 + return FALSE; 1.61 + } 1.62 + 1.63 +#ifdef SK_BUILD_FOR_ANDROID 1.64 + src->current_offset += bytes; 1.65 +#endif 1.66 + src->next_input_byte = (const JOCTET*)src->fBuffer; 1.67 + src->bytes_in_buffer = bytes; 1.68 + return TRUE; 1.69 +} 1.70 + 1.71 +static void sk_skip_input_data(j_decompress_ptr cinfo, long num_bytes) { 1.72 + skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src; 1.73 + 1.74 + if (num_bytes > (long)src->bytes_in_buffer) { 1.75 + size_t bytesToSkip = num_bytes - src->bytes_in_buffer; 1.76 + while (bytesToSkip > 0) { 1.77 + size_t bytes = src->fStream->skip(bytesToSkip); 1.78 + if (bytes <= 0 || bytes > bytesToSkip) { 1.79 +// SkDebugf("xxxxxxxxxxxxxx failure to skip request %d returned %d\n", bytesToSkip, bytes); 1.80 + cinfo->err->error_exit((j_common_ptr)cinfo); 1.81 + return; 1.82 + } 1.83 +#ifdef SK_BUILD_FOR_ANDROID 1.84 + src->current_offset += bytes; 1.85 +#endif 1.86 + bytesToSkip -= bytes; 1.87 + } 1.88 + src->next_input_byte = (const JOCTET*)src->fBuffer; 1.89 + src->bytes_in_buffer = 0; 1.90 + } else { 1.91 + src->next_input_byte += num_bytes; 1.92 + src->bytes_in_buffer -= num_bytes; 1.93 + } 1.94 +} 1.95 + 1.96 +static void sk_term_source(j_decompress_ptr /*cinfo*/) {} 1.97 + 1.98 + 1.99 +/////////////////////////////////////////////////////////////////////////////// 1.100 + 1.101 +skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder) 1.102 + : fStream(SkRef(stream)) 1.103 + , fDecoder(decoder) { 1.104 + 1.105 + init_source = sk_init_source; 1.106 + fill_input_buffer = sk_fill_input_buffer; 1.107 + skip_input_data = sk_skip_input_data; 1.108 + resync_to_restart = jpeg_resync_to_restart; 1.109 + term_source = sk_term_source; 1.110 +#ifdef SK_BUILD_FOR_ANDROID 1.111 + seek_input_data = sk_seek_input_data; 1.112 +#endif 1.113 +// SkDebugf("**************** use memorybase %p %d\n", fMemoryBase, fMemoryBaseSize); 1.114 +} 1.115 + 1.116 +skjpeg_source_mgr::~skjpeg_source_mgr() { 1.117 + SkSafeUnref(fStream); 1.118 +} 1.119 + 1.120 +/////////////////////////////////////////////////////////////////////////////// 1.121 + 1.122 +static void sk_init_destination(j_compress_ptr cinfo) { 1.123 + skjpeg_destination_mgr* dest = (skjpeg_destination_mgr*)cinfo->dest; 1.124 + 1.125 + dest->next_output_byte = dest->fBuffer; 1.126 + dest->free_in_buffer = skjpeg_destination_mgr::kBufferSize; 1.127 +} 1.128 + 1.129 +static boolean sk_empty_output_buffer(j_compress_ptr cinfo) { 1.130 + skjpeg_destination_mgr* dest = (skjpeg_destination_mgr*)cinfo->dest; 1.131 + 1.132 +// if (!dest->fStream->write(dest->fBuffer, skjpeg_destination_mgr::kBufferSize - dest->free_in_buffer)) 1.133 + if (!dest->fStream->write(dest->fBuffer, 1.134 + skjpeg_destination_mgr::kBufferSize)) { 1.135 + ERREXIT(cinfo, JERR_FILE_WRITE); 1.136 + return false; 1.137 + } 1.138 + 1.139 + dest->next_output_byte = dest->fBuffer; 1.140 + dest->free_in_buffer = skjpeg_destination_mgr::kBufferSize; 1.141 + return TRUE; 1.142 +} 1.143 + 1.144 +static void sk_term_destination (j_compress_ptr cinfo) { 1.145 + skjpeg_destination_mgr* dest = (skjpeg_destination_mgr*)cinfo->dest; 1.146 + 1.147 + size_t size = skjpeg_destination_mgr::kBufferSize - dest->free_in_buffer; 1.148 + if (size > 0) { 1.149 + if (!dest->fStream->write(dest->fBuffer, size)) { 1.150 + ERREXIT(cinfo, JERR_FILE_WRITE); 1.151 + return; 1.152 + } 1.153 + } 1.154 + dest->fStream->flush(); 1.155 +} 1.156 + 1.157 +skjpeg_destination_mgr::skjpeg_destination_mgr(SkWStream* stream) 1.158 + : fStream(stream) { 1.159 + this->init_destination = sk_init_destination; 1.160 + this->empty_output_buffer = sk_empty_output_buffer; 1.161 + this->term_destination = sk_term_destination; 1.162 +} 1.163 + 1.164 +void skjpeg_error_exit(j_common_ptr cinfo) { 1.165 + skjpeg_error_mgr* error = (skjpeg_error_mgr*)cinfo->err; 1.166 + 1.167 + (*error->output_message) (cinfo); 1.168 + 1.169 + /* Let the memory manager delete any temp files before we die */ 1.170 + jpeg_destroy(cinfo); 1.171 + 1.172 + longjmp(error->fJmpBuf, -1); 1.173 +}