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

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

mercurial