Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
rdppm.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #include "cdjpeg.h"             
00022 
00023 #ifdef PPM_SUPPORTED
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 #ifdef HAVE_UNSIGNED_CHAR
00042 typedef unsigned char U_CHAR;
00043 #define UCH(x)  ((int) (x))
00044 #else 
00045 #ifdef CHAR_IS_UNSIGNED
00046 typedef char U_CHAR;
00047 #define UCH(x)  ((int) (x))
00048 #else
00049 typedef char U_CHAR;
00050 #define UCH(x)  ((int) (x) & 0xFF)
00051 #endif
00052 #endif 
00053 
00054 
00055 #define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 typedef struct {
00072   struct cjpeg_source_struct pub; 
00073 
00074   U_CHAR *iobuffer;             
00075   JSAMPROW pixrow;              
00076   size_t buffer_width;          
00077   JSAMPLE *rescale;             
00078 } ppm_source_struct;
00079 
00080 typedef ppm_source_struct * ppm_source_ptr;
00081 
00082 
00083 LOCAL(int)
00084 pbm_getc (FILE * infile)
00085 
00086 
00087 {
00088   register int ch;
00089 
00090   ch = getc(infile);
00091   if (ch == '#') {
00092     do {
00093       ch = getc(infile);
00094     } while (ch != '\n' && ch != EOF);
00095   }
00096   return ch;
00097 }
00098 
00099 
00100 LOCAL(unsigned int)
00101 read_pbm_integer (j_compress_ptr cinfo, FILE * infile)
00102 
00103 
00104 
00105 
00106 {
00107   register int ch;
00108   register unsigned int val;
00109 
00110   
00111   do {
00112     ch = pbm_getc(infile);
00113     if (ch == EOF)
00114       ERREXIT(cinfo, JERR_INPUT_EOF);
00115   } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
00116 
00117   if (ch < '0' || ch > '9')
00118     ERREXIT(cinfo, JERR_PPM_NONNUMERIC);
00119 
00120   val = ch - '0';
00121   while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') {
00122     val *= 10;
00123     val += ch - '0';
00124   }
00125   return val;
00126 }
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 
00139 
00140 METHODDEF(JDIMENSION)
00141 get_text_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00142 
00143 {
00144   ppm_source_ptr source = (ppm_source_ptr) sinfo;
00145   FILE * infile = source->pub.input_file;
00146   register JSAMPROW ptr;
00147   register JSAMPLE *rescale = source->rescale;
00148   JDIMENSION col;
00149 
00150   ptr = source->pub.buffer[0];
00151   for (col = cinfo->image_width; col > 0; col--) {
00152     *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00153   }
00154   return 1;
00155 }
00156 
00157 
00158 METHODDEF(JDIMENSION)
00159 get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00160 
00161 {
00162   ppm_source_ptr source = (ppm_source_ptr) sinfo;
00163   FILE * infile = source->pub.input_file;
00164   register JSAMPROW ptr;
00165   register JSAMPLE *rescale = source->rescale;
00166   JDIMENSION col;
00167 
00168   ptr = source->pub.buffer[0];
00169   for (col = cinfo->image_width; col > 0; col--) {
00170     *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00171     *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00172     *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00173   }
00174   return 1;
00175 }
00176 
00177 
00178 METHODDEF(JDIMENSION)
00179 get_scaled_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00180 
00181 {
00182   ppm_source_ptr source = (ppm_source_ptr) sinfo;
00183   register JSAMPROW ptr;
00184   register U_CHAR * bufferptr;
00185   register JSAMPLE *rescale = source->rescale;
00186   JDIMENSION col;
00187 
00188   if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00189     ERREXIT(cinfo, JERR_INPUT_EOF);
00190   ptr = source->pub.buffer[0];
00191   bufferptr = source->iobuffer;
00192   for (col = cinfo->image_width; col > 0; col--) {
00193     *ptr++ = rescale[UCH(*bufferptr++)];
00194   }
00195   return 1;
00196 }
00197 
00198 
00199 METHODDEF(JDIMENSION)
00200 get_scaled_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00201 
00202 {
00203   ppm_source_ptr source = (ppm_source_ptr) sinfo;
00204   register JSAMPROW ptr;
00205   register U_CHAR * bufferptr;
00206   register JSAMPLE *rescale = source->rescale;
00207   JDIMENSION col;
00208 
00209   if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00210     ERREXIT(cinfo, JERR_INPUT_EOF);
00211   ptr = source->pub.buffer[0];
00212   bufferptr = source->iobuffer;
00213   for (col = cinfo->image_width; col > 0; col--) {
00214     *ptr++ = rescale[UCH(*bufferptr++)];
00215     *ptr++ = rescale[UCH(*bufferptr++)];
00216     *ptr++ = rescale[UCH(*bufferptr++)];
00217   }
00218   return 1;
00219 }
00220 
00221 
00222 METHODDEF(JDIMENSION)
00223 get_raw_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00224 
00225 
00226 
00227 
00228 {
00229   ppm_source_ptr source = (ppm_source_ptr) sinfo;
00230 
00231   if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00232     ERREXIT(cinfo, JERR_INPUT_EOF);
00233   return 1;
00234 }
00235 
00236 
00237 METHODDEF(JDIMENSION)
00238 get_word_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00239 
00240 {
00241   ppm_source_ptr source = (ppm_source_ptr) sinfo;
00242   register JSAMPROW ptr;
00243   register U_CHAR * bufferptr;
00244   register JSAMPLE *rescale = source->rescale;
00245   JDIMENSION col;
00246 
00247   if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00248     ERREXIT(cinfo, JERR_INPUT_EOF);
00249   ptr = source->pub.buffer[0];
00250   bufferptr = source->iobuffer;
00251   for (col = cinfo->image_width; col > 0; col--) {
00252     register int temp;
00253     temp  = UCH(*bufferptr++);
00254     temp |= UCH(*bufferptr++) << 8;
00255     *ptr++ = rescale[temp];
00256   }
00257   return 1;
00258 }
00259 
00260 
00261 METHODDEF(JDIMENSION)
00262 get_word_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00263 
00264 {
00265   ppm_source_ptr source = (ppm_source_ptr) sinfo;
00266   register JSAMPROW ptr;
00267   register U_CHAR * bufferptr;
00268   register JSAMPLE *rescale = source->rescale;
00269   JDIMENSION col;
00270 
00271   if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00272     ERREXIT(cinfo, JERR_INPUT_EOF);
00273   ptr = source->pub.buffer[0];
00274   bufferptr = source->iobuffer;
00275   for (col = cinfo->image_width; col > 0; col--) {
00276     register int temp;
00277     temp  = UCH(*bufferptr++);
00278     temp |= UCH(*bufferptr++) << 8;
00279     *ptr++ = rescale[temp];
00280     temp  = UCH(*bufferptr++);
00281     temp |= UCH(*bufferptr++) << 8;
00282     *ptr++ = rescale[temp];
00283     temp  = UCH(*bufferptr++);
00284     temp |= UCH(*bufferptr++) << 8;
00285     *ptr++ = rescale[temp];
00286   }
00287   return 1;
00288 }
00289 
00290 
00291 
00292 
00293 
00294 
00295 METHODDEF(void)
00296 start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00297 {
00298   ppm_source_ptr source = (ppm_source_ptr) sinfo;
00299   int c;
00300   unsigned int w, h, maxval;
00301   boolean need_iobuffer, use_raw_buffer, need_rescale;
00302 
00303   if (getc(source->pub.input_file) != 'P')
00304     ERREXIT(cinfo, JERR_PPM_NOT);
00305 
00306   c = getc(source->pub.input_file); 
00307 
00308   
00309   switch (c) {
00310   case '2':                     
00311   case '3':                     
00312   case '5':                     
00313   case '6':                     
00314     break;
00315   default:
00316     ERREXIT(cinfo, JERR_PPM_NOT);
00317     break;
00318   }
00319 
00320   
00321   w = read_pbm_integer(cinfo, source->pub.input_file);
00322   h = read_pbm_integer(cinfo, source->pub.input_file);
00323   maxval = read_pbm_integer(cinfo, source->pub.input_file);
00324 
00325   if (w <= 0 || h <= 0 || maxval <= 0) 
00326     ERREXIT(cinfo, JERR_PPM_NOT);
00327 
00328   cinfo->data_precision = BITS_IN_JSAMPLE; 
00329   cinfo->image_width = (JDIMENSION) w;
00330   cinfo->image_height = (JDIMENSION) h;
00331 
00332   
00333   need_iobuffer = TRUE;         
00334   use_raw_buffer = FALSE;       
00335   need_rescale = TRUE;          
00336 
00337   switch (c) {
00338   case '2':                     
00339     cinfo->input_components = 1;
00340     cinfo->in_color_space = JCS_GRAYSCALE;
00341     TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h);
00342     source->pub.get_pixel_rows = get_text_gray_row;
00343     need_iobuffer = FALSE;
00344     break;
00345 
00346   case '3':                     
00347     cinfo->input_components = 3;
00348     cinfo->in_color_space = JCS_RGB;
00349     TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h);
00350     source->pub.get_pixel_rows = get_text_rgb_row;
00351     need_iobuffer = FALSE;
00352     break;
00353 
00354   case '5':                     
00355     cinfo->input_components = 1;
00356     cinfo->in_color_space = JCS_GRAYSCALE;
00357     TRACEMS2(cinfo, 1, JTRC_PGM, w, h);
00358     if (maxval > 255) {
00359       source->pub.get_pixel_rows = get_word_gray_row;
00360     } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) {
00361       source->pub.get_pixel_rows = get_raw_row;
00362       use_raw_buffer = TRUE;
00363       need_rescale = FALSE;
00364     } else {
00365       source->pub.get_pixel_rows = get_scaled_gray_row;
00366     }
00367     break;
00368 
00369   case '6':                     
00370     cinfo->input_components = 3;
00371     cinfo->in_color_space = JCS_RGB;
00372     TRACEMS2(cinfo, 1, JTRC_PPM, w, h);
00373     if (maxval > 255) {
00374       source->pub.get_pixel_rows = get_word_rgb_row;
00375     } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) {
00376       source->pub.get_pixel_rows = get_raw_row;
00377       use_raw_buffer = TRUE;
00378       need_rescale = FALSE;
00379     } else {
00380       source->pub.get_pixel_rows = get_scaled_rgb_row;
00381     }
00382     break;
00383   }
00384 
00385   
00386   if (need_iobuffer) {
00387     source->buffer_width = (size_t) w * cinfo->input_components *
00388       ((maxval<=255) ? SIZEOF(U_CHAR) : (2*SIZEOF(U_CHAR)));
00389     source->iobuffer = (U_CHAR *)
00390       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00391                                   source->buffer_width);
00392   }
00393 
00394   
00395   if (use_raw_buffer) {
00396     
00397     
00398     
00399     source->pixrow = (JSAMPROW) source->iobuffer;
00400     source->pub.buffer = & source->pixrow;
00401     source->pub.buffer_height = 1;
00402   } else {
00403     
00404     source->pub.buffer = (*cinfo->mem->alloc_sarray)
00405       ((j_common_ptr) cinfo, JPOOL_IMAGE,
00406        (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1);
00407     source->pub.buffer_height = 1;
00408   }
00409 
00410   
00411   if (need_rescale) {
00412     INT32 val, half_maxval;
00413 
00414     
00415     source->rescale = (JSAMPLE *)
00416       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00417                                   (size_t) (((long) maxval + 1L) * SIZEOF(JSAMPLE)));
00418     half_maxval = maxval / 2;
00419     for (val = 0; val <= (INT32) maxval; val++) {
00420       
00421       source->rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval);
00422     }
00423   }
00424 }
00425 
00426 
00427 
00428 
00429 
00430 
00431 METHODDEF(void)
00432 finish_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00433 {
00434   
00435 }
00436 
00437 
00438 
00439 
00440 
00441 
00442 GLOBAL(cjpeg_source_ptr)
00443 jinit_read_ppm (j_compress_ptr cinfo)
00444 {
00445   ppm_source_ptr source;
00446 
00447   
00448   source = (ppm_source_ptr)
00449       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00450                                   SIZEOF(ppm_source_struct));
00451   
00452   source->pub.start_input = start_input_ppm;
00453   source->pub.finish_input = finish_input_ppm;
00454 
00455   return (cjpeg_source_ptr) source;
00456 }
00457 
00458 #endif