git.y1.nz

fbui

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

libfbui/WindowManager/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 extern int image_ncomponents;
     63 
     64 static int y=0;
     65 int put_scanline_someplace(JSAMPLE* data, int width)
     66 {
     67 	if (!image_buffer) {
     68 		image_buffer = (JSAMPLE*) malloc (width * image_height * 3);
     69 		if (!image_buffer) {
     70 			printf ("failed to malloc image buffer\n");
     71 			exit(2);
     72 		}
     73 	}
     74 
     75 	int i = width;
     76 	unsigned char *tmp = (unsigned char*) data;
     77 	unsigned char *tmp2 = (unsigned char*) (image_buffer + y*width);
     78 	memcpy (tmp2,tmp,width);
     79 	y++;
     80 }
     81 
     82 
     83 /*
     84  * Sample routine for JPEG compression.  We assume that the target file name
     85  * and a compression quality factor are passed in.
     86  */
     87 
     88 
     89 /******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
     90 
     91 /* This half of the example shows how to read data from the JPEG decompressor.
     92  * It's a bit more refined than the above, in that we show:
     93  *   (a) how to modify the JPEG library's standard error-reporting behavior;
     94  *   (b) how to allocate workspace using the library's memory manager.
     95  *
     96  * Just to make this example a little different from the first one, we'll
     97  * assume that we do not intend to put the whole image into an in-memory
     98  * buffer, but to send it line-by-line someplace else.  We need a one-
     99  * scanline-high JSAMPLE array as a work buffer, and we will let the JPEG
    100  * memory manager allocate it for us.  This approach is actually quite useful
    101  * because we don't need to remember to deallocate the buffer separately: it
    102  * will go away automatically when the JPEG object is cleaned up.
    103  */
    104 
    105 /*
    106  * ERROR HANDLING:
    107  *
    108  * The JPEG library's standard error handler (jerror.c) is divided into
    109  * several "methods" which you can override individually.  This lets you
    110  * adjust the behavior without duplicating a lot of code, which you might
    111  * have to update with each future release.
    112  *
    113  * Our example here shows how to override the "error_exit" method so that
    114  * control is returned to the library's caller when a fatal error occurs,
    115  * rather than calling exit() as the standard error_exit method does.
    116  *
    117  * We use C's setjmp/longjmp facility to return control.  This means that the
    118  * routine which calls the JPEG library must first execute a setjmp() call to
    119  * establish the return point.  We want the replacement error_exit to do a
    120  * longjmp().  But we need to make the setjmp buffer accessible to the
    121  * error_exit routine.  To do this, we make a private extension of the
    122  * standard JPEG error handler object.  (If we were using C++, we'd say we
    123  * were making a subclass of the regular error handler.)
    124  *
    125  * Here's the extended error handler struct:
    126  */
    127 
    128 struct my_error_mgr {
    129   struct jpeg_error_mgr pub;	/* "public" fields */
    130 
    131   jmp_buf setjmp_buffer;	/* for return to caller */
    132 };
    133 
    134 typedef struct my_error_mgr * my_error_ptr;
    135 
    136 /*
    137  * Here's the routine that will replace the standard error_exit method:
    138  */
    139 
    140 METHODDEF(void)
    141 my_error_exit (j_common_ptr cinfo)
    142 {
    143   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
    144   my_error_ptr myerr = (my_error_ptr) cinfo->err;
    145 
    146   /* Always display the message. */
    147   /* We could postpone this until after returning, if we chose. */
    148   (*cinfo->err->output_message) (cinfo);
    149 
    150   /* Return control to the setjmp point */
    151   longjmp(myerr->setjmp_buffer, 1);
    152 }
    153 
    154 /*
    155  * Sample routine for JPEG decompression.  We assume that the source file name
    156  * is passed in.  We want to return 1 on success, 0 on error.
    157  */
    158 
    159 GLOBAL(int)
    160 read_JPEG_file (char * filename)
    161 {
    162   /* This struct contains the JPEG decompression parameters and pointers to
    163    * working space (which is allocated as needed by the JPEG library).
    164    */
    165   struct jpeg_decompress_struct cinfo;
    166   /* We use our private extension JPEG error handler.
    167    * Note that this struct must live as long as the main JPEG parameter
    168    * struct, to avoid dangling-pointer problems.
    169    */
    170   struct my_error_mgr jerr;
    171   /* More stuff */
    172   FILE * infile;		/* source file */
    173   JSAMPARRAY buffer;		/* Output row buffer */
    174   int row_stride;		/* physical row width in output buffer */
    175 
    176   /* In this example we want to open the input file before doing anything else,
    177    * so that the setjmp() error recovery below can assume the file is open.
    178    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
    179    * requires it in order to read binary files.
    180    */
    181 
    182   if ((infile = fopen(filename, "rb")) == NULL) {
    183     fprintf(stderr, "can't open %s\n", filename);
    184     return 0;
    185   }
    186 
    187   /* Step 1: allocate and initialize JPEG decompression object */
    188 
    189   /* We set up the normal JPEG error routines, then override error_exit. */
    190   cinfo.err = jpeg_std_error(&jerr.pub);
    191   jerr.pub.error_exit = my_error_exit;
    192   /* Establish the setjmp return context for my_error_exit to use. */
    193   if (setjmp(jerr.setjmp_buffer)) {
    194     /* If we get here, the JPEG code has signaled an error.
    195      * We need to clean up the JPEG object, close the input file, and return.
    196      */
    197     jpeg_destroy_decompress(&cinfo);
    198     fclose(infile);
    199     return 0;
    200   }
    201   /* Now we can initialize the JPEG decompression object. */
    202   jpeg_create_decompress(&cinfo);
    203 
    204   /* Step 2: specify data source (eg, a file) */
    205 
    206   jpeg_stdio_src(&cinfo, infile);
    207 
    208   /* Step 3: read file parameters with jpeg_read_header() */
    209 
    210   (void) jpeg_read_header(&cinfo, TRUE);
    211   /* We can ignore the return value from jpeg_read_header since
    212    *   (a) suspension is not possible with the stdio data source, and
    213    *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
    214    * See libjpeg.doc for more info.
    215    */
    216 
    217   /* Step 4: set parameters for decompression */
    218 
    219   /* In this example, we don't need to change any of the defaults set by
    220    * jpeg_read_header(), so we do nothing here.
    221    */
    222 
    223   /* Step 5: Start decompressor */
    224 
    225   (void) jpeg_start_decompress(&cinfo);
    226   /* We can ignore the return value since suspension is not possible
    227    * with the stdio data source.
    228    */
    229 
    230   /* We may need to do some setup of our own at this point before reading
    231    * the data.  After jpeg_start_decompress() we have the correct scaled
    232    * output image dimensions available, as well as the output colormap
    233    * if we asked for color quantization.
    234    * In this example, we need to make an output work buffer of the right size.
    235    */ 
    236   /* JSAMPLEs per row in output buffer */
    237 
    238   image_height = cinfo.output_height;
    239   image_width = cinfo.output_width;
    240   row_stride = cinfo.output_width * cinfo.output_components;
    241   image_ncomponents = cinfo.output_components;
    242 
    243   /* Make a one-row-high sample array that will go away when done with image */
    244   buffer = (*cinfo.mem->alloc_sarray)
    245 		((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
    246 
    247   /* Step 6: while (scan lines remain to be read) */
    248   /*           jpeg_read_scanlines(...); */
    249 
    250   /* Here we use the library's state variable cinfo.output_scanline as the
    251    * loop counter, so that we don't have to keep track ourselves.
    252    */
    253   while (cinfo.output_scanline < cinfo.output_height) {
    254     /* jpeg_read_scanlines expects an array of pointers to scanlines.
    255      * Here the array is only one element long, but you could ask for
    256      * more than one scanline at a time if that's more convenient.
    257      */
    258     (void) jpeg_read_scanlines(&cinfo, buffer, 1);
    259     /* Assume put_scanline_someplace wants a pointer and sample count. */
    260     put_scanline_someplace(buffer[0], row_stride);
    261   }
    262 
    263   /* Step 7: Finish decompression */
    264 
    265   (void) jpeg_finish_decompress(&cinfo);
    266   /* We can ignore the return value since suspension is not possible
    267    * with the stdio data source.
    268    */
    269 
    270   /* Step 8: Release JPEG decompression object */
    271 
    272   /* This is an important step since it will release a good deal of memory. */
    273   jpeg_destroy_decompress(&cinfo);
    274 
    275   /* After finish_decompress, we can close the input file.
    276    * Here we postpone it until after no more JPEG errors are possible,
    277    * so as to simplify the setjmp error logic above.  (Actually, I don't
    278    * think that jpeg_destroy can do an error exit, but why assume anything...)
    279    */
    280   fclose(infile);
    281 
    282   /* At this point you may want to check to see whether any corrupt-data
    283    * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
    284    */
    285 
    286   /* And we're done! */
    287 y=0;
    288   return 1;
    289 }
    290 
    291 /*
    292  * SOME FINE POINTS:
    293  *
    294  * In the above code, we ignored the return value of jpeg_read_scanlines,
    295  * which is the number of scanlines actually read.  We could get away with
    296  * this because we asked for only one line at a time and we weren't using
    297  * a suspending data source.  See libjpeg.doc for more info.
    298  *
    299  * We cheated a bit by calling alloc_sarray() after jpeg_start_decompress();
    300  * we should have done it beforehand to ensure that the space would be
    301  * counted against the JPEG max_memory setting.  In some systems the above
    302  * code would risk an out-of-memory error.  However, in general we don't
    303  * know the output image dimensions before jpeg_start_decompress(), unless we
    304  * call jpeg_calc_output_dimensions().  See libjpeg.doc for more about this.
    305  *
    306  * Scanlines are returned in the same order as they appear in the JPEG file,
    307  * which is standardly top-to-bottom.  If you must emit data bottom-to-top,
    308  * you can use one of the virtual arrays provided by the JPEG memory manager
    309  * to invert the data.  See wrbmp.c for an example.
    310  *
    311  * As with compression, some operating modes may require temporary files.
    312  * On some systems you may need to set up a signal handler to ensure that
    313  * temporary files are deleted if the program is interrupted.  See libjpeg.doc.
    314  */
    315 
    316 
    317  
    318 

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