ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 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

example.c
Go to the documentation of this file.
00001 /*
00002  * example.c
00003  *
00004  * This file illustrates how to use the IJG code as a subroutine library
00005  * to read or write JPEG image files.  You should look at this code in
00006  * conjunction with the documentation file libjpeg.txt.
00007  *
00008  * This code will not do anything useful as-is, but it may be helpful as a
00009  * skeleton for constructing routines that call the JPEG library.  
00010  *
00011  * We present these routines in the same coding style used in the JPEG code
00012  * (ANSI function definitions, etc); but you are of course free to code your
00013  * routines in a different style if you prefer.
00014  */
00015 
00016 #include <stdio.h>
00017 
00018 /*
00019  * Include file for users of JPEG library.
00020  * You will need to have included system headers that define at least
00021  * the typedefs FILE and size_t before you can include jpeglib.h.
00022  * (stdio.h is sufficient on ANSI-conforming systems.)
00023  * You may also wish to include "jerror.h".
00024  */
00025 
00026 #include "jpeglib.h"
00027 
00028 /*
00029  * <setjmp.h> is used for the optional error recovery mechanism shown in
00030  * the second part of the example.
00031  */
00032 
00033 #include <setjmp.h>
00034 
00035 
00036 
00037 /******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/
00038 
00039 /* This half of the example shows how to feed data into the JPEG compressor.
00040  * We present a minimal version that does not worry about refinements such
00041  * as error recovery (the JPEG code will just exit() if it gets an error).
00042  */
00043 
00044 
00045 /*
00046  * IMAGE DATA FORMATS:
00047  *
00048  * The standard input image format is a rectangular array of pixels, with
00049  * each pixel having the same number of "component" values (color channels).
00050  * Each pixel row is an array of JSAMPLEs (which typically are unsigned chars).
00051  * If you are working with color data, then the color values for each pixel
00052  * must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit
00053  * RGB color.
00054  *
00055  * For this example, we'll assume that this data structure matches the way
00056  * our application has stored the image in memory, so we can just pass a
00057  * pointer to our image buffer.  In particular, let's say that the image is
00058  * RGB color and is described by:
00059  */
00060 
00061 extern JSAMPLE * image_buffer;  /* Points to large array of R,G,B-order data */
00062 extern int image_height;    /* Number of rows in image */
00063 extern int image_width;     /* Number of columns in image */
00064 
00065 
00066 /*
00067  * Sample routine for JPEG compression.  We assume that the target file name
00068  * and a compression quality factor are passed in.
00069  */
00070 
00071 GLOBAL(void)
00072 write_JPEG_file (char * filename, int quality)
00073 {
00074   /* This struct contains the JPEG compression parameters and pointers to
00075    * working space (which is allocated as needed by the JPEG library).
00076    * It is possible to have several such structures, representing multiple
00077    * compression/decompression processes, in existence at once.  We refer
00078    * to any one struct (and its associated working data) as a "JPEG object".
00079    */
00080   struct jpeg_compress_struct cinfo;
00081   /* This struct represents a JPEG error handler.  It is declared separately
00082    * because applications often want to supply a specialized error handler
00083    * (see the second half of this file for an example).  But here we just
00084    * take the easy way out and use the standard error handler, which will
00085    * print a message on stderr and call exit() if compression fails.
00086    * Note that this struct must live as long as the main JPEG parameter
00087    * struct, to avoid dangling-pointer problems.
00088    */
00089   struct jpeg_error_mgr jerr;
00090   /* More stuff */
00091   FILE * outfile;       /* target file */
00092   JSAMPROW row_pointer[1];  /* pointer to JSAMPLE row[s] */
00093   int row_stride;       /* physical row width in image buffer */
00094 
00095   /* Step 1: allocate and initialize JPEG compression object */
00096 
00097   /* We have to set up the error handler first, in case the initialization
00098    * step fails.  (Unlikely, but it could happen if you are out of memory.)
00099    * This routine fills in the contents of struct jerr, and returns jerr's
00100    * address which we place into the link field in cinfo.
00101    */
00102   cinfo.err = jpeg_std_error(&jerr);
00103   /* Now we can initialize the JPEG compression object. */
00104   jpeg_create_compress(&cinfo);
00105 
00106   /* Step 2: specify data destination (eg, a file) */
00107   /* Note: steps 2 and 3 can be done in either order. */
00108 
00109   /* Here we use the library-supplied code to send compressed data to a
00110    * stdio stream.  You can also write your own code to do something else.
00111    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
00112    * requires it in order to write binary files.
00113    */
00114   if ((outfile = fopen(filename, "wb")) == NULL) {
00115     fprintf(stderr, "can't open %s\n", filename);
00116     exit(1);
00117   }
00118   jpeg_stdio_dest(&cinfo, outfile);
00119 
00120   /* Step 3: set parameters for compression */
00121 
00122   /* First we supply a description of the input image.
00123    * Four fields of the cinfo struct must be filled in:
00124    */
00125   cinfo.image_width = image_width;  /* image width and height, in pixels */
00126   cinfo.image_height = image_height;
00127   cinfo.input_components = 3;       /* # of color components per pixel */
00128   cinfo.in_color_space = JCS_RGB;   /* colorspace of input image */
00129   /* Now use the library's routine to set default compression parameters.
00130    * (You must set at least cinfo.in_color_space before calling this,
00131    * since the defaults depend on the source color space.)
00132    */
00133   jpeg_set_defaults(&cinfo);
00134   /* Now you can set any non-default parameters you wish to.
00135    * Here we just illustrate the use of quality (quantization table) scaling:
00136    */
00137   jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
00138 
00139   /* Step 4: Start compressor */
00140 
00141   /* TRUE ensures that we will write a complete interchange-JPEG file.
00142    * Pass TRUE unless you are very sure of what you're doing.
00143    */
00144   jpeg_start_compress(&cinfo, TRUE);
00145 
00146   /* Step 5: while (scan lines remain to be written) */
00147   /*           jpeg_write_scanlines(...); */
00148 
00149   /* Here we use the library's state variable cinfo.next_scanline as the
00150    * loop counter, so that we don't have to keep track ourselves.
00151    * To keep things simple, we pass one scanline per call; you can pass
00152    * more if you wish, though.
00153    */
00154   row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
00155 
00156   while (cinfo.next_scanline < cinfo.image_height) {
00157     /* jpeg_write_scanlines expects an array of pointers to scanlines.
00158      * Here the array is only one element long, but you could pass
00159      * more than one scanline at a time if that's more convenient.
00160      */
00161     row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
00162     (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
00163   }
00164 
00165   /* Step 6: Finish compression */
00166 
00167   jpeg_finish_compress(&cinfo);
00168   /* After finish_compress, we can close the output file. */
00169   fclose(outfile);
00170 
00171   /* Step 7: release JPEG compression object */
00172 
00173   /* This is an important step since it will release a good deal of memory. */
00174   jpeg_destroy_compress(&cinfo);
00175 
00176   /* And we're done! */
00177 }
00178 
00179 
00180 /*
00181  * SOME FINE POINTS:
00182  *
00183  * In the above loop, we ignored the return value of jpeg_write_scanlines,
00184  * which is the number of scanlines actually written.  We could get away
00185  * with this because we were only relying on the value of cinfo.next_scanline,
00186  * which will be incremented correctly.  If you maintain additional loop
00187  * variables then you should be careful to increment them properly.
00188  * Actually, for output to a stdio stream you needn't worry, because
00189  * then jpeg_write_scanlines will write all the lines passed (or else exit
00190  * with a fatal error).  Partial writes can only occur if you use a data
00191  * destination module that can demand suspension of the compressor.
00192  * (If you don't know what that's for, you don't need it.)
00193  *
00194  * If the compressor requires full-image buffers (for entropy-coding
00195  * optimization or a multi-scan JPEG file), it will create temporary
00196  * files for anything that doesn't fit within the maximum-memory setting.
00197  * (Note that temp files are NOT needed if you use the default parameters.)
00198  * On some systems you may need to set up a signal handler to ensure that
00199  * temporary files are deleted if the program is interrupted.  See libjpeg.txt.
00200  *
00201  * Scanlines MUST be supplied in top-to-bottom order if you want your JPEG
00202  * files to be compatible with everyone else's.  If you cannot readily read
00203  * your data in that order, you'll need an intermediate array to hold the
00204  * image.  See rdtarga.c or rdbmp.c for examples of handling bottom-to-top
00205  * source data using the JPEG code's internal virtual-array mechanisms.
00206  */
00207 
00208 
00209 
00210 /******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
00211 
00212 /* This half of the example shows how to read data from the JPEG decompressor.
00213  * It's a bit more refined than the above, in that we show:
00214  *   (a) how to modify the JPEG library's standard error-reporting behavior;
00215  *   (b) how to allocate workspace using the library's memory manager.
00216  *
00217  * Just to make this example a little different from the first one, we'll
00218  * assume that we do not intend to put the whole image into an in-memory
00219  * buffer, but to send it line-by-line someplace else.  We need a one-
00220  * scanline-high JSAMPLE array as a work buffer, and we will let the JPEG
00221  * memory manager allocate it for us.  This approach is actually quite useful
00222  * because we don't need to remember to deallocate the buffer separately: it
00223  * will go away automatically when the JPEG object is cleaned up.
00224  */
00225 
00226 
00227 /*
00228  * ERROR HANDLING:
00229  *
00230  * The JPEG library's standard error handler (jerror.c) is divided into
00231  * several "methods" which you can override individually.  This lets you
00232  * adjust the behavior without duplicating a lot of code, which you might
00233  * have to update with each future release.
00234  *
00235  * Our example here shows how to override the "error_exit" method so that
00236  * control is returned to the library's caller when a fatal error occurs,
00237  * rather than calling exit() as the standard error_exit method does.
00238  *
00239  * We use C's setjmp/longjmp facility to return control.  This means that the
00240  * routine which calls the JPEG library must first execute a setjmp() call to
00241  * establish the return point.  We want the replacement error_exit to do a
00242  * longjmp().  But we need to make the setjmp buffer accessible to the
00243  * error_exit routine.  To do this, we make a private extension of the
00244  * standard JPEG error handler object.  (If we were using C++, we'd say we
00245  * were making a subclass of the regular error handler.)
00246  *
00247  * Here's the extended error handler struct:
00248  */
00249 
00250 struct my_error_mgr {
00251   struct jpeg_error_mgr pub;    /* "public" fields */
00252 
00253   jmp_buf setjmp_buffer;    /* for return to caller */
00254 };
00255 
00256 typedef struct my_error_mgr * my_error_ptr;
00257 
00258 /*
00259  * Here's the routine that will replace the standard error_exit method:
00260  */
00261 
00262 METHODDEF(void)
00263 my_error_exit (j_common_ptr cinfo)
00264 {
00265   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
00266   my_error_ptr myerr = (my_error_ptr) cinfo->err;
00267 
00268   /* Always display the message. */
00269   /* We could postpone this until after returning, if we chose. */
00270   (*cinfo->err->output_message) (cinfo);
00271 
00272   /* Return control to the setjmp point */
00273   longjmp(myerr->setjmp_buffer, 1);
00274 }
00275 
00276 
00277 /*
00278  * Sample routine for JPEG decompression.  We assume that the source file name
00279  * is passed in.  We want to return 1 on success, 0 on error.
00280  */
00281 
00282 
00283 GLOBAL(int)
00284 read_JPEG_file (char * filename)
00285 {
00286   /* This struct contains the JPEG decompression parameters and pointers to
00287    * working space (which is allocated as needed by the JPEG library).
00288    */
00289   struct jpeg_decompress_struct cinfo;
00290   /* We use our private extension JPEG error handler.
00291    * Note that this struct must live as long as the main JPEG parameter
00292    * struct, to avoid dangling-pointer problems.
00293    */
00294   struct my_error_mgr jerr;
00295   /* More stuff */
00296   FILE * infile;        /* source file */
00297   JSAMPARRAY buffer;        /* Output row buffer */
00298   int row_stride;       /* physical row width in output buffer */
00299 
00300   /* In this example we want to open the input file before doing anything else,
00301    * so that the setjmp() error recovery below can assume the file is open.
00302    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
00303    * requires it in order to read binary files.
00304    */
00305 
00306   if ((infile = fopen(filename, "rb")) == NULL) {
00307     fprintf(stderr, "can't open %s\n", filename);
00308     return 0;
00309   }
00310 
00311   /* Step 1: allocate and initialize JPEG decompression object */
00312 
00313   /* We set up the normal JPEG error routines, then override error_exit. */
00314   cinfo.err = jpeg_std_error(&jerr.pub);
00315   jerr.pub.error_exit = my_error_exit;
00316   /* Establish the setjmp return context for my_error_exit to use. */
00317   if (setjmp(jerr.setjmp_buffer)) {
00318     /* If we get here, the JPEG code has signaled an error.
00319      * We need to clean up the JPEG object, close the input file, and return.
00320      */
00321     jpeg_destroy_decompress(&cinfo);
00322     fclose(infile);
00323     return 0;
00324   }
00325   /* Now we can initialize the JPEG decompression object. */
00326   jpeg_create_decompress(&cinfo);
00327 
00328   /* Step 2: specify data source (eg, a file) */
00329 
00330   jpeg_stdio_src(&cinfo, infile);
00331 
00332   /* Step 3: read file parameters with jpeg_read_header() */
00333 
00334   (void) jpeg_read_header(&cinfo, TRUE);
00335   /* We can ignore the return value from jpeg_read_header since
00336    *   (a) suspension is not possible with the stdio data source, and
00337    *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
00338    * See libjpeg.txt for more info.
00339    */
00340 
00341   /* Step 4: set parameters for decompression */
00342 
00343   /* In this example, we don't need to change any of the defaults set by
00344    * jpeg_read_header(), so we do nothing here.
00345    */
00346 
00347   /* Step 5: Start decompressor */
00348 
00349   (void) jpeg_start_decompress(&cinfo);
00350   /* We can ignore the return value since suspension is not possible
00351    * with the stdio data source.
00352    */
00353 
00354   /* We may need to do some setup of our own at this point before reading
00355    * the data.  After jpeg_start_decompress() we have the correct scaled
00356    * output image dimensions available, as well as the output colormap
00357    * if we asked for color quantization.
00358    * In this example, we need to make an output work buffer of the right size.
00359    */ 
00360   /* JSAMPLEs per row in output buffer */
00361   row_stride = cinfo.output_width * cinfo.output_components;
00362   /* Make a one-row-high sample array that will go away when done with image */
00363   buffer = (*cinfo.mem->alloc_sarray)
00364         ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
00365 
00366   /* Step 6: while (scan lines remain to be read) */
00367   /*           jpeg_read_scanlines(...); */
00368 
00369   /* Here we use the library's state variable cinfo.output_scanline as the
00370    * loop counter, so that we don't have to keep track ourselves.
00371    */
00372   while (cinfo.output_scanline < cinfo.output_height) {
00373     /* jpeg_read_scanlines expects an array of pointers to scanlines.
00374      * Here the array is only one element long, but you could ask for
00375      * more than one scanline at a time if that's more convenient.
00376      */
00377     (void) jpeg_read_scanlines(&cinfo, buffer, 1);
00378     /* Assume put_scanline_someplace wants a pointer and sample count. */
00379     put_scanline_someplace(buffer[0], row_stride);
00380   }
00381 
00382   /* Step 7: Finish decompression */
00383 
00384   (void) jpeg_finish_decompress(&cinfo);
00385   /* We can ignore the return value since suspension is not possible
00386    * with the stdio data source.
00387    */
00388 
00389   /* Step 8: Release JPEG decompression object */
00390 
00391   /* This is an important step since it will release a good deal of memory. */
00392   jpeg_destroy_decompress(&cinfo);
00393 
00394   /* After finish_decompress, we can close the input file.
00395    * Here we postpone it until after no more JPEG errors are possible,
00396    * so as to simplify the setjmp error logic above.  (Actually, I don't
00397    * think that jpeg_destroy can do an error exit, but why assume anything...)
00398    */
00399   fclose(infile);
00400 
00401   /* At this point you may want to check to see whether any corrupt-data
00402    * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
00403    */
00404 
00405   /* And we're done! */
00406   return 1;
00407 }
00408 
00409 
00410 /*
00411  * SOME FINE POINTS:
00412  *
00413  * In the above code, we ignored the return value of jpeg_read_scanlines,
00414  * which is the number of scanlines actually read.  We could get away with
00415  * this because we asked for only one line at a time and we weren't using
00416  * a suspending data source.  See libjpeg.txt for more info.
00417  *
00418  * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
00419  * we should have done it beforehand to ensure that the space would be
00420  * counted against the JPEG max_memory setting.  In some systems the above
00421  * code would risk an out-of-memory error.  However, in general we don't
00422  * know the output image dimensions before jpeg_start_decompress(), unless we
00423  * call jpeg_calc_output_dimensions().  See libjpeg.txt for more about this.
00424  *
00425  * Scanlines are returned in the same order as they appear in the JPEG file,
00426  * which is standardly top-to-bottom.  If you must emit data bottom-to-top,
00427  * you can use one of the virtual arrays provided by the JPEG memory manager
00428  * to invert the data.  See wrbmp.c for an example.
00429  *
00430  * As with compression, some operating modes may require temporary files.
00431  * On some systems you may need to set up a signal handler to ensure that
00432  * temporary files are deleted if the program is interrupted.  See libjpeg.txt.
00433  */

Generated on Sun May 27 2012 04:19:22 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.