ReactOS Fundraising Campaign 2012
 
€ 3,873 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

jdatadst.c
Go to the documentation of this file.
00001 /*
00002  * jdatadst.c
00003  *
00004  * Copyright (C) 1994-1996, Thomas G. Lane.
00005  * Modified 2009 by Guido Vollbeding.
00006  * This file is part of the Independent JPEG Group's software.
00007  * For conditions of distribution and use, see the accompanying README file.
00008  *
00009  * This file contains compression data destination routines for the case of
00010  * emitting JPEG data to memory or to a file (or any stdio stream).
00011  * While these routines are sufficient for most applications,
00012  * some will want to use a different destination manager.
00013  * IMPORTANT: we assume that fwrite() will correctly transcribe an array of
00014  * JOCTETs into 8-bit-wide elements on external storage.  If char is wider
00015  * than 8 bits on your machine, you may need to do some tweaking.
00016  */
00017 
00018 /* this is not a core library module, so it doesn't define JPEG_INTERNALS */
00019 #include "jinclude.h"
00020 #include "jpeglib.h"
00021 #include "jerror.h"
00022 
00023 #ifndef HAVE_STDLIB_H       /* <stdlib.h> should declare malloc(),free() */
00024 extern void * malloc JPP((size_t size));
00025 extern void free JPP((void *ptr));
00026 #endif
00027 
00028 
00029 /* Expanded data destination object for stdio output */
00030 
00031 typedef struct {
00032   struct jpeg_destination_mgr pub; /* public fields */
00033 
00034   FILE * outfile;       /* target stream */
00035   JOCTET * buffer;      /* start of buffer */
00036 } my_destination_mgr;
00037 
00038 typedef my_destination_mgr * my_dest_ptr;
00039 
00040 #define OUTPUT_BUF_SIZE  4096   /* choose an efficiently fwrite'able size */
00041 
00042 
00043 /* Expanded data destination object for memory output */
00044 
00045 typedef struct {
00046   struct jpeg_destination_mgr pub; /* public fields */
00047 
00048   unsigned char ** outbuffer;   /* target buffer */
00049   unsigned long * outsize;
00050   unsigned char * newbuffer;    /* newly allocated buffer */
00051   JOCTET * buffer;      /* start of buffer */
00052   size_t bufsize;
00053 } my_mem_destination_mgr;
00054 
00055 typedef my_mem_destination_mgr * my_mem_dest_ptr;
00056 
00057 
00058 /*
00059  * Initialize destination --- called by jpeg_start_compress
00060  * before any data is actually written.
00061  */
00062 
00063 METHODDEF(void)
00064 init_destination (j_compress_ptr cinfo)
00065 {
00066   my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
00067 
00068   /* Allocate the output buffer --- it will be released when done with image */
00069   dest->buffer = (JOCTET *)
00070       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00071                   OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
00072 
00073   dest->pub.next_output_byte = dest->buffer;
00074   dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
00075 }
00076 
00077 METHODDEF(void)
00078 init_mem_destination (j_compress_ptr cinfo)
00079 {
00080   /* no work necessary here */
00081 }
00082 
00083 
00084 /*
00085  * Empty the output buffer --- called whenever buffer fills up.
00086  *
00087  * In typical applications, this should write the entire output buffer
00088  * (ignoring the current state of next_output_byte & free_in_buffer),
00089  * reset the pointer & count to the start of the buffer, and return TRUE
00090  * indicating that the buffer has been dumped.
00091  *
00092  * In applications that need to be able to suspend compression due to output
00093  * overrun, a FALSE return indicates that the buffer cannot be emptied now.
00094  * In this situation, the compressor will return to its caller (possibly with
00095  * an indication that it has not accepted all the supplied scanlines).  The
00096  * application should resume compression after it has made more room in the
00097  * output buffer.  Note that there are substantial restrictions on the use of
00098  * suspension --- see the documentation.
00099  *
00100  * When suspending, the compressor will back up to a convenient restart point
00101  * (typically the start of the current MCU). next_output_byte & free_in_buffer
00102  * indicate where the restart point will be if the current call returns FALSE.
00103  * Data beyond this point will be regenerated after resumption, so do not
00104  * write it out when emptying the buffer externally.
00105  */
00106 
00107 METHODDEF(boolean)
00108 empty_output_buffer (j_compress_ptr cinfo)
00109 {
00110   my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
00111 
00112   if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) !=
00113       (size_t) OUTPUT_BUF_SIZE)
00114     ERREXIT(cinfo, JERR_FILE_WRITE);
00115 
00116   dest->pub.next_output_byte = dest->buffer;
00117   dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
00118 
00119   return TRUE;
00120 }
00121 
00122 METHODDEF(boolean)
00123 empty_mem_output_buffer (j_compress_ptr cinfo)
00124 {
00125   size_t nextsize;
00126   JOCTET * nextbuffer;
00127   my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
00128 
00129   /* Try to allocate new buffer with double size */
00130   nextsize = dest->bufsize * 2;
00131   nextbuffer = malloc(nextsize);
00132 
00133   if (nextbuffer == NULL)
00134     ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
00135 
00136   MEMCOPY(nextbuffer, dest->buffer, dest->bufsize);
00137 
00138   if (dest->newbuffer != NULL)
00139     free(dest->newbuffer);
00140 
00141   dest->newbuffer = nextbuffer;
00142 
00143   dest->pub.next_output_byte = nextbuffer + dest->bufsize;
00144   dest->pub.free_in_buffer = dest->bufsize;
00145 
00146   dest->buffer = nextbuffer;
00147   dest->bufsize = nextsize;
00148 
00149   return TRUE;
00150 }
00151 
00152 
00153 /*
00154  * Terminate destination --- called by jpeg_finish_compress
00155  * after all data has been written.  Usually needs to flush buffer.
00156  *
00157  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
00158  * application must deal with any cleanup that should happen even
00159  * for error exit.
00160  */
00161 
00162 METHODDEF(void)
00163 term_destination (j_compress_ptr cinfo)
00164 {
00165   my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
00166   size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
00167 
00168   /* Write any data remaining in the buffer */
00169   if (datacount > 0) {
00170     if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount)
00171       ERREXIT(cinfo, JERR_FILE_WRITE);
00172   }
00173   fflush(dest->outfile);
00174   /* Make sure we wrote the output file OK */
00175   if (ferror(dest->outfile))
00176     ERREXIT(cinfo, JERR_FILE_WRITE);
00177 }
00178 
00179 METHODDEF(void)
00180 term_mem_destination (j_compress_ptr cinfo)
00181 {
00182   my_mem_dest_ptr dest = (my_mem_dest_ptr) cinfo->dest;
00183 
00184   *dest->outbuffer = dest->buffer;
00185   *dest->outsize = dest->bufsize - dest->pub.free_in_buffer;
00186 }
00187 
00188 
00189 /*
00190  * Prepare for output to a stdio stream.
00191  * The caller must have already opened the stream, and is responsible
00192  * for closing it after finishing compression.
00193  */
00194 
00195 GLOBAL(void)
00196 jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
00197 {
00198   my_dest_ptr dest;
00199 
00200   /* The destination object is made permanent so that multiple JPEG images
00201    * can be written to the same file without re-executing jpeg_stdio_dest.
00202    * This makes it dangerous to use this manager and a different destination
00203    * manager serially with the same JPEG object, because their private object
00204    * sizes may be different.  Caveat programmer.
00205    */
00206   if (cinfo->dest == NULL) {    /* first time for this JPEG object? */
00207     cinfo->dest = (struct jpeg_destination_mgr *)
00208       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
00209                   SIZEOF(my_destination_mgr));
00210   }
00211 
00212   dest = (my_dest_ptr) cinfo->dest;
00213   dest->pub.init_destination = init_destination;
00214   dest->pub.empty_output_buffer = empty_output_buffer;
00215   dest->pub.term_destination = term_destination;
00216   dest->outfile = outfile;
00217 }
00218 
00219 
00220 /*
00221  * Prepare for output to a memory buffer.
00222  * The caller may supply an own initial buffer with appropriate size.
00223  * Otherwise, or when the actual data output exceeds the given size,
00224  * the library adapts the buffer size as necessary.
00225  * The standard library functions malloc/free are used for allocating
00226  * larger memory, so the buffer is available to the application after
00227  * finishing compression, and then the application is responsible for
00228  * freeing the requested memory.
00229  */
00230 
00231 GLOBAL(void)
00232 jpeg_mem_dest (j_compress_ptr cinfo,
00233            unsigned char ** outbuffer, unsigned long * outsize)
00234 {
00235   my_mem_dest_ptr dest;
00236 
00237   if (outbuffer == NULL || outsize == NULL) /* sanity check */
00238     ERREXIT(cinfo, JERR_BUFFER_SIZE);
00239 
00240   /* The destination object is made permanent so that multiple JPEG images
00241    * can be written to the same buffer without re-executing jpeg_mem_dest.
00242    */
00243   if (cinfo->dest == NULL) {    /* first time for this JPEG object? */
00244     cinfo->dest = (struct jpeg_destination_mgr *)
00245       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
00246                   SIZEOF(my_mem_destination_mgr));
00247   }
00248 
00249   dest = (my_mem_dest_ptr) cinfo->dest;
00250   dest->pub.init_destination = init_mem_destination;
00251   dest->pub.empty_output_buffer = empty_mem_output_buffer;
00252   dest->pub.term_destination = term_mem_destination;
00253   dest->outbuffer = outbuffer;
00254   dest->outsize = outsize;
00255   dest->newbuffer = NULL;
00256 
00257   if (*outbuffer == NULL || *outsize == 0) {
00258     /* Allocate initial buffer */
00259     dest->newbuffer = *outbuffer = malloc(OUTPUT_BUF_SIZE);
00260     if (dest->newbuffer == NULL)
00261       ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
00262     *outsize = OUTPUT_BUF_SIZE;
00263   }
00264 
00265   dest->pub.next_output_byte = dest->buffer = *outbuffer;
00266   dest->pub.free_in_buffer = dest->bufsize = *outsize;
00267 }

Generated on Sat May 19 2012 04:17:30 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.