LCOV - code coverage report
Current view: top level - media/libjpeg - jdatadst.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 36 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13