Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
rdrle.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 
00022 #include "cdjpeg.h"             
00023 
00024 #ifdef RLE_SUPPORTED
00025 
00026 
00027 
00028 #include <rle.h>
00029 
00030 
00031 
00032 
00033 
00034 
00035 #if BITS_IN_JSAMPLE != 8
00036   Sorry, this code only copes with 8-bit JSAMPLEs. 
00037 #endif
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 typedef enum
00052   { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind;
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 typedef struct _rle_source_struct * rle_source_ptr;
00063 
00064 typedef struct _rle_source_struct {
00065   struct cjpeg_source_struct pub; 
00066 
00067   rle_kind visual;              
00068   jvirt_sarray_ptr image;       
00069   JDIMENSION row;               
00070   rle_hdr header;               
00071   rle_pixel** rle_row;          
00072 
00073 } rle_source_struct;
00074 
00075 
00076 
00077 
00078 
00079 
00080 METHODDEF(void)
00081 start_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00082 {
00083   rle_source_ptr source = (rle_source_ptr) sinfo;
00084   JDIMENSION width, height;
00085 #ifdef PROGRESS_REPORT
00086   cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
00087 #endif
00088 
00089   
00090   source->header = *rle_hdr_init(NULL);
00091   source->header.rle_file = source->pub.input_file;
00092   switch (rle_get_setup(&(source->header))) {
00093   case RLE_SUCCESS:
00094     
00095     break;
00096   case RLE_NOT_RLE:
00097     ERREXIT(cinfo, JERR_RLE_NOT);
00098     break;
00099   case RLE_NO_SPACE:
00100     ERREXIT(cinfo, JERR_RLE_MEM);
00101     break;
00102   case RLE_EMPTY:
00103     ERREXIT(cinfo, JERR_RLE_EMPTY);
00104     break;
00105   case RLE_EOF:
00106     ERREXIT(cinfo, JERR_RLE_EOF);
00107     break;
00108   default:
00109     ERREXIT(cinfo, JERR_RLE_BADERROR);
00110     break;
00111   }
00112 
00113   
00114   
00115   width  = source->header.xmax - source->header.xmin + 1;
00116   height = source->header.ymax - source->header.ymin + 1;
00117   source->header.xmin = 0;              
00118   source->header.xmax = width-1;
00119 
00120   cinfo->image_width      = width;
00121   cinfo->image_height     = height;
00122   cinfo->data_precision   = 8;  
00123 
00124   if (source->header.ncolors == 1 && source->header.ncmap == 0) {
00125     source->visual     = GRAYSCALE;
00126     TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height);
00127   } else if (source->header.ncolors == 1 && source->header.ncmap == 1) {
00128     source->visual     = MAPPEDGRAY;
00129     TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height,
00130              1 << source->header.cmaplen);
00131   } else if (source->header.ncolors == 1 && source->header.ncmap == 3) {
00132     source->visual     = PSEUDOCOLOR;
00133     TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height,
00134              1 << source->header.cmaplen);
00135   } else if (source->header.ncolors == 3 && source->header.ncmap == 3) {
00136     source->visual     = TRUECOLOR;
00137     TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height,
00138              1 << source->header.cmaplen);
00139   } else if (source->header.ncolors == 3 && source->header.ncmap == 0) {
00140     source->visual     = DIRECTCOLOR;
00141     TRACEMS2(cinfo, 1, JTRC_RLE, width, height);
00142   } else
00143     ERREXIT(cinfo, JERR_RLE_UNSUPPORTED);
00144   
00145   if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) {
00146     cinfo->in_color_space   = JCS_GRAYSCALE;
00147     cinfo->input_components = 1;
00148   } else {
00149     cinfo->in_color_space   = JCS_RGB;
00150     cinfo->input_components = 3;
00151   }
00152 
00153   
00154 
00155 
00156 
00157   if (source->visual != GRAYSCALE) {
00158     source->rle_row = (rle_pixel**) (*cinfo->mem->alloc_sarray)
00159       ((j_common_ptr) cinfo, JPOOL_IMAGE,
00160        (JDIMENSION) width, (JDIMENSION) cinfo->input_components);
00161   }
00162 
00163   
00164   source->image = (*cinfo->mem->request_virt_sarray)
00165     ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
00166      (JDIMENSION) (width * source->header.ncolors),
00167      (JDIMENSION) height, (JDIMENSION) 1);
00168 
00169 #ifdef PROGRESS_REPORT
00170   if (progress != NULL) {
00171     
00172     progress->total_extra_passes++;
00173   }
00174 #endif
00175 
00176   source->pub.buffer_height = 1;
00177 }
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 METHODDEF(JDIMENSION)
00187 get_rle_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00188 {
00189   rle_source_ptr source = (rle_source_ptr) sinfo;
00190 
00191   source->row--;
00192   source->pub.buffer = (*cinfo->mem->access_virt_sarray)
00193     ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE);
00194 
00195   return 1;
00196 }
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 METHODDEF(JDIMENSION)
00205 get_pseudocolor_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00206 {
00207   rle_source_ptr source = (rle_source_ptr) sinfo;
00208   JSAMPROW src_row, dest_row;
00209   JDIMENSION col;
00210   rle_map *colormap;
00211   int val;
00212 
00213   colormap = source->header.cmap;
00214   dest_row = source->pub.buffer[0];
00215   source->row--;
00216   src_row = * (*cinfo->mem->access_virt_sarray)
00217     ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE);
00218 
00219   for (col = cinfo->image_width; col > 0; col--) {
00220     val = GETJSAMPLE(*src_row++);
00221     *dest_row++ = (JSAMPLE) (colormap[val      ] >> 8);
00222     *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8);
00223     *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8);
00224   }
00225 
00226   return 1;
00227 }
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 METHODDEF(JDIMENSION)
00241 load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00242 {
00243   rle_source_ptr source = (rle_source_ptr) sinfo;
00244   JDIMENSION row, col;
00245   JSAMPROW  scanline, red_ptr, green_ptr, blue_ptr;
00246   rle_pixel **rle_row;
00247   rle_map *colormap;
00248   char channel;
00249 #ifdef PROGRESS_REPORT
00250   cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
00251 #endif
00252 
00253   colormap = source->header.cmap;
00254   rle_row = source->rle_row;
00255 
00256   
00257 
00258 
00259 
00260   RLE_CLR_BIT(source->header, RLE_ALPHA); 
00261 
00262 #ifdef PROGRESS_REPORT
00263   if (progress != NULL) {
00264     progress->pub.pass_limit = cinfo->image_height;
00265     progress->pub.pass_counter = 0;
00266     (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00267   }
00268 #endif
00269 
00270   switch (source->visual) {
00271 
00272   case GRAYSCALE:
00273   case PSEUDOCOLOR:
00274     for (row = 0; row < cinfo->image_height; row++) {
00275       rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray)
00276          ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
00277       rle_getrow(&source->header, rle_row);
00278 #ifdef PROGRESS_REPORT
00279       if (progress != NULL) {
00280         progress->pub.pass_counter++;
00281         (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00282       }
00283 #endif
00284     }
00285     break;
00286 
00287   case MAPPEDGRAY:
00288   case TRUECOLOR:
00289     for (row = 0; row < cinfo->image_height; row++) {
00290       scanline = * (*cinfo->mem->access_virt_sarray)
00291         ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
00292       rle_row = source->rle_row;
00293       rle_getrow(&source->header, rle_row);
00294 
00295       for (col = 0; col < cinfo->image_width; col++) {
00296         for (channel = 0; channel < source->header.ncolors; channel++) {
00297           *scanline++ = (JSAMPLE)
00298             (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8);
00299         }
00300       }
00301 
00302 #ifdef PROGRESS_REPORT
00303       if (progress != NULL) {
00304         progress->pub.pass_counter++;
00305         (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00306       }
00307 #endif
00308     }
00309     break;
00310 
00311   case DIRECTCOLOR:
00312     for (row = 0; row < cinfo->image_height; row++) {
00313       scanline = * (*cinfo->mem->access_virt_sarray)
00314         ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE);
00315       rle_getrow(&source->header, rle_row);
00316 
00317       red_ptr   = rle_row[0];
00318       green_ptr = rle_row[1];
00319       blue_ptr  = rle_row[2];
00320 
00321       for (col = cinfo->image_width; col > 0; col--) {
00322         *scanline++ = *red_ptr++;
00323         *scanline++ = *green_ptr++;
00324         *scanline++ = *blue_ptr++;
00325       }
00326 
00327 #ifdef PROGRESS_REPORT
00328       if (progress != NULL) {
00329         progress->pub.pass_counter++;
00330         (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00331       }
00332 #endif
00333     }
00334   }
00335 
00336 #ifdef PROGRESS_REPORT
00337   if (progress != NULL)
00338     progress->completed_extra_passes++;
00339 #endif
00340 
00341   
00342   if (source->visual == PSEUDOCOLOR) {
00343     source->pub.buffer = source->rle_row;
00344     source->pub.get_pixel_rows = get_pseudocolor_row;
00345   } else {
00346     source->pub.get_pixel_rows = get_rle_row;
00347   }
00348   source->row = cinfo->image_height;
00349 
00350   
00351   return (*source->pub.get_pixel_rows) (cinfo, sinfo);   
00352 }
00353 
00354 
00355 
00356 
00357 
00358 
00359 METHODDEF(void)
00360 finish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00361 {
00362   
00363 }
00364 
00365 
00366 
00367 
00368 
00369 
00370 GLOBAL(cjpeg_source_ptr)
00371 jinit_read_rle (j_compress_ptr cinfo)
00372 {
00373   rle_source_ptr source;
00374 
00375   
00376   source = (rle_source_ptr)
00377       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00378                                   SIZEOF(rle_source_struct));
00379   
00380   source->pub.start_input = start_input_rle;
00381   source->pub.finish_input = finish_input_rle;
00382   source->pub.get_pixel_rows = load_image;
00383 
00384   return (cjpeg_source_ptr) source;
00385 }
00386 
00387 #endif