media/libjpeg/jdatadst.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2  * jdatadst.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-2012 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 compression data destination routines for the case of
    12  * emitting JPEG data to memory or to a file (or any stdio stream).
    13  * While these routines are sufficient for most applications,
    14  * some will want to use a different destination manager.
    15  * IMPORTANT: we assume that fwrite() will correctly transcribe an array of
    16  * JOCTETs into 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"
    25 #ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare malloc(),free() */
    26 extern void * malloc JPP((size_t size));
    27 extern void free JPP((void *ptr));
    28 #endif
    31 /* Expanded data destination object for stdio output */
    33 typedef struct {
    34   struct jpeg_destination_mgr pub; /* public fields */
    36   FILE * outfile;		/* target stream */
    37   JOCTET * buffer;		/* start of buffer */
    38 } my_destination_mgr;
    40 typedef my_destination_mgr * my_dest_ptr;
    42 #define OUTPUT_BUF_SIZE  4096	/* choose an efficiently fwrite'able size */
    45 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
    46 /* Expanded data destination object for memory output */
    48 typedef struct {
    49   struct jpeg_destination_mgr pub; /* public fields */
    51   unsigned char ** outbuffer;	/* target buffer */
    52   unsigned long * outsize;
    53   unsigned char * newbuffer;	/* newly allocated buffer */
    54   JOCTET * buffer;		/* start of buffer */
    55   size_t bufsize;
    56 } my_mem_destination_mgr;
    58 typedef my_mem_destination_mgr * my_mem_dest_ptr;
    59 #endif
    62 /*
    63  * Initialize destination --- called by jpeg_start_compress
    64  * before any data is actually written.
    65  */
    67 METHODDEF(void)
    68 init_destination (j_compress_ptr cinfo)
    69 {
    70   my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
    72   /* Allocate the output buffer --- it will be released when done with image */
    73   dest->buffer = (JOCTET *)
    74       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    75 				  OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
    77   dest->pub.next_output_byte = dest->buffer;
    78   dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
    79 }
    81 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
    82 METHODDEF(void)
    83 init_mem_destination (j_compress_ptr cinfo)
    84 {
    85   /* no work necessary here */
    86 }
    87 #endif
    90 /*
    91  * Empty the output buffer --- called whenever buffer fills up.
    92  *
    93  * In typical applications, this should write the entire output buffer
    94  * (ignoring the current state of next_output_byte & free_in_buffer),
    95  * reset the pointer & count to the start of the buffer, and return TRUE
    96  * indicating that the buffer has been dumped.
    97  *
    98  * In applications that need to be able to suspend compression due to output
    99  * overrun, a FALSE return indicates that the buffer cannot be emptied now.
   100  * In this situation, the compressor will return to its caller (possibly with
   101  * an indication that it has not accepted all the supplied scanlines).  The
   102  * application should resume compression after it has made more room in the
   103  * output buffer.  Note that there are substantial restrictions on the use of
   104  * suspension --- see the documentation.
   105  *
   106  * When suspending, the compressor will back up to a convenient restart point
   107  * (typically the start of the current MCU). next_output_byte & free_in_buffer
   108  * indicate where the restart point will be if the current call returns FALSE.
   109  * Data beyond this point will be regenerated after resumption, so do not
   110  * write it out when emptying the buffer externally.
   111  */
   113 METHODDEF(boolean)
   114 empty_output_buffer (j_compress_ptr cinfo)
   115 {
   116   my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
   118   if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) !=
   119       (size_t) OUTPUT_BUF_SIZE)
   120     ERREXIT(cinfo, JERR_FILE_WRITE);
   122   dest->pub.next_output_byte = dest->buffer;
   123   dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
   125   return TRUE;
   126 }
   128 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
   129 METHODDEF(boolean)
   130 empty_mem_output_buffer (j_compress_ptr cinfo)
   131 {
   132   size_t nextsize;
   133   JOCTET * nextbuffer;
   134   my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
   136   /* Try to allocate new buffer with double size */
   137   nextsize = dest->bufsize * 2;
   138   nextbuffer = (JOCTET *) malloc(nextsize);
   140   if (nextbuffer == NULL)
   141     ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
   143   MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
   145   if (dest->newbuffer != NULL)
   146     free(dest->newbuffer);
   148   dest->newbuffer = nextbuffer;
   150   dest->pub.next_output_byte = nextbuffer + dest->bufsize;
   151   dest->pub.free_in_buffer = dest->bufsize;
   153   dest->buffer = nextbuffer;
   154   dest->bufsize = nextsize;
   156   return TRUE;
   157 }
   158 #endif
   161 /*
   162  * Terminate destination --- called by jpeg_finish_compress
   163  * after all data has been written.  Usually needs to flush buffer.
   164  *
   165  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
   166  * application must deal with any cleanup that should happen even
   167  * for error exit.
   168  */
   170 METHODDEF(void)
   171 term_destination (j_compress_ptr cinfo)
   172 {
   173   my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
   174   size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
   176   /* Write any data remaining in the buffer */
   177   if (datacount > 0) {
   178     if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount)
   179       ERREXIT(cinfo, JERR_FILE_WRITE);
   180   }
   181   fflush(dest->outfile);
   182   /* Make sure we wrote the output file OK */
   183   if (ferror(dest->outfile))
   184     ERREXIT(cinfo, JERR_FILE_WRITE);
   185 }
   187 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
   188 METHODDEF(void)
   189 term_mem_destination (j_compress_ptr cinfo)
   190 {
   191   my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
   193   *dest->outbuffer = dest->buffer;
   194   *dest->outsize = (unsigned long)(dest->bufsize - dest->pub.free_in_buffer);
   195 }
   196 #endif
   199 /*
   200  * Prepare for output to a stdio stream.
   201  * The caller must have already opened the stream, and is responsible
   202  * for closing it after finishing compression.
   203  */
   205 GLOBAL(void)
   206 jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
   207 {
   208   my_dest_ptr dest;
   210   /* The destination object is made permanent so that multiple JPEG images
   211    * can be written to the same file without re-executing jpeg_stdio_dest.
   212    * This makes it dangerous to use this manager and a different destination
   213    * manager serially with the same JPEG object, because their private object
   214    * sizes may be different.  Caveat programmer.
   215    */
   216   if (cinfo->dest == NULL) {	/* first time for this JPEG object? */
   217     cinfo->dest = (struct jpeg_destination_mgr *)
   218       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
   219 				  SIZEOF(my_destination_mgr));
   220   }
   222   dest = (my_dest_ptr) cinfo->dest;
   223   dest->pub.init_destination = init_destination;
   224   dest->pub.empty_output_buffer = empty_output_buffer;
   225   dest->pub.term_destination = term_destination;
   226   dest->outfile = outfile;
   227 }
   230 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
   231 /*
   232  * Prepare for output to a memory buffer.
   233  * The caller may supply an own initial buffer with appropriate size.
   234  * Otherwise, or when the actual data output exceeds the given size,
   235  * the library adapts the buffer size as necessary.
   236  * The standard library functions malloc/free are used for allocating
   237  * larger memory, so the buffer is available to the application after
   238  * finishing compression, and then the application is responsible for
   239  * freeing the requested memory.
   240  */
   242 GLOBAL(void)
   243 jpeg_mem_dest (j_compress_ptr cinfo,
   244 	       unsigned char ** outbuffer, unsigned long * outsize)
   245 {
   246   my_mem_dest_ptr dest;
   248   if (outbuffer == NULL || outsize == NULL)	/* sanity check */
   249     ERREXIT(cinfo, JERR_BUFFER_SIZE);
   251   /* The destination object is made permanent so that multiple JPEG images
   252    * can be written to the same buffer without re-executing jpeg_mem_dest.
   253    */
   254   if (cinfo->dest == NULL) {	/* first time for this JPEG object? */
   255     cinfo->dest = (struct jpeg_destination_mgr *)
   256       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
   257 				  SIZEOF(my_mem_destination_mgr));
   258   }
   260   dest = (my_mem_dest_ptr) cinfo->dest;
   261   dest->pub.init_destination = init_mem_destination;
   262   dest->pub.empty_output_buffer = empty_mem_output_buffer;
   263   dest->pub.term_destination = term_mem_destination;
   264   dest->outbuffer = outbuffer;
   265   dest->outsize = outsize;
   266   dest->newbuffer = NULL;
   268   if (*outbuffer == NULL || *outsize == 0) {
   269     /* Allocate initial buffer */
   270     dest->newbuffer = *outbuffer = (unsigned char *) malloc(OUTPUT_BUF_SIZE);
   271     if (dest->newbuffer == NULL)
   272       ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
   273     *outsize = OUTPUT_BUF_SIZE;
   274   }
   276   dest->pub.next_output_byte = dest->buffer = *outbuffer;
   277   dest->pub.free_in_buffer = dest->bufsize = *outsize;
   278 }
   279 #endif

mercurial