media/libjpeg/jdatasrc.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /*
michael@0 2 * jdatasrc.c
michael@0 3 *
michael@0 4 * This file was part of the Independent JPEG Group's software:
michael@0 5 * Copyright (C) 1994-1996, Thomas G. Lane.
michael@0 6 * Modified 2009-2011 by Guido Vollbeding.
michael@0 7 * libjpeg-turbo Modifications:
michael@0 8 * Copyright (C) 2013, D. R. Commander.
michael@0 9 * For conditions of distribution and use, see the accompanying README file.
michael@0 10 *
michael@0 11 * This file contains decompression data source routines for the case of
michael@0 12 * reading JPEG data from memory or from a file (or any stdio stream).
michael@0 13 * While these routines are sufficient for most applications,
michael@0 14 * some will want to use a different source manager.
michael@0 15 * IMPORTANT: we assume that fread() will correctly transcribe an array of
michael@0 16 * JOCTETs from 8-bit-wide elements on external storage. If char is wider
michael@0 17 * than 8 bits on your machine, you may need to do some tweaking.
michael@0 18 */
michael@0 19
michael@0 20 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */
michael@0 21 #include "jinclude.h"
michael@0 22 #include "jpeglib.h"
michael@0 23 #include "jerror.h"
michael@0 24
michael@0 25
michael@0 26 /* Expanded data source object for stdio input */
michael@0 27
michael@0 28 typedef struct {
michael@0 29 struct jpeg_source_mgr pub; /* public fields */
michael@0 30
michael@0 31 FILE * infile; /* source stream */
michael@0 32 JOCTET * buffer; /* start of buffer */
michael@0 33 boolean start_of_file; /* have we gotten any data yet? */
michael@0 34 } my_source_mgr;
michael@0 35
michael@0 36 typedef my_source_mgr * my_src_ptr;
michael@0 37
michael@0 38 #define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */
michael@0 39
michael@0 40
michael@0 41 /*
michael@0 42 * Initialize source --- called by jpeg_read_header
michael@0 43 * before any data is actually read.
michael@0 44 */
michael@0 45
michael@0 46 METHODDEF(void)
michael@0 47 init_source (j_decompress_ptr cinfo)
michael@0 48 {
michael@0 49 my_src_ptr src = (my_src_ptr) cinfo->src;
michael@0 50
michael@0 51 /* We reset the empty-input-file flag for each image,
michael@0 52 * but we don't clear the input buffer.
michael@0 53 * This is correct behavior for reading a series of images from one source.
michael@0 54 */
michael@0 55 src->start_of_file = TRUE;
michael@0 56 }
michael@0 57
michael@0 58 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
michael@0 59 METHODDEF(void)
michael@0 60 init_mem_source (j_decompress_ptr cinfo)
michael@0 61 {
michael@0 62 /* no work necessary here */
michael@0 63 }
michael@0 64 #endif
michael@0 65
michael@0 66
michael@0 67 /*
michael@0 68 * Fill the input buffer --- called whenever buffer is emptied.
michael@0 69 *
michael@0 70 * In typical applications, this should read fresh data into the buffer
michael@0 71 * (ignoring the current state of next_input_byte & bytes_in_buffer),
michael@0 72 * reset the pointer & count to the start of the buffer, and return TRUE
michael@0 73 * indicating that the buffer has been reloaded. It is not necessary to
michael@0 74 * fill the buffer entirely, only to obtain at least one more byte.
michael@0 75 *
michael@0 76 * There is no such thing as an EOF return. If the end of the file has been
michael@0 77 * reached, the routine has a choice of ERREXIT() or inserting fake data into
michael@0 78 * the buffer. In most cases, generating a warning message and inserting a
michael@0 79 * fake EOI marker is the best course of action --- this will allow the
michael@0 80 * decompressor to output however much of the image is there. However,
michael@0 81 * the resulting error message is misleading if the real problem is an empty
michael@0 82 * input file, so we handle that case specially.
michael@0 83 *
michael@0 84 * In applications that need to be able to suspend compression due to input
michael@0 85 * not being available yet, a FALSE return indicates that no more data can be
michael@0 86 * obtained right now, but more may be forthcoming later. In this situation,
michael@0 87 * the decompressor will return to its caller (with an indication of the
michael@0 88 * number of scanlines it has read, if any). The application should resume
michael@0 89 * decompression after it has loaded more data into the input buffer. Note
michael@0 90 * that there are substantial restrictions on the use of suspension --- see
michael@0 91 * the documentation.
michael@0 92 *
michael@0 93 * When suspending, the decompressor will back up to a convenient restart point
michael@0 94 * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
michael@0 95 * indicate where the restart point will be if the current call returns FALSE.
michael@0 96 * Data beyond this point must be rescanned after resumption, so move it to
michael@0 97 * the front of the buffer rather than discarding it.
michael@0 98 */
michael@0 99
michael@0 100 METHODDEF(boolean)
michael@0 101 fill_input_buffer (j_decompress_ptr cinfo)
michael@0 102 {
michael@0 103 my_src_ptr src = (my_src_ptr) cinfo->src;
michael@0 104 size_t nbytes;
michael@0 105
michael@0 106 nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
michael@0 107
michael@0 108 if (nbytes <= 0) {
michael@0 109 if (src->start_of_file) /* Treat empty input file as fatal error */
michael@0 110 ERREXIT(cinfo, JERR_INPUT_EMPTY);
michael@0 111 WARNMS(cinfo, JWRN_JPEG_EOF);
michael@0 112 /* Insert a fake EOI marker */
michael@0 113 src->buffer[0] = (JOCTET) 0xFF;
michael@0 114 src->buffer[1] = (JOCTET) JPEG_EOI;
michael@0 115 nbytes = 2;
michael@0 116 }
michael@0 117
michael@0 118 src->pub.next_input_byte = src->buffer;
michael@0 119 src->pub.bytes_in_buffer = nbytes;
michael@0 120 src->start_of_file = FALSE;
michael@0 121
michael@0 122 return TRUE;
michael@0 123 }
michael@0 124
michael@0 125 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
michael@0 126 METHODDEF(boolean)
michael@0 127 fill_mem_input_buffer (j_decompress_ptr cinfo)
michael@0 128 {
michael@0 129 static const JOCTET mybuffer[4] = {
michael@0 130 (JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0
michael@0 131 };
michael@0 132
michael@0 133 /* The whole JPEG data is expected to reside in the supplied memory
michael@0 134 * buffer, so any request for more data beyond the given buffer size
michael@0 135 * is treated as an error.
michael@0 136 */
michael@0 137 WARNMS(cinfo, JWRN_JPEG_EOF);
michael@0 138
michael@0 139 /* Insert a fake EOI marker */
michael@0 140
michael@0 141 cinfo->src->next_input_byte = mybuffer;
michael@0 142 cinfo->src->bytes_in_buffer = 2;
michael@0 143
michael@0 144 return TRUE;
michael@0 145 }
michael@0 146 #endif
michael@0 147
michael@0 148
michael@0 149 /*
michael@0 150 * Skip data --- used to skip over a potentially large amount of
michael@0 151 * uninteresting data (such as an APPn marker).
michael@0 152 *
michael@0 153 * Writers of suspendable-input applications must note that skip_input_data
michael@0 154 * is not granted the right to give a suspension return. If the skip extends
michael@0 155 * beyond the data currently in the buffer, the buffer can be marked empty so
michael@0 156 * that the next read will cause a fill_input_buffer call that can suspend.
michael@0 157 * Arranging for additional bytes to be discarded before reloading the input
michael@0 158 * buffer is the application writer's problem.
michael@0 159 */
michael@0 160
michael@0 161 METHODDEF(void)
michael@0 162 skip_input_data (j_decompress_ptr cinfo, long num_bytes)
michael@0 163 {
michael@0 164 struct jpeg_source_mgr * src = cinfo->src;
michael@0 165
michael@0 166 /* Just a dumb implementation for now. Could use fseek() except
michael@0 167 * it doesn't work on pipes. Not clear that being smart is worth
michael@0 168 * any trouble anyway --- large skips are infrequent.
michael@0 169 */
michael@0 170 if (num_bytes > 0) {
michael@0 171 while (num_bytes > (long) src->bytes_in_buffer) {
michael@0 172 num_bytes -= (long) src->bytes_in_buffer;
michael@0 173 (void) (*src->fill_input_buffer) (cinfo);
michael@0 174 /* note we assume that fill_input_buffer will never return FALSE,
michael@0 175 * so suspension need not be handled.
michael@0 176 */
michael@0 177 }
michael@0 178 src->next_input_byte += (size_t) num_bytes;
michael@0 179 src->bytes_in_buffer -= (size_t) num_bytes;
michael@0 180 }
michael@0 181 }
michael@0 182
michael@0 183
michael@0 184 /*
michael@0 185 * An additional method that can be provided by data source modules is the
michael@0 186 * resync_to_restart method for error recovery in the presence of RST markers.
michael@0 187 * For the moment, this source module just uses the default resync method
michael@0 188 * provided by the JPEG library. That method assumes that no backtracking
michael@0 189 * is possible.
michael@0 190 */
michael@0 191
michael@0 192
michael@0 193 /*
michael@0 194 * Terminate source --- called by jpeg_finish_decompress
michael@0 195 * after all data has been read. Often a no-op.
michael@0 196 *
michael@0 197 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
michael@0 198 * application must deal with any cleanup that should happen even
michael@0 199 * for error exit.
michael@0 200 */
michael@0 201
michael@0 202 METHODDEF(void)
michael@0 203 term_source (j_decompress_ptr cinfo)
michael@0 204 {
michael@0 205 /* no work necessary here */
michael@0 206 }
michael@0 207
michael@0 208
michael@0 209 /*
michael@0 210 * Prepare for input from a stdio stream.
michael@0 211 * The caller must have already opened the stream, and is responsible
michael@0 212 * for closing it after finishing decompression.
michael@0 213 */
michael@0 214
michael@0 215 GLOBAL(void)
michael@0 216 jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
michael@0 217 {
michael@0 218 my_src_ptr src;
michael@0 219
michael@0 220 /* The source object and input buffer are made permanent so that a series
michael@0 221 * of JPEG images can be read from the same file by calling jpeg_stdio_src
michael@0 222 * only before the first one. (If we discarded the buffer at the end of
michael@0 223 * one image, we'd likely lose the start of the next one.)
michael@0 224 * This makes it unsafe to use this manager and a different source
michael@0 225 * manager serially with the same JPEG object. Caveat programmer.
michael@0 226 */
michael@0 227 if (cinfo->src == NULL) { /* first time for this JPEG object? */
michael@0 228 cinfo->src = (struct jpeg_source_mgr *)
michael@0 229 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
michael@0 230 SIZEOF(my_source_mgr));
michael@0 231 src = (my_src_ptr) cinfo->src;
michael@0 232 src->buffer = (JOCTET *)
michael@0 233 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
michael@0 234 INPUT_BUF_SIZE * SIZEOF(JOCTET));
michael@0 235 }
michael@0 236
michael@0 237 src = (my_src_ptr) cinfo->src;
michael@0 238 src->pub.init_source = init_source;
michael@0 239 src->pub.fill_input_buffer = fill_input_buffer;
michael@0 240 src->pub.skip_input_data = skip_input_data;
michael@0 241 src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
michael@0 242 src->pub.term_source = term_source;
michael@0 243 src->infile = infile;
michael@0 244 src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
michael@0 245 src->pub.next_input_byte = NULL; /* until buffer loaded */
michael@0 246 }
michael@0 247
michael@0 248
michael@0 249 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
michael@0 250 /*
michael@0 251 * Prepare for input from a supplied memory buffer.
michael@0 252 * The buffer must contain the whole JPEG data.
michael@0 253 */
michael@0 254
michael@0 255 GLOBAL(void)
michael@0 256 jpeg_mem_src (j_decompress_ptr cinfo,
michael@0 257 unsigned char * inbuffer, unsigned long insize)
michael@0 258 {
michael@0 259 struct jpeg_source_mgr * src;
michael@0 260
michael@0 261 if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */
michael@0 262 ERREXIT(cinfo, JERR_INPUT_EMPTY);
michael@0 263
michael@0 264 /* The source object is made permanent so that a series of JPEG images
michael@0 265 * can be read from the same buffer by calling jpeg_mem_src only before
michael@0 266 * the first one.
michael@0 267 */
michael@0 268 if (cinfo->src == NULL) { /* first time for this JPEG object? */
michael@0 269 cinfo->src = (struct jpeg_source_mgr *)
michael@0 270 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
michael@0 271 SIZEOF(struct jpeg_source_mgr));
michael@0 272 }
michael@0 273
michael@0 274 src = cinfo->src;
michael@0 275 src->init_source = init_mem_source;
michael@0 276 src->fill_input_buffer = fill_mem_input_buffer;
michael@0 277 src->skip_input_data = skip_input_data;
michael@0 278 src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
michael@0 279 src->term_source = term_source;
michael@0 280 src->bytes_in_buffer = (size_t) insize;
michael@0 281 src->next_input_byte = (JOCTET *) inbuffer;
michael@0 282 }
michael@0 283 #endif

mercurial