LCOV - code coverage report
Current view: directory - media/libjpeg - jdatadst.c (source / functions) Found Hit Coverage
Test: app.info Lines: 34 0 0.0 %
Date: 2012-06-02 Functions: 4 0 0.0 %

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

Generated by: LCOV version 1.7