src/3rdparty/libjpeg/jdatadst.c
changeset 30 5dc02b23752f
parent 0 1918ee327afb
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
     1 /*
     1 /*
     2  * jdatadst.c
     2  * jdatadst.c
     3  *
     3  *
     4  * Copyright (C) 1994-1996, Thomas G. Lane.
     4  * Copyright (C) 1994-1996, Thomas G. Lane.
       
     5  * Modified 2009 by Guido Vollbeding.
     5  * This file is part of the Independent JPEG Group's software.
     6  * This file is part of the Independent JPEG Group's software.
     6  * For conditions of distribution and use, see the accompanying README file.
     7  * For conditions of distribution and use, see the accompanying README file.
     7  *
     8  *
     8  * This file contains compression data destination routines for the case of
     9  * This file contains compression data destination routines for the case of
     9  * emitting JPEG data to a file (or any stdio stream).  While these routines
    10  * emitting JPEG data to memory or to a file (or any stdio stream).
    10  * are sufficient for most applications, some will want to use a different
    11  * While these routines are sufficient for most applications,
    11  * destination manager.
    12  * some will want to use a different destination manager.
    12  * IMPORTANT: we assume that fwrite() will correctly transcribe an array of
    13  * IMPORTANT: we assume that fwrite() will correctly transcribe an array of
    13  * JOCTETs into 8-bit-wide elements on external storage.  If char is wider
    14  * JOCTETs into 8-bit-wide elements on external storage.  If char is wider
    14  * than 8 bits on your machine, you may need to do some tweaking.
    15  * than 8 bits on your machine, you may need to do some tweaking.
    15  */
    16  */
    16 
    17 
    17 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */
    18 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */
    18 #include "jinclude.h"
    19 #include "jinclude.h"
    19 #include "jpeglib.h"
    20 #include "jpeglib.h"
    20 #include "jerror.h"
    21 #include "jerror.h"
    21 
    22 
       
    23 #ifndef HAVE_STDLIB_H		/* <stdlib.h> should declare malloc(),free() */
       
    24 extern void * malloc JPP((size_t size));
       
    25 extern void free JPP((void *ptr));
       
    26 #endif
       
    27 
    22 
    28 
    23 /* Expanded data destination object for stdio output */
    29 /* Expanded data destination object for stdio output */
    24 
    30 
    25 typedef struct {
    31 typedef struct {
    26   struct jpeg_destination_mgr pub; /* public fields */
    32   struct jpeg_destination_mgr pub; /* public fields */
    30 } my_destination_mgr;
    36 } my_destination_mgr;
    31 
    37 
    32 typedef my_destination_mgr * my_dest_ptr;
    38 typedef my_destination_mgr * my_dest_ptr;
    33 
    39 
    34 #define OUTPUT_BUF_SIZE  4096	/* choose an efficiently fwrite'able size */
    40 #define OUTPUT_BUF_SIZE  4096	/* choose an efficiently fwrite'able size */
       
    41 
       
    42 
       
    43 /* Expanded data destination object for memory output */
       
    44 
       
    45 typedef struct {
       
    46   struct jpeg_destination_mgr pub; /* public fields */
       
    47 
       
    48   unsigned char ** outbuffer;	/* target buffer */
       
    49   unsigned long * outsize;
       
    50   unsigned char * newbuffer;	/* newly allocated buffer */
       
    51   JOCTET * buffer;		/* start of buffer */
       
    52   size_t bufsize;
       
    53 } my_mem_destination_mgr;
       
    54 
       
    55 typedef my_mem_destination_mgr * my_mem_dest_ptr;
    35 
    56 
    36 
    57 
    37 /*
    58 /*
    38  * Initialize destination --- called by jpeg_start_compress
    59  * Initialize destination --- called by jpeg_start_compress
    39  * before any data is actually written.
    60  * before any data is actually written.
    49       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    70       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    50 				  OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
    71 				  OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
    51 
    72 
    52   dest->pub.next_output_byte = dest->buffer;
    73   dest->pub.next_output_byte = dest->buffer;
    53   dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
    74   dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
       
    75 }
       
    76 
       
    77 METHODDEF(void)
       
    78 init_mem_destination (j_compress_ptr cinfo)
       
    79 {
       
    80   /* no work necessary here */
    54 }
    81 }
    55 
    82 
    56 
    83 
    57 /*
    84 /*
    58  * Empty the output buffer --- called whenever buffer fills up.
    85  * Empty the output buffer --- called whenever buffer fills up.
    90   dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
   117   dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
    91 
   118 
    92   return TRUE;
   119   return TRUE;
    93 }
   120 }
    94 
   121 
       
   122 METHODDEF(boolean)
       
   123 empty_mem_output_buffer (j_compress_ptr cinfo)
       
   124 {
       
   125   size_t nextsize;
       
   126   JOCTET * nextbuffer;
       
   127   my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
       
   128 
       
   129   /* Try to allocate new buffer with double size */
       
   130   nextsize = dest->bufsize * 2;
       
   131   nextbuffer = malloc(nextsize);
       
   132 
       
   133   if (nextbuffer == NULL)
       
   134     ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
       
   135 
       
   136   MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
       
   137 
       
   138   if (dest->newbuffer != NULL)
       
   139     free(dest->newbuffer);
       
   140 
       
   141   dest->newbuffer = nextbuffer;
       
   142 
       
   143   dest->pub.next_output_byte = nextbuffer + dest->bufsize;
       
   144   dest->pub.free_in_buffer = dest->bufsize;
       
   145 
       
   146   dest->buffer = nextbuffer;
       
   147   dest->bufsize = nextsize;
       
   148 
       
   149   return TRUE;
       
   150 }
       
   151 
    95 
   152 
    96 /*
   153 /*
    97  * Terminate destination --- called by jpeg_finish_compress
   154  * Terminate destination --- called by jpeg_finish_compress
    98  * after all data has been written.  Usually needs to flush buffer.
   155  * after all data has been written.  Usually needs to flush buffer.
    99  *
   156  *
   115   }
   172   }
   116   fflush(dest->outfile);
   173   fflush(dest->outfile);
   117   /* Make sure we wrote the output file OK */
   174   /* Make sure we wrote the output file OK */
   118   if (ferror(dest->outfile))
   175   if (ferror(dest->outfile))
   119     ERREXIT(cinfo, JERR_FILE_WRITE);
   176     ERREXIT(cinfo, JERR_FILE_WRITE);
       
   177 }
       
   178 
       
   179 METHODDEF(void)
       
   180 term_mem_destination (j_compress_ptr cinfo)
       
   181 {
       
   182   my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
       
   183 
       
   184   *dest->outbuffer = dest->buffer;
       
   185   *dest->outsize = dest->bufsize - dest->pub.free_in_buffer;
   120 }
   186 }
   121 
   187 
   122 
   188 
   123 /*
   189 /*
   124  * Prepare for output to a stdio stream.
   190  * Prepare for output to a stdio stream.
   147   dest->pub.init_destination = init_destination;
   213   dest->pub.init_destination = init_destination;
   148   dest->pub.empty_output_buffer = empty_output_buffer;
   214   dest->pub.empty_output_buffer = empty_output_buffer;
   149   dest->pub.term_destination = term_destination;
   215   dest->pub.term_destination = term_destination;
   150   dest->outfile = outfile;
   216   dest->outfile = outfile;
   151 }
   217 }
       
   218 
       
   219 
       
   220 /*
       
   221  * Prepare for output to a memory buffer.
       
   222  * The caller may supply an own initial buffer with appropriate size.
       
   223  * Otherwise, or when the actual data output exceeds the given size,
       
   224  * the library adapts the buffer size as necessary.
       
   225  * The standard library functions malloc/free are used for allocating
       
   226  * larger memory, so the buffer is available to the application after
       
   227  * finishing compression, and then the application is responsible for
       
   228  * freeing the requested memory.
       
   229  */
       
   230 
       
   231 GLOBAL(void)
       
   232 jpeg_mem_dest (j_compress_ptr cinfo,
       
   233 	       unsigned char ** outbuffer, unsigned long * outsize)
       
   234 {
       
   235   my_mem_dest_ptr dest;
       
   236 
       
   237   if (outbuffer == NULL || outsize == NULL)	/* sanity check */
       
   238     ERREXIT(cinfo, JERR_BUFFER_SIZE);
       
   239 
       
   240   /* The destination object is made permanent so that multiple JPEG images
       
   241    * can be written to the same buffer without re-executing jpeg_mem_dest.
       
   242    */
       
   243   if (cinfo->dest == NULL) {	/* first time for this JPEG object? */
       
   244     cinfo->dest = (struct jpeg_destination_mgr *)
       
   245       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
       
   246 				  SIZEOF(my_mem_destination_mgr));
       
   247   }
       
   248 
       
   249   dest = (my_mem_dest_ptr) cinfo->dest;
       
   250   dest->pub.init_destination = init_mem_destination;
       
   251   dest->pub.empty_output_buffer = empty_mem_output_buffer;
       
   252   dest->pub.term_destination = term_mem_destination;
       
   253   dest->outbuffer = outbuffer;
       
   254   dest->outsize = outsize;
       
   255   dest->newbuffer = NULL;
       
   256 
       
   257   if (*outbuffer == NULL || *outsize == 0) {
       
   258     /* Allocate initial buffer */
       
   259     dest->newbuffer = *outbuffer = malloc(OUTPUT_BUF_SIZE);
       
   260     if (dest->newbuffer == NULL)
       
   261       ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
       
   262     *outsize = OUTPUT_BUF_SIZE;
       
   263   }
       
   264 
       
   265   dest->pub.next_output_byte = dest->buffer = *outbuffer;
       
   266   dest->pub.free_in_buffer = dest->bufsize = *outsize;
       
   267 }