git.y1.nz

fbui

Framebuffer-based graphical environment
download: https://git.y1.nz/archives/fbui.tar.gz
README | Files | Log | Refs

libfbui/Dump/jpeg.c

      1 
      2 /*
      3  * example.c
      4  *
      5  * This file illustrates how to use the IJG code as a subroutine library
      6  * to read or write JPEG image files.  You should look at this code in
      7  * conjunction with the documentation file libjpeg.doc.
      8  *
      9  * This code will not do anything useful as-is, but it may be helpful as a
     10  * skeleton for constructing routines that call the JPEG library.  
     11  *
     12  * We present these routines in the same coding style used in the JPEG code
     13  * (ANSI function definitions, etc); but you are of course free to code your
     14  * routines in a different style if you prefer.
     15  */
     16 
     17 #include <stdio.h>
     18 
     19 /*
     20  * Include file for users of JPEG library.
     21  * You will need to have included system headers that define at least
     22  * the typedefs FILE and size_t before you can include jpeglib.h.
     23  * (stdio.h is sufficient on ANSI-conforming systems.)
     24  * You may also wish to include "jerror.h".
     25  */
     26 
     27 #include <jpeglib.h>
     28 
     29 /*
     30  * <setjmp.h> is used for the optional error recovery mechanism shown in
     31  * the second part of the example.
     32  */
     33 
     34 #include <setjmp.h>
     35 
     36 /******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/
     37 
     38 /* This half of the example shows how to feed data into the JPEG compressor.
     39  * We present a minimal version that does not worry about refinements such
     40  * as error recovery (the JPEG code will just exit() if it gets an error).
     41  */
     42 
     43 /*
     44  * IMAGE DATA FORMATS:
     45  *
     46  * The standard input image format is a rectangular array of pixels, with
     47  * each pixel having the same number of "component" values (color channels).
     48  * Each pixel row is an array of JSAMPLEs (which typically are unsigned chars).
     49  * If you are working with color data, then the color values for each pixel
     50  * must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit
     51  * RGB color.
     52  *
     53  * For this example, we'll assume that this data structure matches the way
     54  * our application has stored the image in memory, so we can just pass a
     55  * pointer to our image buffer.  In particular, let's say that the image is
     56  * RGB color and is described by:
     57  */
     58 
     59 extern JSAMPLE * image_buffer;	/* Points to large array of R,G,B-order data */
     60 extern int image_height;	/* Number of rows in image */
     61 extern int image_width;		/* Number of columns in image */
     62 
     63 /*
     64  * Sample routine for JPEG compression.  We assume that the target file name
     65  * and a compression quality factor are passed in.
     66  */
     67 
     68 GLOBAL(void)
     69 write_JPEG_file (char * filename, int quality)
     70 {
     71   /* This struct contains the JPEG compression parameters and pointers to
     72    * working space (which is allocated as needed by the JPEG library).
     73    * It is possible to have several such structures, representing multiple
     74    * compression/decompression processes, in existence at once.  We refer
     75    * to any one struct (and its associated working data) as a "JPEG object".
     76    */
     77   struct jpeg_compress_struct cinfo;
     78   /* This struct represents a JPEG error handler.  It is declared separately
     79    * because applications often want to supply a specialized error handler
     80    * (see the second half of this file for an example).  But here we just
     81    * take the easy way out and use the standard error handler, which will
     82    * print a message on stderr and call exit() if compression fails.
     83    * Note that this struct must live as long as the main JPEG parameter
     84    * struct, to avoid dangling-pointer problems.
     85    */
     86   struct jpeg_error_mgr jerr;
     87   /* More stuff */
     88   FILE * outfile;		/* target file */
     89   JSAMPROW row_pointer[1];	/* pointer to JSAMPLE row[s] */
     90   int row_stride;		/* physical row width in image buffer */
     91 
     92   /* Step 1: allocate and initialize JPEG compression object */
     93 
     94   /* We have to set up the error handler first, in case the initialization
     95    * step fails.  (Unlikely, but it could happen if you are out of memory.)
     96    * This routine fills in the contents of struct jerr, and returns jerr's
     97    * address which we place into the link field in cinfo.
     98    */
     99   cinfo.err = jpeg_std_error(&jerr);
    100   /* Now we can initialize the JPEG compression object. */
    101   jpeg_create_compress(&cinfo);
    102 
    103   /* Step 2: specify data destination (eg, a file) */
    104   /* Note: steps 2 and 3 can be done in either order. */
    105 
    106   /* Here we use the library-supplied code to send compressed data to a
    107    * stdio stream.  You can also write your own code to do something else.
    108    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
    109    * requires it in order to write binary files.
    110    */
    111   if ((outfile = fopen(filename, "wb")) == NULL) {
    112     fprintf(stderr, "can't open %s\n", filename);
    113     exit(1);
    114   }
    115   jpeg_stdio_dest(&cinfo, outfile);
    116 
    117   /* Step 3: set parameters for compression */
    118 
    119   /* First we supply a description of the input image.
    120    * Four fields of the cinfo struct must be filled in:
    121    */
    122   cinfo.image_width = image_width; 	/* image width and height, in pixels */
    123   cinfo.image_height = image_height;
    124   cinfo.input_components = 3;		/* # of color components per pixel */
    125   cinfo.in_color_space = JCS_RGB; 	/* colorspace of input image */
    126   /* Now use the library's routine to set default compression parameters.
    127    * (You must set at least cinfo.in_color_space before calling this,
    128    * since the defaults depend on the source color space.)
    129    */
    130   jpeg_set_defaults(&cinfo);
    131   /* Now you can set any non-default parameters you wish to.
    132    * Here we just illustrate the use of quality (quantization table) scaling:
    133    */
    134   jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
    135 
    136   /* Step 4: Start compressor */
    137 
    138   /* TRUE ensures that we will write a complete interchange-JPEG file.
    139    * Pass TRUE unless you are very sure of what you're doing.
    140    */
    141   jpeg_start_compress(&cinfo, TRUE);
    142 
    143   /* Step 5: while (scan lines remain to be written) */
    144   /*           jpeg_write_scanlines(...); */
    145 
    146   /* Here we use the library's state variable cinfo.next_scanline as the
    147    * loop counter, so that we don't have to keep track ourselves.
    148    * To keep things simple, we pass one scanline per call; you can pass
    149    * more if you wish, though.
    150    */
    151   row_stride = image_width * 3;	/* JSAMPLEs per row in image_buffer */
    152 
    153   while (cinfo.next_scanline < cinfo.image_height) {
    154     /* jpeg_write_scanlines expects an array of pointers to scanlines.
    155      * Here the array is only one element long, but you could pass
    156      * more than one scanline at a time if that's more convenient.
    157      */
    158     row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
    159     (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
    160   }
    161 
    162   /* Step 6: Finish compression */
    163 
    164   jpeg_finish_compress(&cinfo);
    165   /* After finish_compress, we can close the output file. */
    166   fclose(outfile);
    167 
    168   /* Step 7: release JPEG compression object */
    169 
    170   /* This is an important step since it will release a good deal of memory. */
    171   jpeg_destroy_compress(&cinfo);
    172 
    173   /* And we're done! */
    174 }
    175 
    176 /*
    177  * SOME FINE POINTS:
    178  *
    179  * In the above loop, we ignored the return value of jpeg_write_scanlines,
    180  * which is the number of scanlines actually written.  We could get away
    181  * with this because we were only relying on the value of cinfo.next_scanline,
    182  * which will be incremented correctly.  If you maintain additional loop
    183  * variables then you should be careful to increment them properly.
    184  * Actually, for output to a stdio stream you needn't worry, because
    185  * then jpeg_write_scanlines will write all the lines passed (or else exit
    186  * with a fatal error).  Partial writes can only occur if you use a data
    187  * destination module that can demand suspension of the compressor.
    188  * (If you don't know what that's for, you don't need it.)
    189  *
    190  * If the compressor requires full-image buffers (for entropy-coding
    191  * optimization or a multi-scan JPEG file), it will create temporary
    192  * files for anything that doesn't fit within the maximum-memory setting.
    193  * (Note that temp files are NOT needed if you use the default parameters.)
    194  * On some systems you may need to set up a signal handler to ensure that
    195  * temporary files are deleted if the program is interrupted.  See libjpeg.doc.
    196  *
    197  * Scanlines MUST be supplied in top-to-bottom order if you want your JPEG
    198  * files to be compatible with everyone else's.  If you cannot readily read
    199  * your data in that order, you'll need an intermediate array to hold the
    200  * image.  See rdtarga.c or rdbmp.c for examples of handling bottom-to-top
    201  * source data using the JPEG code's internal virtual-array mechanisms.
    202  */
    203 
    204 /******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
    205 
    206 /* This half of the example shows how to read data from the JPEG decompressor.
    207  * It's a bit more refined than the above, in that we show:
    208  *   (a) how to modify the JPEG library's standard error-reporting behavior;
    209  *   (b) how to allocate workspace using the library's memory manager.
    210  *
    211  * Just to make this example a little different from the first one, we'll
    212  * assume that we do not intend to put the whole image into an in-memory
    213  * buffer, but to send it line-by-line someplace else.  We need a one-
    214  * scanline-high JSAMPLE array as a work buffer, and we will let the JPEG
    215  * memory manager allocate it for us.  This approach is actually quite useful
    216  * because we don't need to remember to deallocate the buffer separately: it
    217  * will go away automatically when the JPEG object is cleaned up.
    218  */
    219 
    220 /*
    221  * ERROR HANDLING:
    222  *
    223  * The JPEG library's standard error handler (jerror.c) is divided into
    224  * several "methods" which you can override individually.  This lets you
    225  * adjust the behavior without duplicating a lot of code, which you might
    226  * have to update with each future release.
    227  *
    228  * Our example here shows how to override the "error_exit" method so that
    229  * control is returned to the library's caller when a fatal error occurs,
    230  * rather than calling exit() as the standard error_exit method does.
    231  *
    232  * We use C's setjmp/longjmp facility to return control.  This means that the
    233  * routine which calls the JPEG library must first execute a setjmp() call to
    234  * establish the return point.  We want the replacement error_exit to do a
    235  * longjmp().  But we need to make the setjmp buffer accessible to the
    236  * error_exit routine.  To do this, we make a private extension of the
    237  * standard JPEG error handler object.  (If we were using C++, we'd say we
    238  * were making a subclass of the regular error handler.)
    239  *
    240  * Here's the extended error handler struct:
    241  */
    242 
    243 struct my_error_mgr {
    244   struct jpeg_error_mgr pub;	/* "public" fields */
    245 
    246   jmp_buf setjmp_buffer;	/* for return to caller */
    247 };
    248 
    249 typedef struct my_error_mgr * my_error_ptr;
    250 
    251 /*
    252  * Here's the routine that will replace the standard error_exit method:
    253  */
    254 
    255 METHODDEF(void)
    256 my_error_exit (j_common_ptr cinfo)
    257 {
    258   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
    259   my_error_ptr myerr = (my_error_ptr) cinfo->err;
    260 
    261   /* Always display the message. */
    262   /* We could postpone this until after returning, if we chose. */
    263   (*cinfo->err->output_message) (cinfo);
    264 
    265   /* Return control to the setjmp point */
    266   longjmp(myerr->setjmp_buffer, 1);
    267 }
    268 

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.