1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libjpeg/jdatadst.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,279 @@ 1.4 +/* 1.5 + * jdatadst.c 1.6 + * 1.7 + * This file was part of the Independent JPEG Group's software: 1.8 + * Copyright (C) 1994-1996, Thomas G. Lane. 1.9 + * Modified 2009-2012 by Guido Vollbeding. 1.10 + * libjpeg-turbo Modifications: 1.11 + * Copyright (C) 2013, D. R. Commander. 1.12 + * For conditions of distribution and use, see the accompanying README file. 1.13 + * 1.14 + * This file contains compression data destination routines for the case of 1.15 + * emitting JPEG data to memory or to a file (or any stdio stream). 1.16 + * While these routines are sufficient for most applications, 1.17 + * some will want to use a different destination manager. 1.18 + * IMPORTANT: we assume that fwrite() will correctly transcribe an array of 1.19 + * JOCTETs into 8-bit-wide elements on external storage. If char is wider 1.20 + * than 8 bits on your machine, you may need to do some tweaking. 1.21 + */ 1.22 + 1.23 +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ 1.24 +#include "jinclude.h" 1.25 +#include "jpeglib.h" 1.26 +#include "jerror.h" 1.27 + 1.28 +#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */ 1.29 +extern void * malloc JPP((size_t size)); 1.30 +extern void free JPP((void *ptr)); 1.31 +#endif 1.32 + 1.33 + 1.34 +/* Expanded data destination object for stdio output */ 1.35 + 1.36 +typedef struct { 1.37 + struct jpeg_destination_mgr pub; /* public fields */ 1.38 + 1.39 + FILE * outfile; /* target stream */ 1.40 + JOCTET * buffer; /* start of buffer */ 1.41 +} my_destination_mgr; 1.42 + 1.43 +typedef my_destination_mgr * my_dest_ptr; 1.44 + 1.45 +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ 1.46 + 1.47 + 1.48 +#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) 1.49 +/* Expanded data destination object for memory output */ 1.50 + 1.51 +typedef struct { 1.52 + struct jpeg_destination_mgr pub; /* public fields */ 1.53 + 1.54 + unsigned char ** outbuffer; /* target buffer */ 1.55 + unsigned long * outsize; 1.56 + unsigned char * newbuffer; /* newly allocated buffer */ 1.57 + JOCTET * buffer; /* start of buffer */ 1.58 + size_t bufsize; 1.59 +} my_mem_destination_mgr; 1.60 + 1.61 +typedef my_mem_destination_mgr * my_mem_dest_ptr; 1.62 +#endif 1.63 + 1.64 + 1.65 +/* 1.66 + * Initialize destination --- called by jpeg_start_compress 1.67 + * before any data is actually written. 1.68 + */ 1.69 + 1.70 +METHODDEF(void) 1.71 +init_destination (j_compress_ptr cinfo) 1.72 +{ 1.73 + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; 1.74 + 1.75 + /* Allocate the output buffer --- it will be released when done with image */ 1.76 + dest->buffer = (JOCTET *) 1.77 + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 1.78 + OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); 1.79 + 1.80 + dest->pub.next_output_byte = dest->buffer; 1.81 + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; 1.82 +} 1.83 + 1.84 +#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) 1.85 +METHODDEF(void) 1.86 +init_mem_destination (j_compress_ptr cinfo) 1.87 +{ 1.88 + /* no work necessary here */ 1.89 +} 1.90 +#endif 1.91 + 1.92 + 1.93 +/* 1.94 + * Empty the output buffer --- called whenever buffer fills up. 1.95 + * 1.96 + * In typical applications, this should write the entire output buffer 1.97 + * (ignoring the current state of next_output_byte & free_in_buffer), 1.98 + * reset the pointer & count to the start of the buffer, and return TRUE 1.99 + * indicating that the buffer has been dumped. 1.100 + * 1.101 + * In applications that need to be able to suspend compression due to output 1.102 + * overrun, a FALSE return indicates that the buffer cannot be emptied now. 1.103 + * In this situation, the compressor will return to its caller (possibly with 1.104 + * an indication that it has not accepted all the supplied scanlines). The 1.105 + * application should resume compression after it has made more room in the 1.106 + * output buffer. Note that there are substantial restrictions on the use of 1.107 + * suspension --- see the documentation. 1.108 + * 1.109 + * When suspending, the compressor will back up to a convenient restart point 1.110 + * (typically the start of the current MCU). next_output_byte & free_in_buffer 1.111 + * indicate where the restart point will be if the current call returns FALSE. 1.112 + * Data beyond this point will be regenerated after resumption, so do not 1.113 + * write it out when emptying the buffer externally. 1.114 + */ 1.115 + 1.116 +METHODDEF(boolean) 1.117 +empty_output_buffer (j_compress_ptr cinfo) 1.118 +{ 1.119 + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; 1.120 + 1.121 + if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) != 1.122 + (size_t) OUTPUT_BUF_SIZE) 1.123 + ERREXIT(cinfo, JERR_FILE_WRITE); 1.124 + 1.125 + dest->pub.next_output_byte = dest->buffer; 1.126 + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; 1.127 + 1.128 + return TRUE; 1.129 +} 1.130 + 1.131 +#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) 1.132 +METHODDEF(boolean) 1.133 +empty_mem_output_buffer (j_compress_ptr cinfo) 1.134 +{ 1.135 + size_t nextsize; 1.136 + JOCTET * nextbuffer; 1.137 + my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest; 1.138 + 1.139 + /* Try to allocate new buffer with double size */ 1.140 + nextsize = dest->bufsize * 2; 1.141 + nextbuffer = (JOCTET *) malloc(nextsize); 1.142 + 1.143 + if (nextbuffer == NULL) 1.144 + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); 1.145 + 1.146 + MEMCOPY(nextbuffer, dest->buffer, dest->bufsize); 1.147 + 1.148 + if (dest->newbuffer != NULL) 1.149 + free(dest->newbuffer); 1.150 + 1.151 + dest->newbuffer = nextbuffer; 1.152 + 1.153 + dest->pub.next_output_byte = nextbuffer + dest->bufsize; 1.154 + dest->pub.free_in_buffer = dest->bufsize; 1.155 + 1.156 + dest->buffer = nextbuffer; 1.157 + dest->bufsize = nextsize; 1.158 + 1.159 + return TRUE; 1.160 +} 1.161 +#endif 1.162 + 1.163 + 1.164 +/* 1.165 + * Terminate destination --- called by jpeg_finish_compress 1.166 + * after all data has been written. Usually needs to flush buffer. 1.167 + * 1.168 + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding 1.169 + * application must deal with any cleanup that should happen even 1.170 + * for error exit. 1.171 + */ 1.172 + 1.173 +METHODDEF(void) 1.174 +term_destination (j_compress_ptr cinfo) 1.175 +{ 1.176 + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; 1.177 + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; 1.178 + 1.179 + /* Write any data remaining in the buffer */ 1.180 + if (datacount > 0) { 1.181 + if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount) 1.182 + ERREXIT(cinfo, JERR_FILE_WRITE); 1.183 + } 1.184 + fflush(dest->outfile); 1.185 + /* Make sure we wrote the output file OK */ 1.186 + if (ferror(dest->outfile)) 1.187 + ERREXIT(cinfo, JERR_FILE_WRITE); 1.188 +} 1.189 + 1.190 +#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) 1.191 +METHODDEF(void) 1.192 +term_mem_destination (j_compress_ptr cinfo) 1.193 +{ 1.194 + my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest; 1.195 + 1.196 + *dest->outbuffer = dest->buffer; 1.197 + *dest->outsize = (unsigned long)(dest->bufsize - dest->pub.free_in_buffer); 1.198 +} 1.199 +#endif 1.200 + 1.201 + 1.202 +/* 1.203 + * Prepare for output to a stdio stream. 1.204 + * The caller must have already opened the stream, and is responsible 1.205 + * for closing it after finishing compression. 1.206 + */ 1.207 + 1.208 +GLOBAL(void) 1.209 +jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile) 1.210 +{ 1.211 + my_dest_ptr dest; 1.212 + 1.213 + /* The destination object is made permanent so that multiple JPEG images 1.214 + * can be written to the same file without re-executing jpeg_stdio_dest. 1.215 + * This makes it dangerous to use this manager and a different destination 1.216 + * manager serially with the same JPEG object, because their private object 1.217 + * sizes may be different. Caveat programmer. 1.218 + */ 1.219 + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ 1.220 + cinfo->dest = (struct jpeg_destination_mgr *) 1.221 + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 1.222 + SIZEOF(my_destination_mgr)); 1.223 + } 1.224 + 1.225 + dest = (my_dest_ptr) cinfo->dest; 1.226 + dest->pub.init_destination = init_destination; 1.227 + dest->pub.empty_output_buffer = empty_output_buffer; 1.228 + dest->pub.term_destination = term_destination; 1.229 + dest->outfile = outfile; 1.230 +} 1.231 + 1.232 + 1.233 +#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) 1.234 +/* 1.235 + * Prepare for output to a memory buffer. 1.236 + * The caller may supply an own initial buffer with appropriate size. 1.237 + * Otherwise, or when the actual data output exceeds the given size, 1.238 + * the library adapts the buffer size as necessary. 1.239 + * The standard library functions malloc/free are used for allocating 1.240 + * larger memory, so the buffer is available to the application after 1.241 + * finishing compression, and then the application is responsible for 1.242 + * freeing the requested memory. 1.243 + */ 1.244 + 1.245 +GLOBAL(void) 1.246 +jpeg_mem_dest (j_compress_ptr cinfo, 1.247 + unsigned char ** outbuffer, unsigned long * outsize) 1.248 +{ 1.249 + my_mem_dest_ptr dest; 1.250 + 1.251 + if (outbuffer == NULL || outsize == NULL) /* sanity check */ 1.252 + ERREXIT(cinfo, JERR_BUFFER_SIZE); 1.253 + 1.254 + /* The destination object is made permanent so that multiple JPEG images 1.255 + * can be written to the same buffer without re-executing jpeg_mem_dest. 1.256 + */ 1.257 + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ 1.258 + cinfo->dest = (struct jpeg_destination_mgr *) 1.259 + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, 1.260 + SIZEOF(my_mem_destination_mgr)); 1.261 + } 1.262 + 1.263 + dest = (my_mem_dest_ptr) cinfo->dest; 1.264 + dest->pub.init_destination = init_mem_destination; 1.265 + dest->pub.empty_output_buffer = empty_mem_output_buffer; 1.266 + dest->pub.term_destination = term_mem_destination; 1.267 + dest->outbuffer = outbuffer; 1.268 + dest->outsize = outsize; 1.269 + dest->newbuffer = NULL; 1.270 + 1.271 + if (*outbuffer == NULL || *outsize == 0) { 1.272 + /* Allocate initial buffer */ 1.273 + dest->newbuffer = *outbuffer = (unsigned char *) malloc(OUTPUT_BUF_SIZE); 1.274 + if (dest->newbuffer == NULL) 1.275 + ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); 1.276 + *outsize = OUTPUT_BUF_SIZE; 1.277 + } 1.278 + 1.279 + dest->pub.next_output_byte = dest->buffer = *outbuffer; 1.280 + dest->pub.free_in_buffer = dest->bufsize = *outsize; 1.281 +} 1.282 +#endif