apps/ccam/dma2jpeg.c

Go to the documentation of this file.
00001 /*
00002  * dma2jpeg.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.doc.
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 #include <fcntl.h>  /*open*/
00016 #include <unistd.h> /* close */
00017 
00018 #include <stdio.h>
00019 #include <stdlib.h>
00020 #include <sys/mman.h>           /* mmap */
00021 
00022 /*
00023  * Include file for users of JPEG library.
00024  * You will need to have included system headers that define at least
00025  * the typedefs FILE and size_t before you can include jpeglib.h.
00026  * (stdio.h is sufficient on ANSI-conforming systems.)
00027  * You may also wish to include "jerror.h".
00028  */
00029 
00030 #include "jpeg/jpeglib.h"
00031 #include "imageaccess.h"
00032 #include "dma2jpeg.h"
00033 
00034 
00035 #define D(x)
00036 #define D1(x)
00037 //   MD(fprintf(stderr,"width- %d, height %d, quality - %d, contrast - %d, color - %d, orient - %d, depth - %d\r\n", ImageWidth,ImageHeight, Quality, Contrast, Color, bayerOrient, Depth));
00038 
00039 /******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/
00040 
00041 /* This half of the example shows how to feed data into the JPEG compressor.
00042  * We present a minimal version that does not worry about refinements such
00043  * as error recovery (the JPEG code will just exit() if it gets an error).
00044  */
00045 
00046 
00047 /*
00048  * IMAGE DATA FORMATS:
00049  *
00050  * The standard input image format is a rectangular array of pixels, with
00051  * each pixel having the same number of "component" values (color channels).
00052  * Each pixel row is an array of JSAMPLEs (which typically are unsigned chars).
00053  * If you are working with color data, then the color values for each pixel
00054  * must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit
00055  * RGB color.
00056  *
00057  * For this example, we'll assume that this data structure matches the way
00058  * our application has stored the image in memory, so we can just pass a
00059  * pointer to our image buffer.  In particular, let's say that the image is
00060  * RGB color and is described by:
00061  */
00062 
00063 int dma2jpeg        (int ImageWidth, int ImageHeight, int Quality, int Contrast, int Color, int bayerOrient, int Depth, const char * pseudo, const char * ifn, const char * ofn) {
00064   /* This struct contains the JPEG compression parameters and pointers to
00065    * working space (which is allocated as needed by the JPEG library).
00066    * It is possible to have several such structures, representing multiple
00067    * compression/decompression processes, in existence at once.  We refer
00068    * to any one struct (and its associated working data) as a "JPEG object".
00069    */
00070   struct jpeg_compress_struct cinfo;
00071   /* This struct represents a JPEG error handler.  It is declared separately
00072    * because applications often want to supply a specialized error handler
00073    * (see the second half of this file for an example).  But here we just
00074    * take the easy way out and use the standard error handler, which will
00075    * print a message on stderr and call exit() if compression fails.
00076    * Note that this struct must live as long as the main JPEG parameter
00077    * struct, to avoid dangling-pointer problems.
00078    */
00079 
00080 // int i,j; // i,j - debug
00081   struct jpeg_error_mgr jerr;
00082   /* More stuff */
00083   FILE * outfile;               /* target file */
00084   JSAMPROW row_pointer[1];      /* pointer to JSAMPLE row[s] */
00085   struct pixel_buffers pb;
00086 
00087  // Contrast (0-5) - shift data left by Contrast bits (before shifting right by 2)
00088     if ((Contrast <0) || (Contrast >5 )) Contrast=0;
00089     
00090 
00091   /* Step -1: open dma data memory through 1-st filename */
00092 
00093  MD(fprintf(stderr,"\r\n"));
00094 
00095     if (initPixelBuffers(&pb, ifn,ImageWidth,ImageHeight,Contrast, Color, bayerOrient, Depth, pseudo) <0) return -1;
00096  MD(fprintf(stderr,"\r\n"));
00097 
00098 
00099   /* Step 1: allocate and initialize JPEG compression object */
00100 
00101   /* We have to set up the error handler first, in case the initialization
00102    * step fails.  (Unlikely, but it could happen if you are out of memory.)
00103    * This routine fills in the contents of struct jerr, and returns jerr's
00104    * address which we place into the link field in cinfo.
00105    */
00106   cinfo.err = jpeg_std_error(&jerr);
00107   /* Now we can initialize the JPEG compression object. */
00108   jpeg_create_compress(&cinfo);
00109 
00110   /* Step 2: specify data destination (eg, a file) */
00111   /* Note: steps 2 and 3 can be done in either order. */
00112 
00113   /* Here we use the library-supplied code to send compressed data to a
00114    * stdio stream.  You can also write your own code to do something else.
00115    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
00116    * requires it in order to write binary files.
00117    */
00118 
00119 
00120         if (ofn) {
00121           if ((outfile = fopen(ofn, "wb")) == NULL) {
00122             fprintf(stderr, "can't open %s\n", ofn);
00123             closePixelBuffers(&pb);
00124             exit(1);
00125           }
00126         } else {
00127           outfile=stdout;
00128  MD(fprintf(stderr, "Using stdout\r\n"));
00129 
00130         }
00131 
00132  MD(fprintf(stderr,"\r\n"));
00133 
00134 
00135         jpeg_stdio_dest(&cinfo, outfile);
00136  MD(fprintf(stderr,"\r\n"));
00137 
00138 
00139   /* Step 3: set parameters for compression */
00140 
00141   /* First we supply a description of the input image.
00142    * Four fields of the cinfo struct must be filled in:
00143    */
00144     if (getPalette (&pb)) Color=2;// pseudo color mode
00145 
00146     if (Color==2) { // pseudo color mode
00147           cinfo.image_width = ImageWidth;       /* image width and height, in pixels */
00148           cinfo.image_height = ImageHeight;
00149           cinfo.input_components = 3;           /* # of color components per pixel */
00150           cinfo.in_color_space = JCS_RGB;       /* colorspace of input image */
00151  MD(fprintf(stderr,"\r\n"));
00152 
00153         } else if (Color) {
00154           cinfo.image_width =  (ImageWidth>1)? ImageWidth-2 :0;         /* image width and height, in pixels */
00155           cinfo.image_height = (ImageHeight>1)?ImageHeight-2:0;
00156           cinfo.input_components = 3;           /* # of color components per pixel */
00157           cinfo.in_color_space = JCS_RGB;       /* colorspace of input image */
00158  MD(fprintf(stderr,"\r\n"));
00159 
00160         } else { // if (Color) 
00161           cinfo.image_width = ImageWidth;       /* image width and height, in pixels */
00162           cinfo.image_height = ImageHeight;
00163           cinfo.input_components = 1;           /* # of color components per pixel */
00164           cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
00165  MD(fprintf(stderr,"\r\n"));
00166 
00167         }
00168   /* Now use the library's routine to set default compression parameters.
00169    * (You must set at least cinfo.in_color_space before calling this,
00170    * since the defaults depend on the source color space.)
00171    */
00172 
00173   jpeg_set_defaults(&cinfo);
00174  MD(fprintf(stderr,"\r\n"));
00175 
00176   /* Now you can set any non-default parameters you wish to.
00177    * Here we just illustrate the use of quality (quantization table) scaling:
00178    */
00179 
00180   jpeg_set_quality(&cinfo, Quality, TRUE /* limit to baseline-JPEG values */);
00181 
00182  MD(fprintf(stderr,"\r\n"));
00183 
00184   /* Step 4: Start compressor */
00185 
00186   /* TRUE ensures that we will write a complete interchange-JPEG file.
00187    * Pass TRUE unless you are very sure of what you're doing.
00188    */
00189 
00190   jpeg_start_compress(&cinfo, TRUE);
00191 
00192   /* Step 5: while (scan lines remain to be written) */
00193   /*           jpeg_write_scanlines(...); */
00194 
00195   /* Here we use the library's state variable cinfo.next_scanline as the
00196    * loop counter, so that we don't have to keep track ourselves.
00197    * To keep things simple, we pass one scanline per call; you can pass
00198    * more if you wish, though.
00199    */
00200 //  row_stride = image_width * 3;       /* JSAMPLEs per row in image_buffer */
00201 
00202 
00203   while (cinfo.next_scanline < cinfo.image_height) {
00204     /* jpeg_write_scanlines expects an array of pointers to scanlines.
00205      * Here the array is only one element long, but you could pass
00206      * more than one scanline at a time if that's more convenient.
00207      */
00208 
00209     row_pointer[0] = (char *) getPixelRow(&pb, cinfo.next_scanline + ((Color==1)? 1:0) );
00210 
00211     D(printf ("%4d:",cinfo.next_scanline));
00212     D(for (i=0;i<20;i++) { j=row_pointer[0][i];printf (" %2x",j);});
00213     D(printf ("\r\n"));
00214 // MD(fprintf(stderr,"%d %x    ",cinfo.next_scanline, (int) row_pointer[0]));
00215     (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
00216   }
00217   /* Step 6: Finish compression */
00218  MD(fprintf(stderr,"\r\n"));
00219 
00220   jpeg_finish_compress(&cinfo);
00221   /* After finish_compress, we can close the output file. */
00222  MD(fprintf(stderr,"\r\n"));
00223   closePixelBuffers(&pb);
00224  MD(fprintf(stderr,"done\r\n"));
00225 
00226   /* Step 7: release JPEG compression object */
00227 
00228   /* This is an important step since it will release a good deal of memory. */
00229   jpeg_destroy_compress(&cinfo);
00230 
00231   /* And we're done! */
00232   return 0;
00233 }
00234 
00235 
00236 /*
00237  * SOME FINE POINTS:
00238  *
00239  * In the above loop, we ignored the return value of jpeg_write_scanlines,
00240  * which is the number of scanlines actually written.  We could get away
00241  * with this because we were only relying on the value of cinfo.next_scanline,
00242  * which will be incremented correctly.  If you maintain additional loop
00243  * variables then you should be careful to increment them properly.
00244  * Actually, for output to a stdio stream you needn't worry, because
00245  * then jpeg_write_scanlines will write all the lines passed (or else exit
00246  * with a fatal error).  Partial writes can only occur if you use a data
00247  * destination module that can demand suspension of the compressor.
00248  * (If you don't know what that's for, you don't need it.)
00249  *
00250  * If the compressor requires full-image buffers (for entropy-coding
00251  * optimization or a multi-scan JPEG file), it will create temporary
00252  * files for anything that doesn't fit within the maximum-memory setting.
00253  * (Note that temp files are NOT needed if you use the default parameters.)
00254  * On some systems you may need to set up a signal handler to ensure that
00255  * temporary files are deleted if the program is interrupted.  See libjpeg.doc.
00256  *
00257  * Scanlines MUST be supplied in top-to-bottom order if you want your JPEG
00258  * files to be compatible with everyone else's.  If you cannot readily read
00259  * your data in that order, you'll need an intermediate array to hold the
00260  * image.  See rdtarga.c or rdbmp.c for examples of handling bottom-to-top
00261  * source data using the JPEG code's internal virtual-array mechanisms.
00262  */
00263 
00264 
00265 

Generated on Thu Aug 7 16:18:59 2008 for elphel by  doxygen 1.5.1